diff --git a/source/java/org/alfresco/repo/node/archive/NodeArchiveService.java b/source/java/org/alfresco/repo/node/archive/NodeArchiveService.java
new file mode 100644
index 0000000000..6f59a05945
--- /dev/null
+++ b/source/java/org/alfresco/repo/node/archive/NodeArchiveService.java
@@ -0,0 +1,159 @@
+/*
+ * Copyright (C) 2005 Alfresco, Inc.
+ *
+ * Licensed under the Mozilla Public License version 1.1
+ * with a permitted attribution clause. You may obtain a
+ * copy of the License at
+ *
+ * http://www.alfresco.org/legal/license.txt
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
+ * either express or implied. See the License for the specific
+ * language governing permissions and limitations under the
+ * License.
+ */
+package org.alfresco.repo.node.archive;
+
+import java.util.List;
+
+import org.alfresco.service.cmr.repository.NodeRef;
+import org.alfresco.service.cmr.repository.StoreRef;
+import org.alfresco.service.namespace.QName;
+
+/**
+ * A service interface providing methods that map onto the low-level
+ * node restore functionality.
+ *
+ * @author Derek Hulley
+ */
+public interface NodeArchiveService
+{
+ /**
+ * Get the parent node that holds all nodes archived from the given store.
+ *
+ * @param storeRef the original store of the archived nodes
+ * @return Returns the parent of the archived nodes, or null if archiving
+ * is not configured for the store
+ */
+ public NodeRef getStoreArchiveNode(StoreRef storeRef);
+
+ /**
+ * Attempt to restore the given archived node into its original location.
+ *
+ * TRANSACTIONS: This method will execute in a new transaction.
+ *
+ * @param archivedNodeRef the node's reference in the archive
+ * @return Returns the results of the restore operation
+ */
+ public RestoreNodeReport restoreArchivedNode(NodeRef archivedNodeRef);
+
+ /**
+ * Attempt to restore the given archived node into a new location.
+ *
+ * TRANSACTIONS: This method will execute in a new transaction.
+ *
+ * @param archivedNodeRef the node's reference in the archive. This
+ * must be valid.
+ * @param destinationNodeRef the parent of the restored node, or
+ * null to use the original parent node reference
+ * @param assocTypeQName the type of the primary association to link the
+ * restored node to the destination parent, or null to use
+ * the orginal association type
+ * @param assocQName the name of the primary association to be created,
+ * or null to use the original association name
+ * @return Returns the results of the restore operation
+ */
+ public RestoreNodeReport restoreArchivedNode(
+ NodeRef archivedNodeRef,
+ NodeRef destinationNodeRef,
+ QName assocTypeQName,
+ QName assocQName);
+
+ /**
+ * Attempt to restore a list of archived nodes into their original locations,
+ * using the original association types and names.
+ *
+ * TRANSACTIONS: This method will execute in a new transaction.
+ *
+ * @param archivedNodeRefs the nodes' references in the archive. These
+ * must be valid.
+ * @return Returns the results of the each attempted restore operation
+ */
+ public List restoreArchivedNodes(List archivedNodeRefs);
+
+ /**
+ * Attempt to restore a list of archived nodes into a new location.
+ *
+ * TRANSACTIONS: This method will execute in a new transaction.
+ *
+ * @param archivedNodeRefs the nodes' references in the archive. These
+ * must be valid.
+ * @param destinationNodeRef the parent of the restored nodes, or
+ * null to use the original parent node references
+ * @param assocTypeQName the type of the primary associations to link the
+ * restored node to the destination parent, or null to use
+ * the orginal association types
+ * @param assocQName the name of the primary associations to be created,
+ * or null to use the original association names
+ * @return Returns the results of the each attempted restore operation
+ */
+ public List restoreArchivedNodes(
+ List archivedNodeRefs,
+ NodeRef destinationNodeRef,
+ QName assocTypeQName,
+ QName assocQName);
+
+ /**
+ * Attempt to restore all archived nodes into their original locations.
+ *
+ * TRANSACTIONS: This method will execute in a new transaction.
+ *
+ * @param originalStoreRef the store that the items originally came from
+ * @return Returns the results of the each attempted restore operation
+ */
+ public List restoreAllArchivedNodes(StoreRef originalStoreRef);
+
+ /**
+ * Attempt to restore all archived nodes into a new location.
+ *
+ * TRANSACTIONS: This method will execute in a new transaction.
+ *
+ * @param originalStoreRef the store that the items originally came from
+ * @param destinationNodeRef the parent of the restored nodes, or
+ * null to use the original parent node references
+ * @param assocTypeQName the type of the primary associations to link the
+ * restored node to the destination parent, or null to use
+ * the orginal association types
+ * @param assocQName the name of the primary associations to be created,
+ * or null to use the original association names
+ * @return Returns the results of the each attempted restore operation
+ */
+ public List restoreAllArchivedNodes(
+ StoreRef originalStoreRef,
+ NodeRef destinationNodeRef,
+ QName assocTypeQName,
+ QName assocQName);
+
+ /**
+ * Permanently delete the archived node.
+ *
+ * @param archivedNodeRef the archived node to delete.
+ */
+ public void purgeArchivedNode(NodeRef archivedNodeRef);
+
+ /**
+ * Permanently delete the archived nodes.
+ *
+ * @param archivedNodes the archived nodes to delete.
+ */
+ public void purgeArchivedNodes(List archivedNodes);
+
+ /**
+ * Permanently delete all archived nodes.
+ *
+ * @param originalStoreRef the store that the items originally came from
+ */
+ public void purgeAllArchivedNodes(StoreRef originalStoreRef);
+}
diff --git a/source/java/org/alfresco/repo/node/archive/NodeArchiveServiceImpl.java b/source/java/org/alfresco/repo/node/archive/NodeArchiveServiceImpl.java
new file mode 100644
index 0000000000..b35c9fd677
--- /dev/null
+++ b/source/java/org/alfresco/repo/node/archive/NodeArchiveServiceImpl.java
@@ -0,0 +1,134 @@
+/*
+ * Copyright (C) 2005 Alfresco, Inc.
+ *
+ * Licensed under the Mozilla Public License version 1.1
+ * with a permitted attribution clause. You may obtain a
+ * copy of the License at
+ *
+ * http://www.alfresco.org/legal/license.txt
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
+ * either express or implied. See the License for the specific
+ * language governing permissions and limitations under the
+ * License.
+ */
+package org.alfresco.repo.node.archive;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.alfresco.service.cmr.repository.NodeRef;
+import org.alfresco.service.cmr.repository.NodeService;
+import org.alfresco.service.cmr.repository.StoreRef;
+import org.alfresco.service.namespace.QName;
+import org.alfresco.service.transaction.TransactionService;
+
+/**
+ * Implementation of the node archive abstraction.
+ *
+ * @author Derek Hulley
+ */
+public class NodeArchiveServiceImpl implements NodeArchiveService
+{
+ private NodeService nodeService;
+ private TransactionService transactionService;
+
+ public void setNodeService(NodeService nodeService)
+ {
+ this.nodeService = nodeService;
+ }
+
+ public void setTransactionService(TransactionService transactionService)
+ {
+ this.transactionService = transactionService;
+ }
+
+ public NodeRef getStoreArchiveNode(StoreRef storeRef)
+ {
+ return nodeService.getStoreArchiveNode(storeRef);
+ }
+
+ /**
+ * @see #restoreArchivedNode(NodeRef, NodeRef, QName, QName)
+ */
+ public RestoreNodeReport restoreArchivedNode(NodeRef archivedNodeRef)
+ {
+ return restoreArchivedNode(archivedNodeRef, null, null, null);
+ }
+
+ public RestoreNodeReport restoreArchivedNode(
+ NodeRef archivedNodeRef,
+ NodeRef destinationNodeRef,
+ QName assocTypeQName,
+ QName assocQName)
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * @see #restoreArchivedNode(NodeRef, NodeRef, QName, QName)
+ */
+ public List restoreArchivedNodes(List archivedNodeRefs)
+ {
+ List results = new ArrayList(archivedNodeRefs.size());
+ for (NodeRef nodeRef : archivedNodeRefs)
+ {
+ RestoreNodeReport result = restoreArchivedNode(nodeRef, null, null, null);
+ results.add(result);
+ }
+ return results;
+ }
+
+ /**
+ * @see #restoreArchivedNode(NodeRef, NodeRef, QName, QName)
+ */
+ public List restoreArchivedNodes(
+ List archivedNodeRefs,
+ NodeRef destinationNodeRef,
+ QName assocTypeQName,
+ QName assocQName)
+ {
+ List results = new ArrayList(archivedNodeRefs.size());
+ for (NodeRef nodeRef : archivedNodeRefs)
+ {
+ RestoreNodeReport result = restoreArchivedNode(nodeRef, destinationNodeRef, assocTypeQName, assocQName);
+ results.add(result);
+ }
+ return results;
+ }
+
+ /**
+ * @see #restoreArchivedNode(NodeRef, NodeRef, QName, QName)
+ */
+ public List restoreAllArchivedNodes(StoreRef originalStoreRef)
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ public List restoreAllArchivedNodes(
+ StoreRef originalStoreRef,
+ NodeRef destinationNodeRef,
+ QName assocTypeQName,
+ QName assocQName)
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ public void purgeArchivedNode(NodeRef archivedNodeRef)
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ public void purgeArchivedNodes(List archivedNodes)
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ public void purgeAllArchivedNodes(StoreRef originalStoreRef)
+ {
+ throw new UnsupportedOperationException();
+ }
+
+}
diff --git a/source/java/org/alfresco/repo/node/archive/RestoreNodeReport.java b/source/java/org/alfresco/repo/node/archive/RestoreNodeReport.java
new file mode 100644
index 0000000000..9b83e6f832
--- /dev/null
+++ b/source/java/org/alfresco/repo/node/archive/RestoreNodeReport.java
@@ -0,0 +1,113 @@
+/*
+ * Copyright (C) 2005 Alfresco, Inc.
+ *
+ * Licensed under the Mozilla Public License version 1.1
+ * with a permitted attribution clause. You may obtain a
+ * copy of the License at
+ *
+ * http://www.alfresco.org/legal/license.txt
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
+ * either express or implied. See the License for the specific
+ * language governing permissions and limitations under the
+ * License.
+ */
+package org.alfresco.repo.node.archive;
+
+import java.io.Serializable;
+
+import org.alfresco.service.cmr.repository.NodeRef;
+
+/**
+ * A simple record of an attempt to restore a node from an archive store.
+ *
+ * @author Derek Hulley
+ */
+public class RestoreNodeReport implements Serializable
+{
+ private static final long serialVersionUID = 7375879981852517364L;
+
+ /**
+ * Represents the state of a restore process.
+ */
+ public static enum RestoreStatus
+ {
+ SUCCESS
+ {
+ @Override
+ public boolean isSuccess()
+ {
+ return true;
+ }
+
+ },
+ FAILURE_INVALID_PARENT
+ {
+ },
+ FAILURE_PERMISSION
+ {
+ },
+ FAILURE_INTEGRITY
+ {
+ },
+ FAILURE_OTHER
+ {
+ };
+
+ /**
+ *
+ * @return Returns true if the status represents a successful state
+ */
+ public boolean isSuccess()
+ {
+ return false;
+ }
+ }
+
+ private NodeRef archivedNodeRef;
+ private NodeRef targetParentNodeRef;
+ private NodeRef restoredNodeRef;
+ private RestoreStatus status;
+ private Throwable cause;
+
+ /* package */ RestoreNodeReport(
+ RestoreStatus status,
+ NodeRef archivedNodeRef,
+ NodeRef targetParentNodeRef,
+ NodeRef restoredNodeRef,
+ Throwable cause)
+ {
+ this.status = status;
+ this.archivedNodeRef = archivedNodeRef;
+ this.targetParentNodeRef = targetParentNodeRef;
+ this.restoredNodeRef = restoredNodeRef;
+ this.cause = cause;
+ }
+
+ public NodeRef getArchivedNodeRef()
+ {
+ return archivedNodeRef;
+ }
+
+ public NodeRef getTargetParentNodeRef()
+ {
+ return targetParentNodeRef;
+ }
+
+ public NodeRef getRestoredNodeRef()
+ {
+ return restoredNodeRef;
+ }
+
+ public RestoreStatus getStatus()
+ {
+ return status;
+ }
+
+ public Throwable getCause()
+ {
+ return cause;
+ }
+}