Index: src/edu/ucsb/nceas/metacat/DBSAXHandler.java
===================================================================
--- src/edu/ucsb/nceas/metacat/DBSAXHandler.java	(revision 9582)
+++ src/edu/ucsb/nceas/metacat/DBSAXHandler.java	(revision 9583)
@@ -446,8 +446,10 @@
         				throw new SAXException("Odd number of elements found when parsing schema location: " + 	
         						attributeValue + ". There should be an even number of uri/files in location.");
         			}
+        			//since we don't have format id information here, we set it null
+        			String formatId = null;
         			XMLSchema xmlSchema = 
-        				new XMLSchema(parsedUri.get(j), parsedUri.get(j + 1));
+        				new XMLSchema(parsedUri.get(j), parsedUri.get(j + 1), formatId);
         			schemaList.add(xmlSchema);
         		}
             }
Index: src/edu/ucsb/nceas/metacat/DocumentImpl.java
===================================================================
--- src/edu/ucsb/nceas/metacat/DocumentImpl.java	(revision 9582)
+++ src/edu/ucsb/nceas/metacat/DocumentImpl.java	(revision 9583)
@@ -2657,7 +2657,7 @@
 
     public static String write(DBConnection conn, String xmlString, String pub,
             Reader dtd, String action, String docid, String user,
-            String[] groups, String ruleBase, boolean needValidation, boolean writeAccessRules, byte[] xmlBytes)
+            String[] groups, String ruleBase, boolean needValidation, boolean writeAccessRules, byte[] xmlBytes, String formatId)
             throws Exception
     {
         //this method will be called in handleUpdateOrInsert method
@@ -2665,7 +2665,7 @@
         // get server location for this doc
         int serverLocation = getServerLocationNumber(docid);
         return write(conn, xmlString, pub, dtd, action, docid, user, groups,
-                serverLocation, false, ruleBase, needValidation, writeAccessRules, xmlBytes);
+                serverLocation, false, ruleBase, needValidation, writeAccessRules, xmlBytes, formatId);
     }
 
     /**
@@ -2702,7 +2702,7 @@
     public static String write(DBConnection conn, String xmlString, String pub,
             Reader dtd, String action, String accnum, String user,
             String[] groups, int serverCode, boolean override, String ruleBase,
-            boolean needValidation, boolean writeAccessRules, byte[] xmlBytes) throws Exception
+            boolean needValidation, boolean writeAccessRules, byte[] xmlBytes, String formatId) throws Exception
     {
         // NEW - WHEN CLIENT ALWAYS PROVIDE ACCESSION NUMBER INCLUDING REV IN IT
     	
@@ -2789,7 +2789,7 @@
                     logMetacat.debug("DocumentImpl.write - initializing parser");
                     parser = initializeParser(conn, action, docid, xmlReader, updaterev,
                             user, groups, pub, serverCode, dtd, ruleBase,
-                            needValidation, false, null, null, encoding, writeAccessRules, guidsToSync);
+                            needValidation, false, null, null, encoding, writeAccessRules, guidsToSync, formatId);
                     	// false means it is not a revision doc
                                    //null, null are createdate and updatedate
                                    //null will use current time as create date time
@@ -2893,7 +2893,7 @@
 	        Vector<String>guidsToSync = new Vector<String>();
 
             parser = initializeParser(conn, action, docid, xmlReader, rev, user, groups,
-                    pub, serverCode, dtd, ruleBase, needValidation, false, null, null, encoding, writeAccessRules, guidsToSync);
+                    pub, serverCode, dtd, ruleBase, needValidation, false, null, null, encoding, writeAccessRules, guidsToSync, formatId);
                     // null and null are createtime and updatetime
                     // null will create current time
                     //false means it is not a revision doc
@@ -3037,7 +3037,7 @@
             String pub, Reader dtd, String action, String accnum, String user,
             String[] groups, String homeServer, String notifyServer,
             String ruleBase, boolean needValidation, String tableName, 
-            boolean timedReplication, Date createDate, Date updateDate) throws Exception
+            boolean timedReplication, Date createDate, Date updateDate, String formatId) throws Exception
     {
     	// Get the xml as a string so we can write to file later
     	StringReader xmlReader = new StringReader(xmlString);
@@ -3105,7 +3105,7 @@
 
             parser = initializeParser(conn, action, docid, xmlReader, rev, user, groups,
                     pub, serverCode, dtd, ruleBase, needValidation, 
-                    isRevision, createDate, updateDate, encoding, writeAccessRules, guidsToSync);
+                    isRevision, createDate, updateDate, encoding, writeAccessRules, guidsToSync, formatId);
          
             conn.setAutoCommit(false);
             parser.parse(new InputSource(xmlReader));
@@ -3721,7 +3721,7 @@
             String action, String docid, Reader xml, String rev, String user,
             String[] groups, String pub, int serverCode, Reader dtd,
             String ruleBase, boolean needValidation, boolean isRevision,
-            Date createDate, Date updateDate, String encoding, boolean writeAccessRules, Vector<String> guidsToSync) throws Exception
+            Date createDate, Date updateDate, String encoding, boolean writeAccessRules, Vector<String> guidsToSync, String formatId) throws Exception
     {
         XMLReader parser = null;
         try {
@@ -3751,13 +3751,22 @@
                 // From DB to find the register external schema location
                 String externalSchemaLocation = null;
 //                SchemaLocationResolver resolver = new SchemaLocationResolver();
-                externalSchemaLocation = XMLSchemaService.getInstance().getNameSpaceAndLocationString();
-                logMetacat.debug("DocumentImpl.initalizeParser - 2.0.0 external schema location: " + externalSchemaLocation);
+                logMetacat.debug("DocumentImpl.initalizeParser - the final formatId of the object "+docid+" is "+formatId);
+                externalSchemaLocation = XMLSchemaService.getInstance().getNameSpaceAndLocation(formatId);
+                if(externalSchemaLocation == null) {
+                    logMetacat.info("DocumentImpl.initalizeParser - there is no register schemas for the formatid "+ formatId+". So we will use the old way."+
+                    " Put all registred schema/location paris for the validation.");
+                    externalSchemaLocation = XMLSchemaService.getInstance().getNameSpaceAndLocationStringWithoutFormatId();
+                    
+                } 
+                logMetacat.info("DocumentImpl.initalizeParser - 2.0.0 external schema location: " + externalSchemaLocation);
                 // Set external schemalocation.
                 if (externalSchemaLocation != null
                         && !(externalSchemaLocation.trim()).equals("")) {
                     parser.setProperty(EXTERNALSCHEMALOCATIONPROPERTY,
                             externalSchemaLocation);
+                } else {
+                    throw new Exception ("The schema for the format id "+formatId+" can't be found in any place. So we can't validate the xml instance.");
                 }
                 logMetacat.debug("DocumentImpl.initalizeParser - 2.0.0 parser configured");
             } else if (ruleBase != null && ruleBase.equals(EML210)) {
@@ -3777,13 +3786,22 @@
                 parser.setFeature(SCHEMAVALIDATIONFEATURE, true);
                 // From DB to find the register external schema location
                 String externalSchemaLocation = null;
-                externalSchemaLocation = XMLSchemaService.getInstance().getNameSpaceAndLocationString();
-                logMetacat.debug("DocumentImpl.initalizeParser - 2.1.0 external schema location: " + externalSchemaLocation);
+                logMetacat.debug("DocumentImpl.initalizeParser - the final formatId of the object "+docid+" is "+formatId);
+                externalSchemaLocation = XMLSchemaService.getInstance().getNameSpaceAndLocation(formatId);
+                if(externalSchemaLocation == null) {
+                    logMetacat.info("DocumentImpl.initalizeParser - there is no register schemas for the formatid "+ formatId+". So we will use the old way."+
+                    " Put all registred schema/location paris for the validation.");
+                    externalSchemaLocation = XMLSchemaService.getInstance().getNameSpaceAndLocationStringWithoutFormatId();
+                    
+                } 
+                logMetacat.info("DocumentImpl.initalizeParser - 2.1.0 external schema location: " + externalSchemaLocation);
                 // Set external schemalocation.
                 if (externalSchemaLocation != null
                         && !(externalSchemaLocation.trim()).equals("")) {
                     parser.setProperty(EXTERNALSCHEMALOCATIONPROPERTY,
                             externalSchemaLocation);
+                } else {
+                    throw new Exception ("The schema for the format id "+formatId+" can't be found in any place. So we can't validate the xml instance.");
                 }
                 logMetacat.debug("DocumentImpl.initalizeParser - Using eml 2.1.0 parser configured");
             } else {
@@ -3818,13 +3836,22 @@
                     }
                     // From DB to find the register external schema location
                     String externalSchemaLocation = null;
-                    externalSchemaLocation = xmlss.getNameSpaceAndLocationString();
-                    logMetacat.debug("DocumentImpl.initalizeParser - Generic external schema location: " + externalSchemaLocation);              
+                    logMetacat.debug("DocumentImpl.initalizeParser - the final formatId of the object "+docid+" is "+formatId);
+                    externalSchemaLocation = XMLSchemaService.getInstance().getNameSpaceAndLocation(formatId);
+                    if(externalSchemaLocation == null) {
+                        logMetacat.info("DocumentImpl.initalizeParser - there is no register schemas for the formatid "+ formatId+". So we will use the old way."+
+                        " Put all registred schema/location paris for the validation.");
+                        externalSchemaLocation = XMLSchemaService.getInstance().getNameSpaceAndLocationStringWithoutFormatId();
+                        
+                    } 
+                    logMetacat.info("DocumentImpl.initalizeParser - Generic external schema location: " + externalSchemaLocation);              
                     // Set external schemalocation.
                     if (externalSchemaLocation != null
                             && !(externalSchemaLocation.trim()).equals("")) {
                         parser.setProperty(EXTERNALSCHEMALOCATIONPROPERTY,
                                 externalSchemaLocation);
+                    } else {
+                        throw new Exception ("The schema for the format id "+formatId+" can't be found in any place. So we can't validate the xml instance.");
                     }
 
                 } else if (ruleBase != null && ruleBase.equals(DTD)
Index: src/edu/ucsb/nceas/metacat/DocumentImplWrapper.java
===================================================================
--- src/edu/ucsb/nceas/metacat/DocumentImplWrapper.java	(revision 9582)
+++ src/edu/ucsb/nceas/metacat/DocumentImplWrapper.java	(revision 9583)
@@ -59,14 +59,14 @@
 	}//Constructor
 
 	public String write(DBConnection conn, String xml, String pub, Reader dtd,
-			String action, String docid, String user, String[] groups, byte[]xmlBytes) throws Exception {
+			String action, String docid, String user, String[] groups, byte[]xmlBytes, String formatId) throws Exception {
 		return DocumentImpl.write(conn, xml, pub, dtd, action, docid, user, groups,
-				ruleBase, needValidation, writeAccessRules, xmlBytes);
+				ruleBase, needValidation, writeAccessRules, xmlBytes, formatId);
 	}
 
 	public String writeReplication(DBConnection conn, String xml, byte[]xmlBytes, String pub, Reader dtd,
 			String action, String accnum, String user, String[] groups,
-			String homeServer, String notifyServer, Date createDate, Date updateDate)
+			String homeServer, String notifyServer, Date createDate, Date updateDate, String formatId)
 			throws Exception {
 		//we don't need to check validation in replication
 		// so rule base is null and need validation is false (first false)
@@ -74,7 +74,7 @@
 		// and timed replication is false (last false)
 		return DocumentImpl.writeReplication(conn, xml, xmlBytes, pub, dtd, action, accnum, user,
 				groups, homeServer, notifyServer, ruleBase, false,
-				DocumentImpl.DOCUMENTTABLE, false, createDate, updateDate);
+				DocumentImpl.DOCUMENTTABLE, false, createDate, updateDate, formatId);
 		// last false means is not timed replication
 
 	}
@@ -99,13 +99,13 @@
 	public String writeReplication(DBConnection conn, String xml, byte[]xmlBytes, String pub, Reader dtd,
 			String action, String accnum, String user, String[] groups,
 			String homeServer, String notifyServer, String tableName,
-			boolean timedReplication, Date createDate, Date updateDate)
+			boolean timedReplication, Date createDate, Date updateDate, String formatId)
 			throws Exception {
 		//we don't need to check validation in replication
 		// so rule base is null and need validation is false
 		return DocumentImpl.writeReplication(conn, xml, xmlBytes, pub, dtd, action, accnum, user,
 				groups, homeServer, notifyServer, ruleBase, false, tableName,
-				timedReplication, createDate, updateDate);
+				timedReplication, createDate, updateDate, formatId);
 	}
 
 }
Index: src/edu/ucsb/nceas/metacat/MetaCatServlet.java
===================================================================
--- src/edu/ucsb/nceas/metacat/MetaCatServlet.java	(revision 9582)
+++ src/edu/ucsb/nceas/metacat/MetaCatServlet.java	(revision 9583)
@@ -687,6 +687,7 @@
 		// if we get here, metacat is configured.  If we have not completed the 
 		// second half of the initialization, do so now.  This allows us to initially
 		// configure metacat without a restart.
+		logMetacat.info("MetacatServlet.handleGetOrPost - the _fullyInitailzied value is "+_fullyInitialized);
 		if (!_fullyInitialized) {
 			initSecondHalf(request.getSession().getServletContext());
 		}
@@ -917,8 +918,10 @@
                 }
 				PrintWriter out = response.getWriter();
 				if ((userName != null) && !userName.equals("public")) {
+				    //formatid will be set null here since this is metacat api
+				    String formatId = null;
 					handler.handleInsertOrUpdateAction(request.getRemoteAddr(), request.getHeader("User-Agent"), response, out, params, userName,
-							groupNames, true, true, null);
+							groupNames, true, true, null, formatId);
 				} else {
 					response.setContentType("text/xml");
 					out.println("<?xml version=\"1.0\"?>");
Index: src/edu/ucsb/nceas/metacat/MetacatHandler.java
===================================================================
--- src/edu/ucsb/nceas/metacat/MetacatHandler.java	(revision 9582)
+++ src/edu/ucsb/nceas/metacat/MetacatHandler.java	(revision 9583)
@@ -1628,7 +1628,7 @@
      */
     public String handleInsertOrUpdateAction(String ipAddress, String userAgent,
             HttpServletResponse response, PrintWriter out, Hashtable<String, String[]> params,
-            String user, String[] groups, boolean generateSystemMetadata, boolean writeAccessRules, byte[] xmlBytes) {
+            String user, String[] groups, boolean generateSystemMetadata, boolean writeAccessRules, byte[] xmlBytes, String formatId) {
         Logger logMetacat = Logger.getLogger(MetacatHandler.class);
         DBConnection dbConn = null;
         int serialNumber = -1;
@@ -1805,7 +1805,7 @@
               
               } else {*/
               newdocid = documentWrapper.write(dbConn, doctext[0], pub, dtd,
-                          doAction, accNumber, user, groups, xmlBytes);
+                          doAction, accNumber, user, groups, xmlBytes, formatId);
             
               EventLog.getInstance().log(ipAddress, userAgent, user, accNumber, action[0]);
               
