Index: test/edu/ucsb/nceas/metacattest/ReplicationServerListTest.java
===================================================================
--- test/edu/ucsb/nceas/metacattest/ReplicationServerListTest.java	(revision 6117)
+++ test/edu/ucsb/nceas/metacattest/ReplicationServerListTest.java	(revision 6118)
@@ -39,6 +39,7 @@
 
 import java.io.*;
 import java.net.*;
+import java.util.Date;
 
 /**
  * A JUnit test for testing Step class processing
@@ -269,7 +270,7 @@
    */
   public void testGetLastCheckedDate()
   {
-    String lastCheckedDate = serverList.getLastCheckedDate("dev");
+    Date lastCheckedDate = serverList.getLastCheckedDate("dev");
     assertTrue(lastCheckedDate.equals("0001-01-01 BC"));
   }
   
Index: src/edu/ucsb/nceas/metacat/IdentifierManager.java
===================================================================
--- src/edu/ucsb/nceas/metacat/IdentifierManager.java	(revision 6117)
+++ src/edu/ucsb/nceas/metacat/IdentifierManager.java	(revision 6118)
@@ -51,7 +51,6 @@
 import org.dataone.service.types.Subject;
 import org.dataone.service.types.SystemMetadata;
 
-import edu.ucsb.nceas.metacat.accesscontrol.AccessControlForSingleFile;
 import edu.ucsb.nceas.metacat.accesscontrol.AccessControlInterface;
 import edu.ucsb.nceas.metacat.accesscontrol.XMLAccessAccess;
 import edu.ucsb.nceas.metacat.accesscontrol.XMLAccessDAO;
@@ -690,8 +689,54 @@
         return ids;
     }
     
+    /**
+     * returns a list of system metadata-only guids since the given date
+     * @return a list of system ids in metacat that do not correspond to objects
+     * TODO: need to check which server they are on
+     */
+    public List<String> getUpdatedSystemMetadataIds(Date since)
+       throws Exception
+    {
+        List<String> ids = new Vector<String>();
+        String sql = 
+        	"select guid from " + TYPE_SYSTEM_METADATA +
+        	" where guid not in " +
+        	" (select guid from " + TYPE_IDENTIFIER + ") " +
+        	" and date_modified > ?";
+        DBConnection dbConn = null;
+        int serialNumber = -1;
+        try 
+        {
+            // Get a database connection from the pool
+            dbConn = DBConnectionPool.getDBConnection("IdentifierManager.getUpdatedSystemMetadataIds");
+            serialNumber = dbConn.getCheckOutSerialNumber();
 
+            // Execute the insert statement
+            PreparedStatement stmt = dbConn.prepareStatement(sql);
+            stmt.setDate(1, new java.sql.Date(since.getTime()));
+            ResultSet rs = stmt.executeQuery();
+            while (rs.next()) 
+            {
+                String guid = rs.getString(1);
+                ids.add(guid);
+            } 
+            stmt.close();
+        } 
+        catch (SQLException e) 
+        {
+            logMetacat.error("Error while looking up the updated guids: " 
+                    + e.getMessage());
+        } 
+        finally 
+        {
+            // Return database connection to the pool
+            DBConnectionPool.returnDBConnection(dbConn, serialNumber);
+        }
+        return ids;
+    }
     
+
+    
     /**
      * Determine if an identifier exists already, returning true if so.
      * 
Index: src/edu/ucsb/nceas/metacat/replication/ReplicationServer.java
===================================================================
--- src/edu/ucsb/nceas/metacat/replication/ReplicationServer.java	(revision 6117)
+++ src/edu/ucsb/nceas/metacat/replication/ReplicationServer.java	(revision 6118)
@@ -26,6 +26,8 @@
 
 package edu.ucsb.nceas.metacat.replication;
 
+import java.util.Date;
+
 /**
  * A class express a entry in xml_replication. It include server name,
  * lastChechedDate, replication or not, dataReplication or not, hub or not
@@ -34,7 +36,7 @@
 public class ReplicationServer
 {
   private String serverName = null; //server name
-  private String lastCheckedDate = null; //string of last 
+  private Date lastCheckedDate = null; //string of last 
   private boolean replication = false; //replciate xml document or not
   private boolean dataReplication = false; //replciate data file or not
                                            //it is relative to replcation
@@ -75,7 +77,7 @@
   /**
    * Get last checked date
    */
