more workspace model changes
diff --git a/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/AbstractModelManager.java b/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/AbstractModelManager.java
index 229555f..b92b3e9 100644
--- a/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/AbstractModelManager.java
+++ b/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/AbstractModelManager.java
@@ -13,17 +13,12 @@
 import java.util.ArrayList;
 import java.util.Iterator;
 
-import org.eclipse.core.runtime.IAdaptable;
 import org.eclipse.pde.core.IModelProviderListener;
 
-public abstract class AbstractModelManager implements IAdaptable {
+public abstract class AbstractModelManager {
 	
 	private ArrayList fListeners = new ArrayList();
 
-	public Object getAdapter(Class adapter) {
-		return null;
-	}
-	
 	protected abstract void initialize();
 	
 	/* (non-Javadoc)
diff --git a/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/AbstractNLModel.java b/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/AbstractNLModel.java
index 47be872..e90a01b 100644
--- a/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/AbstractNLModel.java
+++ b/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/AbstractNLModel.java
@@ -38,7 +38,7 @@
 		if (fNLHelper == null)
 			fNLHelper = createNLResourceHelper();
 		
-		return fNLHelper != null ? fNLHelper.getResourceString(key) : null;
+		return fNLHelper != null ? fNLHelper.getResourceString(key) : key;
 	}
 	
 	protected abstract NLResourceHelper createNLResourceHelper();
diff --git a/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/ExternalModelManager.java b/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/ExternalModelManager.java
index d2a7fd3..25c4a8c 100644
--- a/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/ExternalModelManager.java
+++ b/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/ExternalModelManager.java
@@ -32,35 +32,13 @@
 	public static String computeDefaultPlatformPath() {
 		URL installURL = Platform.getInstallLocation().getURL();
 		IPath ppath = new Path(installURL.getFile()).removeTrailingSeparator();
-		return getCorrectPath(ppath.toOSString());
+		return ppath.toOSString();
 	}
 	
 	public static boolean isTargetEqualToHost(String platformPath) {
 		return arePathsEqual(new Path(platformPath), new Path(computeDefaultPlatformPath()));
 	}
 	
-	private static String getCorrectPath(String path) {
-		StringBuffer buf = new StringBuffer();
-		for (int i = 0; i < path.length(); i++) {
-			char c = path.charAt(i);
-			if (Platform.getOS().equals("win32")) { //$NON-NLS-1$
-				if (i == 0 && c == '/')
-					continue;
-			}
-			// Some VMs may return %20 instead of a space
-			if (c == '%' && i + 2 < path.length()) {
-				char c1 = path.charAt(i + 1);
-				char c2 = path.charAt(i + 2);
-				if (c1 == '2' && c2 == '0') {
-					i += 2;
-					buf.append(" "); //$NON-NLS-1$
-					continue;
-				}
-			}
-			buf.append(c);
-		}
-		return buf.toString();
-	}	
 	public static IPath getEclipseHome() {
 		Preferences preferences = PDECore.getDefault().getPluginPreferences();
 		return new Path(preferences.getString(ICoreConstants.PLATFORM_PATH));
diff --git a/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/PDECore.java b/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/PDECore.java
index 18fd73f..8c8c7cd 100644
--- a/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/PDECore.java
+++ b/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/PDECore.java
@@ -30,6 +30,7 @@
 import org.eclipse.pde.core.plugin.IPluginModel;
 import org.eclipse.pde.core.plugin.IPluginModelBase;
 import org.eclipse.pde.internal.core.builders.CompilerFlags;
+import org.eclipse.pde.internal.core.builders.FeatureRebuilder;
 import org.eclipse.pde.internal.core.ifeature.IFeature;
 import org.eclipse.pde.internal.core.ifeature.IFeatureModel;
 import org.eclipse.pde.internal.core.schema.SchemaRegistry;
@@ -149,6 +150,8 @@
 	private BundleContext fBundleContext;
 	private JavaElementChangeListener fJavaElementChangeListener;
 
+	private FeatureRebuilder fFeatureRebuilder;
+
 	public PDECore() {
 		inst = this;
 	}
@@ -208,18 +211,6 @@
 	}
 
 	/**
-	 * Finds a feature with the given ID, any version
-	 * @param id
-	 * @return IFeature or null
-	 */
-	public IFeature findFeature(String id) {
-		IFeatureModel[] models = getFeatureModelManager().findFeatureModels(id);
-		if (models.length > 0)
-			return models[0].getFeature();
-		return null;
-	}
-
-	/**
 	 * Finds a feature with the given ID and satisfying constraints
 	 * of the version and the match.
 	 * @param id
@@ -311,6 +302,8 @@
 		CompilerFlags.initializeDefaults();
 		fJavaElementChangeListener = new JavaElementChangeListener();
 		fJavaElementChangeListener.start();
+		fFeatureRebuilder = new FeatureRebuilder();
+		fFeatureRebuilder.start();
 	}
 
 	public BundleContext getBundleContext() {
@@ -319,10 +312,10 @@
 
 	public void stop(BundleContext context) throws CoreException {
 		PDECore.getDefault().savePluginPreferences();
-		if (fJavaElementChangeListener != null) {
-			fJavaElementChangeListener.shutdown();
-			fJavaElementChangeListener = null;
-		}
+		
+		fJavaElementChangeListener.shutdown();
+		fFeatureRebuilder.stop();
+		
 		if (fSchemaRegistry != null) {
 			fSchemaRegistry.shutdown();
 			fSchemaRegistry = null;
diff --git a/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/PluginModelManager.java b/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/PluginModelManager.java
index 4e1086a..8655462 100644
--- a/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/PluginModelManager.java
+++ b/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/PluginModelManager.java
@@ -209,7 +209,6 @@
 		if ((e.getEventTypes() & IModelProviderEvent.MODELS_REMOVED) != 0) {
 			IModel[] removed = e.getRemovedModels();
 			for (int i = 0; i < removed.length; i++) {
-				if (!(removed[i] instanceof IPluginModelBase)) continue;
 				IPluginModelBase model = (IPluginModelBase) removed[i];
 				IPluginBase plugin = model.getPluginBase();
 				ModelEntry entry = updateTable(plugin.getId(), model, false, delta);
@@ -220,7 +219,6 @@
 		if ((e.getEventTypes() & IModelProviderEvent.MODELS_ADDED) != 0) {
 			IModel[] added = e.getAddedModels();
 			for (int i = 0; i < added.length; i++) {
-				if (!(added[i] instanceof IPluginModelBase)) continue;
 				IPluginModelBase model = (IPluginModelBase) added[i];
 				IPluginBase plugin = model.getPluginBase();
 				ModelEntry entry = updateTable(plugin.getId(), model, true, delta);
@@ -231,7 +229,6 @@
 		if ((e.getEventTypes() & IModelProviderEvent.MODELS_CHANGED) != 0) {
 			IModel[] changed = e.getChangedModels();
 			for (int i = 0; i < changed.length; i++) {
-				if (!(changed[i] instanceof IPluginModelBase)) continue;
 				IPluginModelBase model = (IPluginModelBase) changed[i];
 				BundleDescription desc = model.getBundleDescription();
 				String oldID = desc == null ? null : desc.getSymbolicName();
diff --git a/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/NewTargetModelManager.java b/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/TargetModelManager.java
similarity index 90%
rename from ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/NewTargetModelManager.java
rename to ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/TargetModelManager.java
index eb60c17..224c720 100644
--- a/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/NewTargetModelManager.java
+++ b/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/TargetModelManager.java
@@ -10,7 +10,7 @@
  *******************************************************************************/
 package org.eclipse.pde.internal.core;
 
-public class NewTargetModelManager extends AbstractModelManager {
+public class TargetModelManager extends AbstractModelManager {
 
 	protected void initialize() {
 	}
diff --git a/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/WorkspaceFeatureModelManager.java b/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/WorkspaceFeatureModelManager.java
index 0011592..c83f2df 100644
--- a/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/WorkspaceFeatureModelManager.java
+++ b/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/WorkspaceFeatureModelManager.java
@@ -10,6 +10,8 @@
  *******************************************************************************/
 package org.eclipse.pde.internal.core;
 
+import java.util.HashMap;
+
 import org.eclipse.core.resources.IFile;
 import org.eclipse.core.resources.IProject;
 import org.eclipse.core.resources.IResourceChangeEvent;
@@ -25,10 +27,15 @@
 	}
 
 	protected void createModel(IProject project, boolean notify) {
-		WorkspaceFeatureModel model = new WorkspaceFeatureModel(project.getFile(ICoreConstants.FEATURE_PATH));
-		loadModel(model, false);
-		if (notify)
-			addChange(model, IModelProviderEvent.MODELS_ADDED);
+		if (project.exists(ICoreConstants.FEATURE_PATH)) {
+			WorkspaceFeatureModel model = new WorkspaceFeatureModel(project.getFile(ICoreConstants.FEATURE_PATH));
+			loadModel(model, false);
+			if (fModels == null)
+				fModels = new HashMap();
+			fModels.put(project, model);
+			if (notify)
+				addChange(model, IModelProviderEvent.MODELS_ADDED);
+		}
 	}
 	
 	protected void handleFileDelta(IResourceDelta delta) {
diff --git a/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/WorkspaceModelManager.java b/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/WorkspaceModelManager.java
index 006682f..773c0b7 100644
--- a/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/WorkspaceModelManager.java
+++ b/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/WorkspaceModelManager.java
@@ -169,8 +169,8 @@
 			IResource resource = delta.getResource();
 			if (resource instanceof IProject) {
 				IProject project = (IProject) resource;
-				if (delta.getKind() == IResourceDelta.ADDED 
-						|| (project.isOpen() && (delta.getFlags()&IResourceDelta.OPEN) != 0)) {
+				if (isInterestingProject(project) 
+						&& (delta.getKind() == IResourceDelta.ADDED || (delta.getFlags() & IResourceDelta.OPEN) != 0)) {
 					createModel(project, true);
 					return false;
 				} else if (delta.getKind() == IResourceDelta.REMOVED) {
diff --git a/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/WorkspacePluginModelManager.java b/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/WorkspacePluginModelManager.java
index f4a89bf..8ca711b 100644
--- a/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/WorkspacePluginModelManager.java
+++ b/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/WorkspacePluginModelManager.java
@@ -70,8 +70,13 @@
 		if (project.getFile(".options").exists()) //$NON-NLS-1$
 			PDECore.getDefault().getTracingOptionsManager().reset();
 
-		if (model != null && notify)
-			addChange(model, IModelProviderEvent.MODELS_ADDED);
+		if (model != null) {
+			if (fModels == null) 
+				fModels = new HashMap();
+			fModels.put(project, model);
+			if (notify)
+				addChange(model, IModelProviderEvent.MODELS_ADDED);
+		}
 	}
 	
 	protected void handleFileDelta(IResourceDelta delta) {
diff --git a/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/builders/FeatureErrorReporter.java b/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/builders/FeatureErrorReporter.java
index bd08e15..adb791c 100644
--- a/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/builders/FeatureErrorReporter.java
+++ b/ui/org.eclipse.pde.core/src/org/eclipse/pde/internal/core/builders/FeatureErrorReporter.java
@@ -19,8 +19,8 @@
 import org.eclipse.pde.core.plugin.IPluginModel;
 import org.eclipse.pde.core.plugin.IPluginModelBase;
 import org.eclipse.pde.internal.core.PDECore;
-import org.eclipse.pde.internal.core.ifeature.IFeature;
 import org.eclipse.pde.internal.core.PDECoreMessages;
+import org.eclipse.pde.internal.core.ifeature.IFeatureModel;
 import org.eclipse.pde.internal.core.util.CoreUtility;
 import org.w3c.dom.Attr;
 import org.w3c.dom.Element;
@@ -403,8 +403,8 @@
 	private void validateFeatureID(Element element, Attr attr) {
 		int severity = CompilerFlags.getFlag(fProject, CompilerFlags.F_UNRESOLVED_FEATURES);
 		if (severity != CompilerFlags.IGNORE) {
-			IFeature feature = PDECore.getDefault().findFeature(attr.getValue());	
-			if (feature == null) {
+			IFeatureModel[] models = PDECore.getDefault().getFeatureModelManager().findFeatureModels(attr.getValue());
+			if (models.length == 0) {
 				report(NLS.bind(PDECoreMessages.Builders_Feature_freference, attr.getValue()),  
 						getLine(element, attr.getName()),
 						severity,
diff --git a/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/PDEPlugin.java b/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/PDEPlugin.java
index d477c81..56932db 100644
--- a/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/PDEPlugin.java
+++ b/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/PDEPlugin.java
@@ -191,11 +191,11 @@
 	 * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext)
 	 */
 	public void stop(BundleContext context) throws Exception {
-		if (fLaunchListener!=null)
+		if (fLaunchListener != null)
 			fLaunchListener.shutdown();
-		if (fFormColors!=null) {
+		if (fFormColors != null) {
 			fFormColors.dispose();
-			fFormColors=null;
+			fFormColors = null;
 		}
 		if (fLabelProvider != null) {
 			fLabelProvider.dispose();
@@ -210,7 +210,7 @@
 	}
 
 	public PDELabelProvider getLabelProvider() {
-		if (fLabelProvider==null)
+		if (fLabelProvider == null)
 			fLabelProvider = new PDELabelProvider();
 		return fLabelProvider;
 	}
diff --git a/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/wizards/imports/BinaryProjectFilter.java b/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/wizards/imports/BinaryProjectFilter.java
index 405d5f1..e7a2289 100644
--- a/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/wizards/imports/BinaryProjectFilter.java
+++ b/ui/org.eclipse.pde.ui/src/org/eclipse/pde/internal/ui/wizards/imports/BinaryProjectFilter.java
@@ -11,26 +11,18 @@
 package org.eclipse.pde.internal.ui.wizards.imports;
 
 import org.eclipse.core.resources.IProject;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.Path;
 import org.eclipse.jdt.core.IJavaProject;
 import org.eclipse.jface.viewers.Viewer;
 import org.eclipse.jface.viewers.ViewerFilter;
-import org.eclipse.pde.internal.core.BinaryRepositoryProvider;
-import org.eclipse.pde.internal.core.PDECore;
-import org.eclipse.team.core.RepositoryProvider;
+import org.eclipse.pde.internal.core.WorkspaceModelManager;
 
 public class BinaryProjectFilter extends ViewerFilter {
 
 	/**
-	 * Constructor for BinaryProjectFilter.
-	 */
-	public BinaryProjectFilter() {
-		super();
-	}
-
-	/**
-	 * @see ViewerFilter#select(Viewer, Object, Object)
+	 * Returns <code>false</code> if the given element is a binary plug-in/feature project,
+	 * and <code>true</code> otherwise.
+	 *  
+	 * @see org.eclipse.jface.viewers.ViewerFilter#select(org.eclipse.jface.viewers.Viewer, java.lang.Object, java.lang.Object)
 	 */
 	public boolean select(Viewer viewer, Object parentElement, Object element) {
 		IProject project = null;
@@ -41,36 +33,12 @@
 			project = (IProject) element;
 		}
 		if (project != null) {
-			if (isPluginProject(project) || isFeatureProject(project)) {
-				return !isBinary(project);
+			if (WorkspaceModelManager.isPluginProject(project) 
+					|| WorkspaceModelManager.isFeatureProject(project)) {
+				return !WorkspaceModelManager.isBinaryProject(project);
 			}
 		}
 		return true;
 	}
 	
-	private boolean isPluginProject(IProject project) {
-		if (project.isOpen() == false)
-			return false;
-		return project.exists(new Path("plugin.xml")) //$NON-NLS-1$
-			|| project.exists(new Path("fragment.xml")) || project.exists(new Path("META-INF/MANIFEST.MF")); //$NON-NLS-1$ //$NON-NLS-2$
-	}
-	
-	private boolean isFeatureProject(IProject project) {
-		if (project.isOpen() == false)
-			return false;
-		return project.exists(new Path("feature.xml")); //$NON-NLS-1$
-	}
-	
-	private boolean isBinary(IProject project) {
-		try {
-			String binary = project.getPersistentProperty(PDECore.EXTERNAL_PROJECT_PROPERTY);
-			if (binary != null) {
-				RepositoryProvider provider = RepositoryProvider.getProvider(project);
-				return provider==null || provider instanceof BinaryRepositoryProvider;
-			}
-		} catch (CoreException e) {
-			PDECore.logException(e);
-		}
-		return false;
-	}
 }