@@ -3197,8 +3197,9 @@
                 params.put("doctext", doctextArr);
                 boolean writeAccessRules = true;
                 //call the insert routine
+                String formatId = null;
                 handleInsertOrUpdateAction(request.getRemoteAddr(), request.getHeader("User-Agent"), response, out, 
-                          params, username, groupnames, true, writeAccessRules, null);
+                          params, username, groupnames, true, writeAccessRules, null, formatId);
               }
               catch(Exception e)
               {
Index: src/edu/ucsb/nceas/metacat/SchemaLocationResolver.java
===================================================================
--- src/edu/ucsb/nceas/metacat/SchemaLocationResolver.java	(revision 9582)
+++ src/edu/ucsb/nceas/metacat/SchemaLocationResolver.java	(revision 9583)
@@ -339,7 +339,7 @@
     } 
   }
   
-  public static void main(String[] argus)
+  /*public static void main(String[] argus)
   {
      try
      {
@@ -368,7 +368,7 @@
        logMetacat.error("erorr in Schemalocation.main: " + 
                                 e.getMessage());
      }
-  }
+  }*/
   
   /**
    * Gets the downloadNewSchema's value.
Index: src/edu/ucsb/nceas/metacat/dataone/D1NodeService.java
===================================================================
--- src/edu/ucsb/nceas/metacat/dataone/D1NodeService.java	(revision 9582)
+++ src/edu/ucsb/nceas/metacat/dataone/D1NodeService.java	(revision 9583)
@@ -447,7 +447,11 @@
       	//String objectAsXML = "";
         try {
 	        //objectAsXML = IOUtils.toString(object, "UTF-8");
-	        localId = insertOrUpdateDocument(object,"UTF-8", pid, session, "insert");
+            String formatId = null;
+            if(sysmeta.getFormatId() != null)  {
+                formatId = sysmeta.getFormatId().getValue();
+            }
+	        localId = insertOrUpdateDocument(object,"UTF-8", pid, session, "insert", formatId);
 	        //localId = im.getLocalId(pid.getValue());
 
         } catch (IOException e) {
@@ -1269,7 +1273,7 @@
           " is science metadata: " + e.getMessage());*/
     
     } catch (NotFound e) {
-      logMetacat.debug("There was a problem determining if the object identified by" + 
+      logMetacat.warn("There was a problem determining if the object identified by" + 
           sysmeta.getIdentifier().getValue() + 
           " is science metadata: " + e.getMessage());
     
@@ -1303,7 +1307,7 @@
    * 
    */
   public String insertOrUpdateDocument(InputStream xml, String encoding,  Identifier pid, 
-    Session session, String insertOrUpdate) 
+    Session session, String insertOrUpdate, String formatId) 
     throws ServiceFailure, IOException {
     
   	logMetacat.debug("Starting to insert xml document...");
@@ -1376,7 +1380,7 @@
     // do the insert or update action
     handler = new MetacatHandler(new Timer());
     String result = handler.handleInsertOrUpdateAction(request.getRemoteAddr(), request.getHeader("User-Agent"), null, 
-                        null, params, username, groupnames, false, false, xmlBytes);
+                        null, params, username, groupnames, false, false, xmlBytes, formatId);
     
     if(result.indexOf("<error>") != -1) {
     	String detailCode = "";
Index: src/edu/ucsb/nceas/metacat/dataone/MNodeService.java
===================================================================
--- src/edu/ucsb/nceas/metacat/dataone/MNodeService.java	(revision 9582)
+++ src/edu/ucsb/nceas/metacat/dataone/MNodeService.java	(revision 9583)
@@ -474,8 +474,11 @@
                 //String objectAsXML = "";
                 try {
                     //objectAsXML = IOUtils.toString(object, "UTF-8");
-                	
-                    localId = insertOrUpdateDocument(object, "UTF-8", pid, session, "update");
+                	String formatId = null;
+                	if(sysmeta.getFormatId() != null) {
+                	    formatId = sysmeta.getFormatId().getValue();
+                	}
+                    localId = insertOrUpdateDocument(object, "UTF-8", pid, session, "update", formatId);
                     
                     // register the newPid and the generated localId
                     if (newPid != null) {
Index: src/edu/ucsb/nceas/metacat/replication/ReplicationHandler.java
===================================================================
--- src/edu/ucsb/nceas/metacat/replication/ReplicationHandler.java	(revision 9582)
+++ src/edu/ucsb/nceas/metacat/replication/ReplicationHandler.java	(revision 9583)
@@ -456,6 +456,13 @@
       {
         parserBase = DocumentImpl.EML210;
       }
+      
+      String formatId = null;
+      //get the format id from the system metadata 
+      if(sysMeta != null && sysMeta.getFormatId() != null) {
+          logMetacat.debug("ReplicationService.handleForceReplicateRequest - the format id will be got from the system metadata for the object "+accNumber);
+          formatId = sysMeta.getFormatId().getValue();
+      }
       // Write the document into local host
       DocumentImplWrapper wrapper = new DocumentImplWrapper(parserBase, false, false);
       String newDocid = wrapper.writeReplication(dbConn,
@@ -469,7 +476,7 @@
                               docHomeServer,
                               remoteserver, tableName, true,// true is for time replication 
                               createdDate,
-                              updatedDate);
+                              updatedDate, formatId);
       
       if(sysMeta != null) {
 			// submit for indexing. When the doc writing process fails, the index process will fail as well. But this failure
Index: src/edu/ucsb/nceas/metacat/replication/ReplicationService.java
===================================================================
--- src/edu/ucsb/nceas/metacat/replication/ReplicationService.java	(revision 9582)
+++ src/edu/ucsb/nceas/metacat/replication/ReplicationService.java	(revision 9583)
@@ -731,7 +731,14 @@
 				parserBase = DocumentImpl.EML210;
 			}
 			logReplication.warn("ReplicationService.handleForceReplicateRequest - The parserBase is: " + parserBase);
-
+			
+			String formatId = null;
+		    //get the format id from the system metadata 
+		    if(sysMeta != null && sysMeta.getFormatId() != null) {
+		          logMetacat.debug("ReplicationService.handleForceReplicateRequest - the format id will be got from the system metadata for the object "+docid);
+		          formatId = sysMeta.getFormatId().getValue();
+		    }
+		      
 			// Get DBConnection from pool
 			dbConn = DBConnectionPool
 					.getDBConnection("MetacatReplication.handleForceReplicateRequest");
@@ -742,7 +749,7 @@
 			try {
 				wrapper.writeReplication(dbConn, xmldoc, xmlBytes, null, null,
 						dbaction, docid, null, null, homeServer, server, createdDate,
-						updatedDate);
+						updatedDate, formatId);
 			} finally {
 				if(sysMeta != null) {
 					// submit for indexing. When the doc writing process fails, the index process will fail as well. But this failure
Index: src/edu/ucsb/nceas/metacat/service/XMLSchema.java
===================================================================
--- src/edu/ucsb/nceas/metacat/service/XMLSchema.java	(revision 9582)
+++ src/edu/ucsb/nceas/metacat/service/XMLSchema.java	(revision 9583)
@@ -39,9 +39,11 @@
 	private String fileName = null;
 	private String localFileUri = null;
 	private String localFileDir = null;
+	private String formatId = null;
 	
-	private Logger logMetacat = Logger.getLogger(XMLSchema.class);
 
+    private Logger logMetacat = Logger.getLogger(XMLSchema.class);
+
 	/**
 	 * Constructor - the schema file name will be extracted from the external
 	 * file uri. The local file uri and local file dir will be constructed using
@@ -52,9 +54,10 @@
 	 * @param externalFileUri
 	 *            the external uri where the schema is located
 	 */
-	public XMLSchema(String fileNamespace, String externalFileUri) {
+	public XMLSchema(String fileNamespace, String externalFileUri, String formatId) {
 		setFileNamespace(fileNamespace);
 		setExternalFileUri(externalFileUri);
+		setFormatId(formatId);
 	}
 	
 	/**
@@ -64,9 +67,9 @@
 	 * @param namespace
 	 *            the file's name space
 	 */
-	public XMLSchema(String fileNamespace) {
+	/*public XMLSchema(String fileNamespace) {
 		setFileNamespace(fileNamespace);
-	}
+	}*/
 	
 	/**
 	 * Set the file name. The local file uri and local file dir will also get
@@ -202,4 +205,21 @@
 	public String getLocalFileDir() {
 		return localFileDir;
 	}
+	
+	
+	/**
+	 * Get the format id
+	 * @return the format id
+	 */
+	public String getFormatId() {
+        return formatId;
+    }
+
+	/**
+	 * Set the format id. 
+	 * @param formatId. 
+	 */
+    public void setFormatId(String formatId) {
+            this.formatId = formatId;
+    }
 }
Index: src/edu/ucsb/nceas/metacat/service/XMLSchemaService.java
===================================================================
--- src/edu/ucsb/nceas/metacat/service/XMLSchemaService.java	(revision 9582)
+++ src/edu/ucsb/nceas/metacat/service/XMLSchemaService.java	(revision 9583)
@@ -37,6 +37,7 @@
 import java.sql.PreparedStatement;
 import java.sql.ResultSet;
 import java.sql.SQLException;
+import java.util.Hashtable;
 import java.util.Vector;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
@@ -77,9 +78,14 @@
     private static Vector<String> nameSpaceList = new Vector<String>();
     
     // a convenience string that holds all name spaces and locations in a space
-    // delimited format
-    private static String nameSpaceAndLocationString = ""; 
+    // delimited format. Those items don't have a format id. This is the old way we handle the schema location
+    private static String nameSpaceAndLocationStringWithoutFormatId = ""; 
 	
+    //this hash table is design for schema variants. Two schemas have the same name space,
+    //but they have different content (location). So we different format id to
+    //distinguish them. The key of the hash table is the format id, the values is all the namespace schema location
+    //delimited string for this format id.
+    private static Hashtable<String, String> formatId_NamespaceLocationHash = new Hashtable<String, String>();
 	/**
 	 * private constructor since this is a singleton
 	 */
@@ -142,16 +148,33 @@
 	/**
 	 * Gets the name space and location string. This is a convenience method.
 	 * The string will have space delimited namespaces and locations that are
-	 * held in the registered schema list.
+	 * held in the registered schema list. This is the old way Metacat worked.
+	 * Usually, we will call the method getNameSapceAndLocation(String formatId) first.
+	 * If the method return null, we will call this method.
 	 * 
 	 * @return a string that holds space delimited registered namespaces and
 	 *         locations.
 	 */
-	public String getNameSpaceAndLocationString() {
-		return nameSpaceAndLocationString;
+	public String getNameSpaceAndLocationStringWithoutFormatId() {
+		return nameSpaceAndLocationStringWithoutFormatId;
 	}
 	
+	
 	/**
+	 * Get the all schema-location pairs registered for the formatId.
+	 * The null will be returned, if we can find it.
+	 * @param formatId
+	 * @return
+	 */
+	public String getNameSpaceAndLocation(String formatId) {
+	    if(formatId == null) {
+	        return null;
+	    } else {
+	        return formatId_NamespaceLocationHash.get(formatId);
+	    }
+	}
+	
+	/**
 	 * Gets a list of name spaces. This is a convenience method. The list will 
 	 * have all namespaces that are held in the registered schema list.
 	 * 
@@ -196,7 +219,7 @@
 		registeredSchemaList = new Vector<XMLSchema>();
 
 		// get the system id from the xml_catalog table for all schemas.
-		String sql = "SELECT public_id, system_id FROM xml_catalog where "
+		String sql = "SELECT public_id, system_id, format_id FROM xml_catalog where "
 				+ "entry_type ='" + DocumentImpl.SCHEMA + "'";
 		try {
 			// check out DBConnection
@@ -213,8 +236,9 @@
 			while (resultSet.next()) {
 				String fileNamespace = resultSet.getString(1);
 				String fileLocation = resultSet.getString(2);
-				logMetacat.debug("XMLService.populateRegisteredSchemaList - Registering schema: " + fileNamespace + " " + fileLocation);
-				XMLSchema xmlSchema = new XMLSchema(fileNamespace);
+				String formatId = resultSet.getString(3);
+				logMetacat.debug("XMLService.populateRegisteredSchemaList - Registering schema: " + fileNamespace + " " + fileLocation+ " and format id "+formatId);
+				XMLSchema xmlSchema = new XMLSchema(fileNamespace, fileLocation, formatId);
 				if(fileLocation.startsWith("http://") || fileLocation.startsWith("https://"))
 				{
 				    //System.out.println("processing an http schemal location");
@@ -310,16 +334,35 @@
 	 * in the registered schema list.
 	 */
 	private static void createRegisteredNameSpaceAndLocationString() {
-		boolean firstRow = true;
-		nameSpaceAndLocationString = "";
+		boolean firstRowWithoutFormatid = true;
+		boolean firstRowWithFormatid = true;
+		nameSpaceAndLocationStringWithoutFormatId = "";
 		
 		for (XMLSchema xmlSchema : registeredSchemaList) {
-			if (!firstRow) {
-				nameSpaceAndLocationString += " ";
-			}
-			nameSpaceAndLocationString += xmlSchema.getFileNamespace() + " "
-					+ xmlSchema.getLocalFileUri();
-			firstRow = false;
+		    String formatId = xmlSchema.getFormatId();
+		    if( formatId == null ||formatId.trim().equals("")) {
+		        //this is to handle the old way - no schema variants 
+		        if (!firstRowWithoutFormatid) {
+	                nameSpaceAndLocationStringWithoutFormatId += " ";
+	            }
+	            nameSpaceAndLocationStringWithoutFormatId += xmlSchema.getFileNamespace() + " "
+	                    + xmlSchema.getLocalFileUri();
+	            firstRowWithoutFormatid = false;
+		    } else {
+		        //it has a format id on the xml_catalog table. It is a variant.
+		        if(!formatId_NamespaceLocationHash.containsKey(xmlSchema.getFormatId())) {
+		            //the hash table hasn't stored the value. So put it on the hash.
+		            formatId_NamespaceLocationHash.put(formatId, xmlSchema.getFileNamespace() + " "
+	                        + xmlSchema.getLocalFileUri());
+		        } else {
+		          //the hash table already has it. We will attache the new pair to the exist value
+		            String value = formatId_NamespaceLocationHash.get(formatId);
+		            value += " "+ xmlSchema.getFileNamespace() + " "
+	                        + xmlSchema.getLocalFileUri();
+		            formatId_NamespaceLocationHash.put(formatId, value);
+		        }
+		    }
+			
 		}
 	}
 
@@ -419,8 +462,9 @@
 										+ targetLine
 										+ ". There should be an even number of uri/files in location.");
 					}
+					String formatId = null;
 					XMLSchema xmlSchema = new XMLSchema(parsedUri.get(j), parsedUri
-							.get(j + 1));
+							.get(j + 1), formatId);
 					schemaList.add(xmlSchema);
 				}
 				i = matcher.end();
Index: src/edu/ucsb/nceas/metacat/util/EMLVersionsTransformer.java
===================================================================
--- src/edu/ucsb/nceas/metacat/util/EMLVersionsTransformer.java	(revision 9582)
+++ src/edu/ucsb/nceas/metacat/util/EMLVersionsTransformer.java	(revision 9583)
@@ -159,6 +159,7 @@
              DBConnection dbconn = null;
              StringReader dtd = null;
              int serialNumber = -1;
+             String formatId = null;
              try
              {
             	 dbconn = DBConnectionPool
@@ -165,7 +166,7 @@
                  .getDBConnection("EMLVersionsTransformer.handleSingleEML200Document");
                   serialNumber = dbconn.getCheckOutSerialNumber();
                   documentWrapper.write(dbconn, eml210Content, pub, dtd,
-                          doAction, newId, owner, groups, null);
+                          doAction, newId, owner, groups, null, formatId);
                   logMetacat.warn("Doc "+docidWithRev+" was transformed to eml210 with new id "+newId);
                   transformLog("Doc "+docidWithRev+" was transformed to eml210 with new id "+newId);
              }