-  public String getLastCheckedDate()
+  public Date getLastCheckedDate()
   {
     return this.lastCheckedDate;
   }//getLastCheckedDate
@@ -84,7 +86,7 @@
    * Set a string as last checked date
    * @Param myLastCheckedDate, the string will set to object's lastCheckedDate
    */
-  public void setLastCheckedDate(String myLastCheckedDate)
+  public void setLastCheckedDate(Date myLastCheckedDate)
   {
     this.lastCheckedDate = myLastCheckedDate;
   }//setLastCheckedDate
Index: src/edu/ucsb/nceas/metacat/replication/ReplMessageHandler.java
===================================================================
--- src/edu/ucsb/nceas/metacat/replication/ReplMessageHandler.java	(revision 6117)
+++ src/edu/ucsb/nceas/metacat/replication/ReplMessageHandler.java	(revision 6118)
@@ -42,6 +42,8 @@
 {
   private Vector<String> indivUpdate = new Vector<String>();
   private Vector<Vector<String>> updates = new Vector<Vector<String>>();
+  private Vector<String> indivSystemMetadata = new Vector<String>();
+  private Vector<Vector<String>> systemMetadataEntries = new Vector<Vector<String>>();
   private Vector<String> indivDelete = new Vector<String>();
   private Vector<Vector<String>> deletes = new Vector<Vector<String>>();
   private Vector<String> indivRevision = new Vector<String>();
@@ -51,6 +53,7 @@
   private boolean update = false;
   private boolean delete = false;
   private boolean revision = false;
+  private boolean systemMetadata = false;
   String currentTag = new String();
   StringBuffer textBuffer = null;
   
@@ -81,6 +84,11 @@
       indivRevision = new Vector<String>();
       revision = true;
     }
+    else if (localName.equals("updatedSystemMetadata"))
+    {
+    	indivSystemMetadata = new Vector<String>();
+    	systemMetadata = true;
+    }
             
   }
   
@@ -102,6 +110,11 @@
     {
       indivRevision.add(textBuffer.toString());
     }
+    else if (currentTag.equals("guid") && systemMetadata)
+    {
+      indivSystemMetadata.add(textBuffer.toString());
+      indivSystemMetadata.add(server);
+    }
     
     if(currentTag.equals("rev") && update)
     {
@@ -171,6 +184,11 @@
        revisions.add(new Vector<String>(indivRevision));
        revision = false;
     }
