Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
[cdt-patch] Scanner config discovery and PathEntries

This patch contains new core and UI elements required for integration of 
scanner config discovery feature and CPathEntry framework. Dave's initial 
work in this direction is included.

My contribution is primarily in UI domain:
- new DiscoveredPathContainerPage to manage discovered scanner 
configuration; replaces Paths and Symbols tab of project properties. The 
page is accessible from C/C++ Project Paths property page, Path Containers 
tab, select Discovered Paths container, than Edit....
- new DiscoveryOptionsBlock to manage project's discovery options. 
Replaces ScannerConfigDiscoveryOptions dialog. The page is actually in 
place of Paths and Symbols tab.

There is one small change to CPathEntry framework, namely CPElementSorter, 
to exclude include paths and symbol definitions from alphabetical sort.

Future work (known deficiencies): Remove stored discovered scanner 
configuration when the project is deleted.

Thanks,
Vmir

Index: plugin.xml
===================================================================
RCS file: /home/tools/org.eclipse.cdt-build/org.eclipse.cdt.make.core/plugin.xml,v
retrieving revision 1.18
diff -u -r1.18 plugin.xml
--- plugin.xml	18 May 2004 18:59:34 -0000	1.18
+++ plugin.xml	24 May 2004 21:58:31 -0000
@@ -151,5 +151,12 @@
          </run>
       </cextension>
    </extension>
+   <extension
+         point="org.eclipse.cdt.core.PathEntryContainerInitializer">
+      <pathEntryContainerInitializer
+            class="org.eclipse.cdt.make.internal.core.scannerconfig.DiscoverdPathInitializer"
+            id="org.eclipse.cdt.make.core.DISCOVERED_SCANNER_INFO">
+      </pathEntryContainerInitializer>
+   </extension>
 
 </plugin>
Index: src/org/eclipse/cdt/make/core/MakeCorePlugin.java
===================================================================
RCS file: /home/tools/org.eclipse.cdt-build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/MakeCorePlugin.java,v
retrieving revision 1.21
diff -u -r1.21 MakeCorePlugin.java
--- src/org/eclipse/cdt/make/core/MakeCorePlugin.java	18 May 2004 18:59:34 -0000	1.21
+++ src/org/eclipse/cdt/make/core/MakeCorePlugin.java	24 May 2004 21:58:31 -0000
@@ -18,6 +18,7 @@
 
 import org.eclipse.cdt.core.CCorePlugin;
 import org.eclipse.cdt.make.core.makefile.IMakefile;
+import org.eclipse.cdt.make.core.scannerconfig.IDiscoveredPathManager;
 import org.eclipse.cdt.make.core.scannerconfig.IExternalScannerInfoProvider;
 import org.eclipse.cdt.make.core.scannerconfig.IScannerConfigBuilderInfo;
 import org.eclipse.cdt.make.core.scannerconfig.IScannerInfoConsoleParser;
@@ -25,6 +26,7 @@
 import org.eclipse.cdt.make.internal.core.BuildInfoFactory;
 import org.eclipse.cdt.make.internal.core.MakeTargetManager;
 import org.eclipse.cdt.make.internal.core.makefile.gnu.GNUMakefile;
+import org.eclipse.cdt.make.internal.core.scannerconfig.DiscoveredPathManager;
 import org.eclipse.cdt.make.internal.core.scannerconfig.ScannerConfigInfoFactory;
 import org.eclipse.cdt.make.internal.core.scannerconfig.util.TraceUtil;
 import org.eclipse.core.resources.IFile;
@@ -49,7 +51,6 @@
 public class MakeCorePlugin extends Plugin {
 	public static final String PLUGIN_ID = "org.eclipse.cdt.make.core"; //$NON-NLS-1$
 	public static final String MAKE_PROJECT_ID = MakeCorePlugin.getUniqueIdentifier() + ".make"; //$NON-NLS-1$
-	private MakeTargetManager fTargetManager;
 	public static final String OLD_BUILDER_ID = "org.eclipse.cdt.core.cbuilder"; //$NON-NLS-1$
 
 	public static final String EXTERNAL_SI_PROVIDER_SIMPLE_ID = "ExternalScannerInfoProvider"; //$NON-NLS-1$
@@ -58,6 +59,8 @@
 	public static final String GCC_SPECS_CONSOLE_PARSER_ID = MakeCorePlugin.getUniqueIdentifier() + ".GCCSpecsConsoleParser"; //$NON-NLS-1$
 	public static final String GCC_SCANNER_INFO_CONSOLE_PARSER_ID = MakeCorePlugin.getUniqueIdentifier() + ".GCCScannerInfoConsoleParser"; //$NON-NLS-1$
 	
+	private MakeTargetManager fTargetManager;
+	private DiscoveredPathManager fDiscoveryPathManager;
 	//The shared instance.
 	private static MakeCorePlugin plugin;
 
@@ -206,6 +209,13 @@
 	
 	public static IPath getWorkingDirectory() {
 		return MakeCorePlugin.getDefault().getStateLocation();
+	}
+
+	public IDiscoveredPathManager getDiscoveryManager() {
+		if ( fDiscoveryPathManager == null) {
+			fDiscoveryPathManager = new DiscoveredPathManager();
+		}
+		return fDiscoveryPathManager;
 	}
 
 	/**
Index: src/org/eclipse/cdt/make/core/MakeScannerInfo.java
===================================================================
RCS file: /home/tools/org.eclipse.cdt-build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/MakeScannerInfo.java,v
retrieving revision 1.5
diff -u -r1.5 MakeScannerInfo.java
--- src/org/eclipse/cdt/make/core/MakeScannerInfo.java	15 Apr 2004 19:02:00 -0000	1.5
+++ src/org/eclipse/cdt/make/core/MakeScannerInfo.java	24 May 2004 21:58:31 -0000
@@ -20,6 +20,12 @@
 import org.eclipse.core.resources.IProject;
 import org.eclipse.core.runtime.CoreException;
 
+/**
+ * @deprecated
+ * @author DInglis
+ *
+ */
+
 public class MakeScannerInfo implements IScannerInfo {
 
 	private IProject project;
Index: src/org/eclipse/cdt/make/core/MakeScannerProvider.java
===================================================================
RCS file: /home/tools/org.eclipse.cdt-build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/MakeScannerProvider.java,v
retrieving revision 1.8
diff -u -r1.8 MakeScannerProvider.java
--- src/org/eclipse/cdt/make/core/MakeScannerProvider.java	15 Apr 2004 19:02:00 -0000	1.8
+++ src/org/eclipse/cdt/make/core/MakeScannerProvider.java	24 May 2004 21:58:32 -0000
@@ -7,38 +7,45 @@
  * 
  * Contributors: 
  * QNX Software Systems - Initial API and implementation
-***********************************************************************/
+ ***********************************************************************/
 package org.eclipse.cdt.make.core;
 
 import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.HashMap;
+import java.util.Iterator;
 import java.util.List;
-import java.util.ListIterator;
 import java.util.Map;
+import java.util.Map.Entry;
 
-import org.eclipse.cdt.core.AbstractCExtension;
 import org.eclipse.cdt.core.CCorePlugin;
 import org.eclipse.cdt.core.ICDescriptor;
+import org.eclipse.cdt.core.model.CoreModel;
+import org.eclipse.cdt.core.model.ICProject;
+import org.eclipse.cdt.core.model.IIncludeEntry;
+import org.eclipse.cdt.core.model.IMacroEntry;
+import org.eclipse.cdt.core.model.IPathEntry;
 import org.eclipse.cdt.core.parser.IScannerInfo;
-import org.eclipse.cdt.core.parser.IScannerInfoChangeListener;
-import org.eclipse.cdt.core.parser.IScannerInfoProvider;
-import org.eclipse.core.resources.IFile;
+import org.eclipse.cdt.core.resources.ScannerProvider;
 import org.eclipse.core.resources.IProject;
 import org.eclipse.core.resources.IResource;
 import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.Path;
 import org.eclipse.core.runtime.QualifiedName;
-import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 import org.w3c.dom.Node;
 
-public class MakeScannerProvider extends AbstractCExtension implements IScannerInfoProvider {
+/**
+ * @deprecated @author DInglis
+ *  
+ */
+public class MakeScannerProvider extends ScannerProvider {
 
 	// This is the id of the IScannerInfoProvider extension point entry
 	public static final String INTERFACE_IDENTITY = MakeCorePlugin.getUniqueIdentifier() + ".MakeScannerProvider"; //$NON-NLS-1$
 
 	// Name we will use to store build property with the project
-	private static final QualifiedName scannerInfoProperty = new QualifiedName(MakeCorePlugin.getUniqueIdentifier(), "makeBuildInfo"); //$NON-NLS-1$
+	private static final QualifiedName scannerInfoProperty = new QualifiedName(MakeCorePlugin.getUniqueIdentifier(),
+			"makeBuildInfo"); //$NON-NLS-1$
 	private static final String CDESCRIPTOR_ID = MakeCorePlugin.getUniqueIdentifier() + ".makeScannerInfo"; //$NON-NLS-1$
 
 	public static final String INCLUDE_PATH = "includePath"; //$NON-NLS-1$
@@ -46,9 +53,6 @@
 	public static final String DEFINED_SYMBOL = "definedSymbol"; //$NON-NLS-1$
 	public static final String SYMBOL = "symbol"; //$NON-NLS-1$
 
-	// Listeners interested in build model changes
-	private static Map listeners;
-
 	private static MakeScannerProvider defaultProvider;
 
 	public static MakeScannerProvider getDefault() {
@@ -67,6 +71,8 @@
 		// Try to load one for the project
 		if (scannerInfo == null) {
 			scannerInfo = loadScannerInfo(project);
+		} else {
+			return scannerInfo;
 		}
 
 		// There is nothing persisted for the session, or saved in a file so
@@ -74,34 +80,15 @@
 		if (scannerInfo != null && cacheInfo == true) {
 			project.setSessionProperty(scannerInfoProperty, scannerInfo);
 		}
-		return scannerInfo;
-	}
 
-	/*
-	 * @return
-	 */
-	private synchronized static Map getListeners() {
-		if (listeners == null) {
-			listeners = new HashMap();
-		}
-		return listeners;
-	}
-
-	/**
-	 * @param project
-	 * @param info
-	 */
-	private static void notifyInfoListeners(IProject project, IScannerInfo info) {
-		// Call in the cavalry
-		List listeners = (List)getListeners().get(project);
-		if (listeners == null) {
-			return;
-		}
-		ListIterator iter = listeners.listIterator();
-		while (iter.hasNext()) {
-			((IScannerInfoChangeListener)iter.next()).changeNotification(project, info);
+		// migrate to new C Path Entries
+		if (scannerInfo != null) {
+			updateScannerInfo(scannerInfo);
 		}
-
+		ICDescriptor descriptor = CCorePlugin.getDefault().getCProjectDescription(project);
+		descriptor.remove(CCorePlugin.BUILD_SCANNER_INFO_UNIQ_ID); // remove scanner provider which will fallback to default cpath
+		// provider.
+		return scannerInfo;
 	}
 
 	/*
@@ -110,20 +97,18 @@
 	 * @see org.eclipse.cdt.core.parser.IScannerInfoProvider#getScannerInformation(org.eclipse.core.resources.IResource)
 	 */
 	public IScannerInfo getScannerInformation(IResource resource) {
-		IScannerInfo info = null;
 		try {
-			info = getMakeScannerInfo(resource.getProject(), true);
+			getMakeScannerInfo(resource.getProject(), true);
 		} catch (CoreException e) {
 		}
-		return info;
+		return super.getScannerInformation(resource);
 	}
 
 	/*
-	 * Loads the build file and parses the nodes for build information. The
-	 * information is then associated with the resource for the duration of the
-	 * session.
+	 * Loads the build file and parses the nodes for build information. The information is then associated with the resource for the
+	 * duration of the session.
 	 */
-	public MakeScannerInfo loadScannerInfo(IProject project) throws CoreException {
+	private MakeScannerInfo loadScannerInfo(IProject project) throws CoreException {
 		ICDescriptor descriptor = CCorePlugin.getDefault().getCProjectDescription(project);
 		Node child = descriptor.getProjectData(CDESCRIPTOR_ID).getFirstChild();
 		ArrayList includes = new ArrayList();
@@ -131,10 +116,10 @@
 		while (child != null) {
 			if (child.getNodeName().equals(INCLUDE_PATH)) {
 				// Add the path to the property list
-				includes.add(((Element)child).getAttribute(PATH));
+				includes.add( ((Element)child).getAttribute(PATH));
 			} else if (child.getNodeName().equals(DEFINED_SYMBOL)) {
 				// Add the symbol to the symbol list
-				symbols.add(((Element)child).getAttribute(SYMBOL));
+				symbols.add( ((Element)child).getAttribute(SYMBOL));
 			}
 			child = child.getNextSibling();
 		}
@@ -144,13 +129,36 @@
 		return info;
 	}
 
+	private static void migrateToCPathEntries(MakeScannerInfo info) throws CoreException {
+		Map symbols = info.getDefinedSymbols();
+		String[] includes = info.getIncludePaths();
+		ICProject cProject = CoreModel.getDefault().create(info.getProject());
+		IPathEntry[] entries = cProject.getRawPathEntries();
+		List cPaths = new ArrayList(Arrays.asList(entries));
+
+		for (int i = 0; i < includes.length; i++) {
+			IIncludeEntry include = CoreModel.newIncludeEntry(info.getProject().getFullPath(), null, new Path(includes[i]));
+			if (!cPaths.contains(include)) {
+				cPaths.add(include);
+			}
+		}
+		Iterator syms = symbols.entrySet().iterator();
+		while (syms.hasNext()) {
+			Map.Entry entry = (Entry)syms.next();
+			IMacroEntry sym = CoreModel.newMacroEntry(info.getProject().getFullPath(), (String)entry.getKey(),
+					(String)entry.getValue());
+			if (!cPaths.contains(sym)) {
+				cPaths.add(sym);
+			}
+		}
+		cProject.setRawPathEntries((IPathEntry[])cPaths.toArray(new IPathEntry[cPaths.size()]), null);
+	}
+
 	/**
-	 * The build model manager for standard builds only caches the build
-	 * information for a resource on a per-session basis. This method allows
-	 * clients of the build model manager to programmatically remove the
-	 * association between the resource and the information while the reource
-	 * is still open or in the workspace. The Eclipse core will take care of
-	 * removing it if a resource is closed or deleted.
+	 * The build model manager for standard builds only caches the build information for a resource on a per-session basis. This
+	 * method allows clients of the build model manager to programmatically remove the association between the resource and the
+	 * information while the reource is still open or in the workspace. The Eclipse core will take care of removing it if a resource
+	 * is closed or deleted.
 	 * 
 	 * @param resource
 	 */
@@ -162,22 +170,14 @@
 	}
 
 	/**
-	 * Persists build-specific information in the build file. Build information
-	 * for standard make projects consists of preprocessor symbols and includes
-	 * paths. Other project-related information is stored in the persistent
-	 * properties of the project.
+	 * Persists build-specific information in the build file. Build information for standard make projects consists of preprocessor
+	 * symbols and includes paths. Other project-related information is stored in the persistent properties of the project.
 	 * 
 	 * @param project
 	 */
 	public static void updateScannerInfo(MakeScannerInfo scannerInfo) throws CoreException {
 		IProject project = scannerInfo.getProject();
 
-		// See if there's already one associated with the resource for this
-		// session
-		if (project.getSessionProperty(scannerInfoProperty) != null) {
-			project.setSessionProperty(scannerInfoProperty, scannerInfo);
-		}
-
 		ICDescriptor descriptor = CCorePlugin.getDefault().getCProjectDescription(project);
 
 		Element rootElement = descriptor.getProjectData(CDESCRIPTOR_ID);
@@ -190,79 +190,7 @@
 			child = rootElement.getFirstChild();
 		}
 
-		// Save the build info
-		if (scannerInfo != null) {
-			// Serialize the include paths
-			Document doc = rootElement.getOwnerDocument();
-			ListIterator iter = Arrays.asList(scannerInfo.getIncludePaths()).listIterator();
-			while (iter.hasNext()) {
-				Element pathElement = doc.createElement(INCLUDE_PATH);
-				pathElement.setAttribute(PATH, (String)iter.next());
-				rootElement.appendChild(pathElement);
-			}
-			// Now do the same for the symbols
-			iter = Arrays.asList(scannerInfo.getPreprocessorSymbols()).listIterator();
-			while (iter.hasNext()) {
-				Element symbolElement = doc.createElement(DEFINED_SYMBOL);
-				symbolElement.setAttribute(SYMBOL, (String)iter.next());
-				rootElement.appendChild(symbolElement);
-			}
-			descriptor.saveProjectData();
-		}
-		notifyInfoListeners(project, scannerInfo);
-	}
-
-	/*
-	 * (non-Javadoc)
-	 * 
-	 * @see org.eclipse.cdt.core.parser.IScannerInfoProvider#subscribe(org.eclipse.core.resources.IResource,
-	 *      org.eclipse.cdt.core.parser.IScannerInfoChangeListener)
-	 */
-	public synchronized void subscribe(IResource resource, IScannerInfoChangeListener listener) {
-		IResource project = null;
-		if (resource instanceof IProject) {
-			project = resource;
-		} else if (resource instanceof IFile) {
-			project = ((IFile)resource).getProject();
-		} else {
-			return;
-		}
-		// Get listeners for this resource
-		Map map = getListeners();
-		List list = (List)map.get(project);
-		if (list == null) {
-			// Create a new list
-			list = new ArrayList();
-		}
-		if (!list.contains(listener)) {
-			// Add the new listener for the resource
-			list.add(listener);
-			map.put(project, list);
-		}
-	}
-
-	/*
-	 * (non-Javadoc)
-	 * 
-	 * @see org.eclipse.cdt.core.parser.IScannerInfoProvider#unsubscribe(org.eclipse.core.resources.IResource,
-	 *      org.eclipse.cdt.core.parser.IScannerInfoChangeListener)
-	 */
-	public synchronized void unsubscribe(IResource resource, IScannerInfoChangeListener listener) {
-		IResource project = null;
-		if (resource instanceof IProject) {
-			project = resource;
-		} else if (resource instanceof IFile) {
-			project = ((IFile)resource).getProject();
-		} else {
-			return;
-		}
-		// Remove the listener
-		Map map = getListeners();
-		List list = (List)map.get(project);
-		if (list != null && !list.isEmpty()) {
-			// The list is not empty so try to remove listener
-			list.remove(listener);
-			map.put(project, list);
-		}
+		descriptor.saveProjectData();
+		migrateToCPathEntries(scannerInfo);
 	}
-}
+}
\ No newline at end of file
Index: src/org/eclipse/cdt/make/core/scannerconfig/DiscoveredScannerInfo.java
===================================================================
RCS file: /home/tools/org.eclipse.cdt-build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/scannerconfig/DiscoveredScannerInfo.java,v
retrieving revision 1.1
diff -u -r1.1 DiscoveredScannerInfo.java
--- src/org/eclipse/cdt/make/core/scannerconfig/DiscoveredScannerInfo.java	15 Apr 2004 19:02:00 -0000	1.1
+++ src/org/eclipse/cdt/make/core/scannerconfig/DiscoveredScannerInfo.java	24 May 2004 21:58:32 -0000
@@ -17,14 +17,13 @@
 import java.util.Map;
 
 import org.eclipse.cdt.core.parser.IScannerInfo;
-import org.eclipse.cdt.make.core.MakeScannerInfo;
 import org.eclipse.cdt.make.internal.core.scannerconfig.util.ScannerConfigUtil;
 import org.eclipse.core.resources.IProject;
 import org.eclipse.core.runtime.CoreException;
 
 /**
  * Discovered portion of scanner configuration
- * 
+ * @deprecated
  * @author vhirsl
  */
 public class DiscoveredScannerInfo implements IScannerInfo {
@@ -38,7 +37,7 @@
 	private ArrayList activeSymbols;
 	private ArrayList removedSymbols;
 
-	private MakeScannerInfo userInfo;
+	private  org.eclipse.cdt.make.core.MakeScannerInfo userInfo;
 	
 	/**
 	 * @param project
@@ -69,10 +68,11 @@
 		return iPaths;
 	}
 
-	public MakeScannerInfo getUserScannerInfo() {
+	public  org.eclipse.cdt.make.core.MakeScannerInfo getUserScannerInfo() {
 		return userInfo;
 	}
-	public synchronized void setUserScannerInfo(MakeScannerInfo info) {
+
+	public synchronized void setUserScannerInfo( org.eclipse.cdt.make.core.MakeScannerInfo info) {
 		userInfo = info;
 	}
 	
Index: src/org/eclipse/cdt/make/core/scannerconfig/DiscoveredScannerInfoProvider.java
===================================================================
RCS file: /home/tools/org.eclipse.cdt-build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/scannerconfig/DiscoveredScannerInfoProvider.java,v
retrieving revision 1.3
diff -u -r1.3 DiscoveredScannerInfoProvider.java
--- src/org/eclipse/cdt/make/core/scannerconfig/DiscoveredScannerInfoProvider.java	5 May 2004 02:46:50 -0000	1.3
+++ src/org/eclipse/cdt/make/core/scannerconfig/DiscoveredScannerInfoProvider.java	24 May 2004 21:58:32 -0000
@@ -10,72 +10,39 @@
  **********************************************************************/
 package org.eclipse.cdt.make.core.scannerconfig;
 
-import java.io.ByteArrayOutputStream;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.util.Iterator;
-import java.util.LinkedHashMap;
-import java.util.Map;
-
-import javax.xml.parsers.DocumentBuilder;
-import javax.xml.parsers.DocumentBuilderFactory;
-import javax.xml.parsers.FactoryConfigurationError;
-import javax.xml.parsers.ParserConfigurationException;
-import javax.xml.transform.OutputKeys;
-import javax.xml.transform.Transformer;
-import javax.xml.transform.TransformerConfigurationException;
-import javax.xml.transform.TransformerException;
-import javax.xml.transform.TransformerFactory;
-import javax.xml.transform.TransformerFactoryConfigurationError;
-import javax.xml.transform.dom.DOMSource;
-import javax.xml.transform.stream.StreamResult;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
 
-import org.eclipse.cdt.core.AbstractCExtension;
 import org.eclipse.cdt.core.CCorePlugin;
 import org.eclipse.cdt.core.ICDescriptor;
+import org.eclipse.cdt.core.model.CoreModel;
+import org.eclipse.cdt.core.model.ICProject;
+import org.eclipse.cdt.core.model.IContainerEntry;
+import org.eclipse.cdt.core.model.IPathEntry;
 import org.eclipse.cdt.core.parser.IScannerInfo;
 import org.eclipse.cdt.core.parser.IScannerInfoChangeListener;
-import org.eclipse.cdt.core.parser.IScannerInfoProvider;
+import org.eclipse.cdt.core.resources.ScannerProvider;
 import org.eclipse.cdt.make.core.MakeCorePlugin;
-import org.eclipse.cdt.make.core.MakeScannerInfo;
-import org.eclipse.cdt.make.core.MakeScannerProvider;
-import org.eclipse.cdt.make.internal.core.MakeMessages;
-import org.eclipse.cdt.make.internal.core.scannerconfig.util.ScannerConfigUtil;
-import org.eclipse.cdt.make.internal.core.scannerconfig.util.SymbolEntry;
+import org.eclipse.cdt.make.internal.core.scannerconfig.DiscoveredPathContainer;
 import org.eclipse.core.resources.IProject;
 import org.eclipse.core.resources.IResource;
 import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IPath;
-import org.eclipse.core.runtime.IStatus;
 import org.eclipse.core.runtime.QualifiedName;
-import org.eclipse.core.runtime.Status;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-import org.w3c.dom.Node;
-import org.xml.sax.SAXException;
 
 /**
  * Provider of both user specified and discovered scanner info
  * 
- * @author vhirsl
+ * @deprecated @author vhirsl
  */
-public class DiscoveredScannerInfoProvider extends AbstractCExtension implements IScannerInfoProvider {
-	
+public class DiscoveredScannerInfoProvider extends ScannerProvider {
+
 	// This is the id of the IScannerInfoProvider extension point entry
 	public static final String INTERFACE_IDENTITY = MakeCorePlugin.getUniqueIdentifier() + ".DiscoveredScannerInfoProvider"; //$NON-NLS-1$
 
 	// Name we will use to store build property with the project
-	private static final QualifiedName scannerInfoProperty = new QualifiedName(MakeCorePlugin.getUniqueIdentifier(), "discoveredMakeBuildInfo"); //$NON-NLS-1$
-	private static final String CDESCRIPTOR_ID = MakeCorePlugin.getUniqueIdentifier() + ".discoveredScannerInfo"; //$NON-NLS-1$
-
-	public static final String INCLUDE_PATH = "includePath"; //$NON-NLS-1$
-	public static final String PATH = "path"; //$NON-NLS-1$
-	public static final String DEFINED_SYMBOL = "definedSymbol"; //$NON-NLS-1$
-	public static final String SYMBOL = "symbol"; //$NON-NLS-1$
-	public static final String REMOVED = "removed"; //$NON-NLS-1$
-	
-	private static final String ROOT_ELEM_NAME = "DiscoveredScannerInfo";	//$NON-NLS-1$
+	private static final QualifiedName scannerInfoProperty = new QualifiedName(MakeCorePlugin.getUniqueIdentifier(),
+			"discoveredMakeBuildInfo"); //$NON-NLS-1$
 
 	// Singleton
 	private static DiscoveredScannerInfoProvider instance;
@@ -85,31 +52,38 @@
 		}
 		return instance;
 	}
-	
-	/* (non-Javadoc)
+
+	/*
+	 * (non-Javadoc)
+	 * 
 	 * @see org.eclipse.cdt.core.parser.IScannerInfoProvider#getScannerInformation(org.eclipse.core.resources.IResource)
 	 */
 	public IScannerInfo getScannerInformation(IResource resource) {
-		IScannerInfo info = null;
 		try {
-			info = getDiscoveredScannerInfo(resource.getProject(), true);
+			getDiscoveredScannerInfo(resource.getProject(), true);
 		} catch (CoreException e) {
 		}
-		return info;
+		return super.getScannerInformation(resource);
 	}
-	
-	/* (non-Javadoc)
-	 * @see org.eclipse.cdt.core.parser.IScannerInfoProvider#subscribe(org.eclipse.core.resources.IResource, org.eclipse.cdt.core.parser.IScannerInfoChangeListener)
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.cdt.core.parser.IScannerInfoProvider#subscribe(org.eclipse.core.resources.IResource,
+	 *      org.eclipse.cdt.core.parser.IScannerInfoChangeListener)
 	 */
 	public void subscribe(IResource resource, IScannerInfoChangeListener listener) {
-		MakeScannerProvider.getDefault().subscribe(resource, listener);
+		super.subscribe(resource, listener);
 	}
-	
-	/* (non-Javadoc)
-	 * @see org.eclipse.cdt.core.parser.IScannerInfoProvider#unsubscribe(org.eclipse.core.resources.IResource, org.eclipse.cdt.core.parser.IScannerInfoChangeListener)
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see org.eclipse.cdt.core.parser.IScannerInfoProvider#unsubscribe(org.eclipse.core.resources.IResource,
+	 *      org.eclipse.cdt.core.parser.IScannerInfoChangeListener)
 	 */
 	public void unsubscribe(IResource resource, IScannerInfoChangeListener listener) {
-		MakeScannerProvider.getDefault().unsubscribe(resource, listener);
+		super.unsubscribe(resource, listener);
 	}
 
 	public DiscoveredScannerInfo getDiscoveredScannerInfo(IProject project, boolean cacheInfo) throws CoreException {
@@ -118,86 +92,39 @@
 		// session
 		scannerInfo = (DiscoveredScannerInfo)project.getSessionProperty(scannerInfoProperty);
 
-		// Try to load one for the project
+		// this will convert user info
+		org.eclipse.cdt.make.core.MakeScannerInfo makeScannerInfo = org.eclipse.cdt.make.core.MakeScannerProvider.getDefault().getMakeScannerInfo(
+				project, cacheInfo);
+
 		if (scannerInfo == null) {
-			scannerInfo = loadScannerInfo(project);
-		}
-		else {
-			// TODO VMIR temporary
-			// get the separately stored MakeScannerInfo in case someone accessed it
-			// not through DiscoveredScannerInfoProvider
-			MakeScannerInfo makeScannerInfo = MakeScannerProvider.getDefault().getMakeScannerInfo(project, cacheInfo);
+			scannerInfo = new DiscoveredScannerInfo(project);
 			scannerInfo.setUserScannerInfo(makeScannerInfo);
-		}		
-
-		// There is nothing persisted for the session, or saved in a file so
-		// create a build info object
-		if (scannerInfo != null && cacheInfo == true) {
+			
+			// migrate to new C Path Entries
+			IContainerEntry container = CoreModel.newContainerEntry(DiscoveredPathContainer.CONTAINER_ID);
+			ICProject cProject = CoreModel.getDefault().create(project);
+			if (cProject != null) {
+				IPathEntry[] entries = cProject.getRawPathEntries();
+				List newEntries = new ArrayList(Arrays.asList(entries));
+				if (!newEntries.contains(container)) {
+					newEntries.add(container);
+					cProject.setRawPathEntries((IPathEntry[])newEntries.toArray(new IPathEntry[newEntries.size()]), null);
+				}
+			}
+			ICDescriptor descriptor = CCorePlugin.getDefault().getCProjectDescription(project);
+			descriptor.remove(CCorePlugin.BUILD_SCANNER_INFO_UNIQ_ID); // remove scanner provider which will fallback to default
+																	   // cpath provider.
+			// place holder to that we don't convert again.
 			project.setSessionProperty(scannerInfoProperty, scannerInfo);
 		}
 		return scannerInfo;
 	}
 
-	/*
-	 * Loads the build file and parses the nodes for build information. The
-	 * information is then associated with the resource for the duration of the
-	 * session.
-	 */
-	private DiscoveredScannerInfo loadScannerInfo(IProject project) throws CoreException {
-		LinkedHashMap includes = new LinkedHashMap();
-		LinkedHashMap symbols = new LinkedHashMap();
-//		loadDiscoveredScannerInfoFromCDescriptor(project, includes, symbols);
-		loadDiscoveredScannerInfoFromState(project, includes, symbols);
-		MakeScannerInfo userInfo = MakeScannerProvider.getDefault().loadScannerInfo(project);
-		DiscoveredScannerInfo info = new DiscoveredScannerInfo(project);
-		info.setUserScannerInfo(userInfo);
-		info.setDiscoveredIncludePaths(includes);
-		info.setDiscoveredSymbolDefinitions(symbols);
-		return info;
-	}
-
 	/**
-	 * Loads discovered scanner configuration from .cdtproject file
-	 * @param project
-	 * @param includes
-	 * @param symbols
-	 * @throws CoreException
-	 */
-	private void loadDiscoveredScannerInfoFromCDescriptor(IProject project, LinkedHashMap includes, LinkedHashMap symbols) throws CoreException {
-		ICDescriptor descriptor = CCorePlugin.getDefault().getCProjectDescription(project);
-		Node child = descriptor.getProjectData(CDESCRIPTOR_ID).getFirstChild();
-		loadDiscoveredScannerInfo(includes, symbols, child);
-	}
-
-	/**
-	 * @param includes
-	 * @param symbols
-	 * @param child
-	 */
-	private void loadDiscoveredScannerInfo(LinkedHashMap includes, LinkedHashMap symbols, Node child) {
-		while (child != null) {
-			if (child.getNodeName().equals(INCLUDE_PATH)) {
-				// Add the path to the property list
-				includes.put(((Element)child).getAttribute(PATH), 
-							 Boolean.valueOf(((Element)child).getAttribute(REMOVED)));
-			} else if (child.getNodeName().equals(DEFINED_SYMBOL)) {
-				// Add the symbol to the symbol list
-				String symbol = ((Element)child).getAttribute(SYMBOL);
-				String removed = ((Element)child).getAttribute(REMOVED);
-				boolean bRemoved = (removed != null && removed.equals("true"));	//$NON-NLS-1$
-				ScannerConfigUtil.scAddSymbolString2SymbolEntryMap(symbols, symbol, !bRemoved);
-			}
-			child = child.getNextSibling();
-		}
-	}
-
-	/**
-	 * The build model manager for standard builds only caches the build
-	 * information for a resource on a per-session basis. This method allows
-	 * clients of the build model manager to programmatically remove the
-	 * association between the resource and the information while the reource
-	 * is still open or in the workspace. The Eclipse core will take care of
-	 * removing it if a resource is closed or deleted.
+	 * The build model manager for standard builds only caches the build information for a resource on a per-session basis. This
+	 * method allows clients of the build model manager to programmatically remove the association between the resource and the
+	 * information while the reource is still open or in the workspace. The Eclipse core will take care of removing it if a resource
+	 * is closed or deleted.
 	 * 
 	 * @param resource
 	 */
@@ -209,179 +136,12 @@
 	}
 
 	/**
-	 * Persists build-specific information in the build file. Build information
-	 * for standard make projects consists of preprocessor symbols and includes
-	 * paths. Other project-related information is stored in the persistent
-	 * properties of the project.
+	 * Persists build-specific information in the build file. Build information for standard make projects consists of preprocessor
+	 * symbols and includes paths. Other project-related information is stored in the persistent properties of the project.
 	 * 
 	 * @param scannerInfo
 	 */
 	static void updateScannerInfo(DiscoveredScannerInfo scannerInfo) throws CoreException {
-		IProject project = scannerInfo.getProject();
-
-		// See if there's already one associated with the resource for this
-		// session
-		if (project.getSessionProperty(scannerInfoProperty) != null) {
-			project.setSessionProperty(scannerInfoProperty, scannerInfo);
-		}
-
-//		saveDiscoveredScannerInfoToCDescriptor(scannerInfo, project);
-		saveDiscoveredScannerInfoToState(scannerInfo, project);
-		
-		MakeScannerProvider.updateScannerInfo(scannerInfo.getUserScannerInfo());
-// listeners are notified by MakeScannerProvider.updateScannerInfo
-//		notifyInfoListeners(project, scannerInfo);
-	}
-
-	/**
-	 * Save discovered scanner configuration to .cdtproject file
-	 * @param scannerInfo
-	 * @param project
-	 * @throws CoreException
-	 */
-	private static void saveDiscoveredScannerInfoToCDescriptor(DiscoveredScannerInfo scannerInfo, IProject project) throws CoreException {
-		ICDescriptor descriptor = CCorePlugin.getDefault().getCProjectDescription(project);
-
-		Element rootElement = descriptor.getProjectData(CDESCRIPTOR_ID);
-
-		// Clear out all current children
-		// Note: Probably would be a better idea to merge in the data
-		Node child = rootElement.getFirstChild();
-		while (child != null) {
-			rootElement.removeChild(child);
-			child = rootElement.getFirstChild();
-		}
-		Document doc = rootElement.getOwnerDocument();
-
-		saveDiscoveredScannerInfo(scannerInfo, rootElement, doc);
-	}
-
-	/**
-	 * @param scannerInfo
-	 * @param rootElement
-	 * @param doc
-	 */
-	private static void saveDiscoveredScannerInfo(DiscoveredScannerInfo scannerInfo, Element rootElement, Document doc) {
-		// Save the build info
-		if (scannerInfo != null) {
-			// Serialize the include paths
-			Map discoveredIncludes = scannerInfo.getDiscoveredIncludePaths();
-			Iterator iter = discoveredIncludes.keySet().iterator();
-			while (iter.hasNext()) {
-				Element pathElement = doc.createElement(INCLUDE_PATH);
-				String include = (String) iter.next();
-				pathElement.setAttribute(PATH, include);
-				Boolean removed = (Boolean) discoveredIncludes.get(include);
-				if (removed != null && removed.booleanValue() == true) {
-					pathElement.setAttribute(REMOVED, "true");	//$NON-NLS-1$
-				} 
-				rootElement.appendChild(pathElement);
-			}
-			// Now do the same for the symbols
-			Map discoveredSymbols = scannerInfo.getDiscoveredSymbolDefinitions();
-			iter = discoveredSymbols.keySet().iterator();
-			while (iter.hasNext()) {
-				String symbol = (String) iter.next();
-				SymbolEntry se = (SymbolEntry) discoveredSymbols.get(symbol);
-				for (Iterator i = se.getActiveRaw().iterator(); i.hasNext(); ) {
-					String value = (String) i.next();
-					Element symbolElement = doc.createElement(DEFINED_SYMBOL);
-					symbolElement.setAttribute(SYMBOL, value);
-					rootElement.appendChild(symbolElement);
-				}
-				for (Iterator i = se.getRemovedRaw().iterator(); i.hasNext(); ) {
-					String value = (String) i.next();
-					Element symbolElement = doc.createElement(DEFINED_SYMBOL);
-					symbolElement.setAttribute(SYMBOL, value);
-					symbolElement.setAttribute(REMOVED, "true");	//$NON-NLS-1$
-					rootElement.appendChild(symbolElement);
-				}
-			}
-// descriptor is saved by MakeScannerProvider.updateScannerInfo
-//			descriptor.saveProjectData();
-		}
-	}
-
-	private void loadDiscoveredScannerInfoFromState(IProject project, LinkedHashMap includes, LinkedHashMap symbols) throws CoreException {
-		// Save the document
-		IPath path = MakeCorePlugin.getWorkingDirectory();
-		path = path.append(project.getName() + ".sc"); //$NON-NLS-1$
-		if (path.toFile().exists()) {
-			try {
-				FileInputStream file = new FileInputStream(path.toFile());
-				DocumentBuilder parser = DocumentBuilderFactory.newInstance().newDocumentBuilder();
-				Document document = parser.parse(file);
-				Node rootElement = document.getFirstChild();
-				if (rootElement.getNodeName().equals("scannerInfo")) { //$NON-NLS-1$
-					Node child = rootElement.getFirstChild();
-					loadDiscoveredScannerInfo(includes, symbols, child);
-				}
-			} catch (IOException e) {
-				throw new CoreException(new Status(IStatus.ERROR,
-						MakeCorePlugin.getUniqueIdentifier(), -1,
-						MakeMessages.getString("GCCScannerConfigUtil.Error_Message"), e));	//$NON-NLS-1$
-			} catch (ParserConfigurationException e) {
-				MakeCorePlugin.log(e);
-			} catch (FactoryConfigurationError e) {
-				MakeCorePlugin.log(e);
-			} catch (SAXException e) {
-				MakeCorePlugin.log(e);
-			}
-		}
-	}
-	
-	private static void saveDiscoveredScannerInfoToState(DiscoveredScannerInfo scannerInfo, IProject project) throws CoreException {
-		// Create document
-		try {
-			DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
-			Document doc = builder.newDocument();
-			Element rootElement = doc.createElement("scannerInfo"); //$NON-NLS-1$
-			rootElement.setAttribute("id", CDESCRIPTOR_ID); //$NON-NLS-1$
-			doc.appendChild(rootElement);
-
-			saveDiscoveredScannerInfo(scannerInfo, rootElement, doc);
-		
-			// Transform the document to something we can save in a file
-			ByteArrayOutputStream stream = new ByteArrayOutputStream();
-			Transformer transformer = TransformerFactory.newInstance().newTransformer();
-			transformer.setOutputProperty(OutputKeys.METHOD, "xml");	//$NON-NLS-1$
-			transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");	//$NON-NLS-1$
-			transformer.setOutputProperty(OutputKeys.INDENT, "yes");	//$NON-NLS-1$
-			DOMSource source = new DOMSource(doc);
-			StreamResult result = new StreamResult(stream);
-			transformer.transform(source, result);
-			
-			// Save the document
-			IPath path = MakeCorePlugin.getWorkingDirectory();
-			path = path.append(project.getName() + ".sc"); //$NON-NLS-1$
-			try {
-				FileOutputStream file = new FileOutputStream(path.toFile());
-				file.write(stream.toByteArray());
-				file.close();
-			} catch (IOException e) {
-				throw new CoreException(new Status(IStatus.ERROR,
-						MakeCorePlugin.getUniqueIdentifier(), -1,
-						MakeMessages.getString("GCCScannerConfigUtil.Error_Message"), e));	//$NON-NLS-1$
-			}
-			
-			// Close the streams
-			stream.close();
-		} catch (ParserConfigurationException e) {
-			MakeCorePlugin.log(e);
-		} catch (FactoryConfigurationError e) {
-			MakeCorePlugin.log(e);
-		} catch (TransformerConfigurationException e) {
-			MakeCorePlugin.log(e);
-		} catch (TransformerFactoryConfigurationError e) {
-			MakeCorePlugin.log(e);
-		} catch (TransformerException e) {
-			MakeCorePlugin.log(e);
-		} catch (IOException e) {
-			MakeCorePlugin.log(e);
-		} catch (CoreException e) {
-			// Save to IFile failed
-			MakeCorePlugin.log(e.getStatus());
-		}
-		
+		//		 no longer supported!
 	}
-}
+}
\ No newline at end of file
Index: src/org/eclipse/cdt/make/core/scannerconfig/ScannerConfigNature.java
===================================================================
RCS file: /home/tools/org.eclipse.cdt-build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/scannerconfig/ScannerConfigNature.java,v
retrieving revision 1.2
diff -u -r1.2 ScannerConfigNature.java
--- src/org/eclipse/cdt/make/core/scannerconfig/ScannerConfigNature.java	15 Apr 2004 19:02:00 -0000	1.2
+++ src/org/eclipse/cdt/make/core/scannerconfig/ScannerConfigNature.java	24 May 2004 21:58:32 -0000
@@ -10,15 +10,12 @@
  **********************************************************************/
 package org.eclipse.cdt.make.core.scannerconfig;
 
