[175139] model extensions
diff --git a/plugins/org.eclipse.wst.common.emf/wtpemf/org/eclipse/wst/common/internal/emf/resource/FileNameResourceFactoryRegistry.java b/plugins/org.eclipse.wst.common.emf/wtpemf/org/eclipse/wst/common/internal/emf/resource/FileNameResourceFactoryRegistry.java
index 40101e0..f210859 100644
--- a/plugins/org.eclipse.wst.common.emf/wtpemf/org/eclipse/wst/common/internal/emf/resource/FileNameResourceFactoryRegistry.java
+++ b/plugins/org.eclipse.wst.common.emf/wtpemf/org/eclipse/wst/common/internal/emf/resource/FileNameResourceFactoryRegistry.java
@@ -72,6 +72,9 @@
 	protected synchronized ResourceFactoryDescriptor getDescriptor(URI uri) {
 		return (ResourceFactoryDescriptor) descriptors.get(uri.lastSegment());
 	}
+	protected synchronized Map getDescriptors() {
+		return descriptors;
+	}
 
 	protected final synchronized Resource.Factory getFactory(ResourceFactoryDescriptor descriptor) {  
 		Resource.Factory factory = (Factory) factories.get(descriptor);
diff --git a/plugins/org.eclipse.wst.common.emf/wtpemf/org/eclipse/wst/common/internal/emf/resource/ResourceFactoryDescriptor.java b/plugins/org.eclipse.wst.common.emf/wtpemf/org/eclipse/wst/common/internal/emf/resource/ResourceFactoryDescriptor.java
index 247ae5d..ab3a7bd 100644
--- a/plugins/org.eclipse.wst.common.emf/wtpemf/org/eclipse/wst/common/internal/emf/resource/ResourceFactoryDescriptor.java
+++ b/plugins/org.eclipse.wst.common.emf/wtpemf/org/eclipse/wst/common/internal/emf/resource/ResourceFactoryDescriptor.java
@@ -10,6 +10,7 @@
  *******************************************************************************/ 
 package org.eclipse.wst.common.internal.emf.resource;
 
+import org.eclipse.core.runtime.content.IContentType;
 import org.eclipse.emf.common.util.URI;
 import org.eclipse.emf.ecore.resource.Resource;
 
@@ -24,7 +25,31 @@
 	 */
 	public abstract boolean isEnabledFor(URI fileURI);
 	
-
+	/**
+	 * The contentType is one optional way that a ResourceFactory
+	 * might apply to a URI. Clients should call {@link isEnabledFor} 
+	 * instead of comparing the content Types when searching for an
+	 * applicable descriptor from a set.  
+	 * 
+	 * <p><b>Subclasses may return null.(optional)</b></p>
+	 *  
+	 * @return The content type that this descriptor is applicable to.
+	 */
+	public IContentType getContentType(){
+		return null;
+	}
+	
+	/**
+	 * In the case where more than one factory is defined for the same fileName, 
+	 * and creation is passed a uri only a default factory is needed
+	 * 
+	 *  
+	 * @return The boolean describing the default factory
+	 */
+	public boolean isDefault(){
+		return true;
+	}
+	
 	/**
 	 * The short segment is one possible way that a ResourceFactory
 	 * might apply to a URI. Clients should call {@link isEnabledFor} 
diff --git a/plugins/org.eclipse.wst.common.modulecore/modulecore-src/org/eclipse/wst/common/componentcore/internal/impl/IResourceFactoryExtPtConstants.java b/plugins/org.eclipse.wst.common.modulecore/modulecore-src/org/eclipse/wst/common/componentcore/internal/impl/IResourceFactoryExtPtConstants.java
index 5308a99..1736dcd 100644
--- a/plugins/org.eclipse.wst.common.modulecore/modulecore-src/org/eclipse/wst/common/componentcore/internal/impl/IResourceFactoryExtPtConstants.java
+++ b/plugins/org.eclipse.wst.common.modulecore/modulecore-src/org/eclipse/wst/common/componentcore/internal/impl/IResourceFactoryExtPtConstants.java
@@ -21,7 +21,11 @@
 	
 	String ATT_SHORT_SEGMENT = "shortSegment"; //$NON-NLS-1$ 
 	
-	String ATT_VERSION = "version"; //$NON-NLS-1$ 
+	String TAG_CONTENTTYPE = "contentTypeBinding"; //$NON-NLS-1$ 
+	
+	String ATT_CONTENTTYPEID = "contentTypeId"; //$NON-NLS-1$ 
+	
+	String ATT_ISDEFAULT = "isDefault"; //$NON-NLS-1$ 
 		
 
 }
diff --git a/plugins/org.eclipse.wst.common.modulecore/modulecore-src/org/eclipse/wst/common/componentcore/internal/impl/WTPResourceFactoryRegistry.java b/plugins/org.eclipse.wst.common.modulecore/modulecore-src/org/eclipse/wst/common/componentcore/internal/impl/WTPResourceFactoryRegistry.java
index 008f574..e6c44df 100644
--- a/plugins/org.eclipse.wst.common.modulecore/modulecore-src/org/eclipse/wst/common/componentcore/internal/impl/WTPResourceFactoryRegistry.java
+++ b/plugins/org.eclipse.wst.common.modulecore/modulecore-src/org/eclipse/wst/common/componentcore/internal/impl/WTPResourceFactoryRegistry.java
@@ -10,6 +10,10 @@
  *******************************************************************************/
 package org.eclipse.wst.common.componentcore.internal.impl;
 
+import java.util.Iterator;
+import java.util.Set;
+
+import org.eclipse.core.resources.IFile;
 import org.eclipse.core.runtime.Assert;
 import org.eclipse.core.runtime.CoreException;
 import org.eclipse.core.runtime.IConfigurationElement;
@@ -17,6 +21,8 @@
 import org.eclipse.core.runtime.IStatus;
 import org.eclipse.core.runtime.Platform;
 import org.eclipse.core.runtime.SafeRunner;
+import org.eclipse.core.runtime.content.IContentDescription;
+import org.eclipse.core.runtime.content.IContentType;
 import org.eclipse.emf.common.util.URI;
 import org.eclipse.emf.ecore.resource.Resource;
 import org.eclipse.jem.util.RegistryReader;
@@ -24,6 +30,7 @@
 import org.eclipse.wst.common.internal.emf.resource.FileNameResourceFactoryRegistry;
 import org.eclipse.wst.common.internal.emf.resource.ResourceFactoryDescriptor;
 import org.eclipse.wst.common.internal.emf.utilities.DefaultOverridableResourceFactoryRegistry;
+import org.eclipse.wst.common.internal.emfworkbench.WorkbenchResourceHelper;
 
 /**
  * <p>
@@ -86,6 +93,13 @@
 		super.registerLastFileSegment(aSimpleFileName, aFactory);
 		
 	}  
+	private WTPResourceFactoryRegistryKey getKey(ResourceFactoryDescriptor descriptor) {
+		WTPResourceFactoryRegistryKey key = new WTPResourceFactoryRegistryKey();
+		key.shortName = descriptor.getShortSegment();
+		key.type = descriptor.getContentType();
+		key.isDefault = descriptor.isDefault();
+		return key;
+	}
 	
 	/**
 	 * Declares a subclass to create Resource.Factory(ies) from an extension. 
@@ -93,7 +107,8 @@
 	private class ConfigurationResourceFactoryDescriptor extends ResourceFactoryDescriptor  implements IResourceFactoryExtPtConstants {
 		
 		private String shortSegment;
-		private String version;
+		private IContentType contentType;
+		private boolean isDefault = true;
 		private final IConfigurationElement element; 
 		
 		public ConfigurationResourceFactoryDescriptor(IConfigurationElement ext) throws CoreException {
@@ -110,7 +125,16 @@
 										"The shortSegment attribute of " + TAG_RESOURCE_FACTORY + //$NON-NLS-1$ 
 										" must specify a valid, non-null, non-empty value in " +   //$NON-NLS-1$
 										element.getNamespaceIdentifier(), null));
-			version = element.getAttribute(ATT_VERSION);
+			if ("false".equals(element.getAttribute(ATT_ISDEFAULT)))
+					isDefault = false;
+			
+			IConfigurationElement[] bindings = element.getChildren(TAG_CONTENTTYPE);
+			if (bindings.length > 0) {
+				String contentTypeId = null;
+				contentTypeId = bindings[0].getAttribute(ATT_CONTENTTYPEID);			
+				if (contentTypeId != null)
+					contentType = Platform.getContentTypeManager().getContentType(contentTypeId);
+				}
 		} 
 
 		public boolean isEnabledFor(URI fileURI) {
@@ -142,7 +166,30 @@
 
 		public String getShortSegment() {
 			return shortSegment;
+		}
+
+		public IContentType getContentType() {
+			
+			return contentType;
+		}
+
+		public boolean isDefault() {
+			return isDefault;
 		}  
+		public int hashCode() {
+			if (getContentType() != null)
+				return getShortSegment().hashCode() & getContentType().hashCode();
+			else return super.hashCode();
+		}
+		
+		public boolean equals(Object o) {
+			if(o instanceof ResourceFactoryDescriptor && getContentType() != null)
+				return (getShortSegment().equals(((ResourceFactoryDescriptor)o).getShortSegment()) &&
+						getContentType().equals(((ResourceFactoryDescriptor)o).getContentType()));
+			else if (((ResourceFactoryDescriptor)o).getContentType() != null) return false;
+				
+			return super.equals(o);
+		}
 	}  
 	 
 	
@@ -175,40 +222,51 @@
 	}
 	private class WTPResourceFactoryRegistryKey { 
  		
-		public String version;
 		public String shortName;
+		public IContentType type;
+		public boolean isDefault = true;
 		public WTPResourceFactoryRegistryKey() {
 			super();
 		}
-		public boolean equals(Object arg0) {
-			
-			if (arg0 instanceof WTPResourceFactoryRegistryKey) {
-				WTPResourceFactoryRegistryKey key = (WTPResourceFactoryRegistryKey) arg0;
-				return key.version.equals(version) && key.shortName.equals(shortName);
-			}
-			return false;
-		}
-		public int hashCode() {
-			
-			return version.hashCode() & shortName.hashCode();
-		}
+		
 		
 	}
 
 
 	protected void addDescriptor(ResourceFactoryDescriptor descriptor) {
-		// TODO Auto-generated method stub
-		super.addDescriptor(descriptor);
+		getDescriptors().put(getKey(descriptor), descriptor);
 	}
 
 	protected synchronized ResourceFactoryDescriptor getDescriptor(URI uri) {
 		
-//		WTPResourceFactoryRegistryKey key = new WTPResourceFactoryRegistryKey();
-//		key.shortName = uri.lastSegment();
-//		key.version = J2EEFileUtil.getFastSpecVersion(uri);
-		
-		
-		
+		Set keys = getDescriptors().keySet();
+		IFile file = WorkbenchResourceHelper.getPlatformFile(uri);
+		IContentDescription fileDesc = null;
+		if (file != null && file.exists()) {
+			try {
+				fileDesc = file.getContentDescription();
+			} catch (CoreException e) {
+				// TODO Auto-generated catch block
+				e.printStackTrace();
+			}
+		}
+		for (Iterator iterator = keys.iterator(); iterator.hasNext();) {
+			WTPResourceFactoryRegistryKey key = (WTPResourceFactoryRegistryKey) iterator.next();
+			if (key.shortName.equals(uri.lastSegment())) {
+				ResourceFactoryDescriptor desc = (ResourceFactoryDescriptor)getDescriptors().get(key);
+				if (fileDesc == null) {
+					if (key.type == null) return desc;
+					else if (desc.isDefault()) 
+						return desc;
+				}
+				//Allow the contentType discrimination to take place
+				if ((key.type != null) && (fileDesc != null) && (fileDesc.getContentType().equals(key.type)))
+					return desc;
+				if ((fileDesc != null) && (desc.isDefault()))
+					return desc;
+			}
+		}
+		// Ok no content type match - go to super
 		return super.getDescriptor(uri);
 		}
 }
diff --git a/plugins/org.eclipse.wst.common.modulecore/schema/resourceFactories.exsd b/plugins/org.eclipse.wst.common.modulecore/schema/resourceFactories.exsd
index 476c2ea..dd43bdb 100644
--- a/plugins/org.eclipse.wst.common.modulecore/schema/resourceFactories.exsd
+++ b/plugins/org.eclipse.wst.common.modulecore/schema/resourceFactories.exsd
@@ -49,6 +49,9 @@
          </documentation>
       </annotation>
       <complexType>
+         <sequence>
+            <element ref="contentTypeBinding" minOccurs="0" maxOccurs="1"/>
+         </sequence>
          <attribute name="class" type="string" use="required">
             <annotation>
                <documentation>
@@ -66,10 +69,30 @@
                </documentation>
             </annotation>
          </attribute>
-         <attribute name="version" type="string">
+         <attribute name="isDefault" type="boolean" use="default" value="true">
             <annotation>
                <documentation>
-                  An optional version identifier to differentiate file versions
+                  If multiple factories are declared for the same fileName - then the &quot;default&quot; is used.
+               </documentation>
+            </annotation>
+         </attribute>
+      </complexType>
+   </element>
+
+   <element name="contentTypeBinding">
+      <annotation>
+         <appInfo>
+            <meta.element labelAttribute="contentTypeId"/>
+         </appInfo>
+         <documentation>
+            Advertises that the containing editor understands the given content type and is suitable for editing files of that type.
+         </documentation>
+      </annotation>
+      <complexType>
+         <attribute name="contentTypeId" type="string" use="required">
+            <annotation>
+               <documentation>
+                  The content type identifier. This is an ID defined by the &apos;org.eclipse.core.runtime.contentTypes&apos; extension point.
                </documentation>
             </annotation>
          </attribute>