Index: lib/d1_libclient_java-1.0.1-SNAPSHOT.jar
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: lib/d1_common_java-1.0.1-SNAPSHOT.jar
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: src/edu/ucsb/nceas/metacat/restservice/MNResourceHandler.java
===================================================================
--- src/edu/ucsb/nceas/metacat/restservice/MNResourceHandler.java	(revision 6802)
+++ src/edu/ucsb/nceas/metacat/restservice/MNResourceHandler.java	(revision 6803)
@@ -22,7 +22,6 @@
  */
 package edu.ucsb.nceas.metacat.restservice;
 
-import java.io.ByteArrayInputStream;
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.IOException;
@@ -61,7 +60,6 @@
 import org.dataone.service.exceptions.ServiceFailure;
 import org.dataone.service.exceptions.SynchronizationFailed;
 import org.dataone.service.exceptions.UnsupportedType;
-import org.dataone.service.types.v1.AccessPolicy;
 import org.dataone.service.types.v1.Checksum;
 import org.dataone.service.types.v1.DescribeResponse;
 import org.dataone.service.types.v1.Event;
@@ -76,6 +74,7 @@
 import org.dataone.service.types.v1.Permission;
 import org.dataone.service.types.v1.Subject;
 import org.dataone.service.types.v1.SystemMetadata;
+import org.dataone.service.util.Constants;
 import org.dataone.service.util.DateTimeMarshaller;
 import org.dataone.service.util.ExceptionHandler;
 import org.dataone.service.util.TypeMarshaller;
@@ -82,7 +81,6 @@
 import org.jibx.runtime.JiBXException;
 import org.xml.sax.SAXException;
 