+    else if (localName.equals("updatedSystemMetadata"))
+    {
+       systemMetadataEntries.add(new Vector<String>(indivSystemMetadata));
+       systemMetadata = false;
+    }
   }
   
   /**
@@ -196,6 +214,11 @@
      return revisions;
   }
   
+  public Vector<Vector<String>> getSystemMetadataVect()
+  {
+     return systemMetadataEntries;
+  }
+  
   /**
    * Gets the server name
    * @return
Index: src/edu/ucsb/nceas/metacat/replication/ReplicationHandler.java
===================================================================
--- src/edu/ucsb/nceas/metacat/replication/ReplicationHandler.java	(revision 6117)
+++ src/edu/ucsb/nceas/metacat/replication/ReplicationHandler.java	(revision 6118)
@@ -281,6 +281,21 @@
         REVINSERTNUMBER = 1;
         REVERRORNUMBER  = 1;
         
+        // handle system metadata
+        Vector<Vector<String>> systemMetadataList = message.getSystemMetadataVect();
+        for(int k = 0; k < systemMetadataList.size(); k++) { 
+        	Vector<String> w = systemMetadataList.elementAt(k);
+        	String guid = (String) w.elementAt(0);
+        	String remoteserver = (String) w.elementAt(1);
+        	try {
+        		handleSystemMetadata(remoteserver, guid);
+        	}
+        	catch (Exception ee) {
+        		logMetacat.error("Error replicating system metedata for guid: " + guid, ee);
+        		continue;
+        	}
+        }
+        
         totalServerListParseTime += (System.currentTimeMillis() - startServerListParseTime);
     }//for response
 
@@ -796,9 +811,63 @@
        DBConnectionPool.returnDBConnection(dbConn, serialNumber);
     }//finally
   }
+  
+  	/**
+	 * Handle replicate system metadata
+	 * 
+	 * @param remoteserver
+	 * @param guid
+	 * @throws HandlerException
+	 */
+	private void handleSystemMetadata(String remoteserver, String guid) 
+		throws HandlerException {
+		try {
 
+			// Try get the system metadata from remote server
+			String sysMetaURLStr = "https://" + remoteserver + "?server="
+					+ MetacatUtil.getLocalReplicationServerName()
+					+ "&action=getsystemmetadata&guid=" + guid;
+			sysMetaURLStr = MetacatUtil.replaceWhiteSpaceForURL(sysMetaURLStr);
+			URL sysMetaUrl = new URL(sysMetaURLStr);
+			logReplication.info("ReplicationHandler.handleSystemMetadata - Sending message: "
+							+ sysMetaUrl.toString());
+			String systemMetadataXML = ReplicationService.getURLContent(sysMetaUrl);
 
+			logReplication.info("ReplicationHandler.handleSystemMetadata - guid in repl: " + guid);
 
+			// process system metadata
+			if (systemMetadataXML != null) {
+				SystemMetadata sysMeta = (SystemMetadata) ServiceTypeUtil
+						.deserializeServiceType(SystemMetadata.class,
+								new ByteArrayInputStream(systemMetadataXML
+										.getBytes("UTF-8")));
+				// String guid = sysMeta.getIdentifier().getValue();
+				if (!IdentifierManager.getInstance().identifierExists(guid)) {
+					logReplication.debug("Creating system metadata for guid: " + guid);
+					IdentifierManager.getInstance().createSystemMetadata(sysMeta);
+				}
+				IdentifierManager.getInstance().updateSystemMetadata(sysMeta);
+			}
+
+			logReplication.info("ReplicationHandler.handleSystemMetadata - Successfully replicated system metadata for guid: "
+							+ guid);
+
+			String ip = getIpFromURL(sysMetaUrl);
+			EventLog.getInstance().log(ip, ReplicationService.REPLICATIONUSER, guid, "systemMetadata");
+
+		} catch (Exception e) {
+			logMetacat.error("ReplicationHandler.handleSystemMetadata - "
+					+ ReplicationService.METACAT_REPL_ERROR_MSG);
+			logReplication
+					.error("ReplicationHandler.handleSystemMetadata - Failed to write system metadata "
+							+ guid + " into db because " + e.getMessage());
+			throw new HandlerException(
+					"ReplicationHandler.handleSystemMetadata - generic exception "
+							+ "writing Replication: " + e.getMessage());
+		}
+
+	}
+
   /**
    * updates xml_catalog with entries from other servers.
    */
Index: src/edu/ucsb/nceas/metacat/replication/ReplicationService.java
===================================================================
--- src/edu/ucsb/nceas/metacat/replication/ReplicationService.java	(revision 6117)
+++ src/edu/ucsb/nceas/metacat/replication/ReplicationService.java	(revision 6118)
@@ -49,6 +49,7 @@
 import java.util.Date;
 import java.util.Enumeration;
 import java.util.Hashtable;
+import java.util.List;
 import java.util.Timer;
 import java.util.Vector;
 
@@ -1010,7 +1011,36 @@
 		}
 
 	}