-import org.eclipse.cdt.core.CCorePlugin;
-import org.eclipse.cdt.core.ICDescriptor;
 import org.eclipse.cdt.make.core.MakeCorePlugin;
-import org.eclipse.cdt.make.core.MakeScannerProvider;
-import org.eclipse.core.runtime.CoreException;
 import org.eclipse.core.resources.ICommand;
 import org.eclipse.core.resources.IProject;
 import org.eclipse.core.resources.IProjectDescription;
 import org.eclipse.core.resources.IProjectNature;
+import org.eclipse.core.runtime.CoreException;
 
 /**
  * @see IProjectNature
@@ -93,8 +90,6 @@
 		description.setNatureIds(newIds);
 		project.setDescription(description, null);
 		
-		// set DiscoveredScannerInfoProvider as a default one for the project
-		updateProjectsScannerInfoProvider(project, true);
 	}
 	
 	public static void removeScannerConfigNature(IProject project) throws CoreException {
@@ -112,8 +107,6 @@
 			}
 		}
 
-		// fall back to MakeScannerProvider
-		updateProjectsScannerInfoProvider(project, false);
 	}
 
 	/**
@@ -135,19 +128,4 @@
 		return null;
 	}
 
-	/**
-	 * @param project
-	 * @param b
-	 */
-	private static void updateProjectsScannerInfoProvider(IProject project, boolean discovered) {
-		try {
-			ICDescriptor desc = CCorePlugin.getDefault().getCProjectDescription(project);
-			desc.remove(CCorePlugin.BUILD_SCANNER_INFO_UNIQ_ID);
-			desc.create(CCorePlugin.BUILD_SCANNER_INFO_UNIQ_ID, (discovered)?
-					DiscoveredScannerInfoProvider.INTERFACE_IDENTITY:
-					MakeScannerProvider.INTERFACE_IDENTITY);
-		} catch (CoreException e) {
-			MakeCorePlugin.log(e.getStatus());
-		}
-	}
 }
Index: src/org/eclipse/cdt/make/internal/core/MakeMessages.properties
===================================================================
RCS file: /home/tools/org.eclipse.cdt-build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/MakeMessages.properties,v
retrieving revision 1.1
diff -u -r1.1 MakeMessages.properties
--- src/org/eclipse/cdt/make/internal/core/MakeMessages.properties	5 May 2004 02:46:50 -0000	1.1
+++ src/org/eclipse/cdt/make/internal/core/MakeMessages.properties	24 May 2004 21:58:32 -0000
@@ -30,3 +30,5 @@
 ScannerInfoCollector.Updating=Updating Scanner Configuration for project 
 
 GCCScannerConfigUtil.Error_Message=Error creating specs file
+
+DiscoveredContainer.description=Discovered Paths
\ No newline at end of file
Index: src/org/eclipse/cdt/make/internal/core/MakeProject.java
===================================================================
RCS file: /home/tools/org.eclipse.cdt-build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/MakeProject.java,v
retrieving revision 1.9
diff -u -r1.9 MakeProject.java
--- src/org/eclipse/cdt/make/internal/core/MakeProject.java	15 Apr 2004 19:02:00 -0000	1.9
+++ src/org/eclipse/cdt/make/internal/core/MakeProject.java	24 May 2004 21:58:32 -0000
@@ -15,7 +15,6 @@
 import org.eclipse.cdt.core.ICDescriptor;
 import org.eclipse.cdt.core.ICOwner;
 import org.eclipse.cdt.make.core.MakeCorePlugin;
-import org.eclipse.cdt.make.core.scannerconfig.DiscoveredScannerInfoProvider;
 import org.eclipse.core.runtime.CoreException;
 import org.eclipse.core.runtime.Preferences;
 