-import edu.ucsb.nceas.metacat.dataone.CNodeService;
 import edu.ucsb.nceas.metacat.dataone.MNodeService;
 
 /**
@@ -175,15 +173,6 @@
                     // node response
                     node();
                     status = true;
-                } else if (resource.startsWith(RESOURCE_ACCESS_RULES)) {
-                    if (httpVerb == PUT) {
-                    	// after the command
-                        extra = parseTrailing(resource, RESOURCE_ACCESS_RULES);
-	                	// set the access rules
-	                    setAccess(extra);
-	                    status = true;
-	                    logMetacat.debug("done setting access");
-                    }
                 } else if (resource.startsWith(RESOURCE_IS_AUTHORIZED)) {
                     if (httpVerb == GET) {
                     	// after the command
@@ -248,8 +237,19 @@
                     if (httpVerb == GET) {
                     	// after the command
                         extra = parseTrailing(resource, RESOURCE_MONITOR);
-                    	// health monitoring calls
-                        status = monitor(extra);
+                        
+                        // ping
+                        if (extra.toLowerCase().equals("ping")) {
+                            logMetacat.debug("processing ping request");
+                            Date result = MNodeService.getInstance(request).ping();
+                            // TODO: send to output	
+                            status = true;
+                            
+                        } else {
+	                    	// health monitoring calls
+	                        status = monitor(extra);
+                        }
+                        
                     }
                 } else if (resource.startsWith(RESOURCE_REPLICATE)) {
                 	if (httpVerb == POST) {
@@ -452,12 +452,7 @@
         logMetacat.debug("verb is GET");
         logMetacat.debug("pathInfo is " + pathInfo);
         
-        if (pathInfo.toLowerCase().equals("ping")) {
-            logMetacat.debug("processing ping request");
-            boolean result = MNodeService.getInstance(request).ping();
-            return result;
-            
-        } else if (pathInfo.toLowerCase().equals("status")) {
+        if (pathInfo.toLowerCase().equals("status")) {
             logMetacat.debug("processing status request");
             // TODO: implement in MNCore
             //MNodeService.getInstance().getStatus();
@@ -1075,34 +1070,6 @@
         TypeMarshaller.marshalTypeToOutputStream(id, out);
         
     }    
-    
-    /**
-     * set the access perms on a document
-     * @throws JiBXException 
-     * @throws InvalidRequest 
-     * @throws NotImplemented 
-     * @throws NotAuthorized 
-     * @throws NotFound 
-     * @throws ServiceFailure 
-     * @throws InvalidToken 
-     * @throws IllegalAccessException 
-     * @throws InstantiationException 
-     * @throws IOException 
-     * @throws SAXException 
-     * @throws ParserConfigurationException 
-     */
-    protected void setAccess(String pid) throws JiBXException, InvalidToken, ServiceFailure, NotFound, NotAuthorized, NotImplemented, InvalidRequest, IOException, InstantiationException, IllegalAccessException, ParserConfigurationException, SAXException
-    {
-    
-        //String pid = params.get("pid")[0];
-        Identifier id = new Identifier();
-        id.setValue(pid);
-        
-        AccessPolicy accessPolicy = collectAccessPolicy();
-        MNodeService.getInstance(request).setAccessPolicy(session, id, accessPolicy);
-        
-        
-    }
 
 	protected SynchronizationFailed collectSynchronizationFailed() throws IOException, ServiceFailure, InvalidRequest, JiBXException, InstantiationException, IllegalAccessException, ParserConfigurationException, SAXException  {
 		
Index: src/edu/ucsb/nceas/metacat/restservice/CNResourceHandler.java
===================================================================
--- src/edu/ucsb/nceas/metacat/restservice/CNResourceHandler.java	(revision 6802)
+++ src/edu/ucsb/nceas/metacat/restservice/CNResourceHandler.java	(revision 6803)
@@ -56,6 +56,8 @@
 import org.dataone.service.exceptions.UnsupportedType;
 import org.dataone.service.types.v1.AccessPolicy;
 import org.dataone.service.types.v1.Checksum;
+import org.dataone.service.types.v1.ChecksumAlgorithmList;
+import org.dataone.service.types.v1.DescribeResponse;
 import org.dataone.service.types.v1.Event;
 import org.dataone.service.types.v1.Identifier;
 import org.dataone.service.types.v1.Log;
@@ -71,6 +73,7 @@
 import org.dataone.service.types.v1.ReplicationStatus;
 import org.dataone.service.types.v1.Subject;
 import org.dataone.service.types.v1.SystemMetadata;
+import org.dataone.service.util.Constants;
 import org.dataone.service.util.DateTimeMarshaller;
 import org.dataone.service.util.TypeMarshaller;
 import org.jibx.runtime.JiBXException;
@@ -77,6 +80,7 @@
 import org.xml.sax.SAXException;
 
 import edu.ucsb.nceas.metacat.dataone.CNodeService;
+import edu.ucsb.nceas.metacat.dataone.MNodeService;
 import edu.ucsb.nceas.metacat.properties.PropertyService;
 import edu.ucsb.nceas.utilities.PropertyNotFoundException;
 
@@ -247,6 +251,9 @@
                     } else if (httpVerb == POST) {
                         putObject(extra, FUNCTION_NAME_INSERT);
                         status = true;
+                    } else if (httpVerb == HEAD) {
+                        describeObject(extra);
+                        status = true;
                     }
 
                 } else if (resource.startsWith(RESOURCE_FORMATS)) {
@@ -330,6 +337,21 @@
                     isNodeAuthorized(extra);
                     status = true;
 
+                } else if (resource.startsWith(Constants.RESOURCE_MONITOR_PING)) {
+                    if (httpVerb == GET) {
+                    	// after the command
+                        extra = parseTrailing(resource, Constants.RESOURCE_MONITOR_PING);
+                        
+                        logMetacat.debug("processing ping request");
+                        Date result = CNodeService.getInstance(request).ping();
+                        // TODO: send to output	
+                        status = true;
+                    }
+                } else if (resource.startsWith(Constants.RESOURCE_CHECKSUM)) {
+                    if (httpVerb == GET) {
+                        listChecksumAlgorithms();
+                        status = true;
+                    }
                 }
 
                 if (!status) {
@@ -653,8 +675,60 @@
                 stylesheet);
 
     }