+	
+	/**
+	 * Sends System Metadata as XML
+	 */
+	protected static void handleGetSystemMetadataRequest(
+			Hashtable<String, String[]> params, HttpServletResponse response) {
+		String guid = ((String[]) (params.get("guid")))[0];
+		String systemMetadataXML = null;
+		try {
+			
+			// serialize the System Metadata as XML 
+			SystemMetadata systemMetadata = IdentifierManager.getInstance().getSystemMetadata(guid);
+			ByteArrayOutputStream baos = new ByteArrayOutputStream();
+			ServiceTypeUtil.serializeServiceType(SystemMetadata.class, systemMetadata, baos);
+			systemMetadataXML = baos.toString("UTF-8");
+				
+			// get a writer for sending back to response
+			response.setContentType("text/xml");
+			Writer out = response.getWriter();
+			out.write(systemMetadataXML);
+			out.close();
 
+		} catch (Exception e) {
+			String msg = "ReplicationService.handleGetSystemMetadataRequest for guid: " + guid + " : " + e.getMessage();
+			logMetacat.error(msg);                         
+			logReplication.error(msg);
+		}
+
+	}
+
 	/**
 	 * Sends a datafile to a remote host
 	 */
@@ -1432,6 +1462,20 @@
 			// add revision doc list  
 			doclist.append(prepareRevisionDoc(dbConn, revisionSql.toString(),
 					replicateData));
+			
+			// add the system metadata entries		 
+			Date since = new Date(System.currentTimeMillis());
+			since = serverList.getLastCheckedDate(server);
+			List<String> systemMetadataEntries = 
+				IdentifierManager.getInstance().getUpdatedSystemMetadataIds(since);
+			for (int i = 0; i < systemMetadataEntries.size(); i++) {
+				String guid = systemMetadataEntries.get(i);
+				doclist.append("<updatedSystemMetadata>");
+				doclist.append("<guid>");
+				doclist.append(guid);
+				doclist.append("</guid>");
+				doclist.append("</updatedSystemMetadata>");
+			}
 
 			doclist.append("</updates></replication>");
 			logReplication.info("ReplicationService.handleUpdateRequest - doclist: " + doclist.toString());
Index: src/edu/ucsb/nceas/metacat/replication/ReplicationServerList.java
===================================================================
--- src/edu/ucsb/nceas/metacat/replication/ReplicationServerList.java	(revision 6117)
+++ src/edu/ucsb/nceas/metacat/replication/ReplicationServerList.java	(revision 6118)
@@ -27,15 +27,18 @@
 
 package edu.ucsb.nceas.metacat.replication;
 
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.Date;
+import java.util.Vector;
+
+import org.apache.log4j.Logger;
+
 import edu.ucsb.nceas.metacat.database.DBConnection;
 import edu.ucsb.nceas.metacat.database.DBConnectionPool;
 import edu.ucsb.nceas.metacat.database.DatabaseService;
 
-import java.util.Vector;
-import java.sql.*;
-
-import org.apache.log4j.Logger;
-
 /**
  * A class represent a replication server list in xml_replcation table
  */
@@ -95,7 +98,7 @@
         String serverName = rs.getString(1);
         logMetacat.info("ServerName: "+serverName);
         //Last check date
-        String lastChecked = rs.getString(2);
+        Date lastChecked = rs.getDate(2);
         logMetacat.info("Last checked time: "+lastChecked);
         //Replication value
         int replication = rs.getInt(3);
@@ -313,7 +316,7 @@
    * @param givenServerName, the server's name which we want to get last checked
    * out date
    */
-  public synchronized String getLastCheckedDate(String givenServerName)
+  public synchronized Date getLastCheckedDate(String givenServerName)
   {
     int index = -1;//Variable to store the index
     ReplicationServer server = null;//Variable for replication server
Index: src/edu/ucsb/nceas/metacat/replication/ReplicationServlet.java
===================================================================
--- src/edu/ucsb/nceas/metacat/replication/ReplicationServlet.java	(revision 6117)
+++ src/edu/ucsb/nceas/metacat/replication/ReplicationServlet.java	(revision 6118)
@@ -207,6 +207,8 @@
 				ReplicationService.handleGetLockRequest(params, response);
 			} else if (action.equals("getdocumentinfo")) {
 				ReplicationService.handleGetDocumentInfoRequest(params, response);
+			} else if (action.equals("getsystemmetadata")) {
+				ReplicationService.handleGetSystemMetadataRequest(params, response);
 			} else if (action.equals("gettime")) {
 				ReplicationService.handleGetTimeRequest(params, response);
 			} else if (action.equals("getcatalog")) {