@@ -24,14 +23,10 @@
 	public void configure(ICDescriptor cDescriptor) throws CoreException {
 		cDescriptor.remove(CCorePlugin.BUILD_SCANNER_INFO_UNIQ_ID);
 		cDescriptor.remove(CCorePlugin.BUILDER_MODEL_ID);
-		cDescriptor.create(CCorePlugin.BUILD_SCANNER_INFO_UNIQ_ID, DiscoveredScannerInfoProvider.INTERFACE_IDENTITY);
 		updateBinaryParsers(cDescriptor);
 	}
 
 	public void update(ICDescriptor cDescriptor, String extensionID) throws CoreException {
-		if (extensionID.equals(CCorePlugin.BUILD_SCANNER_INFO_UNIQ_ID)) {
-			cDescriptor.create(CCorePlugin.BUILD_SCANNER_INFO_UNIQ_ID, DiscoveredScannerInfoProvider.INTERFACE_IDENTITY);
-		}
 		if (extensionID.equals(CCorePlugin.BINARY_PARSER_UNIQ_ID)) {
 			updateBinaryParsers(cDescriptor);
 		}
Index: src/org/eclipse/cdt/make/internal/core/scannerconfig/ScannerInfoCollector.java
===================================================================
RCS file: /home/tools/org.eclipse.cdt-build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/ScannerInfoCollector.java,v
retrieving revision 1.10
diff -u -r1.10 ScannerInfoCollector.java
--- src/org/eclipse/cdt/make/internal/core/scannerconfig/ScannerInfoCollector.java	18 May 2004 18:59:34 -0000	1.10
+++ src/org/eclipse/cdt/make/internal/core/scannerconfig/ScannerInfoCollector.java	24 May 2004 21:58:33 -0000
@@ -18,10 +18,18 @@
 import java.util.Map;
 
 import org.eclipse.cdt.core.CCProjectNature;
-import org.eclipse.cdt.core.CCorePlugin;
 import org.eclipse.cdt.core.CProjectNature;
-import org.eclipse.cdt.core.parser.IScannerInfo;
-import org.eclipse.cdt.core.parser.IScannerInfoProvider;
+import org.eclipse.cdt.make.core.MakeCorePlugin;
+import org.eclipse.cdt.make.core.MakeProjectNature;
+import org.eclipse.cdt.make.core.scannerconfig.IExternalScannerInfoProvider;
+import org.eclipse.cdt.make.core.scannerconfig.IScannerConfigBuilderInfo;
+import org.eclipse.cdt.make.core.scannerconfig.IScannerInfoCollector;
+import org.eclipse.cdt.make.core.scannerconfig.ScannerConfigBuilder;
+import org.eclipse.cdt.make.core.scannerconfig.IDiscoveredPathManager.IDiscoveredPathInfo;
+import org.eclipse.cdt.make.internal.core.MakeMessages;
+import org.eclipse.cdt.make.internal.core.scannerconfig.util.CygpathTranslator;
+import org.eclipse.cdt.make.internal.core.scannerconfig.util.ScannerConfigUtil;
+import org.eclipse.cdt.make.internal.core.scannerconfig.util.TraceUtil;
 import org.eclipse.core.resources.IProject;
 import org.eclipse.core.resources.IResource;
 import org.eclipse.core.runtime.CoreException;
@@ -31,18 +39,6 @@
 import org.eclipse.core.runtime.Path;
 import org.eclipse.core.runtime.Platform;
 import org.eclipse.core.runtime.SubProgressMonitor;
-import org.eclipse.cdt.make.core.MakeProjectNature;
-
-import org.eclipse.cdt.make.core.MakeCorePlugin;
-import org.eclipse.cdt.make.core.scannerconfig.DiscoveredScannerInfo;
-import org.eclipse.cdt.make.core.scannerconfig.IScannerConfigBuilderInfo;
-import org.eclipse.cdt.make.core.scannerconfig.IExternalScannerInfoProvider;
-import org.eclipse.cdt.make.core.scannerconfig.IScannerInfoCollector;
-import org.eclipse.cdt.make.core.scannerconfig.ScannerConfigBuilder;
-import org.eclipse.cdt.make.internal.core.MakeMessages;
-import org.eclipse.cdt.make.internal.core.scannerconfig.util.CygpathTranslator;
-import org.eclipse.cdt.make.internal.core.scannerconfig.util.ScannerConfigUtil;
-import org.eclipse.cdt.make.internal.core.scannerconfig.util.TraceUtil;
 
 
 /**
@@ -152,27 +148,21 @@
 	 * @param project
 	 * @param monitor
 	 */
-	private void updateScannerConfig(IProject project, IProgressMonitor monitor) {
-		IScannerInfoProvider provider = CCorePlugin.getDefault().getScannerInfoProvider(project);
+	private void updateScannerConfig(IProject project, IProgressMonitor monitor) throws CoreException {
+		IDiscoveredPathInfo pathInfo = MakeCorePlugin.getDefault().getDiscoveryManager().getDiscoveredInfo(project);
 		monitor.beginTask(MakeMessages.getString("ScannerInfoCollector.Processing"), 100); //$NON-NLS-1$
-		if (provider != null) {
-			IScannerInfo scanInfo = provider.getScannerInformation(project);
-			if (scanInfo != null) {
-				if (scanInfo instanceof DiscoveredScannerInfo) {
-					DiscoveredScannerInfo discScanInfo = (DiscoveredScannerInfo)scanInfo;
-					String projectName = project.getName();
-					monitor.subTask(MakeMessages.getString("ScannerInfoCollector.Processing")); //$NON-NLS-1$
-					if (scannerConfigNeedsUpdate(discScanInfo, projectName)) {
-						monitor.worked(50);
-						monitor.subTask(MakeMessages.getString("ScannerInfoCollector.Updating") + projectName); //$NON-NLS-1$
-						try {
-							// update scanner configuration
-							discScanInfo.update();
-							monitor.worked(50);
-						} catch (CoreException e) {
-							MakeCorePlugin.log(e);
-						}
-					}
+		if (pathInfo != null) {
+			String projectName = project.getName();
+			monitor.subTask(MakeMessages.getString("ScannerInfoCollector.Processing")); //$NON-NLS-1$
+			if (scannerConfigNeedsUpdate(pathInfo)) {
+				monitor.worked(50);
+				monitor.subTask(MakeMessages.getString("ScannerInfoCollector.Updating") + projectName); //$NON-NLS-1$
+				try {
+					// update scanner configuration
+					MakeCorePlugin.getDefault().getDiscoveryManager().updateDiscoveredInfo(pathInfo);
+					monitor.worked(50);
+				} catch (CoreException e) {
+					MakeCorePlugin.log(e);
 				}
 			}
 		}
@@ -186,12 +176,12 @@
 	 * @param projectName
 	 * @return
 	 */
-	private boolean scannerConfigNeedsUpdate(DiscoveredScannerInfo discScanInfo, String projectName) {
-		List includes = (List) discoveredIncludes.get(projectName);
-		List symbols = (List) discoveredSymbols.get(projectName);
+	private boolean scannerConfigNeedsUpdate(IDiscoveredPathInfo discPathInfo) {
+		List includes = (List) discoveredIncludes.get(discPathInfo.getProject().getName());
+		List symbols = (List) discoveredSymbols.get(discPathInfo.getProject().getName());
 		
-		boolean addedIncludes = includePathsNeedUpdate(discScanInfo, projectName, includes);
-		boolean addedSymbols = definedSymbolsNeedUpdate(discScanInfo, projectName, symbols);
+		boolean addedIncludes = includePathsNeedUpdate(discPathInfo, includes);
+		boolean addedSymbols = definedSymbolsNeedUpdate(discPathInfo, symbols);
 		
 		return (addedIncludes | addedSymbols);
 	}
@@ -199,13 +189,14 @@
 	/**
 	 * Compare include paths with already discovered.
 	 * 
-	 * @param discScanInfo
+	 * @param discPathInfo
 	 * @param projectName
 	 * @param includes
 	 * @return
 	 */
-	private boolean includePathsNeedUpdate(DiscoveredScannerInfo discScanInfo, String projectName, List includes) {
+	private boolean includePathsNeedUpdate(IDiscoveredPathInfo discPathInfo, List includes) {
 		boolean addedIncludes = false;
+		String projectName = discPathInfo.getProject().getName();
 		if (includes != null) {
 			// Step 1. Add discovered scanner config to the existing discovered scanner config 
 			// add the includes from the latest discovery
@@ -222,7 +213,7 @@
 			List finalSumIncludes = translateIncludePaths(sumIncludes);
 			
 			// Step 2. Get project's scanner config
-			LinkedHashMap persistedIncludes = discScanInfo.getDiscoveredIncludePaths();
+			LinkedHashMap persistedIncludes = discPathInfo.getIncludeMap();
 	
 			// Step 3. Merge scanner config from steps 1 and 2
 			// order is important, use list to preserve it
@@ -248,7 +239,7 @@
 			}
 			
 			// Step 4. Set resulting scanner config
-			discScanInfo.setDiscoveredIncludePaths(newPersistedIncludes);
+			discPathInfo.setIncludeMap(newPersistedIncludes);
 			
 			// Step 5. Invalidate discovered include paths
 			discoveredIncludes.put(projectName, null);
@@ -259,13 +250,14 @@
 	/**
 	 * Compare symbol definitions with already discovered.
 	 * 
-	 * @param discScanInfo
+	 * @param discPathInfo
 	 * @param projectName
 	 * @param symbols
 	 * @return
 	 */
-	private boolean definedSymbolsNeedUpdate(DiscoveredScannerInfo discScanInfo, String projectName, List symbols) {
+	private boolean definedSymbolsNeedUpdate(IDiscoveredPathInfo discPathInfo, List symbols) {
 		boolean addedSymbols = false;
+		String projectName = discPathInfo.getProject().getName();
 		if (symbols != null) {
 			// Step 1. Add discovered scanner config to the existing discovered scanner config 
 			// add the symbols from the latest discovery
@@ -277,14 +269,14 @@
 			addedSymbols = ScannerConfigUtil.scAddSymbolsList2SymbolEntryMap(sumSymbols, symbols, false);
 			
 			// Step 2. Get project's scanner config
-			LinkedHashMap persistedSymbols = discScanInfo.getDiscoveredSymbolDefinitions();
+			LinkedHashMap persistedSymbols = discPathInfo.getSymbolMap();
 			
 			// Step 3. Merge scanner config from steps 1 and 2
 			LinkedHashMap candidateSymbols = new LinkedHashMap(persistedSymbols);
 			addedSymbols |= ScannerConfigUtil.scAddSymbolEntryMap2SymbolEntryMap(candidateSymbols, sumSymbols);
 			
 			// Step 4. Set resulting scanner config
-			discScanInfo.setDiscoveredSymbolDefinitions(candidateSymbols);
+			discPathInfo.setSymbolMap(candidateSymbols);
 			
 			// Step 5. Invalidate discovered symbol definitions
 			discoveredSymbols.put(projectName, null);
@@ -376,7 +368,7 @@
 	 * @param project
 	 * @param monitor
 	 */
-	public synchronized void updateScannerConfiguration(IProject project, IProgressMonitor monitor) {
+	public synchronized void updateScannerConfiguration(IProject project, IProgressMonitor monitor) throws CoreException {
 		currentProject = project;
 		String projectName = project.getName();
 		// check TSO for the project
Index: src/org/eclipse/cdt/make/internal/core/scannerconfig/util/ScannerConfigUtil.java
===================================================================
RCS file: /home/tools/org.eclipse.cdt-build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/util/ScannerConfigUtil.java,v
retrieving revision 1.5
diff -u -r1.5 ScannerConfigUtil.java
--- src/org/eclipse/cdt/make/internal/core/scannerconfig/util/ScannerConfigUtil.java	7 May 2004 20:44:28 -0000	1.5
+++ src/org/eclipse/cdt/make/internal/core/scannerconfig/util/ScannerConfigUtil.java	24 May 2004 21:58:33 -0000
@@ -19,6 +19,8 @@
 import java.util.Map;
 import java.util.Set;
 
+import org.eclipse.core.runtime.IPath;
+
 /**
  * Utility class that handles some Scanner Config specifig collection conversions
  * 
@@ -269,5 +271,19 @@
 			}
 		}
 		return (String[]) allTokens.toArray(new String[allTokens.size()]);
+	}
+
+	/**
+	 * Converts array of IPath-s to array of String-s
+	 * 
+	 * @param paths
+	 * @return
+	 */
+	public static String[] iPathArray2StringArray(IPath[] paths) {
+		String[] rv = new String[paths.length];
+		for (int i = 0; i < paths.length; ++i) {
+			rv[i] = paths[i].toString(); 
+		}
+		return rv;
 	}
 }
Index: src/org/eclipse/cdt/make/core/scannerconfig/IDiscoveredPathManager.java
===================================================================
RCS file: src/org/eclipse/cdt/make/core/scannerconfig/IDiscoveredPathManager.java
diff -N src/org/eclipse/cdt/make/core/scannerconfig/IDiscoveredPathManager.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ src/org/eclipse/cdt/make/core/scannerconfig/IDiscoveredPathManager.java	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,46 @@
+/*******************************************************************************
+ * 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.make.core.scannerconfig;
+
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+
+public interface IDiscoveredPathManager {
+
+	interface IDiscoveredPathInfo {
+
+		IProject getProject();
+
+		IPath[] getIncludePaths();
+		Map 	getSymbols();
+		
+		void setIncludeMap(LinkedHashMap map);
+		void setSymbolMap(LinkedHashMap map);
+
+		LinkedHashMap getIncludeMap();
+		LinkedHashMap getSymbolMap();
+	}
+
+	interface IDiscoveredInfoListener {
+
+		void infoChanged(IDiscoveredPathInfo info);
+		void infoRemoved(IProject project);
+	}
+
+	IDiscoveredPathInfo getDiscoveredInfo(IProject project) throws CoreException;
+	void removeDiscoveredInfo(IProject project);
+	void updateDiscoveredInfo(IDiscoveredPathInfo info) throws CoreException;
+
+	void addDiscoveredInfoListener(IDiscoveredInfoListener listener);
+	void removeDiscoveredInfoListener(IDiscoveredInfoListener listener);
+}
Index: src/org/eclipse/cdt/make/internal/core/scannerconfig/DiscoverdPathInitializer.java
===================================================================
RCS file: src/org/eclipse/cdt/make/internal/core/scannerconfig/DiscoverdPathInitializer.java
diff -N src/org/eclipse/cdt/make/internal/core/scannerconfig/DiscoverdPathInitializer.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ src/org/eclipse/cdt/make/internal/core/scannerconfig/DiscoverdPathInitializer.java	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,24 @@
+/*******************************************************************************
+ * 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.make.internal.core.scannerconfig;
+
+import org.eclipse.cdt.core.model.CoreModel;
+import org.eclipse.cdt.core.model.ICProject;
+import org.eclipse.cdt.core.model.PathEntryContainerInitializer;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+
+
+public class DiscoverdPathInitializer extends PathEntryContainerInitializer {
+
+	public void initialize(IPath containerPath, ICProject project) throws CoreException {
+		CoreModel.getDefault().setPathEntryContainer(new ICProject[]{project}, new DiscoveredPathContainer(project.getProject()), null);
+	}
+
+}
Index: src/org/eclipse/cdt/make/internal/core/scannerconfig/DiscoveredPathContainer.java
===================================================================
RCS file: src/org/eclipse/cdt/make/internal/core/scannerconfig/DiscoveredPathContainer.java
diff -N src/org/eclipse/cdt/make/internal/core/scannerconfig/DiscoveredPathContainer.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ src/org/eclipse/cdt/make/internal/core/scannerconfig/DiscoveredPathContainer.java	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,99 @@
+/*******************************************************************************
+ * 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.make.internal.core.scannerconfig;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import org.eclipse.cdt.core.model.CoreModel;
+import org.eclipse.cdt.core.model.IPathEntry;
+import org.eclipse.cdt.core.model.IPathEntryContainer;
+import org.eclipse.cdt.make.core.MakeCorePlugin;
+import org.eclipse.cdt.make.core.scannerconfig.IDiscoveredPathManager.IDiscoveredInfoListener;
+import org.eclipse.cdt.make.core.scannerconfig.IDiscoveredPathManager.IDiscoveredPathInfo;
+import org.eclipse.cdt.make.internal.core.MakeMessages;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.Path;
+
+public class DiscoveredPathContainer implements IPathEntryContainer {
+
+	public static IPath CONTAINER_ID = new Path("org.eclipse.cdt.make.core.DISCOVERED_SCANNER_INFO"); //$NON-NLS-1$
+
+	private final IProject fProject;
+	private static Map fgPathEntries;
+
+	public DiscoveredPathContainer(IProject project) {
+		fProject = project;
+	}
+
+	public static IPathEntry[] getPathEntries(IProject project) throws CoreException {
+		if (fgPathEntries == null) {
+			fgPathEntries = new HashMap(10);
+			IDiscoveredInfoListener listener = new IDiscoveredInfoListener() {
+
+				public void infoRemoved(IProject project) {
+					fgPathEntries.remove(project);
+				}
+
+				public void infoChanged(IDiscoveredPathInfo info) {
+					fgPathEntries.remove(info.getProject());
+				}
+			};
+			MakeCorePlugin.getDefault().getDiscoveryManager().addDiscoveredInfoListener(listener);
+		}
+		IPathEntry[] entries = (IPathEntry[])fgPathEntries.get(project);
+		if (entries == null) {
+			entries = computeNewPathEntries(project);
+			fgPathEntries.put(project, entries);
+		}
+		return entries;
+	}
+
+	private static IPathEntry[] computeNewPathEntries(IProject project) throws CoreException {
+		IDiscoveredPathInfo info = MakeCorePlugin.getDefault().getDiscoveryManager().getDiscoveredInfo(project);
+		IPath[] includes = info.getIncludePaths();
+		Map syms = info.getSymbols();
+		List entries = new ArrayList(includes.length + syms.size());
+		for (int i = 0; i < includes.length; i++) {
+			entries.add(CoreModel.newIncludeEntry(Path.EMPTY, Path.EMPTY, includes[i])); //$NON-NLS-1$ //$NON-NLS-2$
+		}
+		Iterator iter = syms.entrySet().iterator();
+		while (iter.hasNext()) {
+			Entry entry = (Entry)iter.next();
+			entries.add(CoreModel.newMacroEntry(Path.EMPTY, (String)entry.getKey(), (String)entry.getValue())); //$NON-NLS-1$
+		}
+		return (IPathEntry[])entries.toArray(new IPathEntry[entries.size()]);
+	}
+
+	public IPathEntry[] getPathEntries() {
+		IPathEntry[] fPathEntries;
+		try {
+			fPathEntries = getPathEntries(fProject);
+		} catch (CoreException e) {
+			MakeCorePlugin.log(e);
+			return new IPathEntry[0];
+		}
+		return fPathEntries;
+	}
+
+	public String getDescription() {
+		return MakeMessages.getString("DiscoveredContainer.description"); //$NON-NLS-1$
+	}
+
+	public IPath getPath() {
+		return CONTAINER_ID;
+	}
+
+}
Index: src/org/eclipse/cdt/make/internal/core/scannerconfig/DiscoveredPathInfo.java
===================================================================
RCS file: src/org/eclipse/cdt/make/internal/core/scannerconfig/DiscoveredPathInfo.java
diff -N src/org/eclipse/cdt/make/internal/core/scannerconfig/DiscoveredPathInfo.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ src/org/eclipse/cdt/make/internal/core/scannerconfig/DiscoveredPathInfo.java	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,119 @@
+/*******************************************************************************
+ * 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.make.internal.core.scannerconfig;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.cdt.make.core.scannerconfig.IDiscoveredPathManager.IDiscoveredPathInfo;
+import org.eclipse.cdt.make.internal.core.scannerconfig.util.ScannerConfigUtil;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.Path;
+
+
+public class DiscoveredPathInfo implements IDiscoveredPathInfo {
+	final private IProject project;
+	private LinkedHashMap discoveredPaths;
+	private LinkedHashMap discoveredSymbols;
+
+	private List activePaths;
+	private Map activeSymbols;
+
+	public DiscoveredPathInfo(IProject project) {
+		this.project = project;
+	}
+
+	public IProject getProject() {
+		return project;
+	}
+
+	public synchronized Map getSymbols() {
+		if (activeSymbols == null) {
+			createSymbolsMap();
+		}
+		Map dSymbols = ScannerConfigUtil.scSymbolEntryMap2Map(discoveredSymbols);
+		return dSymbols;
+	}
+
+	public synchronized IPath[] getIncludePaths() {
+		if ( activePaths == null) {
+			createPathLists();
+		}
+		return (IPath[])activePaths.toArray(new IPath[activePaths.size()]);
+	}
+
+	public LinkedHashMap getIncludeMap() {
+		if (discoveredPaths == null) {
+			return new LinkedHashMap();
+		}
+		return new LinkedHashMap(discoveredPaths);
+	}
+
+	public synchronized void setIncludeMap(LinkedHashMap paths) {
+		discoveredPaths = new LinkedHashMap(paths);
+		activePaths = null;
+	}
+	
+	/**
+	 * Populates active and removed include path lists
+	 */
+	private void createPathLists() {
+		List aPaths = getActivePathList();
+		aPaths.clear();
+		
+		for (Iterator i = discoveredPaths.keySet().iterator(); i.hasNext(); ) {
+			String path = (String) i.next();
+			Boolean removed = (Boolean) discoveredPaths.get(path);
+			if (removed == null || removed.booleanValue() == false) {
+				aPaths.add(new Path(path));
+			}
+		}
+	}
+
+	public LinkedHashMap getSymbolMap() {
+		if (discoveredSymbols == null) {
+			return new LinkedHashMap();
+		}
+		return new LinkedHashMap(discoveredSymbols);
+	}
+	
+	public synchronized void setSymbolMap(LinkedHashMap symbols) {
+		discoveredSymbols = new LinkedHashMap(symbols);
+		activeSymbols = null;
+	}
+	
+	/**
+	 * Populates active symbols sets
+	 */
+	private void createSymbolsMap() {
+		Map aSymbols = getActiveSymbolsMap();
+		aSymbols.clear();
+		
+		aSymbols.putAll(ScannerConfigUtil.scSymbolEntryMap2Map(discoveredSymbols));
+	}
+
+	private List getActivePathList() {
+		if (activePaths == null) {
+			activePaths = new ArrayList();
+		}
+		return activePaths;
+	}
+
+	private Map getActiveSymbolsMap() {
+		if (activeSymbols == null) {
+			activeSymbols = new HashMap();
+		}
+		return activeSymbols;
+	}
+}
Index: src/org/eclipse/cdt/make/internal/core/scannerconfig/DiscoveredPathManager.java
===================================================================
RCS file: src/org/eclipse/cdt/make/internal/core/scannerconfig/DiscoveredPathManager.java
diff -N src/org/eclipse/cdt/make/internal/core/scannerconfig/DiscoveredPathManager.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ src/org/eclipse/cdt/make/internal/core/scannerconfig/DiscoveredPathManager.java	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,284 @@
+/*******************************************************************************
+ * 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.make.internal.core.scannerconfig;
+
+import java.io.ByteArrayOutputStream;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Vector;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.OutputKeys;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+
+import org.eclipse.cdt.core.CCorePlugin;
+import org.eclipse.cdt.make.core.MakeCorePlugin;
+import org.eclipse.cdt.make.core.scannerconfig.IDiscoveredPathManager;
+import org.eclipse.cdt.make.internal.core.MakeMessages;
+import org.eclipse.cdt.make.internal.core.scannerconfig.util.ScannerConfigUtil;
+import org.eclipse.cdt.make.internal.core.scannerconfig.util.SymbolEntry;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.ISafeRunnable;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.Status;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.xml.sax.SAXException;
+
+public class DiscoveredPathManager implements IDiscoveredPathManager {
+
+	private static final String CDESCRIPTOR_ID = MakeCorePlugin.getUniqueIdentifier() + ".discoveredScannerInfo"; //$NON-NLS-1$
+	public static final String INCLUDE_PATH = "includePath"; //$NON-NLS-1$
+	public static final String PATH = "path"; //$NON-NLS-1$
+	public static final String DEFINED_SYMBOL = "definedSymbol"; //$NON-NLS-1$
+	public static final String SYMBOL = "symbol"; //$NON-NLS-1$
+	public static final String REMOVED = "removed"; //$NON-NLS-1$
+
+	private static final String ROOT_ELEM_NAME = "DiscoveredScannerInfo"; //$NON-NLS-1$
+
+	private Map fDiscoveredMap = new HashMap();
+	private List listeners = Collections.synchronizedList(new Vector());
+
+	private static final int INFO_CHANGED = 1;
+	private static final int INFO_REMOVED = 2;
+	
+	public IDiscoveredPathInfo getDiscoveredInfo(IProject project) throws CoreException {
+		DiscoveredPathInfo info = (DiscoveredPathInfo)fDiscoveredMap.get(project);
+		if (info == null) {
+			info = loadPathInfo(project);
+			fDiscoveredMap.put(project, info);
+		}
+		return info;
+	}
+
+	private DiscoveredPathInfo loadPathInfo(IProject project) throws CoreException {
+		LinkedHashMap includes = new LinkedHashMap();
+		LinkedHashMap symbols = new LinkedHashMap();
+		loadDiscoveredScannerInfoFromState(project, includes, symbols);
+		DiscoveredPathInfo info = new DiscoveredPathInfo(project);
+		info.setIncludeMap(includes);
+		info.setSymbolMap(symbols);
+		return info;
+	}
+
+	public void removeDiscoveredInfo(IProject project) {
+		IPath path = MakeCorePlugin.getWorkingDirectory();
+		path = path.append(project.getName() + ".sc"); //$NON-NLS-1$
+		if (path.toFile().exists()) {
+			path.toFile().delete();
+		}
+		DiscoveredPathInfo info = (DiscoveredPathInfo)fDiscoveredMap.remove(project);
+		fireUpdate(INFO_REMOVED, info);
+	}
+
+	public void updateDiscoveredInfo(IDiscoveredPathInfo info) throws CoreException {
+		if (fDiscoveredMap.get(info.getProject()) != null) {
+			saveDiscoveredScannerInfoToState((DiscoveredPathInfo)info);
+			fireUpdate(INFO_CHANGED, info);
+		}
+	}
+
+	private void loadDiscoveredScannerInfoFromState(IProject project, LinkedHashMap includes, LinkedHashMap symbols)
+			throws CoreException {
+		// Save the document
+		IPath path = MakeCorePlugin.getWorkingDirectory();
+		path = path.append(project.getName() + ".sc"); //$NON-NLS-1$
+		if (path.toFile().exists()) {
+			try {
+				FileInputStream file = new FileInputStream(path.toFile());
+				DocumentBuilder parser = DocumentBuilderFactory.newInstance().newDocumentBuilder();
+				Document document = parser.parse(file);
+				Node rootElement = document.getFirstChild();
+				if (rootElement.getNodeName().equals("scannerInfo")) { //$NON-NLS-1$
+					Node child = rootElement.getFirstChild();
+					loadDiscoveredScannerInfo(includes, symbols, child);
+				}
+			} catch (IOException e) {
+				throw new CoreException(new Status(IStatus.ERROR, MakeCorePlugin.getUniqueIdentifier(), -1,
+						MakeMessages.getString("GCCScannerConfigUtil.Error_Message"), e)); //$NON-NLS-1$
+			} catch (ParserConfigurationException e) {
+				MakeCorePlugin.log(e);
+				throw new CoreException(new Status(IStatus.ERROR, MakeCorePlugin.getUniqueIdentifier(), -1,
+						MakeMessages.getString("GCCScannerConfigUtil.Error_Message"), e)); //$NON-NLS-1$
+			} catch (SAXException e) {
+				MakeCorePlugin.log(e);
+				throw new CoreException(new Status(IStatus.ERROR, MakeCorePlugin.getUniqueIdentifier(), -1,
+						MakeMessages.getString("GCCScannerConfigUtil.Error_Message"), e)); //$NON-NLS-1$
+			}
+		}
+	}
+
+	/**
+	 * @param includes
+	 * @param symbols
+	 * @param child
+	 */
+	private void loadDiscoveredScannerInfo(LinkedHashMap includes, LinkedHashMap symbols, Node child) {
+		while (child != null) {
+			if (child.getNodeName().equals(INCLUDE_PATH)) {
+				// Add the path to the property list
+				includes.put( ((Element)child).getAttribute(PATH), Boolean.valueOf( ((Element)child).getAttribute(REMOVED)));
+			} else if (child.getNodeName().equals(DEFINED_SYMBOL)) {
+				// Add the symbol to the symbol list
+				String symbol = ((Element)child).getAttribute(SYMBOL);
+				String removed = ((Element)child).getAttribute(REMOVED);
+				boolean bRemoved = (removed != null && removed.equals("true")); //$NON-NLS-1$
+				ScannerConfigUtil.scAddSymbolString2SymbolEntryMap(symbols, symbol, !bRemoved);
+			}
+			child = child.getNextSibling();
+		}
+	}
+
+	/**
+	 * @param scannerInfo
+	 * @param rootElement
+	 * @param doc
+	 */
+	private static void saveDiscoveredScannerInfo(DiscoveredPathInfo info, Element rootElement, Document doc) {
+		// Save the build info
+		if (info != null) {
+			// Serialize the include paths
+			Map discoveredIncludes = info.getIncludeMap();
+			Iterator iter = discoveredIncludes.keySet().iterator();
+			while (iter.hasNext()) {
+				Element pathElement = doc.createElement(INCLUDE_PATH);
+				String include = (String)iter.next();
+				pathElement.setAttribute(PATH, include);
+				Boolean removed = (Boolean)discoveredIncludes.get(include);
+				if (removed != null && removed.booleanValue() == true) {
+					pathElement.setAttribute(REMOVED, "true"); //$NON-NLS-1$
+				}
+				rootElement.appendChild(pathElement);
+			}
+			// Now do the same for the symbols
+			Map discoveredSymbols = info.getSymbolMap();
+			iter = discoveredSymbols.keySet().iterator();
+			while (iter.hasNext()) {
+				String symbol = (String)iter.next();
+				SymbolEntry se = (SymbolEntry)discoveredSymbols.get(symbol);
+				for (Iterator i = se.getActiveRaw().iterator(); i.hasNext();) {
+					String value = (String)i.next();
+					Element symbolElement = doc.createElement(DEFINED_SYMBOL);
+					symbolElement.setAttribute(SYMBOL, value);
+					rootElement.appendChild(symbolElement);
+				}
+				for (Iterator i = se.getRemovedRaw().iterator(); i.hasNext();) {
+					String value = (String)i.next();
+					Element symbolElement = doc.createElement(DEFINED_SYMBOL);
+					symbolElement.setAttribute(SYMBOL, value);
+					symbolElement.setAttribute(REMOVED, "true"); //$NON-NLS-1$
+					rootElement.appendChild(symbolElement);
+				}
+			}
+		}
+	}
+
+	private static void saveDiscoveredScannerInfoToState(DiscoveredPathInfo info) throws CoreException {
+		// Create document
+		try {
+			DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
+			Document doc = builder.newDocument();
+			Element rootElement = doc.createElement("scannerInfo"); //$NON-NLS-1$
+			rootElement.setAttribute("id", CDESCRIPTOR_ID); //$NON-NLS-1$
+			doc.appendChild(rootElement);
+
+			saveDiscoveredScannerInfo(info, rootElement, doc);
+
+			// Transform the document to something we can save in a file
+			ByteArrayOutputStream stream = new ByteArrayOutputStream();
+			Transformer transformer = TransformerFactory.newInstance().newTransformer();
+			transformer.setOutputProperty(OutputKeys.METHOD, "xml"); //$NON-NLS-1$
+			transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8"); //$NON-NLS-1$
+			transformer.setOutputProperty(OutputKeys.INDENT, "yes"); //$NON-NLS-1$
+			DOMSource source = new DOMSource(doc);
+			StreamResult result = new StreamResult(stream);
+			transformer.transform(source, result);
+
+			// Save the document
+			IPath path = MakeCorePlugin.getWorkingDirectory();
+			path = path.append(info.getProject().getName() + ".sc"); //$NON-NLS-1$
+			try {
+				FileOutputStream file = new FileOutputStream(path.toFile());
+				file.write(stream.toByteArray());
+				file.close();
+			} catch (IOException e) {
+				throw new CoreException(new Status(IStatus.ERROR, MakeCorePlugin.getUniqueIdentifier(), -1,
+						MakeMessages.getString("GCCScannerConfigUtil.Error_Message"), e)); //$NON-NLS-1$
+			}
+
+			// Close the streams
+			stream.close();
+		} catch (TransformerException e) {
+			MakeCorePlugin.log(e);
+			throw new CoreException(new Status(IStatus.ERROR, MakeCorePlugin.getUniqueIdentifier(), -1,
+					MakeMessages.getString("GCCScannerConfigUtil.Error_Message"), e)); //$NON-NLS-1$
+		} catch (IOException e) {
+			MakeCorePlugin.log(e);
+			throw new CoreException(new Status(IStatus.ERROR, MakeCorePlugin.getUniqueIdentifier(), -1,
+					MakeMessages.getString("GCCScannerConfigUtil.Error_Message"), e)); //$NON-NLS-1$
+		} catch (ParserConfigurationException e) {
+			MakeCorePlugin.log(e);
+			throw new CoreException(new Status(IStatus.ERROR, MakeCorePlugin.getUniqueIdentifier(), -1,
+					MakeMessages.getString("GCCScannerConfigUtil.Error_Message"), e)); //$NON-NLS-1$
+		}
+	}
+
+	private void fireUpdate(final int type, final IDiscoveredPathInfo info) {
+		synchronized (listeners) {
+			final Iterator iterator = listeners.iterator();
+			while (iterator.hasNext()) {
+				Platform.run(new ISafeRunnable() {
+
+					public void handleException(Throwable exception) {
+						IStatus status = new Status(IStatus.ERROR, CCorePlugin.PLUGIN_ID, -1,
+								CCorePlugin.getResourceString("CDescriptorManager.exception.listenerError"), exception); //$NON-NLS-1$
+						CCorePlugin.log(status);
+					}
+
+					public void run() throws Exception {
+						switch (type) {
+							case INFO_CHANGED :
+								((IDiscoveredInfoListener)iterator.next()).infoChanged(info);
+								break;
+							case INFO_REMOVED :
+								((IDiscoveredInfoListener)iterator.next()).infoRemoved(info.getProject());
+								break;
+						}
+					}
+				});
+			}
+		}
+	}
+	
+	public void addDiscoveredInfoListener(IDiscoveredInfoListener listener) {
+		listeners.add(listener);
+	}
+
+	public void removeDiscoveredInfoListener(IDiscoveredInfoListener listener) {
+		listeners.remove(listener);
+	}
+
+}
Index: plugin.properties
===================================================================
RCS file: /home/tools/org.eclipse.cdt-build/org.eclipse.cdt.make.ui/plugin.properties,v
retrieving revision 1.12
diff -u -r1.12 plugin.properties
--- plugin.properties	12 May 2004 13:38:22 -0000	1.12
+++ plugin.properties	24 May 2004 21:59:22 -0000
@@ -45,3 +45,5 @@
 MakefileEditor.name=Makefile Editor
 
 ProjectPathProperies.name=C/C++ Project Paths
+
+DiscoveredScannerInfoContainer.name=Discovered scanner configuration container
Index: plugin.xml
===================================================================
RCS file: /home/tools/org.eclipse.cdt-build/org.eclipse.cdt.make.ui/plugin.xml,v
retrieving revision 1.35
diff -u -r1.35 plugin.xml
--- plugin.xml	12 May 2004 13:38:22 -0000	1.35
+++ plugin.xml	24 May 2004 21:59:23 -0000
@@ -437,4 +437,11 @@
       </perspectiveExtension>
    </extension>
 
-</plugin>
+
+   <extension
+         point="org.eclipse.cdt.ui.PathContainerPage">
+      <PathContainerPage
+            class="org.eclipse.cdt.make.ui.dialogs.DiscoveredPathContainerPage"
+            name="%DiscoveredScannerInfoContainer.name"
+            id="org.eclipse.cdt.make.core.DISCOVERED_SCANNER_INFO"/>
+   </extension></plugin>
Index: src/org/eclipse/cdt/make/internal/ui/MakeProjectOptionBlock.java
===================================================================
RCS file: /home/tools/org.eclipse.cdt-build/org.eclipse.cdt.make.ui/src/org/eclipse/cdt/make/internal/ui/MakeProjectOptionBlock.java,v
retrieving revision 1.7
diff -u -r1.7 MakeProjectOptionBlock.java
--- src/org/eclipse/cdt/make/internal/ui/MakeProjectOptionBlock.java	3 Apr 2004 03:58:10 -0000	1.7
+++ src/org/eclipse/cdt/make/internal/ui/MakeProjectOptionBlock.java	24 May 2004 21:59:23 -0000
@@ -10,7 +10,7 @@
 
 import org.eclipse.cdt.make.core.MakeBuilder;
 import org.eclipse.cdt.make.core.MakeCorePlugin;
-import org.eclipse.cdt.make.ui.dialogs.BuildPathInfoBlock;
+import org.eclipse.cdt.make.ui.dialogs.DiscoveryOptionsBlock;
 import org.eclipse.cdt.make.ui.dialogs.SettingsBlock;
 import org.eclipse.cdt.ui.dialogs.BinaryParserBlock;
 import org.eclipse.cdt.ui.dialogs.ICOptionContainer;
@@ -30,7 +30,7 @@
 		addTab(new SettingsBlock(MakeCorePlugin.getDefault().getPluginPreferences(), MakeBuilder.BUILDER_ID));
 		addTab(new ErrorParserBlock(MakeCorePlugin.getDefault().getPluginPreferences()));
 		addTab(new BinaryParserBlock());
-		addTab(new BuildPathInfoBlock());
+		addTab(new DiscoveryOptionsBlock());
 	}
 
 }
Index: src/org/eclipse/cdt/make/internal/ui/MakeResources.properties
===================================================================
RCS file: /home/tools/org.eclipse.cdt-build/org.eclipse.cdt.make.ui/src/org/eclipse/cdt/make/internal/ui/MakeResources.properties,v
retrieving revision 1.19
diff -u -r1.19 MakeResources.properties
--- src/org/eclipse/cdt/make/internal/ui/MakeResources.properties	30 Apr 2004 00:35:11 -0000	1.19
+++ src/org/eclipse/cdt/make/internal/ui/MakeResources.properties	24 May 2004 21:59:23 -0000
@@ -219,7 +219,8 @@
 ManageDefinedSymbolsDialog.discoveredGroup.title=Discovered symbol definitions
 
 # --- ScannerConfigOptionsDialog ---
-ScannerConfigOptionsDialog.title=Scanner configuration discovery options
+ScannerConfigOptionsDialog.title=Discovery Options
+ScannerConfigOptionsDialog.description=Set the scanner configuration discovery options for this project
 ScannerConfigOptionsDialog.siBuilder.parser.group_label=Build output parser options
 ScannerConfigOptionsDialog.siBuilder.parser.enable.label=Enable build output parser
 ScannerConfigOptionsDialog.siBuilder.parser.label=Make build output parser:
@@ -230,3 +231,8 @@
 ScannerConfigOptionsDialog.siProvider.cmd.label=Generate scanner info command:
 ScannerConfigOptionsDialog.siProvider.parser.label=Command output parser:
 ScannerConfigOptionsDialog.siProvider.cmd.error_message=Must enter a 'generate scanner info' command
+
+# --- DiscoveredScannerConfigurationContainerPage ---
+DiscoveredScannerConfigurationContainerPage.title=Edit container
+DiscoveredScannerConfigurationContainerPage.description=Manage discovered scanner configuration
+DiscoveredScannerConfigurationContainerPage.list.title=Discovered include paths and symbol definitions
Index: src/org/eclipse/cdt/make/ui/IMakeHelpContextIds.java
===================================================================
RCS file: /home/tools/org.eclipse.cdt-build/org.eclipse.cdt.make.ui/src/org/eclipse/cdt/make/ui/IMakeHelpContextIds.java,v
retrieving revision 1.2
diff -u -r1.2 IMakeHelpContextIds.java
--- src/org/eclipse/cdt/make/ui/IMakeHelpContextIds.java	24 Feb 2004 02:04:02 -0000	1.2
+++ src/org/eclipse/cdt/make/ui/IMakeHelpContextIds.java	24 May 2004 21:59:23 -0000
@@ -17,4 +17,5 @@
 	
 	public static final String MAKE_PATH_SYMBOL_SETTINGS = PREFIX + "cdt_paths_symbols_page"; //$NON-NLS-1$
 	public static final String MAKE_BUILDER_SETTINGS = PREFIX + "cdt_make_builder_page"; //$NON-NLS-1$
+	public static final String SCANNER_CONFIG_DISCOVERY_OPTIONS = PREFIX + "cdt_discovery_options_page"; //$NON-NLS-1$
 }
Index: src/org/eclipse/cdt/make/ui/dialogs/BuildPathInfoBlock.java
===================================================================
RCS file: /home/tools/org.eclipse.cdt-build/org.eclipse.cdt.make.ui/src/org/eclipse/cdt/make/ui/dialogs/BuildPathInfoBlock.java,v
retrieving revision 1.10
diff -u -r1.10 BuildPathInfoBlock.java
--- src/org/eclipse/cdt/make/ui/dialogs/BuildPathInfoBlock.java	5 May 2004 18:29:32 -0000	1.10
+++ src/org/eclipse/cdt/make/ui/dialogs/BuildPathInfoBlock.java	24 May 2004 21:59:24 -0000
@@ -12,16 +12,15 @@
 package org.eclipse.cdt.make.ui.dialogs;
 
 import java.util.ArrayList;
+import java.util.LinkedHashMap;
 import java.util.StringTokenizer;
 
-import org.eclipse.cdt.core.CCorePlugin;
-import org.eclipse.cdt.core.parser.IScannerInfo;
 import org.eclipse.cdt.internal.ui.util.SWTUtil;
 import org.eclipse.cdt.make.core.MakeCorePlugin;
 import org.eclipse.cdt.make.core.MakeProjectNature;
-import org.eclipse.cdt.make.core.MakeScannerInfo;
-import org.eclipse.cdt.make.core.scannerconfig.DiscoveredScannerInfo;
+import org.eclipse.cdt.make.core.scannerconfig.IDiscoveredPathManager.IDiscoveredPathInfo;
 import org.eclipse.cdt.make.core.scannerconfig.ScannerConfigNature;
+import org.eclipse.cdt.make.internal.core.scannerconfig.util.ScannerConfigUtil;
 import org.eclipse.cdt.make.internal.ui.MakeUIPlugin;
 import org.eclipse.cdt.make.ui.IMakeHelpContextIds;
 import org.eclipse.cdt.ui.dialogs.AbstractCOptionPage;
@@ -243,26 +242,17 @@
 		if (project != null) {
 			// Store the paths and symbols 
 			monitor.beginTask(MakeUIPlugin.getResourceString("BuildPathInfoBlock.monitor.settingScannerInfo"), 3); //$NON-NLS-1$
-			IScannerInfo info = CCorePlugin.getDefault().getScannerInfoProvider(project).getScannerInformation(project);
-			if (info instanceof MakeScannerInfo) {
-				MakeScannerInfo mInfo = (MakeScannerInfo) info;
-				mInfo.setIncludePaths(getPathListContents());
-				monitor.worked(1);
-				mInfo.setPreprocessorSymbols(getSymbolListContents());
-				monitor.worked(1);
-				mInfo.update();
-				monitor.done();
-			}
-			else if (info instanceof DiscoveredScannerInfo) {
-				DiscoveredScannerInfo dInfo = (DiscoveredScannerInfo) info;
-				manageIncludesDialog.saveTo(dInfo);
-				monitor.worked(1);
-				manageSymbolsDialog.saveTo(dInfo);
-				monitor.worked(1);
-				dInfo.update();
-				monitor.done();
+			IDiscoveredPathInfo info = MakeCorePlugin.getDefault().getDiscoveryManager().getDiscoveredInfo(project);
+			boolean changed = manageIncludesDialog.saveTo(info);
+			monitor.worked(1);
+			changed |= manageSymbolsDialog.saveTo(info);
+			monitor.worked(1);
+			if (changed) {
+				MakeCorePlugin.getDefault().getDiscoveryManager().updateDiscoveredInfo(info);
 			}
-		} else {
+			monitor.done();
+		} 
+		else {
 			setIncludes(MakeCorePlugin.getDefault().getPluginPreferences());
 			setSymbols(MakeCorePlugin.getDefault().getPluginPreferences());
 		}
@@ -276,10 +266,10 @@
 		
 		pathList.removeAll();
 		symbolList.removeAll();
-		if (getContainer().getProject() != null) {
-			pathList.setItems(getIncludes(MakeCorePlugin.getDefault().getPluginPreferences()));
-			symbolList.setItems(getSymbols(MakeCorePlugin.getDefault().getPluginPreferences()));
-		}
+//		if (getContainer().getProject() != null) {
+//			pathList.setItems(getIncludes(MakeCorePlugin.getDefault().getPluginPreferences()));
+//			symbolList.setItems(getSymbols(MakeCorePlugin.getDefault().getPluginPreferences()));
+//		}
 		manageIncludesDialog.restore();
 		manageSymbolsDialog.restore();
 		getContainer().updateContainer();
@@ -475,20 +465,25 @@
 	private void setListContents() {
 		IProject project = getContainer().getProject();
 		if (project != null) {
-			IScannerInfo info = CCorePlugin.getDefault().getScannerInfoProvider(project).getScannerInformation(project);
-			if (info instanceof MakeScannerInfo) {
-				MakeScannerInfo mInfo = (MakeScannerInfo) info;
-				pathList.setItems(mInfo.getIncludePaths());
-				symbolList.setItems(mInfo.getPreprocessorSymbols());
-			}
-			else if (info instanceof DiscoveredScannerInfo) {
-				DiscoveredScannerInfo dInfo = (DiscoveredScannerInfo) info;
-				pathList.setItems(dInfo.getIncludePaths());
-				symbolList.setItems(dInfo.getPreprocessorSymbols());
-			}
-		} else {
-			pathList.setItems(getIncludes(MakeCorePlugin.getDefault().getPluginPreferences()));
-			symbolList.setItems(getSymbols(MakeCorePlugin.getDefault().getPluginPreferences()));
+//			IScannerInfo info = CCorePlugin.getDefault().getScannerInfoProvider(project).getScannerInformation(project);
+//			if (info != null) {
+//				pathList.setItems(info.getIncludePaths());
+//				symbolList.setItems(info.getPreprocessorSymbols());
+//			}
+			try {
+				IDiscoveredPathInfo info = MakeCorePlugin.getDefault().getDiscoveryManager().getDiscoveredInfo(project);
+				pathList.setItems(ScannerConfigUtil.iPathArray2StringArray(info.getIncludePaths()));
+				LinkedHashMap discoveredSymbols = info.getSymbolMap();
+				ArrayList activeSymbols = new ArrayList();
+				activeSymbols.addAll(ScannerConfigUtil.scSymbolsSymbolEntryMap2List(discoveredSymbols, true));
+				symbolList.setItems((String[]) activeSymbols.toArray(new String[activeSymbols.size()]));
+			} catch (CoreException e) {
+				MakeCorePlugin.log(e);
+			}
 		}
+//		else {
+//			pathList.setItems(getIncludes(MakeCorePlugin.getDefault().getPluginPreferences()));
+//			symbolList.setItems(getSymbols(MakeCorePlugin.getDefault().getPluginPreferences()));
+//		}
 	}
 }
Index: src/org/eclipse/cdt/make/ui/dialogs/ManageDefinedSymbolsDialog.java
===================================================================
RCS file: /home/tools/org.eclipse.cdt-build/org.eclipse.cdt.make.ui/src/org/eclipse/cdt/make/ui/dialogs/ManageDefinedSymbolsDialog.java,v
retrieving revision 1.2
diff -u -r1.2 ManageDefinedSymbolsDialog.java
--- src/org/eclipse/cdt/make/ui/dialogs/ManageDefinedSymbolsDialog.java	30 Apr 2004 00:35:11 -0000	1.2
+++ src/org/eclipse/cdt/make/ui/dialogs/ManageDefinedSymbolsDialog.java	24 May 2004 21:59:24 -0000
@@ -19,9 +19,8 @@
 
 import org.eclipse.cdt.internal.ui.util.SWTUtil;
 import org.eclipse.cdt.make.core.MakeCorePlugin;
-import org.eclipse.cdt.make.core.MakeScannerInfo;
-import org.eclipse.cdt.make.core.scannerconfig.DiscoveredScannerInfo;
-import org.eclipse.cdt.make.core.scannerconfig.DiscoveredScannerInfoProvider;
+import org.eclipse.cdt.make.core.scannerconfig.IDiscoveredPathManager.IDiscoveredPathInfo;
+import org.eclipse.cdt.make.internal.core.scannerconfig.DiscoveredPathInfo;
 import org.eclipse.cdt.make.internal.core.scannerconfig.ScannerInfoCollector;
 import org.eclipse.cdt.make.internal.core.scannerconfig.util.ScannerConfigUtil;
 import org.eclipse.cdt.make.internal.core.scannerconfig.util.SymbolEntry;
@@ -30,14 +29,11 @@
 import org.eclipse.cdt.ui.dialogs.ICOptionContainer;
 import org.eclipse.cdt.utils.ui.controls.ControlFactory;
 import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.CoreException;
 import org.eclipse.core.runtime.Preferences;
 import org.eclipse.jface.dialogs.Dialog;
 import org.eclipse.jface.dialogs.IDialogConstants;
-import org.eclipse.jface.dialogs.InputDialog;
-import org.eclipse.jface.window.Window;
 import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.MouseAdapter;
-import org.eclipse.swt.events.MouseEvent;
 import org.eclipse.swt.events.SelectionAdapter;
 import org.eclipse.swt.events.SelectionEvent;
 import org.eclipse.swt.graphics.FontData;
@@ -94,7 +90,6 @@
 	
 	boolean alreadyCreated;	// Set when dialog is created for the first time (vs. reopened)
 	private ArrayList returnSymbols;
-	private ArrayList userSymbols;
 	private ArrayList deletedDiscoveredSymbols;
 	private LinkedHashMap discoveredSymbols;
 	private LinkedHashMap workingDiscoveredSymbols; // working copy of discoveredSymbols, until either OK or CANCEL is pressed
@@ -106,11 +101,6 @@
 	private Shell fShell;
 	private MessageLine fStatusLine;
 
-	private List userList;
-	private Button addSymbol;
-	private Button editSymbol;
-	private Button removeSymbol;
-	
 	private Group discoveredGroup;
 	private Label selectedLabel;
 	private Label removedLabel;
@@ -129,19 +119,18 @@
 		fShell = parentShell;
 		fContainer = container;
 		fProject = fContainer.getProject();
-		DiscoveredScannerInfo scanInfo;
+		IDiscoveredPathInfo scanInfo;
 		if (fProject != null) {
-			scanInfo = (DiscoveredScannerInfo) DiscoveredScannerInfoProvider.getDefault().getScannerInformation(fProject);
+			try {
+				scanInfo = MakeCorePlugin.getDefault().getDiscoveryManager().getDiscoveredInfo(fProject); 
+			} catch (CoreException e) {
+				scanInfo = new DiscoveredPathInfo(fProject);
+			}
 		}
 		else {
-			scanInfo = new DiscoveredScannerInfo(null);
-			MakeScannerInfo makeInfo = new MakeScannerInfo(null);
-			Preferences store = MakeCorePlugin.getDefault().getPluginPreferences();
-			makeInfo.setPreprocessorSymbols(BuildPathInfoBlock.getSymbols(store));
-			scanInfo.setUserScannerInfo(makeInfo);
+			scanInfo = new DiscoveredPathInfo(fProject);
 		}
-		userSymbols = new ArrayList(Arrays.asList(scanInfo.getUserSymbolDefinitions()));
-		discoveredSymbols = scanInfo.getDiscoveredSymbolDefinitions();
+		discoveredSymbols = scanInfo.getSymbolMap();
 		setDirty(false);
 		fDirty = false;
 	}
@@ -179,13 +168,10 @@
 		fStatusLine.setLayoutData(gd);
 		fStatusLine.setMessage(getTitle(DIALOG_TITLE));
 		
-		createUserControls(composite);
 		createOptionsControls(composite);
 		createDiscoveredControls(composite);
 		
 		setListContents();
-		userList.select(0);
-		enableUserButtons();
 		discActiveList.select(0);
 		enableDiscoveredButtons();
 		
@@ -198,7 +184,6 @@
 	private void setListContents() {
 		workingDiscoveredSymbols = new LinkedHashMap(discoveredSymbols);
 		
-		userList.setItems((String[]) userSymbols.toArray(new String[userSymbols.size()]));
 		discActiveList.setItems(getDiscDefinedSymbols(workingDiscoveredSymbols, ACTIVE));
 		discRemovedList.setItems(getDiscDefinedSymbols(workingDiscoveredSymbols, REMOVED));
 	}
@@ -238,141 +223,6 @@
 	/**
 	 * @param composite
 	 */
-	private void createUserControls(Composite composite) {
-		// Create group
-		Group userGroup = ControlFactory.createGroup(composite, getTitle(USER_GROUP), 3);
-		((GridData) userGroup.getLayoutData()).horizontalSpan = 2;
-		((GridData) userGroup.getLayoutData()).grabExcessHorizontalSpace = false;
-		
-		// Create list
-		userList = new List(userGroup, SWT.BORDER | SWT.SINGLE | SWT.H_SCROLL | SWT.V_SCROLL);
-		userList.addSelectionListener(new SelectionAdapter() {
-			public void widgetSelected(SelectionEvent e) {
-				enableUserButtons();
-			}
-		});
-		userList.addMouseListener(new MouseAdapter() {
-			public void mouseDoubleClick(MouseEvent e) {
-				editUserListItem();
-			}
-		});
-
-		// Make it occupy the first column
-		GridData gd = new GridData(GridData.FILL_BOTH);
-		gd.grabExcessHorizontalSpace = true;
-		gd.horizontalSpan = 1;
-		gd.heightHint = getDefaultFontHeight(userList, PROJECT_LIST_MULTIPLIER);
-		gd.widthHint = convertWidthInCharsToPixels(INITIAL_LIST_WIDTH);
-		userList.setLayoutData(gd);
-
-		// Create buttons
-		// Create a composite for the buttons
-		Composite pathButtonComp = ControlFactory.createComposite(userGroup, 1);
-
-		// Add the buttons
-		addSymbol = ControlFactory.createPushButton(pathButtonComp, getTitle(NEW));
-		addSymbol.addSelectionListener(new SelectionAdapter() {
-			public void widgetSelected(SelectionEvent e) {
-				handleAddSymbol();
-			}
-		});
-		addSymbol.setEnabled(true);
-		SWTUtil.setButtonDimensionHint(addSymbol);
-
-		editSymbol = ControlFactory.createPushButton(pathButtonComp, getTitle(EDIT));
-		editSymbol.addSelectionListener(new SelectionAdapter() {
-			public void widgetSelected(SelectionEvent e) {
-				editUserListItem();
-			}
-		});
-		editSymbol.setEnabled(true);
-		SWTUtil.setButtonDimensionHint(editSymbol);
-
-		removeSymbol = ControlFactory.createPushButton(pathButtonComp, getTitle(REMOVE));
-		removeSymbol.addSelectionListener(new SelectionAdapter() {
-			public void widgetSelected(SelectionEvent e) {
-				handleRemoveSymbol();
-			}
-		});
-		SWTUtil.setButtonDimensionHint(removeSymbol);
-	}
-
-	protected void handleAddSymbol() {
-		// Popup an entry dialog
-		InputDialog dialog = new InputDialog(fShell, getTitle(SYMBOL_TITLE),
-				getTitle(SYMBOL_LABEL), "", null); //$NON-NLS-1$
-		String symbol = null;
-		if (dialog.open() == Window.OK) {
-			symbol = dialog.getValue();
-			if (symbol != null && symbol.length() > 0) {
-				setDirty(true);
-				userList.add(symbol);
-				userList.select(userList.getItemCount() - 1);
-				enableUserButtons();
-			}
-		}
-	}
-
-	/*
-	 * Double-click handler to allow edit of path information
-	 */
-	protected void editUserListItem() {
-		// Edit the selection index
-		int index = userList.getSelectionIndex();
-		if (index != -1) {
-			String selItem = userList.getItem(index);
-			if (selItem != null) {
-				InputDialog dialog = new InputDialog(fShell, getTitle(EDIT_SYMBOL_TITLE),
-						getTitle(SYMBOL_LABEL), selItem, null);
-				String newItem = null;
-				if (dialog.open() == Window.OK) {
-					newItem = dialog.getValue();
-					if (newItem != null && !newItem.equals(selItem)) {
-						userList.setItem(index, newItem);
-						setDirty(true);
-					}
-				}
-			}
-		}
-	}
-
-	protected void handleRemoveSymbol() {
-		// Get the selection index
-		int index = userList.getSelectionIndex();
-		if (index == -1) {
-			return;
-		}
-
-		// Remove the element at that index
-		userList.remove(index);
-		index = index - 1 < 0 ? 0 : index - 1;
-		userList.select(index);
-		setDirty(true);
-
-		// Check if the buttons should still be enabled
-		enableUserButtons();
-	}
-
-	/*
-	 * Enables the buttons on the path control if the right conditions are met
-	 */
-	protected void enableUserButtons() {
-		// Enable the remove button if there is at least 1 item in the list
-		int items = userList.getItemCount();
-		if (items > 0) {
-			editSymbol.setEnabled(true);
-			removeSymbol.setEnabled(true);
-			// Enable the up/down buttons depending on what item is selected
-			int index = userList.getSelectionIndex();
-		} else {
-			editSymbol.setEnabled(false);
-			removeSymbol.setEnabled(false);
-		}
-	}
-
-	/**
-	 * @param composite
-	 */
 	private void createOptionsControls(Composite composite) {
 		// TODO Auto-generated method stub
 		
@@ -630,13 +480,10 @@
 	 */
 	protected void buttonPressed(int buttonId) {
 		if (IDialogConstants.OK_ID == buttonId) {
-			// Store user part
-			userSymbols = new ArrayList(Arrays.asList(userList.getItems()));
 			// Store discovered part
 			discoveredSymbols = workingDiscoveredSymbols;
 			// Return sum of user and active discovered paths
-			returnSymbols = new ArrayList(userSymbols.size() + discActiveList.getItemCount());
-			returnSymbols.addAll(userSymbols);
+			returnSymbols = new ArrayList(discActiveList.getItemCount());
 			returnSymbols.addAll(new ArrayList(Arrays.asList(discActiveList.getItems())));
 
 			fDirty = fWorkingDirty;
@@ -656,11 +503,11 @@
 	/**
 	 * Called by BuildPathInfoBlock.performApply
 	 * @param info
+	 * @return boolean - true if changed
 	 */
-	public void saveTo(DiscoveredScannerInfo info) {
+	public boolean saveTo(IDiscoveredPathInfo info) {
 		if (fDirty || (fProject == null && fContainer.getProject() != null)) {// New Standard Make project wizard
-			info.setUserDefinedSymbols(userSymbols);
-			info.setDiscoveredSymbolDefinitions(discoveredSymbols);
+			info.setSymbolMap(discoveredSymbols);
 			// remove deleted symbols from discovered SC
 			if (deletedDiscoveredSymbols != null) {
 				for (Iterator i = deletedDiscoveredSymbols.iterator(); i.hasNext(); ) {
@@ -670,7 +517,9 @@
 			}
 		}
 		setDirty(false);
+		boolean rc = fDirty;
 		fDirty = false;
+		return rc;
 	}
 
 	/**
@@ -678,13 +527,8 @@
 	 */
 	public void restore() {
 		if (fProject != null) {
-			userSymbols = new ArrayList(Arrays.asList(BuildPathInfoBlock.getSymbols(
-					MakeCorePlugin.getDefault().getPluginPreferences())));
 			// remove discovered symbols
 			ScannerInfoCollector.getInstance().deleteAllSymbols(fProject);
-		}
-		else {
-			userSymbols = new ArrayList();
 		}
 		discoveredSymbols = new LinkedHashMap();
 		deletedDiscoveredSymbols = null;
Index: src/org/eclipse/cdt/make/ui/dialogs/ManageIncludePathsDialog.java
===================================================================
RCS file: /home/tools/org.eclipse.cdt-build/org.eclipse.cdt.make.ui/src/org/eclipse/cdt/make/ui/dialogs/ManageIncludePathsDialog.java,v
retrieving revision 1.3
diff -u -r1.3 ManageIncludePathsDialog.java
--- src/org/eclipse/cdt/make/ui/dialogs/ManageIncludePathsDialog.java	5 May 2004 18:29:32 -0000	1.3
+++ src/org/eclipse/cdt/make/ui/dialogs/ManageIncludePathsDialog.java	24 May 2004 21:59:25 -0000
@@ -18,23 +18,19 @@
 
 import org.eclipse.cdt.internal.ui.util.SWTUtil;
 import org.eclipse.cdt.make.core.MakeCorePlugin;
-import org.eclipse.cdt.make.core.MakeScannerInfo;
-import org.eclipse.cdt.make.core.scannerconfig.DiscoveredScannerInfo;
-import org.eclipse.cdt.make.core.scannerconfig.DiscoveredScannerInfoProvider;
+import org.eclipse.cdt.make.core.scannerconfig.IDiscoveredPathManager.IDiscoveredPathInfo;
+import org.eclipse.cdt.make.internal.core.scannerconfig.DiscoveredPathInfo;
 import org.eclipse.cdt.make.internal.core.scannerconfig.ScannerInfoCollector;
 import org.eclipse.cdt.make.internal.ui.MakeUIPlugin;
 import org.eclipse.cdt.make.internal.ui.MessageLine;
 import org.eclipse.cdt.ui.dialogs.ICOptionContainer;
 import org.eclipse.cdt.utils.ui.controls.ControlFactory;
 import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.CoreException;
 import org.eclipse.core.runtime.Preferences;
 import org.eclipse.jface.dialogs.Dialog;
 import org.eclipse.jface.dialogs.IDialogConstants;
-import org.eclipse.jface.dialogs.InputDialog;
-import org.eclipse.jface.window.Window;
 import org.eclipse.swt.SWT;
-import org.eclipse.swt.events.MouseAdapter;
-import org.eclipse.swt.events.MouseEvent;
 import org.eclipse.swt.events.SelectionAdapter;
 import org.eclipse.swt.events.SelectionEvent;
 import org.eclipse.swt.graphics.FontData;
@@ -95,7 +91,6 @@
 	private static final int DISC_DOWN = 1;
 	
 	private ArrayList returnPaths;
-	private ArrayList userPaths;
 	private ArrayList deletedDiscoveredPaths;
 	private LinkedHashMap discoveredPaths;
 	private LinkedHashMap workingDiscoveredPaths; // working copy of discoveredPaths, until either OK or CANCEL is pressed
@@ -107,13 +102,6 @@
 	private Shell fShell;
 	private MessageLine fStatusLine;
 
-	private List userList;
-	private Button addPath;
-	private Button editPath;
-	private Button removePath;
-	private Button pathUp;
-	private Button pathDown;
-	
 	private Group discoveredGroup;
 	private Label selectedLabel;
 	private Label removedLabel;
@@ -134,19 +122,18 @@
 		fShell = parentShell;
 		fContainer = container;
 		fProject = fContainer.getProject();
-		DiscoveredScannerInfo scanInfo;
+		IDiscoveredPathInfo scanInfo;
 		if (fProject != null) {
-			scanInfo = (DiscoveredScannerInfo) DiscoveredScannerInfoProvider.getDefault().getScannerInformation(fProject);
+			try {
+				scanInfo = MakeCorePlugin.getDefault().getDiscoveryManager().getDiscoveredInfo(fProject); 
+			} catch (CoreException e) {
+				scanInfo = new DiscoveredPathInfo(fProject);
+			}
 		}
 		else {
-			scanInfo = new DiscoveredScannerInfo(null);
-			MakeScannerInfo makeInfo = new MakeScannerInfo(null);
-			Preferences store = MakeCorePlugin.getDefault().getPluginPreferences();
-			makeInfo.setIncludePaths(BuildPathInfoBlock.getIncludes(store));
-			scanInfo.setUserScannerInfo(makeInfo);
+			scanInfo = new DiscoveredPathInfo(fProject);
 		}
-		userPaths = new ArrayList(Arrays.asList(scanInfo.getUserIncludePaths()));
-		discoveredPaths = scanInfo.getDiscoveredIncludePaths();
+		discoveredPaths = scanInfo.getIncludeMap();
 		setDirty(false);
 		fDirty = false;
 	}
@@ -183,14 +170,10 @@
 		fStatusLine.setLayoutData(gd);
 		fStatusLine.setMessage(getTitle(DIALOG_TITLE));
 		
-		createUserControls(composite);
 		createOptionsControls(composite);
 		createDiscoveredControls(composite);
 		
 		setListContents();
-		userList.select(0);
-		userList.setFocus();
-		enableUserButtons();
 		discActiveList.select(0);
 		discActiveList.setFocus();
 		enableDiscoveredButtons();
@@ -204,7 +187,6 @@
 	private void setListContents() {
 		workingDiscoveredPaths = new LinkedHashMap(discoveredPaths);
 
-		userList.setItems((String[]) userPaths.toArray(new String[userPaths.size()]));
 		discActiveList.setItems(getDiscIncludePaths(workingDiscoveredPaths, ACTIVE));
 		discRemovedList.setItems(getDiscIncludePaths(workingDiscoveredPaths, REMOVED));
 	}
@@ -245,200 +227,6 @@
 	/**
 	 * @param composite
 	 */
-	private void createUserControls(Composite composite) {
-		// Create group
-		Group userGroup = ControlFactory.createGroup(composite, getTitle(USER_GROUP), 3);
-		((GridData) userGroup.getLayoutData()).horizontalSpan = 2;
-		((GridData) userGroup.getLayoutData()).grabExcessHorizontalSpace = false;
-		
-		// Create list
-		userList = new List(userGroup, SWT.BORDER | SWT.SINGLE | SWT.H_SCROLL | SWT.V_SCROLL);
-		userList.addSelectionListener(new SelectionAdapter() {
-			public void widgetSelected(SelectionEvent e) {
-				enableUserButtons();
-			}
-		});
-		userList.addMouseListener(new MouseAdapter() {
-			public void mouseDoubleClick(MouseEvent e) {
-				editUserListItem();
-			}
-		});
-
-		// Make it occupy the first column
-		GridData gd = new GridData(GridData.FILL_BOTH);
-		gd.grabExcessHorizontalSpace = true;
-		gd.horizontalSpan = 1;
-		gd.heightHint = getDefaultFontHeight(userList, PROJECT_LIST_MULTIPLIER);
-		gd.widthHint = convertWidthInCharsToPixels(INITIAL_LIST_WIDTH);
-		userList.setLayoutData(gd);
-
-		// Create buttons
-		// Create a composite for the buttons
-		Composite pathButtonComp = ControlFactory.createComposite(userGroup, 1);
-
-		// Add the buttons
-		addPath = ControlFactory.createPushButton(pathButtonComp, getTitle(NEW));
-		addPath.addSelectionListener(new SelectionAdapter() {
-			public void widgetSelected(SelectionEvent e) {
-				handleAddPath();
-			}
-		});
-		addPath.setEnabled(true);
-		SWTUtil.setButtonDimensionHint(addPath);
-
-		editPath = ControlFactory.createPushButton(pathButtonComp, getTitle(EDIT));
-		editPath.addSelectionListener(new SelectionAdapter() {
-			public void widgetSelected(SelectionEvent e) {
-				editUserListItem();
-			}
-		});
-		editPath.setEnabled(true);
-		SWTUtil.setButtonDimensionHint(editPath);
-
-		removePath = ControlFactory.createPushButton(pathButtonComp, getTitle(REMOVE));
-		removePath.addSelectionListener(new SelectionAdapter() {
-			public void widgetSelected(SelectionEvent e) {
-				handleRemovePath();
-			}
-		});
-		SWTUtil.setButtonDimensionHint(removePath);
-
-		pathUp = ControlFactory.createPushButton(pathButtonComp, getTitle(UP));
-		pathUp.addSelectionListener(new SelectionAdapter() {
-			public void widgetSelected(SelectionEvent e) {
-				handlePathUp();
-			}
-		});
-		SWTUtil.setButtonDimensionHint(pathUp);
-
-		pathDown = ControlFactory.createPushButton(pathButtonComp, getTitle(DOWN));
-		pathDown.addSelectionListener(new SelectionAdapter() {
-			public void widgetSelected(SelectionEvent e) {
-				handlePathDown();
-			}
-		});
-		SWTUtil.setButtonDimensionHint(pathDown);
-	}
-
-	protected void handleAddPath() {
-		// Popup an entry dialog
-		InputDialog dialog = new BuildPathInfoBlock.
-			SelectPathInputDialog(fShell, getTitle(PATH_TITLE), getTitle(PATH_LABEL), "", null); //$NON-NLS-1$
-		String path = null;
-		if (dialog.open() == Window.OK) {
-			path = dialog.getValue();
-			if (path != null && path.length() > 0) {
-				setDirty(true);
-				userList.add(path);
-				userList.select(userList.getItemCount() - 1);
-				enableUserButtons();
-			}
-		}
-	}
-
-	/*
-	 * Double-click handler to allow edit of path information
-	 */
-	protected void editUserListItem() {
-		// Edit the selection index
-		int index = userList.getSelectionIndex();
-		if (index != -1) {
-			String selItem = userList.getItem(index);
-			if (selItem != null) {
-				InputDialog dialog = new BuildPathInfoBlock.SelectPathInputDialog(
-						fShell, getTitle(EDIT_PATH_TITLE), getTitle(PATH_LABEL), selItem, null);
-				String newItem = null;
-				if (dialog.open() == Window.OK) {
-					newItem = dialog.getValue();
-					if (newItem != null && !newItem.equals(selItem)) {
-						userList.setItem(index, newItem);
-						setDirty(true);
-					}
-				}
-			}
-		}
-	}
-
-	protected void handleRemovePath() {
-		// Get the selection index
-		int index = userList.getSelectionIndex();
-		if (index == -1) {
-			return;
-		}
-
-		// Remove the element at that index
-		userList.remove(index);
-		index = index - 1 < 0 ? 0 : index - 1;
-		userList.select(index);
-		setDirty(true);
-
-		// Check if the buttons should still be enabled
-		enableUserButtons();
-	}
-
-	protected void handlePathUp() {
-		// Get the selection index
-		int index = userList.getSelectionIndex();
-		if (index == -1 || index == 0) {
-			return;
-		}
-		// Swap the items in the list
-		String selItem = userList.getItem(index);
-		userList.remove(index);
-		userList.add(selItem, --index);
-		setDirty(true);
-
-		// Keep the index selected
-		userList.select(index);
-		enableUserButtons();
-	}
-
-	protected void handlePathDown() {
-		// Get the selection index
-		int index = userList.getSelectionIndex();
-		int items = userList.getItemCount();
-		if (index == -1 || index == items - 1) {
-			return;
-		}
-		// Swap the items in the list
-		String selItem = userList.getItem(index);
-		userList.remove(index);
-		if (index + 1 == items) {
-			userList.add(selItem);
-		} else {
-			userList.add(selItem, ++index);
-		}
-		setDirty(true);
-
-		// Keep the swapped item selected
-		userList.select(index);
-		enableUserButtons();
-	}
-
-	/*
-	 * Enables the buttons on the path control if the right conditions are met
-	 */
-	protected void enableUserButtons() {
-		// Enable the remove button if there is at least 1 item in the list
-		int items = userList.getItemCount();
-		if (items > 0) {
-			editPath.setEnabled(true);
-			removePath.setEnabled(true);
-			// Enable the up/down buttons depending on what item is selected
-			int index = userList.getSelectionIndex();
-			pathUp.setEnabled(items > 1 && index > 0);
-			pathDown.setEnabled(items > 1 && index < (items - 1));
-		} else {
-			editPath.setEnabled(false);
-			removePath.setEnabled(false);
-			pathUp.setEnabled(false);
-			pathDown.setEnabled(false);
-		}
-	}
-
-	/**
-	 * @param composite
-	 */
 	private void createOptionsControls(Composite composite) {
 		// TODO Auto-generated method stub
 		
@@ -753,13 +541,10 @@
 	 */
 	protected void buttonPressed(int buttonId) {
 		if (IDialogConstants.OK_ID == buttonId) {
-			// Store user part
-			userPaths = new ArrayList(Arrays.asList(userList.getItems()));
 			// Store discovered part
 			discoveredPaths = workingDiscoveredPaths;
 			// Return sum of user and active discovered paths
-			returnPaths = new ArrayList(userPaths.size() + discActiveList.getItemCount());
-			returnPaths.addAll(userPaths);
+			returnPaths = new ArrayList(discActiveList.getItemCount());
 			returnPaths.addAll(new ArrayList(Arrays.asList(discActiveList.getItems())));
 			
 			fDirty = fWorkingDirty;
@@ -779,11 +564,11 @@
 	/**
 	 * Called by BuildPathInfoBlock.performApply
 	 * @param info
+	 * @return boolean - true if changed
 	 */
-	public void saveTo(DiscoveredScannerInfo info) {
+	public boolean saveTo(IDiscoveredPathInfo info) {
 		if (fDirty || (fProject == null && fContainer.getProject() != null)) {// New Standard Make project wizard
-			info.setUserIncludePaths(userPaths);
-			info.setDiscoveredIncludePaths(discoveredPaths);
+			info.setIncludeMap(discoveredPaths);
 			// remove deleted paths from discovered SC
 			if (deletedDiscoveredPaths != null) {
 				for (Iterator i = deletedDiscoveredPaths.iterator(); i.hasNext(); ) {
@@ -793,7 +578,9 @@
 			}
 		}
 		setDirty(false);
+		boolean rc = fDirty;
 		fDirty = false;
+		return rc;
 	}
 
 	/**
@@ -801,13 +588,8 @@
 	 */
 	public void restore() {
 		if (fProject != null) {
-			userPaths = new ArrayList(Arrays.asList(BuildPathInfoBlock.getIncludes(
-					MakeCorePlugin.getDefault().getPluginPreferences())));
 			// remove discovered paths
 			ScannerInfoCollector.getInstance().deleteAllPaths(fProject);
-		}
-		else {
-			userPaths = new ArrayList();
 		}
 		discoveredPaths = new LinkedHashMap();
 		deletedDiscoveredPaths = null;
Index: src/org/eclipse/cdt/make/internal/ui/scannerconfig/DiscoveredElement.java
===================================================================
RCS file: src/org/eclipse/cdt/make/internal/ui/scannerconfig/DiscoveredElement.java
diff -N src/org/eclipse/cdt/make/internal/ui/scannerconfig/DiscoveredElement.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ src/org/eclipse/cdt/make/internal/ui/scannerconfig/DiscoveredElement.java	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,221 @@
+/**********************************************************************
+ * 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 - Initial API and implementation
+ **********************************************************************/
+package org.eclipse.cdt.make.internal.ui.scannerconfig;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Iterator;
+
+import org.eclipse.core.resources.IProject;
+
+/**
+ * Similar to CPElement. Describes discovered paths and symbols available
+ * through DiscoveredPathInfo instead of CPathEntry.
+ * 
+ * @author vhirsl
+ */
+public class DiscoveredElement {
+	public static final int CONTAINER = 1;
+	public static final int INCLUDE_PATH = 2;
+	public static final int SYMBOL_DEFINITION = 3;
+	public static final int PATHS_GROUP = 4;
+	public static final int SYMBOLS_GROUP = 5;
+	
+	private IProject fProject;
+	private String fEntry;
+	private int fEntryKind; 
+	private boolean fRemoved;
+	private boolean fSystem;
+	
+	private ArrayList fChildren = new ArrayList();
+	private DiscoveredElement fParent;
+	
+	public DiscoveredElement(IProject project, String entry, int kind, boolean removed, boolean system) {
+		fProject = project;
+		fEntry = entry;
+		fEntryKind = kind;
+		fRemoved = removed;
+		fSystem = system;
+	}
+
+	public static DiscoveredElement createNew(DiscoveredElement parent,
+											  IProject project,
+											  String entry,
+											  int kind,
+											  boolean removed,
+											  boolean system) {
+		DiscoveredElement rv = null;
+		switch (kind) {
+			case CONTAINER: {
+				rv = new DiscoveredElement(project, entry, kind, removed, system);
+				DiscoveredElement group = new DiscoveredElement(project, null, PATHS_GROUP, false, false);
+				rv.fChildren.add(group);
+				group.fParent = rv;
+				group = new DiscoveredElement(project, null, SYMBOLS_GROUP, false, false);
+				rv.fChildren.add(group);
+				group.fParent = rv;
+			}
+			break;
+			case INCLUDE_PATH: {
+				if (parent != null) {
+					DiscoveredElement group = null;
+					if (parent.getEntryKind() == PATHS_GROUP) {
+						parent = parent.getParent();
+						group = parent;
+					}
+					else if (parent.getEntryKind() == CONTAINER) {
+						for (Iterator i = parent.fChildren.iterator(); i.hasNext(); ) {
+							DiscoveredElement child = (DiscoveredElement) i.next();
+							if (child.getEntryKind() == PATHS_GROUP) {
+								group = child;
+								break;
+							}
+						}
+						if (group == null) {
+							return null;
+						}
+					}
+					if (parent.getEntryKind() == CONTAINER) {
+						rv = new DiscoveredElement(project, entry, kind, removed, system);
+						group.fChildren.add(rv);
+						rv.setParent(group);
+					}
+				}
+			}
+			break;
+			case SYMBOL_DEFINITION: {
+				if (parent != null) {
+					DiscoveredElement group = null;
+					if (parent.getEntryKind() == SYMBOLS_GROUP) {
+						parent = parent.getParent();
+						group = parent;
+					}
+					else if (parent.getEntryKind() == CONTAINER) {
+						for (Iterator i = parent.fChildren.iterator(); i.hasNext(); ) {
+							DiscoveredElement child = (DiscoveredElement) i.next();
+							if (child.getEntryKind() == SYMBOLS_GROUP) {
+								group = child;
+								break;
+							}
+						}
+						if (group == null) {
+							return null;
+						}
+					}
+					if (parent.getEntryKind() == CONTAINER) {
+						rv = new DiscoveredElement(project, entry, kind, removed, system);
+						group.fChildren.add(rv);
+						rv.setParent(group);
+					}
+				}
+			}			
+			break;
+		}
+		return rv;
+	}
+	/**
+	 * @return Returns the fProject.
+	 */
+	public IProject getProject() {
+		return fProject;
+	}
+	/**
+	 * @return Returns the fEntry.
+	 */
+	public String getEntry() {
+		return fEntry;
+	}
+	/**
+	 * @param string
+	 */
+	public void setEntry(String entry) {
+		fEntry = entry;
+	}
+	/**
+	 * @return Returns the fEntryKind.
+	 */
+	public int getEntryKind() {
+		return fEntryKind;
+	}
+	/**
+	 * @param entryKind The fEntryKind to set.
+	 */
+	public void setEntryKind(int entryKind) {
+		fEntryKind = entryKind;
+	}
+	/**
+	 * @return Returns the fRemoved.
+	 */
+	public boolean isRemoved() {
+		return fRemoved;
+	}
+	/**
+	 * @param removed The fRemoved to set.
+	 */
+	public void setRemoved(boolean removed) {
+		fRemoved = removed;
+	}
+	/**
+	 * @return Returns the fParent.
+	 */
+	public DiscoveredElement getParent() {
+		return fParent;
+	}
+	/**
+	 * @param parent The fParent to set.
+	 */
+	private void setParent(DiscoveredElement parent) {
+		fParent = parent;
+	}
+
+	/**
+	 * Returns children of the discovered element 
+	 * @return
+	 */
+	public Object[] getChildren() {
+		switch(fEntryKind) {
+			case INCLUDE_PATH:
+			case SYMBOL_DEFINITION:
+				return new Object[0];
+		}
+		return fChildren.toArray();
+	}
+
+	public boolean hasChildren() {
+		switch(fEntryKind) {
+			case INCLUDE_PATH:
+			case SYMBOL_DEFINITION:
+				return false;
+		}
+		return (fChildren.size() > 0);
+	}
+
+	public void setChildren(Object[] children) {
+		fChildren = new ArrayList(Arrays.asList(children));
+	}
+
+	/**
+	 * 
+	 */
+	public boolean delete() {
+		boolean rc = false;
+		DiscoveredElement parent = getParent();
+		if (parent != null) {
+			rc = parent.fChildren.remove(this);
+			for (Iterator i = fChildren.iterator(); i.hasNext(); ) {
+				DiscoveredElement child = (DiscoveredElement) i.next();
+				child.setParent(null);
+				rc |= true;
+			}
+		}
+		return rc;
+	}
+}
Index: src/org/eclipse/cdt/make/internal/ui/scannerconfig/DiscoveredElementLabelProvider.java
===================================================================
RCS file: src/org/eclipse/cdt/make/internal/ui/scannerconfig/DiscoveredElementLabelProvider.java
diff -N src/org/eclipse/cdt/make/internal/ui/scannerconfig/DiscoveredElementLabelProvider.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ src/org/eclipse/cdt/make/internal/ui/scannerconfig/DiscoveredElementLabelProvider.java	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,181 @@
+/**********************************************************************
+ * 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 - Initial API and implementation
+ **********************************************************************/
+package org.eclipse.cdt.make.internal.ui.scannerconfig;
+
+import org.eclipse.cdt.internal.ui.CPluginImages;
+import org.eclipse.cdt.internal.ui.dialogs.cpaths.CPathEntryMessages;
+import org.eclipse.cdt.internal.ui.util.ImageDescriptorRegistry;
+import org.eclipse.cdt.ui.CUIPlugin;
+import org.eclipse.jface.resource.CompositeImageDescriptor;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jface.viewers.IColorProvider;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.ImageData;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.graphics.RGB;
+import org.eclipse.swt.widgets.Display;
+
+/**
+ * Label provider for DiscoveredElement-s. DiscoveredElement can be active or removed.
+ * 
+ * @author vhirsl
+ */
+public class DiscoveredElementLabelProvider extends LabelProvider implements IColorProvider {
+	private final Color inDirect = new Color(Display.getDefault(), new RGB(170, 170, 170));
+
+	private ImageDescriptor fIncludeIcon, fMacroIcon, fContainerImage;
+	private ImageDescriptor fRemovedIncludeIcon, fRemovedMacroIcon;
+	private ImageDescriptorRegistry fRegistry;
+
+	public DiscoveredElementLabelProvider() {
+		fRegistry = CUIPlugin.getImageDescriptorRegistry();
+		fIncludeIcon = CPluginImages.DESC_OBJS_INCLUDES_FOLDER;
+		fMacroIcon = CPluginImages.DESC_OBJS_MACRO;
+		fContainerImage = CPluginImages.DESC_OBJS_LIBRARY;
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.viewers.ILabelProvider#getImage(java.lang.Object)
+	 */
+	public Image getImage(Object element) {
+		if (element instanceof DiscoveredElement) {
+			DiscoveredElement elem = (DiscoveredElement) element;
+			Image image = composeImage(elem);
+			if (image != null) {
+				return image;
+			}
+		}
+		return super.getImage(element);
+	}
+	/**
+	 * @param elem
+	 * @return
+	 */
+	private Image composeImage(DiscoveredElement elem) {
+		Image image = null;
+		switch (elem.getEntryKind()) {
+			case DiscoveredElement.PATHS_GROUP:
+				image = CPluginImages.get(CPluginImages.IMG_OBJS_INCLUDES_CONTAINER);
+				break;
+			case DiscoveredElement.CONTAINER:
+				image = fRegistry.get(fContainerImage);
+				break;
+			case DiscoveredElement.INCLUDE_PATH:
+				image = fRegistry.get(fIncludeIcon);
+				break;
+			case DiscoveredElement.SYMBOLS_GROUP:
+			case DiscoveredElement.SYMBOL_DEFINITION:
+				image = fRegistry.get(fMacroIcon);
+			    break;
+		}
+		if (image != null && elem.isRemoved()) {
+			image = new DiscoveredElementImageDescriptor(image, true).createImage();
+		}
+		return image;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.viewers.ILabelProvider#getText(java.lang.Object)
+	 */
+	public String getText(Object element) {
+		if (element instanceof DiscoveredElement) {
+			DiscoveredElement elem = (DiscoveredElement) element;
+			switch (elem.getEntryKind()) {
+				case DiscoveredElement.PATHS_GROUP:
+					return CPathEntryMessages.getString("CPElementLabelProvider.Includes"); //$NON-NLS-1$
+				case DiscoveredElement.SYMBOLS_GROUP:
+					return CPathEntryMessages.getString("CPElementLabelProvider.PreprocessorSymbols"); //$NON-NLS-1$
+				case DiscoveredElement.CONTAINER:
+				case DiscoveredElement.INCLUDE_PATH:
+				case DiscoveredElement.SYMBOL_DEFINITION:
+					return elem.getEntry() + (elem.isRemoved() ? " (removed)" : "");
+			}
+		}
+		return super.getText(element);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.viewers.IColorProvider#getForeground(java.lang.Object)
+	 */
+	public Color getForeground(Object element) {
+		if (element instanceof DiscoveredElement) {
+			DiscoveredElement elem = (DiscoveredElement) element;
+			switch (elem.getEntryKind()) {
+				case DiscoveredElement.INCLUDE_PATH:
+				case DiscoveredElement.SYMBOL_DEFINITION:
+					if (elem.isRemoved()) {
+						return inDirect;
+					}
+			}
+		}
+		return null;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.viewers.IColorProvider#getBackground(java.lang.Object)
+	 */
+	public Color getBackground(Object element) {
+		return null;
+	}
+
+	/**
+	 * ComositeImageDescriptor adds 'removed' image overlay to the DiscoveredElement
+	 * 
+	 * @author vhirsl
+	 */
+	private class DiscoveredElementImageDescriptor extends CompositeImageDescriptor {
+		private Image fBaseImage;
+		private boolean showRemoved;
+		private Point fSize;
+
+		public DiscoveredElementImageDescriptor(Image baseImage, boolean removed) {
+			fBaseImage = baseImage;
+			showRemoved = removed;
+		}
+
+		/* (non-Javadoc)
+		 * @see org.eclipse.jface.resource.CompositeImageDescriptor#drawCompositeImage(int, int)
+		 */
+		protected void drawCompositeImage(int width, int height) {
+			ImageData bg = fBaseImage.getImageData();
+			if (bg == null) {
+				bg = DEFAULT_IMAGE_DATA;
+			}
+			drawImage(bg, 0, 0);
+			drawOverlays();
+		}
+
+		/**
+		 * Add any overlays to the image as specified in the flags.
+		 */
+		protected void drawOverlays() {
+			ImageData data = null;
+			if (showRemoved) {
+				data = CPluginImages.DESC_OVR_ERROR.getImageData();
+				drawImage(data, 0, 0);
+			}
+		}
+		
+		/* (non-Javadoc)
+		 * @see org.eclipse.jface.resource.CompositeImageDescriptor#getSize()
+		 */
+		protected Point getSize() {
+			if (fSize == null) {
+				ImageData data = fBaseImage.getImageData();
+				fSize = new Point(data.width, data.height);
+			}
+			return fSize;
+		}
+
+	}
+}
Index: src/org/eclipse/cdt/make/internal/ui/scannerconfig/DiscoveredElementSorter.java
===================================================================
RCS file: src/org/eclipse/cdt/make/internal/ui/scannerconfig/DiscoveredElementSorter.java
diff -N src/org/eclipse/cdt/make/internal/ui/scannerconfig/DiscoveredElementSorter.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ src/org/eclipse/cdt/make/internal/ui/scannerconfig/DiscoveredElementSorter.java	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,58 @@
+/**********************************************************************
+ * 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 - Initial API and implementation
+ **********************************************************************/
+package org.eclipse.cdt.make.internal.ui.scannerconfig;
+
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.ViewerSorter;
+
+/**
+ * TODO Provide description
+ * 
+ * @author vhirsl
+ */
+public class DiscoveredElementSorter extends ViewerSorter {
+	private static final int CONTAINER = 0;
+	private static final int PATHS_GROUP = 1;
+	private static final int SYMBOLS_GROUP = 2;
+	private static final int OTHER = 5;
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.viewers.ViewerSorter#category(java.lang.Object)
+	 */
+	public int category(Object element) {
+		if (element instanceof DiscoveredElement) {
+			DiscoveredElement elem = (DiscoveredElement) element;
+			switch (elem.getEntryKind()) {
+				case DiscoveredElement.CONTAINER:
+					return CONTAINER;
+				case DiscoveredElement.PATHS_GROUP:
+					return PATHS_GROUP;
+				case DiscoveredElement.SYMBOLS_GROUP:
+					return SYMBOLS_GROUP;
+			}
+		}
+		return OTHER;
+	}
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.viewers.ViewerSorter#sort(org.eclipse.jface.viewers.Viewer, java.lang.Object[])
+	 */
+	public void sort(Viewer viewer, Object[] elements) {
+		if (elements.length > 0 && elements[0] instanceof DiscoveredElement) {
+			DiscoveredElement firstElem = (DiscoveredElement) elements[0];
+			switch (firstElem.getEntryKind()) {
+				case DiscoveredElement.INCLUDE_PATH:
+				case DiscoveredElement.SYMBOL_DEFINITION:
+					return;
+			}
+		}
+		super.sort(viewer, elements);
+	}
+}
Index: src/org/eclipse/cdt/make/ui/dialogs/DiscoveredPathContainerPage.java
===================================================================
RCS file: src/org/eclipse/cdt/make/ui/dialogs/DiscoveredPathContainerPage.java
diff -N src/org/eclipse/cdt/make/ui/dialogs/DiscoveredPathContainerPage.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ src/org/eclipse/cdt/make/ui/dialogs/DiscoveredPathContainerPage.java	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,619 @@
+/**********************************************************************
+ * 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 - Initial API and implementation
+ **********************************************************************/
+package org.eclipse.cdt.make.ui.dialogs;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.List;
+
+import org.eclipse.cdt.core.model.CModelException;
+import org.eclipse.cdt.core.model.CoreModel;
+import org.eclipse.cdt.core.model.ICProject;
+import org.eclipse.cdt.core.model.IContainerEntry;
+import org.eclipse.cdt.core.model.IPathEntry;
+import org.eclipse.cdt.core.model.IPathEntryContainer;
+import org.eclipse.cdt.internal.ui.CPluginImages;
+import org.eclipse.cdt.internal.ui.util.PixelConverter;
+import org.eclipse.cdt.internal.ui.wizards.dialogfields.DialogField;
+import org.eclipse.cdt.internal.ui.wizards.dialogfields.IDialogFieldListener;
+import org.eclipse.cdt.internal.ui.wizards.dialogfields.ITreeListAdapter;
+import org.eclipse.cdt.internal.ui.wizards.dialogfields.LayoutUtil;
+import org.eclipse.cdt.internal.ui.wizards.dialogfields.TreeListDialogField;
+import org.eclipse.cdt.make.core.MakeCorePlugin;
+import org.eclipse.cdt.make.core.scannerconfig.IDiscoveredPathManager.IDiscoveredPathInfo;
+import org.eclipse.cdt.make.internal.core.scannerconfig.DiscoveredPathContainer;
+import org.eclipse.cdt.make.internal.core.scannerconfig.ScannerInfoCollector;
+import org.eclipse.cdt.make.internal.core.scannerconfig.util.ScannerConfigUtil;
+import org.eclipse.cdt.make.internal.core.scannerconfig.util.SymbolEntry;
+import org.eclipse.cdt.make.internal.ui.MakeUIPlugin;
+import org.eclipse.cdt.make.internal.ui.scannerconfig.DiscoveredElement;
+import org.eclipse.cdt.make.internal.ui.scannerconfig.DiscoveredElementLabelProvider;
+import org.eclipse.cdt.make.internal.ui.scannerconfig.DiscoveredElementSorter;
+import org.eclipse.cdt.ui.wizards.ICPathContainerPage;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.ViewerFilter;
+import org.eclipse.jface.wizard.WizardPage;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.KeyEvent;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * A dialog page to manage discovered scanner configuration
+ * 
+ * @author vhirsl
+ */
+public class DiscoveredPathContainerPage extends WizardPage	implements ICPathContainerPage {
+	private static final String PREFIX = "DiscoveredScannerConfigurationContainerPage"; //$NON-NLS-1$
+
+	private static final String DISC_COMMON_PREFIX = "ManageScannerConfigDialogCommon"; //$NON-NLS-1$
+	private static final String UP = DISC_COMMON_PREFIX + ".discoveredGroup.buttons.up.label"; //$NON-NLS-1$
+	private static final String DOWN = DISC_COMMON_PREFIX + ".discoveredGroup.buttons.down.label"; //$NON-NLS-1$
+	private static final String REMOVE = DISC_COMMON_PREFIX + ".discoveredGroup.buttons.remove.label"; //$NON-NLS-1$
+	private static final String RESTORE = DISC_COMMON_PREFIX + ".discoveredGroup.buttons.restore.label"; //$NON-NLS-1$
+	private static final String DELETE = DISC_COMMON_PREFIX + ".discoveredGroup.buttons.delete.label"; //$NON-NLS-1$
+	
+	private static final String CONTAINER_LABEL = PREFIX + ".title"; //$NON-NLS-1$
+	private static final String CONTAINER_DESCRIPTION = PREFIX + ".description"; //$NON-NLS-1$
+	private static final String CONTAINER_LIST_LABEL = PREFIX + ".list.title"; //$NON-NLS-1$
+	
+	private final int IDX_UP = 0;
+	private final int IDX_DOWN = 1;
+	private final int IDX_REMOVE = 2;
+	private final int IDX_RESTORE = 3;
+
+	private final int IDX_DELETE = 5;
+
+	private static final int DISC_UP = 0;
+	private static final int DISC_DOWN = 1;
+	
+	private static final int DO_REMOVE = 0;
+	private static final int DO_RESTORE = 1;
+
+	private ICProject fCProject;
+	private IContainerEntry fPathEntry;
+
+	private TreeListDialogField fDiscoveredContainerList;
+	private boolean dirty;
+	
+	public DiscoveredPathContainerPage() {
+		super("DiscoveredScannerConfigurationContainerPage"); //$NON-NLS-1$
+
+		setTitle(MakeUIPlugin.getResourceString(CONTAINER_LABEL));
+		setDescription(MakeUIPlugin.getResourceString(CONTAINER_DESCRIPTION));
+		setImageDescriptor(CPluginImages.DESC_WIZBAN_ADD_LIBRARY);
+
+		String[] buttonLabels = new String[]{
+				/* IDX_UP */	MakeUIPlugin.getResourceString(UP),
+				/* IDX_DOWN */	MakeUIPlugin.getResourceString(DOWN),
+				/* IDX_REMOVE */MakeUIPlugin.getResourceString(REMOVE),
+				/* IDX_RESTORE */MakeUIPlugin.getResourceString(RESTORE),
+				null,
+				/* IDX_DELETE */MakeUIPlugin.getResourceString(DELETE),
+		};
+
+		DiscoveredContainerAdapter adapter = new DiscoveredContainerAdapter();
+
+		fDiscoveredContainerList = new TreeListDialogField(adapter, buttonLabels, new DiscoveredElementLabelProvider());
+		fDiscoveredContainerList.setDialogFieldListener(adapter);
+		fDiscoveredContainerList.setLabelText(MakeUIPlugin.getResourceString(CONTAINER_LIST_LABEL)); //$NON-NLS-1$
+
+		fDiscoveredContainerList.setViewerSorter(new DiscoveredElementSorter());
+		dirty = false;
+	}
+	/* (non-Javadoc)
+	 * @see org.eclipse.cdt.ui.wizards.ICPathContainerPage#initialize(org.eclipse.cdt.core.model.ICProject, org.eclipse.cdt.core.model.IPathEntry[])
+	 */
+	public void initialize(ICProject project, IPathEntry[] currentEntries) {
+		fCProject = project;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.cdt.ui.wizards.ICPathContainerPage#finish()
+	 */
+	public boolean finish() {
+		if (!dirty) {
+			return true;
+		}
+		IDiscoveredPathInfo info;
+		try {
+			info = MakeCorePlugin.getDefault().
+					getDiscoveryManager().getDiscoveredInfo(fCProject.getProject());
+			
+			LinkedHashMap includes = new LinkedHashMap();
+			LinkedHashMap symbols = new LinkedHashMap();
+			
+			DiscoveredElement container = (DiscoveredElement) fDiscoveredContainerList.getElement(0);
+			if (container != null && container.getEntryKind() == DiscoveredElement.CONTAINER) {
+				Object[] cChildren = container.getChildren();
+				if (cChildren != null) {
+					for (int i = 0; i < cChildren.length; ++i) {
+						DiscoveredElement group = (DiscoveredElement) cChildren[i];
+						switch (group.getEntryKind()) {
+							case DiscoveredElement.PATHS_GROUP: {
+								// get the include paths
+								Object[] gChildren = group.getChildren();
+								if (gChildren != null) {
+									for (int j = 0; j < gChildren.length; ++j) {
+										DiscoveredElement include = (DiscoveredElement) gChildren[j];
+										includes.put(include.getEntry(), Boolean.valueOf(include.isRemoved()));
+									}
+								}
+							}
+							break;
+							case DiscoveredElement.SYMBOLS_GROUP: {
+								// get the symbol definitions
+								Object[] gChildren = group.getChildren();
+								if (gChildren != null) {
+									for (int j = 0; j < gChildren.length; ++j) {
+										DiscoveredElement symbol = (DiscoveredElement) gChildren[j];
+										ScannerConfigUtil.scAddSymbolString2SymbolEntryMap(symbols, symbol.getEntry(), !symbol.isRemoved());
+									}
+								}
+							}
+							break;
+						}
+					}
+				}
+			}
+			info.setIncludeMap(includes);
+			info.setSymbolMap(symbols);
+			
+			try {
+				// update scanner configuration
+				MakeCorePlugin.getDefault().getDiscoveryManager().updateDiscoveredInfo(info);
+				return true;
+			} catch (CoreException e) {
+				MakeCorePlugin.log(e);
+			}
+		} catch (CoreException e) {
+			MakeCorePlugin.log(e);
+		}
+		return false;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.cdt.ui.wizards.ICPathContainerPage#getContainerEntries()
+	 */
+	public IPathEntry[] getContainerEntries() {
+		return new IPathEntry[] { fPathEntry }; 
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.cdt.ui.wizards.ICPathContainerPage#setSelection(org.eclipse.cdt.core.model.IPathEntry)
+	 */
+	public void setSelection(IPathEntry containerEntry) {
+		if (containerEntry != null) {
+			if (containerEntry.getEntryKind() == IPathEntry.CDT_CONTAINER) {
+				fPathEntry = (IContainerEntry) containerEntry;
+			}
+		}
+		else {
+			fPathEntry = CoreModel.newContainerEntry(DiscoveredPathContainer.CONTAINER_ID);		
+		}
+		if (fPathEntry != null) {
+			DiscoveredElement element = populateDiscoveredElements(fPathEntry);
+			ArrayList elements = new ArrayList();
+			elements.add(element);
+			fDiscoveredContainerList.addElements(elements);
+		}
+	}
+
+	/**
+	 * @param pathEntry
+	 * @return
+	 */
+	private DiscoveredElement populateDiscoveredElements(IContainerEntry pathEntry) {
+		IDiscoveredPathInfo info;
+		DiscoveredElement container = null;
+		try {
+			info = MakeCorePlugin.getDefault().
+					getDiscoveryManager().getDiscoveredInfo(fCProject.getProject());
+			container = DiscoveredElement.createNew(null, fCProject.getProject(), null,
+					DiscoveredElement.CONTAINER, false, false);
+			try {
+				IPathEntryContainer peContainer = CoreModel.getPathEntryContainer(pathEntry.getPath(), fCProject);
+				if (peContainer != null) {
+					container.setEntry(peContainer.getDescription());
+				}
+				// get include paths
+				LinkedHashMap paths = info.getIncludeMap();
+				for (Iterator i = paths.keySet().iterator(); i.hasNext(); ) {
+					String include = (String) i.next();
+					Boolean removed = (Boolean) paths.get(include);
+					removed = (removed == null) ? Boolean.FALSE : removed;
+					DiscoveredElement.createNew(container, fCProject.getProject(), include, 
+							DiscoveredElement.INCLUDE_PATH, removed.booleanValue(), false);
+				}
+				// get defined symbols 
+				LinkedHashMap symbols = info.getSymbolMap();
+				for (Iterator i = symbols.keySet().iterator(); i.hasNext(); ) {
+					String symbol = (String) i.next();
+					SymbolEntry se = (SymbolEntry) symbols.get(symbol);
+					for (Iterator j = se.getActiveRaw().iterator(); j.hasNext();) {
+						String value = (String) j.next();
+						DiscoveredElement.createNew(container, fCProject.getProject(), value, 
+								DiscoveredElement.SYMBOL_DEFINITION, false, false);
+					}
+					for (Iterator j = se.getRemovedRaw().iterator(); j.hasNext();) {
+						String value = (String) j.next();
+						DiscoveredElement.createNew(container, fCProject.getProject(), value, 
+								DiscoveredElement.SYMBOL_DEFINITION, true, false);
+					}
+				}
+			} catch (CModelException e) {
+				MakeUIPlugin.log(e.getStatus());
+			}
+		} catch (CoreException e) {
+			MakeUIPlugin.log(e);
+		}
+		return container;
+	}
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.dialogs.IDialogPage#createControl(org.eclipse.swt.widgets.Composite)
+	 */
+	public void createControl(Composite parent) {
+		PixelConverter converter = new PixelConverter(parent);
+
+		Composite composite = new Composite(parent, SWT.NONE);
+
+		LayoutUtil.doDefaultLayout(composite, new DialogField[]{fDiscoveredContainerList}, true);
+		LayoutUtil.setHorizontalGrabbing(fDiscoveredContainerList.getTreeControl(null));
+
+		int buttonBarWidth = converter.convertWidthInCharsToPixels(24);
+		fDiscoveredContainerList.setButtonsMinWidth(buttonBarWidth);
+
+		fDiscoveredContainerList.getTreeViewer().addFilter(new ViewerFilter() {
+			public boolean select(Viewer viewer, Object parentElement, Object element) {
+				if (element instanceof DiscoveredElement) {
+					DiscoveredElement elem = (DiscoveredElement) element;
+					switch (elem.getEntryKind()) {
+						case DiscoveredElement.PATHS_GROUP:
+						case DiscoveredElement.SYMBOLS_GROUP:
+							return elem.getChildren().length != 0;
+					}
+				}
+				return true;
+			}
+		});
+
+		setControl(composite);
+	}
+
+	/**
+	 * @author vhirsl
+	 */
+	private class DiscoveredContainerAdapter implements IDialogFieldListener, ITreeListAdapter {
+		private final Object[] EMPTY_ARR = new Object[0];
+
+		// ---------- IDialogFieldListener --------
+		/* (non-Javadoc)
+		 * @see org.eclipse.cdt.internal.ui.wizards.dialogfields.IDialogFieldListener#dialogFieldChanged(org.eclipse.cdt.internal.ui.wizards.dialogfields.DialogField)
+		 */
+		public void dialogFieldChanged(DialogField field) {
+			// TODO Auto-generated method stub
+			
+		}
+
+		// -------- IListAdapter --------
+		/* (non-Javadoc)
+		 * @see org.eclipse.cdt.internal.ui.wizards.dialogfields.ITreeListAdapter#customButtonPressed(org.eclipse.cdt.internal.ui.wizards.dialogfields.TreeListDialogField, int)
+		 */
+		public void customButtonPressed(TreeListDialogField field, int index) {
+			containerPageCustomButtonPressed(field, index);
+		}
+
+		/* (non-Javadoc)
+		 * @see org.eclipse.cdt.internal.ui.wizards.dialogfields.ITreeListAdapter#selectionChanged(org.eclipse.cdt.internal.ui.wizards.dialogfields.TreeListDialogField)
+		 */
+		public void selectionChanged(TreeListDialogField field) {
+			containerPageSelectionChanged(field);
+		}
+
+		/* (non-Javadoc)
+		 * @see org.eclipse.cdt.internal.ui.wizards.dialogfields.ITreeListAdapter#doubleClicked(org.eclipse.cdt.internal.ui.wizards.dialogfields.TreeListDialogField)
+		 */
+		public void doubleClicked(TreeListDialogField field) {
+			// TODO Auto-generated method stub
+
+		}
+
+		/* (non-Javadoc)
+		 * @see org.eclipse.cdt.internal.ui.wizards.dialogfields.ITreeListAdapter#keyPressed(org.eclipse.cdt.internal.ui.wizards.dialogfields.TreeListDialogField, org.eclipse.swt.events.KeyEvent)
+		 */
+		public void keyPressed(TreeListDialogField field, KeyEvent event) {
+			// TODO Auto-generated method stub
+
+		}
+
+		/* (non-Javadoc)
+		 * @see org.eclipse.cdt.internal.ui.wizards.dialogfields.ITreeListAdapter#getChildren(org.eclipse.cdt.internal.ui.wizards.dialogfields.TreeListDialogField, java.lang.Object)
+		 */
+		public Object[] getChildren(TreeListDialogField field, Object element) {
+			if (element instanceof DiscoveredElement) {
+				DiscoveredElement elem = (DiscoveredElement) element;
+				return elem.getChildren();
+			}
+			return EMPTY_ARR;
+		}
+
+		/* (non-Javadoc)
+		 * @see org.eclipse.cdt.internal.ui.wizards.dialogfields.ITreeListAdapter#getParent(org.eclipse.cdt.internal.ui.wizards.dialogfields.TreeListDialogField, java.lang.Object)
+		 */
+		public Object getParent(TreeListDialogField field, Object element) {
+			if (element instanceof DiscoveredElement) {
+				DiscoveredElement elem = (DiscoveredElement) element;
+				return elem.getParent();
+			}
+			return null;
+		}
+
+		/* (non-Javadoc)
+		 * @see org.eclipse.cdt.internal.ui.wizards.dialogfields.ITreeListAdapter#hasChildren(org.eclipse.cdt.internal.ui.wizards.dialogfields.TreeListDialogField, java.lang.Object)
+		 */
+		public boolean hasChildren(TreeListDialogField field, Object element) {
+			if (element instanceof DiscoveredElement) {
+				DiscoveredElement elem = (DiscoveredElement) element;
+				return elem.hasChildren();
+			}
+			return false;
+		}
+	}
+
+	/**
+	 * @param field
+	 * @param index
+	 */
+	private void containerPageCustomButtonPressed(TreeListDialogField field, int index) {
+		DiscoveredElement[] containers = null;
+		switch (index) {
+			case IDX_UP:
+				/* move entry up */
+				dirty |= moveUp();
+				break;
+			case IDX_DOWN:
+				/* move entry down */
+				dirty |= moveDown();
+				break;
+			case IDX_REMOVE:
+				/* remove */
+				dirty |= removeRestoreEntry(DO_REMOVE);
+				break;
+			case IDX_RESTORE:
+				/* restore */
+				dirty |= removeRestoreEntry(DO_RESTORE);
+				break;
+			case IDX_DELETE:
+				/* delete */
+				dirty |= deleteEntry();
+				break;
+		}
+	}
+	/**
+	 * 
+	 */
+	private boolean moveUp() {
+		boolean rc = false;
+		List selElements = fDiscoveredContainerList.getSelectedElements();
+		for (Iterator i = selElements.iterator(); i.hasNext(); ) {
+			DiscoveredElement elem = (DiscoveredElement) i.next();
+			DiscoveredElement parent = elem.getParent();
+			Object[] children = parent.getChildren();
+			for (int j = 0; j < children.length; ++j) {
+				DiscoveredElement child = (DiscoveredElement) children[j];
+				if (elem.equals(child)) {
+					int prevIndex = j - 1;
+					if (prevIndex >= 0) {
+						// swap the two
+						children[j] = children[prevIndex];
+						children[prevIndex] = elem;
+						rc = true;
+						break;
+					}
+				}
+			}
+			parent.setChildren(children);
+		}
+		fDiscoveredContainerList.refresh();
+		fDiscoveredContainerList.postSetSelection(new StructuredSelection(selElements));
+		fDiscoveredContainerList.setFocus();
+		return rc;
+	}
+	/**
+	 * 
+	 */
+	private boolean moveDown() {
+		boolean rc = false;
+		List selElements = fDiscoveredContainerList.getSelectedElements();
+		List revSelElements = new ArrayList(selElements);
+		Collections.reverse(revSelElements);
+		for (Iterator i = revSelElements.iterator(); i.hasNext(); ) {
+			DiscoveredElement elem = (DiscoveredElement) i.next();
+			DiscoveredElement parent = elem.getParent();
+			Object[] children = parent.getChildren();
+			for (int j = children.length - 1; j >= 0; --j) {
+				DiscoveredElement child = (DiscoveredElement) children[j];
+				if (elem.equals(child)) {
+					int prevIndex = j + 1;
+					if (prevIndex < children.length) {
+						// swap the two
+						children[j] = children[prevIndex];
+						children[prevIndex] = elem;
+						rc = true;
+						break;
+					}
+				}
+			}
+			parent.setChildren(children);
+		}
+		fDiscoveredContainerList.refresh();
+		fDiscoveredContainerList.postSetSelection(new StructuredSelection(selElements));
+		fDiscoveredContainerList.setFocus();
+		return rc;
+	}
+	/**
+	 * 
+	 * @param remove
+	 */
+	private boolean removeRestoreEntry(int action) {
+		boolean rc = false;
+		boolean remove = (action == DO_REMOVE);
+		List selElements = fDiscoveredContainerList.getSelectedElements();
+		for (int i = selElements.size() - 1; i >= 0; --i) {
+			DiscoveredElement elem = (DiscoveredElement) selElements.get(i);
+			switch (elem.getEntryKind()) {
+				case DiscoveredElement.INCLUDE_PATH:
+				case DiscoveredElement.SYMBOL_DEFINITION:
+					elem.setRemoved(remove);
+					rc = true;
+			}
+		}
+		fDiscoveredContainerList.refresh();
+		fDiscoveredContainerList.setFocus();
+		return rc;
+	}
+	/**
+	 * 
+	 */
+	private boolean deleteEntry() {
+		boolean rc = false;
+		List newSelection = new ArrayList();
+		List selElements = fDiscoveredContainerList.getSelectedElements();
+		for (int i = 0; i < selElements.size(); ++i) {
+			DiscoveredElement elem = (DiscoveredElement) selElements.get(i);
+			if (elem.getEntryKind() != DiscoveredElement.CONTAINER) {
+				DiscoveredElement parent = elem.getParent();
+				if (parent != null) {
+					Object[] children = parent.getChildren();
+					if (elem.delete()) {
+						switch (elem.getEntryKind()) {
+							case DiscoveredElement.PATHS_GROUP:
+								ScannerInfoCollector.getInstance().deleteAllPaths(fCProject.getProject());
+								break;
+							case DiscoveredElement.SYMBOLS_GROUP:
+								ScannerInfoCollector.getInstance().deleteAllSymbols(fCProject.getProject());
+								break;
+							case DiscoveredElement.INCLUDE_PATH:
+								ScannerInfoCollector.getInstance().deletePath(fCProject.getProject(), elem.getEntry());
+								break;
+							case DiscoveredElement.SYMBOL_DEFINITION:
+								ScannerInfoCollector.getInstance().deleteSymbol(fCProject.getProject(), elem.getEntry());
+								break;
+						}
+						rc = true;
+						// set new selection
+						for (int j = 0; j < children.length; ++j) {
+							DiscoveredElement child = (DiscoveredElement) children[j];
+							if (elem.equals(child)) {
+								newSelection.clear();
+								if (j + 1 < children.length) {
+									newSelection.add(children[j + 1]);
+								}
+								else if (j - 1 >= 0) {
+									newSelection.add(children[j - 1]);
+								}
+								else {
+									newSelection.add(parent);
+								}
+								break;
+							}
+						}
+					}
+				}
+			}
+		}
+		fDiscoveredContainerList.refresh();
+		fDiscoveredContainerList.postSetSelection(new StructuredSelection(newSelection));
+		fDiscoveredContainerList.setFocus();
+		return rc;
+	}
+
+	/**
+	 * @param field
+	 */
+	private void containerPageSelectionChanged(TreeListDialogField field) {
+		List selElements = fDiscoveredContainerList.getSelectedElements();
+		fDiscoveredContainerList.enableButton(IDX_UP, canMoveUpDown(selElements, DISC_UP));
+		fDiscoveredContainerList.enableButton(IDX_DOWN, canMoveUpDown(selElements, DISC_DOWN));
+		fDiscoveredContainerList.enableButton(IDX_REMOVE, canRemoveRestore(selElements));
+		fDiscoveredContainerList.enableButton(IDX_RESTORE, canRemoveRestore(selElements));
+		fDiscoveredContainerList.enableButton(IDX_DELETE, canDelete(selElements));
+	}
+	/**
+	 * @param selElements
+	 * @return
+	 */
+	private boolean canMoveUpDown(List selElements, int direction) {
+		if (selElements.size() == 0) {
+			return false;
+		}
+		for (int i = 0; i < selElements.size(); i++) {
+			DiscoveredElement elem = (DiscoveredElement) selElements.get(i);
+			switch (elem.getEntryKind()) {
+				case DiscoveredElement.CONTAINER:
+				case DiscoveredElement.PATHS_GROUP:
+				case DiscoveredElement.SYMBOLS_GROUP:
+				case DiscoveredElement.SYMBOL_DEFINITION:
+					return false;
+			}
+			DiscoveredElement parent = elem.getParent();
+			DiscoveredElement borderElem = null;
+			int borderElementIndex = (direction == DISC_UP) ? 0 : parent.getChildren().length - 1;
+			if (parent.getEntryKind() == DiscoveredElement.PATHS_GROUP) {
+				borderElem = (DiscoveredElement)(parent.getChildren())[borderElementIndex];
+			}
+			if (borderElem != null) {
+				if (borderElem.equals(elem)) {
+					return false;
+				}
+			}
+		}
+		return true;
+	}
+	/**
+	 * @param selElements
+	 * @return
+	 */
+	private boolean canRemoveRestore(List selElements) {
+		if (selElements.size() == 0) {
+			return false;
+		}
+		for (int i = 0; i < selElements.size(); i++) {
+			DiscoveredElement elem = (DiscoveredElement) selElements.get(i);
+			switch (elem.getEntryKind()) {
+				case DiscoveredElement.CONTAINER:
+				case DiscoveredElement.PATHS_GROUP:
+				case DiscoveredElement.SYMBOLS_GROUP:
+					return false;
+			}
+		}
+		return true;
+	}
+	/**
+	 * @param selElements
+	 * @return
+	 */
+	private boolean canDelete(List selElements) {
+		if (selElements.size() == 0) {
+			return false;
+		}
+		for (int i = 0; i < selElements.size(); i++) {
+			DiscoveredElement elem = (DiscoveredElement) selElements.get(i);
+			if (elem.getEntryKind() == DiscoveredElement.CONTAINER) {
+					return false;
+			}
+		}
+		return true;
+	}
+}
Index: src/org/eclipse/cdt/make/ui/dialogs/DiscoveryOptionsBlock.java
===================================================================
RCS file: src/org/eclipse/cdt/make/ui/dialogs/DiscoveryOptionsBlock.java
diff -N src/org/eclipse/cdt/make/ui/dialogs/DiscoveryOptionsBlock.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ src/org/eclipse/cdt/make/ui/dialogs/DiscoveryOptionsBlock.java	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,563 @@
+/**********************************************************************
+ * 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 - Initial API and implementation
+ **********************************************************************/
+package org.eclipse.cdt.make.ui.dialogs;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.cdt.core.model.CModelException;
+import org.eclipse.cdt.core.model.CoreModel;
+import org.eclipse.cdt.core.model.ICProject;
+import org.eclipse.cdt.core.model.IPathEntry;
+import org.eclipse.cdt.make.core.MakeCorePlugin;
+import org.eclipse.cdt.make.core.MakeProjectNature;
+import org.eclipse.cdt.make.core.scannerconfig.IScannerConfigBuilderInfo;
+import org.eclipse.cdt.make.core.scannerconfig.ScannerConfigBuilder;
+import org.eclipse.cdt.make.core.scannerconfig.ScannerConfigNature;
+import org.eclipse.cdt.make.internal.core.scannerconfig.DiscoveredPathContainer;
+import org.eclipse.cdt.make.internal.ui.MakeUIPlugin;
+import org.eclipse.cdt.make.ui.IMakeHelpContextIds;
+import org.eclipse.cdt.ui.dialogs.AbstractCOptionPage;
+import org.eclipse.cdt.ui.dialogs.ICOptionContainer;
+import org.eclipse.cdt.utils.ui.controls.ControlFactory;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IExtension;
+import org.eclipse.core.runtime.IExtensionPoint;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.Preferences;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Combo;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Group;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Listener;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.ui.help.WorkbenchHelp;
+
+/**
+ * A dialog to set scanner config discovery options
+ * 
+ * @author vhirsl
+ */
+public class DiscoveryOptionsBlock extends AbstractCOptionPage {
+	private static final String PREFIX_BP = "BuildPathInfoBlock"; //$NON-NLS-1$
+	private static final String SC_GROUP_LABEL = PREFIX_BP + ".scGroup.label";	//$NON-NLS-1$
+	private static final String SC_ENABLED_LABEL = PREFIX_BP + ".scGroup.enabled.label";	//$NON-NLS-1$
+//	private static final String SC_OPTIONS_LABEL = PREFIX + ".scGroup.options.label";	//$NON-NLS-1$
+	private static final String MISSING_BUILDER_MSG = "ScannerConfigOptionsDialog.label.missingBuilderInformation";	//$NON-NLS-1$
+
+	private static final String PREFIX = "ScannerConfigOptionsDialog"; //$NON-NLS-1$
+	private static final String DIALOG_TITLE = PREFIX + ".title"; //$NON-NLS-1$
+	private static final String DIALOG_DESCRIPTION = PREFIX + ".description"; //$NON-NLS-1$
+	private static final String SI_BUILD_PARSER_GROUP = PREFIX + ".siBuilder.parser.group_label"; //$NON-NLS-1$ 
+	private static final String ENABLE_SI_BUILD_PARSER = PREFIX + ".siBuilder.parser.enable.label"; //$NON-NLS-1$
+	private static final String SI_BUILD_PARSER_LABEL = PREFIX + ".siBuilder.parser.label"; //$NON-NLS-1$
+	private static final String SI_PROVIDER_CMD_GROUP = PREFIX + ".siProvider.cmd.group_label"; //$NON-NLS-1$
+	private static final String ENABLE_SI_PROVIDER_COMMAND = PREFIX + ".siProvider.cmd.enable.label";	//$NON-NLS-1$
+	private static final String SI_PROVIDER_CMD_USE_DEFAULT = PREFIX + ".siProvider.cmd.use_default"; //$NON-NLS-1$
+	private static final String SI_PROVIDER_CMD_LABEL = PREFIX + ".siProvider.cmd.label"; //$NON-NLS-1$
+	private static final String SI_PROVIDER_PARSER_LABEL = PREFIX + ".siProvider.parser.label"; //$NON-NLS-1$
+	private static final String SI_PROVIDER_CMD_ERROR_MESSAGE = PREFIX + ".siProvider.cmd.error_message"; //$NON-NLS-1$
+
+	private Button scEnabledButton;
+	private boolean needsSCNature = false;
+
+	private Button defESIProviderCommandButton;
+	private Text esiProviderCommand;
+	private Button enableBuilderParserButton;
+	private Combo makeBuilderSIParserComboBox;
+	private Button enableProviderCommandButton;
+	private Combo esiProviderParserComboBox;
+
+	private Preferences fPrefs;
+	private IScannerConfigBuilderInfo fBuildInfo;
+	private boolean fInitialized = false;
+	private Map builderParsers = new HashMap();
+	private String initialBuilderParserId = null;
+	private Map providerParsers = new HashMap();
+	private String initialProviderParserId = null;
+	private boolean fCreatePathContainer = false;
+	
+
+	public DiscoveryOptionsBlock() {
+		super(MakeUIPlugin.getResourceString(DIALOG_TITLE));
+		setDescription(MakeUIPlugin.getResourceString(DIALOG_DESCRIPTION));
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.cdt.ui.dialogs.ICOptionPage#setContainer(org.eclipse.cdt.ui.dialogs.ICOptionContainer)
+	 */
+	public void setContainer(ICOptionContainer container) {
+		super.setContainer(container);
+
+		fPrefs = getContainer().getPreferences();
+		IProject project = getContainer().getProject();
+
+		fInitialized = true;
+		if (project != null) {
+			try {
+				fBuildInfo = MakeCorePlugin.createScannerConfigBuildInfo(project, ScannerConfigBuilder.BUILDER_ID);
+			}
+			catch (CoreException e) {
+				fInitialized = false;
+				fBuildInfo = MakeCorePlugin.createScannerConfigBuildInfo(fPrefs, ScannerConfigBuilder.BUILDER_ID, true);
+			}
+		}
+		else {
+			fBuildInfo = MakeCorePlugin.createScannerConfigBuildInfo(fPrefs, ScannerConfigBuilder.BUILDER_ID, false);
+			fCreatePathContainer = true;
+		}
+		retrieveSIConsoleParsers();
+		initialBuilderParserId = fBuildInfo.getMakeBuilderConsoleParserId();	//$NON-NLS-1$
+		initialProviderParserId = fBuildInfo.getESIProviderConsoleParserId();	//$NON-NLS-1$
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.cdt.ui.dialogs.ICOptionPage#performApply(org.eclipse.core.runtime.IProgressMonitor)
+	 */
+	public void performApply(IProgressMonitor monitor) throws CoreException {
+		IProject project = getContainer().getProject();
+		IScannerConfigBuilderInfo buildInfo;
+		if (project != null) {
+			buildInfo = MakeCorePlugin.createScannerConfigBuildInfo(project, ScannerConfigBuilder.BUILDER_ID);
+			if (fCreatePathContainer) {
+				createDiscoveredPathContainer(project);
+			}
+		}
+		else {
+			buildInfo = MakeCorePlugin.createScannerConfigBuildInfo(fPrefs, ScannerConfigBuilder.BUILDER_ID, false);
+		}
+
+		buildInfo.setAutoDiscoveryEnabled(isScannerConfigDiscoveryEnabled());
+		if (isScannerConfigDiscoveryEnabled()) {
+			buildInfo.setMakeBuilderConsoleParserEnabled(isBuilderParserEnabled());
+			if (isBuilderParserEnabled()) {
+				buildInfo.setMakeBuilderConsoleParserId((String) builderParsers.get(makeBuilderSIParserComboBox.getText()));
+			}
+			buildInfo.setESIProviderCommandEnabled(isProviderCommandEnabled());
+			if (isProviderCommandEnabled()) {
+				buildInfo.setUseDefaultESIProviderCmd(useDefaultESIProviderCmd());
+				if (!useDefaultESIProviderCmd()) {
+					storeSIProviderCommandLine(buildInfo);
+				}
+				buildInfo.setESIProviderConsoleParserId((String) providerParsers.get(esiProviderParserComboBox.getText()));
+			}
+		}
+	}
+
+	/**
+	 * @param project
+	 * @throws CModelException
+	 */
+	private void createDiscoveredPathContainer(IProject project) throws CModelException {
+		IPathEntry container = CoreModel.newContainerEntry(DiscoveredPathContainer.CONTAINER_ID);
+		ICProject cProject = CoreModel.getDefault().create(project);
+		if (cProject != null) {
+			IPathEntry[] entries = cProject.getRawPathEntries();
+			List newEntries = new ArrayList(Arrays.asList(entries));
+			if (!newEntries.contains(container)) {
+				newEntries.add(container);
+				cProject.setRawPathEntries((IPathEntry[])newEntries.
+						toArray(new IPathEntry[newEntries.size()]), new NullProgressMonitor());
+			}
+		}
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.cdt.ui.dialogs.ICOptionPage#performDefaults()
+	 */
+	public void performDefaults() {
+		IScannerConfigBuilderInfo info;
+		// Populate with the default values
+		if (getContainer().getProject() != null) {
+			// get the preferences
+			info = MakeCorePlugin.createScannerConfigBuildInfo(fPrefs, ScannerConfigBuilder.BUILDER_ID, false);
+		}
+		else {
+			// get the defaults
+			info = MakeCorePlugin.createScannerConfigBuildInfo(fPrefs, ScannerConfigBuilder.BUILDER_ID, true);
+		}
+		
+		setScannerConfigDiscoveryEnabled(info.isAutoDiscoveryEnabled());
+		enableBuilderParserButton.setSelection(info.isMakeBuilderConsoleParserEnabled());
+		makeBuilderSIParserComboBox.setText(getParserName(builderParsers, info.getMakeBuilderConsoleParserId()));
+		enableProviderCommandButton.setSelection(info.isESIProviderCommandEnabled());
+		defESIProviderCommandButton.setSelection(info.isDefaultESIProviderCmd());
+		setESIProviderCommand(info);
+		esiProviderParserComboBox.setText(getParserName(providerParsers, info.getESIProviderConsoleParserId()));
+		
+		enableAllControls();
+	}
+
+	/**
+	 * @param parsers
+	 * @param consoleParserId
+	 * @return
+	 */
+	private String getParserName(Map parsers, String consoleParserId) {
+		for (Iterator i = parsers.keySet().iterator(); i.hasNext(); ) {
+			String parserName = (String) i.next();
+			String parserId = (String) parsers.get(parserName);
+			if (parserId.equals(consoleParserId)) {
+				return parserName;
+			}
+		}
+		return consoleParserId;
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.dialogs.IDialogPage#createControl(org.eclipse.swt.widgets.Composite)
+	 */
+	public void createControl(Composite parent) {
+		// Create the composite control for the tab
+		int tabColumns = 2;
+		Font font = parent.getFont();
+		Composite composite = ControlFactory.createComposite(parent, tabColumns);
+		((GridLayout) composite.getLayout()).makeColumnsEqualWidth = false;
+		composite.setFont(font);
+		GridData gd;
+		setControl(composite);
+
+		WorkbenchHelp.setHelp(getControl(), IMakeHelpContextIds.SCANNER_CONFIG_DISCOVERY_OPTIONS);
+
+		// Create a group for scanner config discovery
+		if (createScannerConfigControls(composite, tabColumns)) {
+			createBuildOutputParserControls(composite);
+			createAfterBuildCmdControls(composite);
+			// enable controls depending on the state of auto discovery
+			enableAllControls();
+		}
+	}
+
+	/**
+	 * @param composite
+	 */
+	private boolean createScannerConfigControls(Composite parent, int numColumns) {
+		// Check if it is an old project
+		IProject project = getContainer().getProject();
+		boolean showMissingBuilder = false;
+		try {
+			if (project != null &&
+					project.hasNature(MakeProjectNature.NATURE_ID) &&
+					!project.hasNature(ScannerConfigNature.NATURE_ID)) {
+				needsSCNature = true;	// an old project
+			}
+		} 
+		catch (CoreException e) {
+			showMissingBuilder = true;
+		}
+		
+		Group scGroup = ControlFactory.createGroup(parent, MakeUIPlugin.getResourceString(SC_GROUP_LABEL), numColumns);
+		scGroup.setFont(parent.getFont());
+		((GridData) scGroup.getLayoutData()).grabExcessHorizontalSpace = true;
+		((GridData) scGroup.getLayoutData()).horizontalSpan = numColumns;
+		((GridData) scGroup.getLayoutData()).horizontalAlignment = GridData.FILL;
+		
+		if (showMissingBuilder || (!needsSCNature && !fInitialized)) {
+			ControlFactory.createLabel(scGroup, MakeUIPlugin.getResourceString(MISSING_BUILDER_MSG));
+			return false;
+		}
+		
+		// Add checkbox
+		scEnabledButton = ControlFactory.createCheckBox(scGroup, MakeUIPlugin.getResourceString(SC_ENABLED_LABEL));
+		scEnabledButton.setFont(parent.getFont());
+		((GridData) scEnabledButton.getLayoutData()).horizontalSpan = numColumns;
+		((GridData) scEnabledButton.getLayoutData()).grabExcessHorizontalSpace = true;
+		// VMIR* old projects will have discovery disabled by default
+		scEnabledButton.setSelection(needsSCNature ? false : fBuildInfo.isAutoDiscoveryEnabled());
+		scEnabledButton.addSelectionListener(new SelectionAdapter() {
+			public void widgetSelected(SelectionEvent e) {
+				handleScannerConfigEnable();
+			}
+		});
+//		handleScannerConfigEnable(); Only if true in VMIR*
+		return true;
+	}
+
+	/**
+	 * Handles scanner configuration discovery selection change
+	 */
+	protected void handleScannerConfigEnable() {
+		boolean enable = scEnabledButton.getSelection();
+		if (enable && needsSCNature) {
+			// first install the SC nature
+			try {
+				ScannerConfigNature.addScannerConfigNature(getContainer().getProject());
+				needsSCNature = false;
+			} 
+			catch (CoreException e) {
+				MakeCorePlugin.log(e.getStatus());
+			}
+		}
+		enableAllControls();
+	}
+
+	/**
+	 * Fills console parser maps
+	 */
+	private void retrieveSIConsoleParsers() {
+		IExtensionPoint ep = Platform.getExtensionRegistry().
+			getExtensionPoint(MakeCorePlugin.getUniqueIdentifier(), MakeCorePlugin.SI_CONSOLE_PARSER_SIMPLE_ID);
+		if (ep != null) {
+			IExtension[] extensions = ep.getExtensions();
+			for (int i = 0; i < extensions.length; ++i) {
+				String parserId = extensions[i].getUniqueIdentifier();
+				String label = extensions[i].getLabel();
+				IConfigurationElement[] elements = extensions[i].getConfigurationElements();
+				String commandId = elements[0].getAttribute("commandId");	//$NON-NLS-1$
+				if (commandId.equals("makeBuilder") || commandId.equals("all")) {	//$NON-NLS-1$//$NON-NLS-2$
+					builderParsers.put(label, parserId);
+				}
+				if (commandId.equals("externalScannerInfoProvider") || commandId.equals("all")) {	//$NON-NLS-1$//$NON-NLS-2$
+					providerParsers.put(label, parserId);
+				}
+			}
+		}
+	}
+
+	private void createBuildOutputParserControls(Composite parent) {
+//		ControlFactory.insertSpace(parent, 1, 10);
+		Group bopGroup = ControlFactory.createGroup(parent, 
+			MakeUIPlugin.getResourceString(SI_BUILD_PARSER_GROUP), 2);
+		((GridLayout)bopGroup.getLayout()).marginHeight = 5;
+		((GridLayout)bopGroup.getLayout()).marginWidth = 5;
+		((GridData)bopGroup.getLayoutData()).verticalAlignment = GridData.FILL;
+		((GridData)bopGroup.getLayoutData()).horizontalSpan = 2;
+
+		enableBuilderParserButton = ControlFactory.createCheckBox(bopGroup, 
+			MakeUIPlugin.getResourceString(ENABLE_SI_BUILD_PARSER));
+		((GridData)enableBuilderParserButton.getLayoutData()).horizontalSpan = 2;
+		boolean enabledBuilderParser = fBuildInfo.isMakeBuilderConsoleParserEnabled();
+		enableBuilderParserButton.setSelection(enabledBuilderParser);
+		enableBuilderParserButton.addSelectionListener(new SelectionAdapter() {
+			public void widgetSelected(SelectionEvent e) {
+				makeBuilderSIParserComboBox.setEnabled(isBuilderParserEnabled());
+			}
+		});
+			
+		Label label = ControlFactory.createLabel(bopGroup, 
+				MakeUIPlugin.getResourceString(SI_BUILD_PARSER_LABEL));
+		((GridData)label.getLayoutData()).grabExcessHorizontalSpace = false;
+		
+		makeBuilderSIParserComboBox = new Combo(bopGroup, SWT.DROP_DOWN | SWT.READ_ONLY);
+
+		// fill the combobox and set the initial value
+		for (Iterator items = builderParsers.keySet().iterator(); items.hasNext(); ) {
+			String parser = (String) items.next();
+			makeBuilderSIParserComboBox.add(parser);
+			if (initialBuilderParserId.equals(builderParsers.get(parser))) {
+				makeBuilderSIParserComboBox.setText(parser);
+			}
+		}
+		makeBuilderSIParserComboBox.setEnabled(enabledBuilderParser);
+	}
+	
+	private void createAfterBuildCmdControls(Composite parent) {
+		Group abcGroup = ControlFactory.createGroup(parent, 
+				MakeUIPlugin.getResourceString(SI_PROVIDER_CMD_GROUP), 2);
+		((GridData)abcGroup.getLayoutData()).horizontalSpan = 2;
+		
+		enableProviderCommandButton = ControlFactory.createCheckBox(abcGroup, 
+				MakeUIPlugin.getResourceString(ENABLE_SI_PROVIDER_COMMAND));
+		((GridData)enableProviderCommandButton.getLayoutData()).horizontalSpan = 2;
+		((GridData)enableProviderCommandButton.getLayoutData()).horizontalAlignment = GridData.FILL_HORIZONTAL;
+		boolean enabledProviderCommand = fBuildInfo.isESIProviderCommandEnabled();
+		enableProviderCommandButton.setSelection(enabledProviderCommand);
+		enableProviderCommandButton.addSelectionListener(new SelectionAdapter() {
+			public void widgetSelected(SelectionEvent e) {
+				defESIProviderCommandButton.setEnabled(isProviderCommandEnabled());
+				esiProviderCommand.setEnabled(isProviderCommandEnabled() && !useDefaultESIProviderCmd());
+				esiProviderParserComboBox.setEnabled(isProviderCommandEnabled());
+				getContainer().updateContainer();
+			}
+		});
+		
+		createESIProviderCmdControls(abcGroup);
+
+		Label label = ControlFactory.createLabel(abcGroup, 
+				MakeUIPlugin.getResourceString(SI_PROVIDER_PARSER_LABEL));
+		((GridData)label.getLayoutData()).grabExcessHorizontalSpace = false;
+		
+		esiProviderParserComboBox = new Combo(abcGroup, SWT.DROP_DOWN | SWT.READ_ONLY);
+
+		// fill the combobox and set the initial value
+		for (Iterator items = providerParsers.keySet().iterator(); items.hasNext(); ) {
+			String parser = (String) items.next();
+			esiProviderParserComboBox.add(parser);
+			if (initialProviderParserId.equals(providerParsers.get(parser))) {
+				esiProviderParserComboBox.setText(parser);
+			}
+		}
+		defESIProviderCommandButton.setEnabled(enabledProviderCommand);
+		esiProviderCommand.setEnabled(enabledProviderCommand && !useDefaultESIProviderCmd());
+		esiProviderParserComboBox.setEnabled(enabledProviderCommand);
+	}
+	
+	private void createESIProviderCmdControls(Composite parent) {
+		defESIProviderCommandButton = ControlFactory.createCheckBox(parent, 
+				MakeUIPlugin.getResourceString(SI_PROVIDER_CMD_USE_DEFAULT));
+		defESIProviderCommandButton.addSelectionListener(new SelectionAdapter() {
+			public void widgetSelected(SelectionEvent e) {
+				esiProviderCommand.setEnabled(!useDefaultESIProviderCmd());
+				getContainer().updateContainer();
+			}
+		});
+		((GridData) (defESIProviderCommandButton.getLayoutData())).horizontalAlignment = GridData.FILL_HORIZONTAL;
+		((GridData) (defESIProviderCommandButton.getLayoutData())).horizontalSpan = 2;
+		Label label = ControlFactory.createLabel(parent, 
+				MakeUIPlugin.getResourceString(SI_PROVIDER_CMD_LABEL));
+		((GridData) (label.getLayoutData())).horizontalAlignment = GridData.BEGINNING;
+		((GridData) (label.getLayoutData())).grabExcessHorizontalSpace = false;
+		esiProviderCommand = ControlFactory.createTextField(parent, SWT.SINGLE | SWT.BORDER);
+		((GridData) (esiProviderCommand.getLayoutData())).horizontalAlignment = GridData.FILL;
+		((GridData) (esiProviderCommand.getLayoutData())).grabExcessHorizontalSpace = true;
+		setESIProviderCommand(fBuildInfo);
+		if (fBuildInfo.isDefaultESIProviderCmd()) {
+			esiProviderCommand.setEnabled(false);
+		}
+		esiProviderCommand.addListener(SWT.Modify, new Listener() {
+			public void handleEvent(Event e) {
+				getContainer().updateContainer();
+			}
+		});
+		defESIProviderCommandButton.setSelection(fBuildInfo.isDefaultESIProviderCmd());
+	}
+
+	/**
+	 * 
+	 */
+	private void setESIProviderCommand(IScannerConfigBuilderInfo buildInfo) {
+		IPath sCommand = buildInfo.getESIProviderCommand();
+		if (sCommand != null) {
+			StringBuffer cmd = new StringBuffer(sCommand.toOSString());
+			String args = buildInfo.getESIProviderArguments();
+			if (args != null && args.length() > 0) { 
+				cmd.append(' ');
+				cmd.append(args);
+			}
+			esiProviderCommand.setText(cmd.toString());
+		}
+	}
+
+	/**
+	 * @param enable
+	 */
+	private void enableAllControls() {
+		enableBuilderParserButton.setEnabled(isScannerConfigDiscoveryEnabled());
+		makeBuilderSIParserComboBox.setEnabled(isScannerConfigDiscoveryEnabled() && isBuilderParserEnabled());
+		enableProviderCommandButton.setEnabled(isScannerConfigDiscoveryEnabled());
+		defESIProviderCommandButton.setEnabled(isScannerConfigDiscoveryEnabled() && isProviderCommandEnabled());
+		esiProviderCommand.setEnabled(isScannerConfigDiscoveryEnabled() && isProviderCommandEnabled() && !useDefaultESIProviderCmd());
+		esiProviderParserComboBox.setEnabled(isScannerConfigDiscoveryEnabled() && isProviderCommandEnabled());
+	}
+
+	private boolean useDefaultESIProviderCmd() {
+		return defESIProviderCommandButton.getSelection();
+	}
+
+	private String getSIProviderCommandLine() {
+		return esiProviderCommand.getText().trim();
+	}
+
+	private boolean isBuilderParserEnabled() {
+		return enableBuilderParserButton.getSelection();
+	}
+
+	private boolean isProviderCommandEnabled() {
+		return enableProviderCommandButton.getSelection();
+	}
+
+	/**
+	 * Retrieves the state of scanner config discovery
+	 * 
+	 * @return boolean
+	 */
+	private boolean isScannerConfigDiscoveryEnabled() {
+		return scEnabledButton.getSelection();
+	}
+	
+	/**
+	 * Enables or disables the scanner config discovery
+	 * 
+	 * @param enabled (boolean)
+	 */
+	private void setScannerConfigDiscoveryEnabled(boolean enabled) {
+		scEnabledButton.setSelection(enabled);
+	}
+
+	/**
+	 * @param buildInfo
+	 * @throws CoreException
+	 */
+	private void storeSIProviderCommandLine(IScannerConfigBuilderInfo buildInfo) throws CoreException {
+		String esiProviderLine = getSIProviderCommandLine();
+		int start = 0;
+		int end = -1;
+		if (esiProviderLine.startsWith("\"")) { //$NON-NLS-1$
+			start = 1;
+			end = esiProviderLine.indexOf('"', 1);
+		}
+		else {
+			end = esiProviderLine.indexOf(' ');
+		}
+		IPath path;
+		if (end == -1) {
+			path = new Path(esiProviderLine);
+		} else {
+			path = new Path(esiProviderLine.substring(start, end));
+		}
+		buildInfo.setESIProviderCommand(path);
+		String args = ""; //$NON-NLS-1$
+		if (end != -1) {
+			args = esiProviderLine.substring(end + 1);
+		}
+		buildInfo.setESIProviderArguments(args);
+	}
+	/* (non-Javadoc)
+	 * @see org.eclipse.cdt.ui.dialogs.ICOptionPage#isValid()
+	 */
+	public boolean isValid() {
+		if (isProviderCommandEnabled() == true && 
+				useDefaultESIProviderCmd() == false) {
+			String cmd = getSIProviderCommandLine();
+			if (cmd == null || cmd.length() == 0) {
+				return false;
+			}
+		}
+		return true;
+	}
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.dialogs.IDialogPage#getErrorMessage()
+	 */
+	public String getErrorMessage() {
+		if (!isValid()) {
+			return MakeUIPlugin.getResourceString(SI_PROVIDER_CMD_ERROR_MESSAGE);
+		}
+		return null;
+	}
+}
Index: src/org/eclipse/cdt/internal/ui/dialogs/cpaths/CPElementSorter.java
===================================================================
RCS file: /home/tools/org.eclipse.cdt-core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/dialogs/cpaths/CPElementSorter.java,v
retrieving revision 1.1
diff -u -r1.1 CPElementSorter.java
--- src/org/eclipse/cdt/internal/ui/dialogs/cpaths/CPElementSorter.java	28 Apr 2004 17:46:29 -0000	1.1
+++ src/org/eclipse/cdt/internal/ui/dialogs/cpaths/CPElementSorter.java	24 May 2004 21:59:49 -0000
@@ -9,6 +9,7 @@
 package org.eclipse.cdt.internal.ui.dialogs.cpaths;
 
 import org.eclipse.cdt.core.model.IPathEntry;
+import org.eclipse.jface.viewers.Viewer;
 import org.eclipse.jface.viewers.ViewerSorter;
 
 public class CPElementSorter extends ViewerSorter {
@@ -38,4 +39,19 @@
 		return OTHER;
 	}
 
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.viewers.ViewerSorter#sort(org.eclipse.jface.viewers.Viewer, java.lang.Object[])
+	 */
+	public void sort(Viewer viewer, Object[] elements) {
+		// include paths and symbol definitions must not be sorted
+		if (elements.length > 0 && elements[0] instanceof CPElement) {
+			CPElement firstElement = (CPElement) elements[0];
+			switch (firstElement.getEntryKind()) {
+				case IPathEntry.CDT_INCLUDE:
+				case IPathEntry.CDT_MACRO:
+					return;
+			}
+		}
+		super.sort(viewer, elements);
+	}
 }

Back to the top