+    
+    private void listChecksumAlgorithms() throws IOException, ServiceFailure,
+			NotImplemented, JiBXException {
+		logMetacat.debug("Entering listFormats()");
 
+		ChecksumAlgorithmList result = CNodeService.getInstance(request).listChecksumAlgorithms();
+
+		// get the response output stream
+		OutputStream out = response.getOutputStream();
+		response.setStatus(200);
+		response.setContentType("text/xml");
+
+		// style the object with a processing directive
+		String stylesheet = null;
+		try {
+			stylesheet = PropertyService.getProperty("dataone.types.xsl");
+		} catch (PropertyNotFoundException e) {
+			logMetacat.warn("Could not locate DataONE types XSLT: "
+					+ e.getMessage());
+		}
+
+		TypeMarshaller.marshalTypeToOutputStream(result, out, stylesheet);
+
+	}
+    
     /**
+     * http://mule1.dataone.org/ArchitectureDocs-current/apis/CN_APIs.html#CNRead.describe
+     * @param pid
+     * @throws InvalidToken
+     * @throws ServiceFailure
+     * @throws NotAuthorized
+     * @throws NotFound
+     * @throws NotImplemented
+     * @throws InvalidRequest
+     */
+    private void describeObject(String pid) throws InvalidToken, ServiceFailure, NotAuthorized, NotFound, NotImplemented, InvalidRequest
+    {
+        response.setStatus(200);
+        response.setContentType("text/xml");
+        
+        Identifier id = new Identifier();
+        id.setValue(pid);
+
+        DescribeResponse dr = CNodeService.getInstance(request).describe(session, id);
+        //response.addHeader("pid", pid);
+        response.addHeader("DataONE-Checksum", dr.getDataONE_Checksum().getAlgorithm() + "," + dr.getDataONE_Checksum().getValue());
+        response.addHeader("Content-Length", dr.getContent_Length() + "");
+        response.addHeader("Last-Modified", DateTimeMarshaller.serializeDateToUTC(dr.getLast_Modified()));
+        response.addHeader("DataONE-ObjectFormat", dr.getDataONE_ObjectFormatIdentifier().getValue());
+        response.addHeader("DataONE-SerialVersion", dr.getSerialVersion().toString());
+
+    }
+
+    /**
      * Return the requested object format
      * 
      * @param fmtidStr
@@ -839,8 +913,7 @@
         Subject subject = TypeMarshaller.unmarshalTypeFromStream(Subject.class,
                 new ByteArrayInputStream(subjectStr.getBytes("UTF-8")));
 
-        Identifier retPid = CNodeService.getInstance(request).setOwner(session,
-                pid, subject, serialVersion);
+        Identifier retPid = CNodeService.getInstance(request).setRightsHolder(session, pid, subject, serialVersion);
         OutputStream out = response.getOutputStream();
         response.setStatus(200);
         response.setContentType("text/xml");
Index: src/edu/ucsb/nceas/metacat/util/MetacatPopulator.java
===================================================================
--- src/edu/ucsb/nceas/metacat/util/MetacatPopulator.java	(revision 6802)
+++ src/edu/ucsb/nceas/metacat/util/MetacatPopulator.java	(revision 6803)
@@ -254,11 +254,6 @@
 	              SystemMetadata resourceMapSysMeta = generateSystemMetadata(rmDoc);
 	              mn.create(session, resourceMapId, IOUtils.toInputStream(resourceMapXML, MetaCatServlet.DEFAULT_ENCODING), resourceMapSysMeta);
 	              
-	              // clean up the permissions (FORCE public read)
-	              for (Identifier dataId: dataIds) {
-	            	  mn.setAccessPolicy(session, dataId, sysmeta.getAccessPolicy());
-	            	  System.out.println("Set public access policy for: " + dataId.getValue());
-	              }
             }
               
             }
Index: src/edu/ucsb/nceas/metacat/dataone/ObjectFormatService.java
===================================================================
--- src/edu/ucsb/nceas/metacat/dataone/ObjectFormatService.java	(revision 6802)
+++ src/edu/ucsb/nceas/metacat/dataone/ObjectFormatService.java	(revision 6803)
@@ -97,8 +97,7 @@
 	 * @return objectFormat - the desired object format
 	 */
 	public ObjectFormat getFormat(ObjectFormatIdentifier fmtid)
