Bug 293467  - 3.0.5P - Fix for js.common
diff --git a/jsf/plugins/org.eclipse.jst.jsf.common/META-INF/MANIFEST.MF b/jsf/plugins/org.eclipse.jst.jsf.common/META-INF/MANIFEST.MF
index b617290..9eb6ccb 100644
--- a/jsf/plugins/org.eclipse.jst.jsf.common/META-INF/MANIFEST.MF
+++ b/jsf/plugins/org.eclipse.jst.jsf.common/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@
 Bundle-ManifestVersion: 2
 Bundle-Name: %plugin.name
 Bundle-SymbolicName: org.eclipse.jst.jsf.common;singleton:=true
-Bundle-Version: 1.1.4.qualifier
+Bundle-Version: 1.1.5.qualifier
 Bundle-Activator: org.eclipse.jst.jsf.common.JSFCommonPlugin$Implementation
 Bundle-Localization: plugin
 Export-Package: org.eclipse.jst.jsf.common;x-internal:=true,
diff --git a/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/internal/DomainLoadingStrategy.java b/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/internal/DomainLoadingStrategy.java
index 93317b1..01a38e6 100644
--- a/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/internal/DomainLoadingStrategy.java
+++ b/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/internal/DomainLoadingStrategy.java
@@ -59,7 +59,7 @@
 	 * @see org.eclipse.jst.jsf.common.metadata.internal.IDomainLoadingStrategy#reload()
 	 */
 	public void reload() throws ModelNotSetException {
-		System.out.println("reload");//debug
+		//System.out.println("reload");//debug //$NON-NLS-1$
 		if (_model == null)
 			throw new ModelNotSetException();
 		
@@ -77,7 +77,7 @@
 	 */
 	protected void mergeModel(MetaDataModel model, List/*<IMetaDataSourceModelProvider>*/ sources) {		
 
-		StandardModelFactory.debug(">> Begin Merge: "+model.getModelKey()+"("+sources.size()+ " sources)", StandardModelFactory.DEBUG_MD_LOAD);
+		StandardModelFactory.debug(">> Begin Merge: "+model.getModelKey()+"("+sources.size()+ " sources)", StandardModelFactory.DEBUG_MD_LOAD); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
 
 		IMetaDataModelMergeAssistant assistant = createModelMergeAssistant(model);
 		for (Iterator/*<IMetaDataSourceModelProvider>*/ it = sources.iterator();it.hasNext();){
@@ -86,19 +86,19 @@
 			while (translators.hasNext()){
 				IMetaDataTranslator translator = (IMetaDataTranslator)translators.next();
 				if (translator.canTranslate(mds)){
-					StandardModelFactory.debug(">>> Merging: "+model.getModelKey()+"::"+mds, StandardModelFactory.DEBUG_MD_LOAD);
+					StandardModelFactory.debug(">>> Merging: "+model.getModelKey()+"::"+mds, StandardModelFactory.DEBUG_MD_LOAD);  //$NON-NLS-1$//$NON-NLS-2$
 					assistant.setSourceModelProvider(mds);
 					try {
 						translator.translate(assistant);
 					} catch (Exception e) {							
-						StandardModelFactory.debug(">>>> Error during translate/merge of: "+model.getModelKey()+": "+mds, StandardModelFactory.DEBUG_MD_LOAD);															
-						JSFCommonPlugin.log(IStatus.ERROR, "Error during load of: "+mds, e);
+						StandardModelFactory.debug(">>>> Error during translate/merge of: "+model.getModelKey()+": "+mds, StandardModelFactory.DEBUG_MD_LOAD);															 //$NON-NLS-1$ //$NON-NLS-2$
+						JSFCommonPlugin.log(IStatus.ERROR, "Error during load of: "+mds, e); //$NON-NLS-1$
 					}
 				}				
 			}
 		}
 		assistant.setMergeComplete();
-		StandardModelFactory.debug(">> End Merge: "+model.getModelKey(),StandardModelFactory.DEBUG_MD_LOAD);
+		StandardModelFactory.debug(">> End Merge: "+model.getModelKey(),StandardModelFactory.DEBUG_MD_LOAD); //$NON-NLS-1$
 	}
 	
 	/**
@@ -135,25 +135,23 @@
 		List/*<IMetaDataSourceModelProvider>*/ sources = new ArrayList/*<IMetaDataSourceModelProvider>*/();		
 		for (Iterator/*<IDomainSourceModelType>*/ it = sourceTypes.iterator();it.hasNext();){
 			IDomainSourceModelType sourceType = (IDomainSourceModelType)it.next();
-			IMetaDataLocator locator = sourceType.getLocator();
-			//We MUST set the sourceType here to associate the handler with locator to use for the source models
-			locator.setDomainSourceModelType(sourceType);
-			
-			//set project context in locator for those that care
-			if (locator instanceof IPathSensitiveMetaDataLocator)
-				((IPathSensitiveMetaDataLocator)locator).setProjectContext(model.getModelKey().getProject());
-			
-			List/*<IMetaDataSourceModelProvider>*/ providers = sourceType.getLocator().locateMetaDataModelProviders(model.getModelKey().getUri());
-			if (providers != null && !providers.isEmpty()){
-				for (Iterator mdProviders =providers.iterator();mdProviders.hasNext();){
-					IMetaDataSourceModelProvider provider = (IMetaDataSourceModelProvider)mdProviders.next();
-					//We MUST set the sourceType here to associate the translators to use for the source models
-					provider.setLocator(sourceType.getLocator());
-					sources.add(provider);
+			IMetaDataLocator locator = sourceType.getLocator(model.getModelKey().getProject());
+			if (locator != null) {
+				//We MUST set the sourceType here to associate the handler with locator to use for the source models
+				locator.setDomainSourceModelType(sourceType);
+								
+				List/*<IMetaDataSourceModelProvider>*/ providers = locator.locateMetaDataModelProviders(model.getModelKey().getUri());
+				if (providers != null && !providers.isEmpty()){
+					for (Iterator mdProviders =providers.iterator();mdProviders.hasNext();){
+						IMetaDataSourceModelProvider provider = (IMetaDataSourceModelProvider)mdProviders.next();
+						//We MUST set the sourceType here to associate the translators to use for the source models
+						provider.setLocator(locator);
+						sources.add(provider);
+					}
 				}
+				//listen for changes
+				locator.addObserver(this);
 			}
-			//listen for changes
-			sourceType.getLocator().addObserver(this);
 		}
 		return sources;
 	}
diff --git a/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/internal/DomainSourceModelTypeDescriptor.java b/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/internal/DomainSourceModelTypeDescriptor.java
index 18259ce..dd623ca 100644
--- a/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/internal/DomainSourceModelTypeDescriptor.java
+++ b/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/internal/DomainSourceModelTypeDescriptor.java
@@ -15,6 +15,7 @@
 import java.util.Iterator;
 import java.util.Set;
 
+import org.eclipse.core.resources.IProject;
 import org.eclipse.core.runtime.IConfigurationElement;
 import org.eclipse.core.runtime.IExtensionPoint;
 import org.eclipse.core.runtime.IExtensionRegistry;
@@ -28,15 +29,14 @@
  * <code>com.eclipse.jst.jsf.common.domainSourceModelTypeTranslators</code> ext-pt
  */
 public class DomainSourceModelTypeDescriptor {
-	private static final String TRANSLATORS_EXTENSION_POINT_ID = "domainSourceModelTypeTranslators";
-	private static final String STANDARD_FILE_NULL_TRANSLATOR = "org.eclipse.jst.jsf.common.metadata.internal.StandardMetaDataFilesTranslator";
-	private String domain = "DEFAULT";
+	private static final String TRANSLATORS_EXTENSION_POINT_ID = "domainSourceModelTypeTranslators"; //$NON-NLS-1$
+	private static final String STANDARD_FILE_NULL_TRANSLATOR = "org.eclipse.jst.jsf.common.metadata.internal.StandardMetaDataFilesTranslator"; //$NON-NLS-1$
+	private String domain = "DEFAULT"; //$NON-NLS-1$
 	private String domainSourceModelTypeId;
-	private String locatorClassName = "org.eclipse.jst.jsf.common.metadata.internal.StandardMetaDataLocator";
+	private String locatorClassName = "org.eclipse.jst.jsf.common.metadata.internal.StandardMetaDataLocator"; //$NON-NLS-1$
 	private Set translatorDescriptors;
 	private String bundleId = JSFCommonPlugin.PLUGIN_ID;
 	private int ordinal;
-	private IDomainSourceModelType _instance;
 	
 	/**
 	 * Constructor
@@ -70,7 +70,7 @@
 			IConfigurationElement[] elements = point.getConfigurationElements();
 			for (int i = 0; i < elements.length; i++) {
 				IConfigurationElement element = elements[i];
-				String srcHdlrId = element.getAttribute("domainSourceModelTypeId");
+				String srcHdlrId = element.getAttribute("domainSourceModelTypeId"); //$NON-NLS-1$
 				if (srcHdlrId.equals(domainSourceModelTypeId))
 					addTranslatorDescriptor(element);
 			}
@@ -78,7 +78,7 @@
 	}
 	
 	private void addTranslatorDescriptor(IConfigurationElement element) {
-		String translator = element.getAttribute("translatorClass");
+		String translator = element.getAttribute("translatorClass"); //$NON-NLS-1$
 		DomainSourceModelTranslatorDescriptor d = new DomainSourceModelTranslatorDescriptor(translator, element.getContributor().getName());
 		getTranslatorDescriptors().add(d);
 	}
@@ -98,19 +98,9 @@
 	}
 	 
 	/**
-	 * @return singleton instance of the {@link IDomainSourceModelType}
+	 * @return new instance of the {@link IDomainSourceModelType}
 	 */
 	public IDomainSourceModelType getInstance(){
-		if (_instance == null){
-			_instance = newInstance();
-		}
-		return _instance;
-	}
-	/**
-	 * @return new instance of {@link IDomainSourceModelType} 
-	 */
-	private IDomainSourceModelType newInstance(){		
-
 		return new DomainSourceModelTypeImpl();
 	}
 	
@@ -143,9 +133,9 @@
 		/* (non-Javadoc)
 		 * @see org.eclipse.jst.jsf.common.metadata.internal.IDomainSourceModelType#getLocator()
 		 */
-		public IMetaDataLocator getLocator() {
+		public IMetaDataLocator getLocator(IProject project) {
 			if (locator == null){
-				locator = MetaDataLocatorFactory.getInstance().getLocator(locatorClassName, bundleId);
+				locator = MetaDataLocatorFactory.getInstance().getLocator(locatorClassName, bundleId, project);
 			}
 								
 			return locator;
@@ -165,12 +155,12 @@
 		 * @see java.lang.Object#toString()
 		 */
 		public String toString(){
-			StringBuffer buf = new StringBuffer("DomainSourceModelTypeImpl");
-			buf.append("(domain = ");
+			StringBuffer buf = new StringBuffer("DomainSourceModelTypeImpl"); //$NON-NLS-1$
+			buf.append("(domain = "); //$NON-NLS-1$
 			buf.append(getDomain());
-			buf.append(", locator = ");
-			buf.append(getLocator());
-			buf.append(")");
+			buf.append(", locator = "); //$NON-NLS-1$
+			buf.append(locator != null ? locator.toString() : "null"); //$NON-NLS-1$
+			buf.append(")"); //$NON-NLS-1$
 			return buf.toString();
 		}
 		
@@ -187,10 +177,10 @@
 					return translators;
 				} catch (InstantiationException e) {
                     // TODO: other error handling?
-					JSFCommonPlugin.log(e, "Error in createTranslatorInstances(STANDARD_FILE_NULL_TRANSLATOR)");
+					JSFCommonPlugin.log(e, "Error in createTranslatorInstances(STANDARD_FILE_NULL_TRANSLATOR)"); //$NON-NLS-1$
 				} catch (IllegalAccessException e) {
                     // TODO: other error handling?
-                    JSFCommonPlugin.log(e, "Error in createTranslatorInstances(STANDARD_FILE_NULL_TRANSLATOR)");
+                    JSFCommonPlugin.log(e, "Error in createTranslatorInstances(STANDARD_FILE_NULL_TRANSLATOR)"); //$NON-NLS-1$
 				}
 
 			}
@@ -203,10 +193,10 @@
 					translators.add(klass.newInstance());
 				} catch (InstantiationException e) {
                     // TODO: other error handling?
-                    JSFCommonPlugin.log(e, "Error in createTranslatorInstances");
+                    JSFCommonPlugin.log(e, "Error in createTranslatorInstances"); //$NON-NLS-1$
 				} catch (IllegalAccessException e) {
                     // TODO: other error handling?
-                    JSFCommonPlugin.log(e, "Error in createTranslatorInstances");
+                    JSFCommonPlugin.log(e, "Error in createTranslatorInstances"); //$NON-NLS-1$
 				}
 			}
 			return translators;
diff --git a/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/internal/DomainSourceTypesRegistry.java b/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/internal/DomainSourceTypesRegistry.java
index 9ace164..000fdef 100644
--- a/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/internal/DomainSourceTypesRegistry.java
+++ b/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/internal/DomainSourceTypesRegistry.java
@@ -30,10 +30,9 @@
  * Registry of Domain Source Types loaded from domainSourceModelTypes ext-pt.
  */
 public class DomainSourceTypesRegistry{
-	private static final String EXTENSION_POINT_ID = "domainSourceModelTypes";
+	private static final String EXTENSION_POINT_ID = "domainSourceModelTypes"; //$NON-NLS-1$
 	private static DomainSourceTypesRegistry INSTANCE;
 	private Map/*<String, List/*<DomainSourceModelTypeDescriptor>>*/ domainSourceTypeDescriptors;
-	private Map/*<String, List/*<IDomainSourceModelType>*/ domainSourceTypes;
 	
 	private DomainSourceTypesRegistry(){
 		init();
@@ -53,10 +52,7 @@
 	 * @param domain identifier
 	 * @return list of <code>IDomainSourceModelType</code> sorted in descending order by ordinal
 	 */
-	public List/*<IDomainSourceModelType>*/ getDomainSourceTypes(String domain){
-		if (getDomainSourceTypes().containsKey(domain))
-			return (List)getDomainSourceTypes().get(domain);
-		
+	public List/*<IDomainSourceModelType>*/ getDomainSourceTypes(String domain){		
 		List/*<DomainSourceModelTypeDescriptor>*/ list = getDomainSourceModelDescriptors(domain);
 		List/*<IDomainSourceModelType>*/ types = new ArrayList/*<IDomainSourceModelType>*/();
 		for(Iterator/*<DomainSourceModelTypeDescriptor>*/ it=list.iterator();it.hasNext();){
@@ -78,7 +74,6 @@
 			
 		});
 		
-		getDomainSourceTypes().put(domain, types);
 		return types;
 	}
 	
@@ -110,12 +105,12 @@
 	}
 
 	private void addDomainSourceTypeDescriptor(IConfigurationElement element) {
-		String domainId = element.getAttribute("domainId");
-		String srcHdlrId = element.getAttribute("domainSourceModelTypeId");
-		String locator = element.getAttribute("locator");
-		String ordinalStr = element.getAttribute("ordinal");
+		String domainId = element.getAttribute("domainId"); //$NON-NLS-1$
+		String srcHdlrId = element.getAttribute("domainSourceModelTypeId"); //$NON-NLS-1$
+		String locator = element.getAttribute("locator"); //$NON-NLS-1$
+		String ordinalStr = element.getAttribute("ordinal"); //$NON-NLS-1$
 		int ordinal = 1;
-		if (ordinalStr!=null && !ordinalStr.equals("")){
+		if (ordinalStr!=null && !ordinalStr.equals("")){ //$NON-NLS-1$
 			ordinal = Integer.parseInt(ordinalStr);
 		}
 		DomainSourceModelTypeDescriptor d = new DomainSourceModelTypeDescriptor(domainId, srcHdlrId, locator, element.getContributor().getName(), ordinal);
@@ -134,11 +129,11 @@
 		return domainSourceTypeDescriptors;
 	}
 	
-	private Map/*<String, List/*<IDomainSourceModelType>>*/ getDomainSourceTypes() {
-		if (domainSourceTypes == null){
-			domainSourceTypes = new HashMap/*<String, List/*<IDomainSourceModelType>>*/();
-		}
-		return domainSourceTypes;
-	}
+//	private Map/*<String, List/*<IDomainSourceModelType>>*/ getDomainSourceTypes() {
+//		if (domainSourceTypes == null){
+//			domainSourceTypes = new HashMap/*<String, List/*<IDomainSourceModelType>>*/();
+//		}
+//		return domainSourceTypes;
+//	}
 
 }
\ No newline at end of file
diff --git a/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/internal/IDomainSourceModelType.java b/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/internal/IDomainSourceModelType.java
index 296c4a7..67ed292 100644
--- a/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/internal/IDomainSourceModelType.java
+++ b/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/internal/IDomainSourceModelType.java
@@ -13,6 +13,8 @@
 
 import java.util.Set;
 
+import org.eclipse.core.resources.IProject;
+
 /**
  * Binds a domain of metadata to a source model type which is defined by a {@link IMetaDataLocator} 
  * and set of {@link IMetaDataTranslator}s
@@ -24,9 +26,10 @@
 	 */
 	public String getDomain();
 	/**
-	 * @return IMetaDataLocator
+	 * @param project - may be null
+	 * @return instance of IMetaDataLocator - may return null if the locator cannot operate in the current context
 	 */
-	public IMetaDataLocator getLocator();
+	public IMetaDataLocator getLocator(IProject project);
 //	public int getOrdinal();
 	/**
 	 * @return set of {@link IMetaDataTranslator}s for the domain source model type
diff --git a/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/internal/MetaDataLocatorFactory.java b/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/internal/MetaDataLocatorFactory.java
index ed92cf1..a590590 100644
--- a/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/internal/MetaDataLocatorFactory.java
+++ b/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/internal/MetaDataLocatorFactory.java
@@ -10,10 +10,17 @@
  *******************************************************************************/
 package org.eclipse.jst.jsf.common.metadata.internal;
 
+import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.Iterator;
+import java.util.List;
 import java.util.Map;
+import java.util.StringTokenizer;
 
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResourceChangeEvent;
+import org.eclipse.core.resources.IResourceChangeListener;
+import org.eclipse.core.resources.ResourcesPlugin;
 import org.eclipse.core.runtime.IStatus;
 import org.eclipse.jst.jsf.common.JSFCommonPlugin;
 
@@ -21,56 +28,84 @@
  * Creates instances of IMetaDataLocators and caches them so that there is only one instance of a particular locator
  * when client requests one. 
  */
-public class MetaDataLocatorFactory {
-	private static MetaDataLocatorFactory INSTANCE = null;
+public class MetaDataLocatorFactory  
+	implements IResourceChangeListener {
 	
+	private static MetaDataLocatorFactory INSTANCE = null;
+	private Map<String, IMetaDataLocator> _locators;
+	
+	private static final boolean DEBUG = false;
 	/**
 	 * @return singleton instance of the MetaDataLocatorFactory
 	 */
 	public synchronized static MetaDataLocatorFactory getInstance(){
 		if (INSTANCE == null){
 			INSTANCE = new MetaDataLocatorFactory();
+			ResourcesPlugin.getWorkspace().addResourceChangeListener(INSTANCE, IResourceChangeEvent.PRE_CLOSE);
 		}
 		return INSTANCE;
 	}
 
-	private HashMap _locators;
 
-	private Map getLocators() {
+
+	private Map<String, IMetaDataLocator> getLocators() {
 		if (_locators == null){
-			_locators = new HashMap();
+			_locators = new HashMap<String, IMetaDataLocator>();
 		}
 		return _locators;
 	}
 	
 	/**
-	 * @param locatorClassName
-	 * @param bundleId
-	 * @return IMetaDataLocator
+	 * @param locatorClassName - may NOT be null
+	 * @param bundleId - may NOT be null
+	 * @param project - may be null
+	 * @return shared instance of IMetaDataLocator 
+	 * 			may return null if is IPathSensitiveMetaDataLocator and there is no project context 
 	 */
-	public IMetaDataLocator getLocator(String locatorClassName, String bundleId){
+	public IMetaDataLocator getLocator(final String locatorClassName, final String bundleId, final IProject project){
+		final Class klass = JSFCommonPlugin.loadClass(locatorClassName, bundleId);
 		String key = getKey(locatorClassName, bundleId);
-		IMetaDataLocator locator = (IMetaDataLocator)getLocators().get(key);
-		if (locator == null){
-			Class klass = JSFCommonPlugin.loadClass(locatorClassName, bundleId);
-			try {
-				locator = (IMetaDataLocator)klass.newInstance();
-				if (locator != null) {
+		IMetaDataLocator locator = null;
+		try {
+			IMetaDataLocator tempLocator = (IMetaDataLocator)klass.newInstance();
+			if (tempLocator != null) {				
+				if (tempLocator instanceof IPathSensitiveMetaDataLocator) {
+					if (project == null)
+						return null;
+					
+					key = getKey(locatorClassName, project.getName());
+				}
+				
+				locator = getLocators().get(key);
+				if (locator == null) {
+					locator = tempLocator;					
+					if (locator instanceof IPathSensitiveMetaDataLocator)
+						((IPathSensitiveMetaDataLocator)locator).setProjectContext(project);					
+					
+					if (DEBUG)
+						System.out.println("Created locator: "+locator.toString()); //$NON-NLS-1$
+					
 					getLocators().put(key, locator);
 					locator.startLocating();
 				}
-			} catch (InstantiationException e) {
-				JSFCommonPlugin.log(IStatus.ERROR, "Could not instantiate IMetaDataLocator: "+key, e);
-			} catch (IllegalAccessException e) {
-				JSFCommonPlugin.log(IStatus.ERROR, "IllegalAccessException while creating IMetaDataLocator: "+key, e);
 			}
+		} catch (InstantiationException e) {
+			JSFCommonPlugin.log(IStatus.ERROR, "Could not instantiate IMetaDataLocator: "+key, e); //$NON-NLS-1$
+		} catch (IllegalAccessException e) {
+			JSFCommonPlugin.log(IStatus.ERROR, "IllegalAccessException while creating IMetaDataLocator: "+key, e); //$NON-NLS-1$
 		}
+		
 		return locator;
 	}
 
-	private String getKey(String locatorClassName, String bundleId) {
-		StringBuffer buf = new StringBuffer(bundleId);
-		buf.append(":");
+	/**
+	 * @param locatorClassName
+	 * @param contextId - this may be the bundleID or the projectName if it is a path sensitive locator
+	 * @return key 
+	 */
+	private String getKey(final String locatorClassName, final String contextId) {
+		StringBuffer buf = new StringBuffer(contextId);
+		buf.append(":"); //$NON-NLS-1$
 		buf.append(locatorClassName);
 		return buf.toString();
 	}
@@ -79,10 +114,56 @@
 	 * Stops and disposes all locators
 	 */
 	public void dispose(){
+		ResourcesPlugin.getWorkspace().removeResourceChangeListener(this);
 		for (Iterator it=getLocators().values().iterator();it.hasNext();){
 			IMetaDataLocator locator = (IMetaDataLocator)it.next();
 			locator.stopLocating();			
 		}
 		getLocators().clear();
 	}
+	
+    /*
+     * (non-Javadoc)
+     * 
+     * @see
+     * org.eclipse.core.resources.IResourceChangeListener#resourceChanged(org
+     * .eclipse.core.resources.IResourceChangeEvent)
+     */
+    public void resourceChanged(final IResourceChangeEvent event) {
+        if (event.getType() == IResourceChangeEvent.PRE_CLOSE
+                || event.getType() == IResourceChangeEvent.PRE_DELETE) {
+            // a project is closing - release and cleanup
+            final IProject aProject = (IProject) event.getResource();
+            
+            if (aProject != null) {
+            	List<String> locatorsToRemove = new ArrayList<String>();
+	    		for (Iterator it=getLocators().keySet().iterator();it.hasNext();){
+	    			String key = (String)it.next();	    			
+	    			if (locatorIsForProject(key, aProject.getName())) {
+	    				locatorsToRemove.add(key);
+	    			}
+	    		}
+
+	    		if (! locatorsToRemove.isEmpty()) {
+	    			for (String key : locatorsToRemove) {
+	    				IMetaDataLocator locator = getLocators().get(key);
+						
+						if (DEBUG)
+							System.out.println("Removed locator: "+locator.toString()); //$NON-NLS-1$
+	    				
+	    				locator.stopLocating();
+	    				getLocators().remove(key);
+	    			}
+	    		}
+            }
+        }
+    }
+
+	private boolean locatorIsForProject(final String key, final String projectName) {
+		StringTokenizer t = new StringTokenizer(key, ":"); //$NON-NLS-1$
+		String contextId = t.nextToken();
+		if (contextId.equals(projectName))
+			return true;
+		return false;
+	}
 }
diff --git a/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/internal/MetaDataModelManager.java b/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/internal/MetaDataModelManager.java
index fe56907..d3cc95a 100644
--- a/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/internal/MetaDataModelManager.java
+++ b/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/internal/MetaDataModelManager.java
@@ -137,10 +137,10 @@
         synchronized (GLOBAL_INSTANCE_LOCK) {
             ModelKeyDescriptor modelKeyDescriptor = StandardModelFactory.getInstance().createModelKeyDescriptor(modelContext);
 
-            StandardModelFactory.debug(">START getModel: "+modelKeyDescriptor, StandardModelFactory.DEBUG_MD_GET);
+            StandardModelFactory.debug(">START getModel: "+modelKeyDescriptor, StandardModelFactory.DEBUG_MD_GET); //$NON-NLS-1$
 
             MetaDataModel model = models.get(modelKeyDescriptor);
-            if (model == null || project == null) {
+            if (model == null || project == null) { //<---  why is the project == null test here?!?!
                 // long in = System.currentTimeMillis();
                 model = loadMetadata(modelKeyDescriptor);
                 //System.out.println("Time to load "+modelContext.getURI()+": "+
@@ -157,7 +157,7 @@
                 ((Model) model.getRoot())
                         .setCurrentModelContext(modelKeyDescriptor);
 
-            StandardModelFactory.debug(">END getModel: "+modelKeyDescriptor, StandardModelFactory.DEBUG_MD_GET);
+            StandardModelFactory.debug(">END getModel: "+modelKeyDescriptor, StandardModelFactory.DEBUG_MD_GET); //$NON-NLS-1$
             return model;
         }
     }
@@ -194,7 +194,7 @@
         if (!Thread.holdsLock(GLOBAL_INSTANCE_LOCK)) {
             JSFCommonPlugin
                     .log(IStatus.ERROR,
-                            "Internal Error: loadMetadata must not be called if class lock not held");
+                            "Internal Error: loadMetadata must not be called if class lock not held"); //$NON-NLS-1$
             return null;
         }
 
diff --git a/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/internal/MetaDataModelMergeAssistantImpl.java b/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/internal/MetaDataModelMergeAssistantImpl.java
index f53cdd2..49f9aa4 100644
--- a/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/internal/MetaDataModelMergeAssistantImpl.java
+++ b/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/internal/MetaDataModelMergeAssistantImpl.java
@@ -43,7 +43,6 @@
 		IMetaDataModelMergeAssistant {
 	
 	private MetaDataModel mergedModel;
-	private Copier copier;
 	private SimpleEntityQueryVisitorImpl entityVisitor;
 	private SimpleTraitQueryVisitorImpl traitVisitor;
 	private IMetaDataSourceModelProvider provider;
@@ -54,7 +53,6 @@
 	 */
 	public MetaDataModelMergeAssistantImpl(MetaDataModel model) {
 		this.mergedModel = model;
-		copier = new Copier();
 		entityVisitor = new SimpleEntityQueryVisitorImpl(new HierarchicalSearchControl(1, 
 			HierarchicalSearchControl.SCOPE_ALL_LEVELS));
 		traitVisitor = new SimpleTraitQueryVisitorImpl(new SearchControl(1));
@@ -110,7 +108,7 @@
 				ret = (Entity)rs.getResults().get(0);				
 			rs.close();
 		} catch (MetaDataException e) {
-			JSFCommonPlugin.log(IStatus.ERROR, "Error in getMergedEntity()", e);
+			JSFCommonPlugin.log(IStatus.ERROR, "Error in getMergedEntity()", e); //$NON-NLS-1$
 		}
 		return ret;
 	}
@@ -175,6 +173,7 @@
 	}
 
 	private /*synchronized*/ Entity addEntityInternal(final Entity parent, final Entity entity) {
+		Copier copier = new Copier();
 		Entity mmEntity =(Entity)copier.copy(entity);
 		copier.copyReferences();
 		parent.getChildEntities().add(mmEntity);
@@ -209,11 +208,11 @@
 	public void setMergeComplete() {
 		Model model = (Model)getMergedModel().getRoot();
 		if (model != null){
-			StandardModelFactory.debug(">> Begin processIncludeGroups for: "+getMergedModel().getModelKey(),StandardModelFactory.DEBUG_MD_LOAD);
+			StandardModelFactory.debug(">> Begin processIncludeGroups for: "+getMergedModel().getModelKey(),StandardModelFactory.DEBUG_MD_LOAD); //$NON-NLS-1$
 			
 			processIncludeGroups(model);			
 			
-			StandardModelFactory.debug(">> End processIncludeGroups for: "+getMergedModel().getModelKey(),StandardModelFactory.DEBUG_MD_LOAD);
+			StandardModelFactory.debug(">> End processIncludeGroups for: "+getMergedModel().getModelKey(),StandardModelFactory.DEBUG_MD_LOAD); //$NON-NLS-1$
 		}		
 	}
 	
@@ -226,7 +225,8 @@
 	 * @param trait
 	 * @return merged Trait
 	 */
-	private Trait addTraitInternal(final Entity parent, final Trait trait) {		
+	private Trait addTraitInternal(final Entity parent, final Trait trait) {
+		Copier copier = new Copier();
 		Trait mmTrait =(Trait)copier.copy(trait);
 		copier.copyReferences();
 		parent.getTraits().add(mmTrait);
@@ -254,7 +254,7 @@
 				ret = (Entity)rs.getResults().get(0);				
 			rs.close();
 		} catch (MetaDataException e) {
-			JSFCommonPlugin.log(IStatus.ERROR, "Error in getMergedEntity()", e);
+			JSFCommonPlugin.log(IStatus.ERROR, "Error in getMergedEntity()", e); //$NON-NLS-1$
 		}
 		return ret;
 	}
@@ -265,7 +265,7 @@
 		while (e.eContainer() != null){
 			buf.insert(0, e.getId());
 			if (e.eContainer()!=null && e.eContainer().eContainer() != null)
-				buf.insert(0,"/");
+				buf.insert(0,"/"); //$NON-NLS-1$
 			e = (Entity)e.eContainer();
 		}
 		return buf.toString();
@@ -287,7 +287,7 @@
 				ret = (Trait)rs.getResults().get(0);				
 			rs.close();
 		} catch (MetaDataException e) {
-			JSFCommonPlugin.log(IStatus.ERROR, "Error in getMergedTrait()", e);
+			JSFCommonPlugin.log(IStatus.ERROR, "Error in getMergedTrait()", e); //$NON-NLS-1$
 		}
 		return ret;
 	}
@@ -337,8 +337,8 @@
 			addIncludeRefs(entity, entityGroup);
 		}
 		else {
-			JSFCommonPlugin.log(IStatus.ERROR, "Unable to load external metadata model refs for "+modelContext.getURI()
-					+ " into "+ entity.getModel().getCurrentModelContext().getUri());
+			JSFCommonPlugin.log(IStatus.ERROR, "Unable to load external metadata model refs for "+modelContext.getURI() //$NON-NLS-1$
+					+ " into "+ entity.getModel().getCurrentModelContext().getUri()); //$NON-NLS-1$
 		}
 	}
 
diff --git a/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/internal/StandardMetaDataFilesTranslator.java b/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/internal/StandardMetaDataFilesTranslator.java
index 4a4efdd..f9869ff 100644
--- a/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/internal/StandardMetaDataFilesTranslator.java
+++ b/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/metadata/internal/StandardMetaDataFilesTranslator.java
@@ -14,6 +14,7 @@
 import java.util.Iterator;
 
 import org.eclipse.core.runtime.IStatus;
+import org.eclipse.emf.ecore.util.EcoreUtil.Copier;
 import org.eclipse.jst.jsf.common.JSFCommonPlugin;
 import org.eclipse.jst.jsf.common.metadata.Entity;
 import org.eclipse.jst.jsf.common.metadata.EntityGroup;
@@ -42,16 +43,20 @@
 		//assert assistant.getSourceModel() instanceof ModelKeyDescriptor;
 		
 		MetaDataModel mm = assistant.getMergedModel();
-		if (mm.getRoot() == null)
-			mm.setRoot(assistant.getSourceModelProvider().getSourceModel());
-		
+		Model mk = (Model)assistant.getSourceModelProvider().getSourceModel();
+		if (mm.getRoot() == null) {
+			//create copy, otherwise source model becomes merged model because of reference
+			Copier copier = new Copier();		
+			Model newModel = (Model)copier.copy(mk.getModel());
+			copier.copyReferences();
+			mm.setRoot(newModel);
+		}
 		else {
-			//for each entity and trait call "add".   assistant will handle merge.
-			Model mk = (Model)assistant.getSourceModelProvider().getSourceModel();
+			//for each entity and trait call "add".   assistant will handle merge.			
 			if (mk != null) {//possible that model was not loaded 
 				traverseAndAdd(assistant, mk);
 			} else if (StandardModelFactory.DEBUG_MD_LOAD) {
-				JSFCommonPlugin.log(IStatus.ERROR,"Unable to load source model: "+assistant.getSourceModelProvider());
+				JSFCommonPlugin.log(IStatus.ERROR,"Unable to load source model: "+assistant.getSourceModelProvider()); //$NON-NLS-1$
 			}
 		}			
 	}
diff --git a/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/util/TypeUtil.java b/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/util/TypeUtil.java
index d781689..1d2a550 100644
--- a/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/util/TypeUtil.java
+++ b/jsf/plugins/org.eclipse.jst.jsf.common/src/org/eclipse/jst/jsf/common/util/TypeUtil.java
@@ -15,16 +15,15 @@
 import java.util.ArrayList;
 import java.util.List;
 
-import org.eclipse.core.runtime.NullProgressMonitor;
 import org.eclipse.jdt.core.IField;
 import org.eclipse.jdt.core.IJavaProject;
 import org.eclipse.jdt.core.IType;
-import org.eclipse.jdt.core.ITypeHierarchy;
 import org.eclipse.jdt.core.ITypeParameter;
 import org.eclipse.jdt.core.JavaModelException;
 import org.eclipse.jdt.core.Signature;
 import org.eclipse.jst.jsf.common.JSFCommonPlugin;
 import org.eclipse.jst.jsf.common.internal.types.TypeConstants;
+import org.eclipse.jst.jsf.common.internal.types.TypeInfoCache;
 
 /**
  * Utility for handling IType's and type signatures
@@ -359,11 +358,13 @@
                                 throws JavaModelException
     {
         IType resolvedType = null;
+
+        final TypeInfoCache typeInfoCache = TypeInfoCache.getInstance();
+        IType[] superTypes = typeInfoCache.getCachedSupertypes(childType);
+        if (superTypes == null) {
+        	superTypes = typeInfoCache.cacheSupertypesFor(childType);
+        }
         
-        // not resolved? try the supertypes
-        final ITypeHierarchy typeHierarchy =
-            childType.newSupertypeHierarchy(new NullProgressMonitor());
-        IType[] superTypes = typeHierarchy.getAllSupertypes(childType);
         String[][]   resolved;
         
         LOOP_UNTIL_FIRST_MATCH:
@@ -394,9 +395,8 @@
      */
     public static IType resolveType(final IJavaProject javaProject, final String fullyResolvedTypeSignature)
     {
-        final String fullyQualifiedName =
-            getFullyQualifiedName(fullyResolvedTypeSignature);
-        
+        String fullyQualifiedName = getFullyQualifiedName(fullyResolvedTypeSignature);
+        fullyQualifiedName = Signature.getTypeErasure(fullyQualifiedName);
         try {
             return javaProject.findType(fullyQualifiedName);
         } catch (JavaModelException e) {