-			throws ServiceFailure, NotFound,
-			InsufficientResources, NotImplemented {
+			throws ServiceFailure, NotFound, NotImplemented {
 
 		logMetacat.debug("CNCoreImpl.getFormat() called.");
 
@@ -129,7 +128,7 @@
 	 * 
 	 * @return objectFormatList - the list of object formats
 	 */
-	public ObjectFormatList listFormats() throws ServiceFailure, InsufficientResources, NotImplemented {
+	public ObjectFormatList listFormats() throws ServiceFailure, NotImplemented {
 
 		objectFormatList = getCachedList();
 
Index: src/edu/ucsb/nceas/metacat/dataone/MNodeService.java
===================================================================
--- src/edu/ucsb/nceas/metacat/dataone/MNodeService.java	(revision 6802)
+++ src/edu/ucsb/nceas/metacat/dataone/MNodeService.java	(revision 6803)
@@ -99,6 +99,7 @@
 import edu.ucsb.nceas.metacat.database.DBConnectionPool;
 import edu.ucsb.nceas.metacat.dataone.hazelcast.HazelcastService;
 import edu.ucsb.nceas.metacat.properties.PropertyService;
+import edu.ucsb.nceas.metacat.shared.ServiceException;
 import edu.ucsb.nceas.metacat.util.SystemUtil;
 import edu.ucsb.nceas.utilities.PropertyNotFoundException;
 
@@ -587,39 +588,6 @@
     }
 
     /**
-     * This method provides a lighter weight mechanism than 
-     * MN_read.getSystemMetadata() for a client to determine basic 
-     * properties of the referenced object.
-     * 
-     * @param session - the Session object containing the credentials for the Subject
-     * @param pid - the identifier of the object to be described
-     * 
-     * @return describeResponse - A set of values providing a basic description 
-     *                            of the object.
-     * 
-     * @throws InvalidToken
-     * @throws ServiceFailure
-     * @throws NotAuthorized
-     * @throws NotFound
-     * @throws NotImplemented
-     * @throws InvalidRequest
-     */
-    @Override
-    public DescribeResponse describe(Session session, Identifier pid) 
-        throws InvalidToken, ServiceFailure, NotAuthorized, NotFound, NotImplemented {
-
-      // get system metadata and construct the describe response
-        SystemMetadata sysmeta = getSystemMetadata(session, pid);
-        DescribeResponse describeResponse = 
-        	new DescribeResponse(sysmeta.getFormatId(), sysmeta.getSize(), 
-        			sysmeta.getDateSysMetadataModified(),
-        			sysmeta.getChecksum(), sysmeta.getSerialVersion());
-
-        return describeResponse;
-
-    }
-
-    /**
      * Return the object identified by the given object identifier
      * 
      * @param session - the Session object containing the credentials for the Subject
@@ -818,9 +786,11 @@
             Ping canPing = new Ping();
             canPing.setSuccess(false);
             try {
-                canPing.setSuccess(ping());
-            } catch (InsufficientResources e) {
+            	Date pingDate = ping();
+                canPing.setSuccess(pingDate != null);
+            } catch (BaseException e) {
                 e.printStackTrace();
+                // guess it can't be pinged
             }
             
             node.setPing(canPing);
@@ -955,38 +925,6 @@
     }
 
     /**
-     * Low level “are you alive” operation. A valid ping response is 
-     * indicated by a HTTP status of 200.
-     * 
-     * @return true if the service is alive
-     * 
-     * @throws InvalidToken
-     * @throws ServiceFailure
-     * @throws NotImplemented
-     */
-    @Override
-    public boolean ping() 
-        throws NotImplemented, ServiceFailure, InsufficientResources {
-
-        // test if we can get a database connection
-        boolean alive = false;
-        int serialNumber = -1;
-        DBConnection dbConn = null;
-        try {
-            dbConn = DBConnectionPool.getDBConnection("MNodeService.ping");
-            serialNumber = dbConn.getCheckOutSerialNumber();
-            alive = true;
-        } catch (SQLException e) {
-            return alive;
-        } finally {
-            // Return the database connection
-            DBConnectionPool.returnDBConnection(dbConn, serialNumber);
-        }
-
-        return alive;
-    }
-
-    /**
      * A callback method used by a CN to indicate to a MN that it cannot 
      * complete synchronization of the science metadata identified by pid.  Log
      * the event in the metacat event log.
@@ -1111,20 +1049,6 @@
     }
 
     /**
-     * Set the access policy
-     */
-    @Deprecated
-    @Override
-    public boolean setAccessPolicy(Session session, Identifier pid,
-        AccessPolicy policy) 
-        throws InvalidToken, ServiceFailure, NotFound, NotAuthorized, 
-        NotImplemented, InvalidRequest {
-        
-        throw new NotImplemented("4401", "This method is deprecated for Member Nodes.");
-        
-    }
-
-    /**
      * A method to notify the Member Node that the authoritative copy of 
      * system metadata on the Coordinating Nodes has changed.
      * 
Index: src/edu/ucsb/nceas/metacat/dataone/CNodeService.java
===================================================================
--- src/edu/ucsb/nceas/metacat/dataone/CNodeService.java	(revision 6802)
+++ src/edu/ucsb/nceas/metacat/dataone/CNodeService.java	(revision 6803)
@@ -52,6 +52,7 @@
 import org.dataone.service.exceptions.UnsupportedType;
 import org.dataone.service.types.v1.AccessPolicy;
 import org.dataone.service.types.v1.Checksum;
+import org.dataone.service.types.v1.ChecksumAlgorithmList;
 import org.dataone.service.types.v1.Identifier;
 import org.dataone.service.types.v1.Node;
 import org.dataone.service.types.v1.NodeList;
@@ -598,8 +599,7 @@
    */
   @Override
   public ObjectFormat getFormat(ObjectFormatIdentifier fmtid)
-    throws ServiceFailure, NotFound, InsufficientResources,
-    NotImplemented {
+    throws ServiceFailure, NotFound, NotImplemented {
      
       return ObjectFormatService.getInstance().getFormat(fmtid);
       
@@ -618,8 +618,7 @@
    */
   @Override
   public ObjectFormatList listFormats() 
-    throws ServiceFailure, InsufficientResources, 
-    NotImplemented {
+    throws ServiceFailure, NotImplemented {
 
     return ObjectFormatService.getInstance().listFormats();
   }
@@ -801,7 +800,7 @@
    * @throws InvalidRequest
    */  
   @Override
-  public Identifier setOwner(Session session, Identifier pid, Subject userId,
+  public Identifier setRightsHolder(Session session, Identifier pid, Subject userId,
       long serialVersion)
       throws InvalidToken, ServiceFailure, NotFound, NotAuthorized,
       NotImplemented, InvalidRequest {
@@ -1258,5 +1257,14 @@
 
         return objectList;
   }
+
+	@Override
+	public ChecksumAlgorithmList listChecksumAlgorithms()
+			throws ServiceFailure, NotImplemented {
+		ChecksumAlgorithmList cal = new ChecksumAlgorithmList();
+		cal.addAlgorithm("MD5");
+		cal.addAlgorithm("SHA-1");
+		return null;
+	}
     
 }
Index: src/edu/ucsb/nceas/metacat/dataone/D1NodeService.java
===================================================================
--- src/edu/ucsb/nceas/metacat/dataone/D1NodeService.java	(revision 6802)
+++ src/edu/ucsb/nceas/metacat/dataone/D1NodeService.java	(revision 6803)
@@ -57,6 +57,7 @@
 import org.dataone.service.exceptions.UnsupportedType;
 import org.dataone.service.types.v1.AccessPolicy;
 import org.dataone.service.types.v1.AccessRule;
+import org.dataone.service.types.v1.DescribeResponse;
 import org.dataone.service.types.v1.Event;
 import org.dataone.service.types.v1.Identifier;
 import org.dataone.service.types.v1.Group;
@@ -79,6 +80,8 @@
 import edu.ucsb.nceas.metacat.IdentifierManager;
 import edu.ucsb.nceas.metacat.McdbDocNotFoundException;
 import edu.ucsb.nceas.metacat.MetacatHandler;
+import edu.ucsb.nceas.metacat.database.DBConnection;
+import edu.ucsb.nceas.metacat.database.DBConnectionPool;
 import edu.ucsb.nceas.metacat.dataone.hazelcast.HazelcastService;
 import edu.ucsb.nceas.metacat.properties.PropertyService;
 import edu.ucsb.nceas.metacat.replication.ForceReplicationHandler;
@@ -108,6 +111,69 @@
 	}
   
   /**
+   * This method provides a lighter weight mechanism than 
+   * getSystemMetadata() for a client to determine basic 
+   * properties of the referenced object.
+   * 
+   * @param session - the Session object containing the credentials for the Subject
+   * @param pid - the identifier of the object to be described
+   * 
+   * @return describeResponse - A set of values providing a basic description 
+   *                            of the object.
+   * 
+   * @throws InvalidToken
+   * @throws ServiceFailure
+   * @throws NotAuthorized
+   * @throws NotFound
+   * @throws NotImplemented
+   * @throws InvalidRequest
+   */
+  public DescribeResponse describe(Session session, Identifier pid) 
+      throws InvalidToken, ServiceFailure, NotAuthorized, NotFound, NotImplemented {
+
+    // get system metadata and construct the describe response
+      SystemMetadata sysmeta = getSystemMetadata(session, pid);
+      DescribeResponse describeResponse = 
+      	new DescribeResponse(sysmeta.getFormatId(), sysmeta.getSize(), 
+      			sysmeta.getDateSysMetadataModified(),
+      			sysmeta.getChecksum(), sysmeta.getSerialVersion());
+
+      return describeResponse;
+
+  }
+  
+  /**
+   * Low level, "are you alive" operation. A valid ping response is 
+   * indicated by a HTTP status of 200.
+   * 
+   * @return true if the service is alive
+   * 
+   * @throws NotImplemented
+   * @throws ServiceFailure
+   * @throws InsufficientResources
+   */
+  public Date ping() 
+      throws NotImplemented, ServiceFailure, InsufficientResources {
+
+      // test if we can get a database connection
+      int serialNumber = -1;
+      DBConnection dbConn = null;
+      try {
+          dbConn = DBConnectionPool.getDBConnection("MNodeService.ping");
+          serialNumber = dbConn.getCheckOutSerialNumber();
+      } catch (SQLException e) {
+      	ServiceFailure sf = new ServiceFailure("", e.getMessage());
+      	sf.initCause(e);
+          throw sf;
+      } finally {
+          // Return the database connection
+          DBConnectionPool.returnDBConnection(dbConn, serialNumber);
+      }
+
+      return Calendar.getInstance().getTime();
+  }
+  
+  /**
    * Adds a new object to the Node, where the object is either a data 
    * object or a science metadata object. This method is called by clients 
    * to create new data objects on Member Nodes or internally for Coordinating
Index: src/edu/ucsb/nceas/metacat/admin/D1Admin.java
===================================================================
--- src/edu/ucsb/nceas/metacat/admin/D1Admin.java	(revision 6802)
+++ src/edu/ucsb/nceas/metacat/admin/D1Admin.java	(revision 6803)
@@ -36,8 +36,10 @@
 import org.dataone.client.CNode;
 import org.dataone.client.D1Client;
 import org.dataone.client.auth.CertificateManager;
+import org.dataone.service.exceptions.BaseException;
 import org.dataone.service.exceptions.IdentifierNotUnique;
 import org.dataone.service.exceptions.InvalidRequest;
+import org.dataone.service.exceptions.InvalidToken;
 import org.dataone.service.exceptions.NotAuthorized;
 import org.dataone.service.exceptions.NotFound;
 import org.dataone.service.exceptions.NotImplemented;
@@ -354,18 +356,8 @@
 	            PropertyService.setProperty("dataone.memberNodeId", mnodeRef.getValue());
 	            
             }
-        } catch (ServiceFailure e) {
+        } catch (BaseException e) {
             logMetacat.warn("Could not register as node with DataONE (" + e.getCode() + "/" + e.getDetail_code() + "): " + e.getDescription());
-        } catch (NotFound e) {
-            logMetacat.warn("Could not register as node with DataONE (" + e.getCode() + "/" + e.getDetail_code() + "): " + e.getDescription());
-        } catch (NotImplemented e) {
-            logMetacat.warn("Could not register as node with DataONE (" + e.getCode() + "/" + e.getDetail_code() + "): " + e.getDescription());
-        } catch (NotAuthorized e) {
-            logMetacat.warn("Could not register as node with DataONE (" + e.getCode() + "/" + e.getDetail_code() + "): " + e.getDescription());
-        } catch (InvalidRequest e) {
-            logMetacat.warn("Could not register as node with DataONE (" + e.getCode() + "/" + e.getDetail_code() + "): " + e.getDescription());
-        } catch (IdentifierNotUnique e) {
-            logMetacat.warn("Could not register as node with DataONE (" + e.getCode() + "/" + e.getDetail_code() + "): " + e.getDescription());
         } catch (PropertyNotFoundException e) {
             logMetacat.warn("Could not find the location for client certificates: " + e.getMessage());
         } catch (GeneralPropertyException e) {
