diff --git a/objectstore_middletier/CMakeLists.txt b/objectstore_middletier/CMakeLists.txt
index dfdad4cfed5f8a360505f46366301af0a3161387..f573827aee7d5bcc74b61a38dafb9dbb0be45438 100644
--- a/objectstore_middletier/CMakeLists.txt
+++ b/objectstore_middletier/CMakeLists.txt
@@ -10,6 +10,7 @@ add_library (CTAObjectStoreMiddleTier
 
 set(MiddleTierUnitTests
   MiddleTierAdminAbstractTest.cpp
+  MiddleTierUserAbstractTest.cpp
   MiddleTierTest.cpp
 )
 
diff --git a/objectstore_middletier/MiddleTierAdminAbstractTest.hpp b/objectstore_middletier/MiddleTierAbstractTest.hpp
similarity index 71%
rename from objectstore_middletier/MiddleTierAdminAbstractTest.hpp
rename to objectstore_middletier/MiddleTierAbstractTest.hpp
index 325de740b0055afc8d9f5f57eb20628f8a3abf94..a285c8f722b63d31fbeede1fe58d10ec415539ee 100644
--- a/objectstore_middletier/MiddleTierAdminAbstractTest.hpp
+++ b/objectstore_middletier/MiddleTierAbstractTest.hpp
@@ -22,13 +22,7 @@ namespace unitTests {
     localMiddleTier * m_localMiddleTier;
   };
 
-  class MiddleTierAdminAbstractTest: public ::testing::TestWithParam<MiddleTierFactory*> {
-  protected:
-    MiddleTierAdminAbstractTest() {}
-//    virtual void SetUp() {
-//      m_middleTierFactory = GetParam();
-//    }
-//    MiddleTierFactory * m_middleTierFactory;
+  class MiddleTierAbstractTest: public ::testing::TestWithParam<MiddleTierFactory*> {
   };
 
 }
diff --git a/objectstore_middletier/MiddleTierAdminAbstractTest.cpp b/objectstore_middletier/MiddleTierAdminAbstractTest.cpp
index 3aeaa809745b903b94bc09730c0f5675d2a652f6..9a68307490c2eaba43236905e357690ba5051eb2 100644
--- a/objectstore_middletier/MiddleTierAdminAbstractTest.cpp
+++ b/objectstore_middletier/MiddleTierAdminAbstractTest.cpp
@@ -16,15 +16,13 @@
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-#include "MiddleTierAdminAbstractTest.hpp"
-#include "cta/SqliteMiddleTierAdmin.hpp"
-#include "cta/SqliteMiddleTierUser.hpp"
+#include "MiddleTierAbstractTest.hpp"
 #include <memory>
 
 #include <gtest/gtest.h>
 namespace unitTests {
 
-TEST_P(MiddleTierAdminAbstractTest, createStorageClass_new) {
+TEST_P(MiddleTierAbstractTest, admin_createStorageClass_new) {
   using namespace cta;
 
   const SecurityIdentity requester;
@@ -54,8 +52,8 @@ TEST_P(MiddleTierAdminAbstractTest, createStorageClass_new) {
   }
 }
 
-TEST_P(MiddleTierAdminAbstractTest,
-  createStorageClass_already_existing) {
+TEST_P(MiddleTierAbstractTest,
+  admin_createStorageClass_already_existing) {
   using namespace cta;
 
   const SecurityIdentity requester;
@@ -87,8 +85,8 @@ TEST_P(MiddleTierAdminAbstractTest,
     std::exception);
 }
 
-TEST_P(MiddleTierAdminAbstractTest,
-  createStorageClass_lexicographical_order) {
+TEST_P(MiddleTierAbstractTest,
+  admin_createStorageClass_lexicographical_order) {
   using namespace cta;
 
   const SecurityIdentity requester;
@@ -120,7 +118,7 @@ TEST_P(MiddleTierAdminAbstractTest,
   }
 }
 
-TEST_P(MiddleTierAdminAbstractTest, deleteStorageClass_existing) {
+TEST_P(MiddleTierAbstractTest, admin_deleteStorageClass_existing) {
   using namespace cta;
 
   const SecurityIdentity requester;
@@ -157,8 +155,8 @@ TEST_P(MiddleTierAdminAbstractTest, deleteStorageClass_existing) {
   }
 }
 
-TEST_P(MiddleTierAdminAbstractTest,
-  deleteStorageClass_in_use_by_directory) {
+TEST_P(MiddleTierAbstractTest,
+  admin_deleteStorageClass_in_use_by_directory) {
   using namespace cta;
 
   const SecurityIdentity requester;
@@ -215,7 +213,7 @@ TEST_P(MiddleTierAdminAbstractTest,
   }
 }
 
-TEST_P(MiddleTierAdminAbstractTest, deleteStorageClass_in_use_by_route) {
+TEST_P(MiddleTierAbstractTest, admin_deleteStorageClass_in_use_by_route) {
   using namespace cta;
 
   const SecurityIdentity requester;
@@ -307,7 +305,7 @@ TEST_P(MiddleTierAdminAbstractTest, deleteStorageClass_in_use_by_route) {
   }
 }
 
-TEST_P(MiddleTierAdminAbstractTest, deleteStorageClass_non_existing) {
+TEST_P(MiddleTierAbstractTest, admin_deleteStorageClass_non_existing) {
   using namespace cta;
 
   const SecurityIdentity requester;
@@ -329,7 +327,7 @@ TEST_P(MiddleTierAdminAbstractTest, deleteStorageClass_non_existing) {
   }
 }
 
-TEST_P(MiddleTierAdminAbstractTest, deleteTapePool_in_use) {
+TEST_P(MiddleTierAbstractTest, admin_deleteTapePool_in_use) {
   using namespace cta;
 
   const SecurityIdentity requester;
@@ -385,7 +383,7 @@ TEST_P(MiddleTierAdminAbstractTest, deleteTapePool_in_use) {
   }
 }
 
-TEST_P(MiddleTierAdminAbstractTest, createArchivalRoute_new) {
+TEST_P(MiddleTierAbstractTest, admin_createArchivalRoute_new) {
   using namespace cta;
 
   const SecurityIdentity requester;
@@ -427,8 +425,8 @@ TEST_P(MiddleTierAdminAbstractTest, createArchivalRoute_new) {
   }
 }
 
-TEST_P(MiddleTierAdminAbstractTest,
-  createArchivalRoute_already_existing) {
+TEST_P(MiddleTierAbstractTest,
+  admin_createArchivalRoute_already_existing) {
   using namespace cta;
 
   const SecurityIdentity requester;
@@ -473,7 +471,7 @@ TEST_P(MiddleTierAdminAbstractTest,
     copyNb, tapePoolName, comment), std::exception);
 }
 
-TEST_P(MiddleTierAdminAbstractTest, deleteArchivalRoute_existing) {
+TEST_P(MiddleTierAbstractTest, admin_deleteArchivalRoute_existing) {
   using namespace cta;
 
   const SecurityIdentity requester;
@@ -524,7 +522,7 @@ TEST_P(MiddleTierAdminAbstractTest, deleteArchivalRoute_existing) {
   }
 }
 
-TEST_P(MiddleTierAdminAbstractTest, deleteArchivalRoute_non_existing) {
+TEST_P(MiddleTierAbstractTest, admin_deleteArchivalRoute_non_existing) {
   using namespace cta;
 
   const SecurityIdentity requester;
@@ -554,7 +552,7 @@ TEST_P(MiddleTierAdminAbstractTest, deleteArchivalRoute_non_existing) {
     std::exception);
 }
 
-TEST_P(MiddleTierAdminAbstractTest, createTape_new) {
+TEST_P(MiddleTierAbstractTest, admin_createTape_new) {
   using namespace cta;
 
   const SecurityIdentity requester;
@@ -630,8 +628,8 @@ TEST_P(MiddleTierAdminAbstractTest, createTape_new) {
   } 
 }
 
-TEST_P(MiddleTierAdminAbstractTest,
-  createTape_new_non_existing_library) {
+TEST_P(MiddleTierAbstractTest,
+  admin_createTape_new_non_existing_library) {
   using namespace cta;
 
   const SecurityIdentity requester;
@@ -680,7 +678,7 @@ TEST_P(MiddleTierAdminAbstractTest,
     capacityInBytes, tapeComment), std::exception);
 }
 
-TEST_P(MiddleTierAdminAbstractTest, createTape_new_non_existing_pool) {
+TEST_P(MiddleTierAbstractTest, admin_createTape_new_non_existing_pool) {
   using namespace cta;
 
   const SecurityIdentity requester;
diff --git a/objectstore_middletier/MiddleTierTest.cpp b/objectstore_middletier/MiddleTierTest.cpp
index 8928497e96213f1388b617e57bd5f881107518f2..f07191c5d059e40c0b42272ca6042f4d7c689d25 100644
--- a/objectstore_middletier/MiddleTierTest.cpp
+++ b/objectstore_middletier/MiddleTierTest.cpp
@@ -16,7 +16,7 @@
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-#include "MiddleTierAdminAbstractTest.hpp"
+#include "MiddleTierAbstractTest.hpp"
 #include "ObjectStoreMiddleTierAdmin.hpp"
 #include "objectstore/BackendRados.hpp"
 #include "objectstore/BackendVFS.hpp"
@@ -38,7 +38,7 @@ unitTests::MiddleTierFull middleTierRados;
 middleTierRados.admin = &mtaRados;
 middleTierRados.user = NULL;
 
-INSTANTIATE_TEST_CASE_P(MiddleTierRados, MiddleTierAdminAbstractTest , ::testing::Values(middleTierRados));
+INSTANTIATE_TEST_CASE_P(MiddleTierRados, MiddleTierAbstractTest , ::testing::Values(middleTierRados));
 #endif
 
 #if TEST_VFS
@@ -70,7 +70,7 @@ public:
 } g_SQLiteMiddleTierFactory;
 
 // Macro chokes on implicit casting of pointer so we have to do it ourselves
-INSTANTIATE_TEST_CASE_P(MiddleTierSQL, MiddleTierAdminAbstractTest, ::testing::Values(
+INSTANTIATE_TEST_CASE_P(MiddleTierSQL, MiddleTierAbstractTest, ::testing::Values(
     (MiddleTierFactory*)&g_SQLiteMiddleTierFactory));
 #endif
 
diff --git a/objectstore_middletier/MiddleTierUserAbstractTest.cpp b/objectstore_middletier/MiddleTierUserAbstractTest.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..9f4a05b814ed702ca488a37da8f4f7a0395a1a01
--- /dev/null
+++ b/objectstore_middletier/MiddleTierUserAbstractTest.cpp
@@ -0,0 +1,928 @@
+/*
+ * The CERN Tape Archive (CTA) project
+ * Copyright (C) 2015  CERN
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "MiddleTierAbstractTest.hpp"
+#include <gtest/gtest.h>
+#include <set>
+#include <memory>
+
+namespace unitTests {
+
+class cta_client_SqliteMiddleTierUserTest: public ::testing::Test {
+protected:
+
+  virtual void SetUp() {
+  }
+
+  virtual void TearDown() {
+  }
+};
+
+TEST_P(MiddleTierAbstractTest,
+  user_getDirContents_root_dir_is_empty) {
+  using namespace cta;
+
+  std::auto_ptr<localMiddleTier> m_middleTier(GetParam()->allocateLocalMiddleTier());
+  const SecurityIdentity requester;
+  const std::string dirPath = "/";
+
+  DirIterator itor;
+  ASSERT_NO_THROW(itor = m_middleTier->user().getDirContents(requester, "/"));
+  ASSERT_FALSE(itor.hasMore());
+}
+
+TEST_P(MiddleTierAbstractTest, user_createDir_empty_string) {
+  using namespace cta;
+
+  std::auto_ptr<localMiddleTier> m_middleTier(GetParam()->allocateLocalMiddleTier());
+  const SecurityIdentity requester;
+  const std::string dirPath = "";
+
+  ASSERT_THROW(m_middleTier->user().createDir(requester, dirPath), std::exception);
+}
+
+TEST_P(MiddleTierAbstractTest,
+  user_createDir_consecutive_slashes) {
+  using namespace cta;
+
+  std::auto_ptr<localMiddleTier> m_middleTier(GetParam()->allocateLocalMiddleTier());
+  const SecurityIdentity requester;
+  const std::string dirPath = "//";
+
+  ASSERT_THROW(m_middleTier->user().createDir(requester, dirPath), std::exception);
+}
+
+TEST_P(MiddleTierAbstractTest, user_createDir_invalid_chars) {
+  using namespace cta;
+
+  std::auto_ptr<localMiddleTier> m_middleTier(GetParam()->allocateLocalMiddleTier());
+  const SecurityIdentity requester;
+  const std::string dirPath = "/grandparent/?parent";
+  
+  ASSERT_THROW(m_middleTier->user().createDir(requester, dirPath), std::exception);
+}
+
+TEST_P(MiddleTierAbstractTest, user_createDir_top_level) {
+  using namespace cta;
+
+  std::auto_ptr<localMiddleTier> m_middleTier(GetParam()->allocateLocalMiddleTier());
+  const SecurityIdentity requester;
+  const std::string dirPath = "/grandparent";
+  
+  ASSERT_NO_THROW(m_middleTier->user().createDir(requester, dirPath));
+
+  DirIterator itor;
+
+  ASSERT_NO_THROW(itor = m_middleTier->user().getDirContents(requester, "/"));
+
+  ASSERT_TRUE(itor.hasMore());
+
+  DirEntry entry;
+
+  ASSERT_NO_THROW(entry = itor.next());
+
+  ASSERT_EQ(std::string("grandparent"), entry.getName());
+}
+
+TEST_P(MiddleTierAbstractTest, user_createDir_second_level) {
+  using namespace cta;
+
+  std::auto_ptr<localMiddleTier> m_middleTier(GetParam()->allocateLocalMiddleTier());
+  const SecurityIdentity requester;
+
+  ASSERT_TRUE(m_middleTier->user().getDirStorageClass(requester, "/").empty());
+
+  {
+    const std::string topLevelDirPath = "/grandparent";
+
+    ASSERT_NO_THROW(m_middleTier->user().createDir(requester, topLevelDirPath));
+  }
+
+  {
+    DirIterator itor;
+
+    ASSERT_NO_THROW(itor = m_middleTier->user().getDirContents(requester, "/"));
+
+    ASSERT_TRUE(itor.hasMore());
+
+    DirEntry entry;
+
+    ASSERT_NO_THROW(entry = itor.next());
+
+    ASSERT_EQ(std::string("grandparent"), entry.getName());
+  }
+
+  ASSERT_TRUE(m_middleTier->user().getDirStorageClass(requester, "/grandparent").empty());
+
+  {
+    const std::string secondLevelDirPath = "/grandparent/parent";
+
+    ASSERT_NO_THROW(m_middleTier->user().createDir(requester, secondLevelDirPath));
+  }
+
+  {
+    DirIterator itor;
+
+    ASSERT_NO_THROW(itor = m_middleTier->user().getDirContents(requester, "/"));
+
+    ASSERT_TRUE(itor.hasMore());
+
+    DirEntry entry;
+
+    ASSERT_NO_THROW(entry = itor.next());
+
+    ASSERT_EQ(std::string("grandparent"), entry.getName());
+  }
+
+  {
+    DirIterator itor;
+
+    ASSERT_NO_THROW(itor = m_middleTier->user().getDirContents(requester, "/grandparent"));
+
+    ASSERT_TRUE(itor.hasMore());
+
+    DirEntry entry;
+
+    ASSERT_NO_THROW(entry = itor.next());
+
+    ASSERT_EQ(std::string("parent"), entry.getName());
+  }
+
+  ASSERT_TRUE(m_middleTier->user().getDirStorageClass(requester,
+    "/grandparent/parent").empty());
+}
+
+TEST_P(MiddleTierAbstractTest,
+  user_createDir_inherit_storage_class) {
+  using namespace cta;
+
+  std::auto_ptr<localMiddleTier> m_middleTier(GetParam()->allocateLocalMiddleTier());
+  const SecurityIdentity requester;
+
+  ASSERT_TRUE(m_middleTier->user().getDirStorageClass(requester, "/").empty());
+
+  {
+    const std::string name = "TestStorageClass";
+    const uint16_t nbCopies = 2;
+    const std::string comment = "Comment";
+    ASSERT_NO_THROW(m_middleTier->admin().createStorageClass(requester, name, nbCopies, comment));
+  }
+
+  {
+    const std::string topLevelDirPath = "/grandparent";
+
+    ASSERT_NO_THROW(m_middleTier->user().createDir(requester, topLevelDirPath));
+  }
+
+  {
+    DirIterator itor;
+
+    ASSERT_NO_THROW(itor = m_middleTier->user().getDirContents(requester, "/"));
+
+    ASSERT_TRUE(itor.hasMore());
+
+    DirEntry entry;
+
+    ASSERT_NO_THROW(entry = itor.next());
+
+    ASSERT_EQ(std::string("grandparent"), entry.getName());
+
+    ASSERT_TRUE(m_middleTier->user().getDirStorageClass(requester, "/grandparent").empty());
+
+    ASSERT_NO_THROW(m_middleTier->user().setDirStorageClass(requester, "/grandparent",
+      "TestStorageClass"));
+  }
+
+  ASSERT_EQ(std::string("TestStorageClass"),
+    m_middleTier->user().getDirStorageClass(requester, "/grandparent"));
+
+  {
+    const std::string secondLevelDirPath = "/grandparent/parent";
+
+    ASSERT_NO_THROW(m_middleTier->user().createDir(requester, secondLevelDirPath));
+  }
+
+  {
+    DirIterator itor;
+
+    ASSERT_NO_THROW(itor = m_middleTier->user().getDirContents(requester, "/"));
+
+    ASSERT_TRUE(itor.hasMore());
+
+    DirEntry entry;
+
+    ASSERT_NO_THROW(entry = itor.next());
+
+    ASSERT_EQ(std::string("grandparent"), entry.getName());
+  }
+
+  {
+    DirIterator itor;
+
+    ASSERT_NO_THROW(itor = m_middleTier->user().getDirContents(requester, "/grandparent"));
+
+    ASSERT_TRUE(itor.hasMore());
+
+    DirEntry entry;
+
+    ASSERT_NO_THROW(entry = itor.next());
+
+    ASSERT_EQ(std::string("parent"), entry.getName());
+  }
+
+  ASSERT_EQ(std::string("TestStorageClass"),
+    m_middleTier->user().getDirStorageClass(requester, "/grandparent/parent"));
+}
+
+TEST_P(MiddleTierAbstractTest, user_deleteDir_root) {
+  using namespace cta;
+
+  std::auto_ptr<localMiddleTier> m_middleTier(GetParam()->allocateLocalMiddleTier());
+  const SecurityIdentity requester;
+  const std::string dirPath = "/";
+
+  ASSERT_THROW(m_middleTier->user().deleteDir(requester, "/"), std::exception);
+}
+
+TEST_P(MiddleTierAbstractTest, user_deleteDir_existing_top_level) {
+  using namespace cta;
+
+  std::auto_ptr<localMiddleTier> m_middleTier(GetParam()->allocateLocalMiddleTier());
+  const SecurityIdentity requester;
+  const std::string dirPath = "/grandparent";
+  
+  ASSERT_NO_THROW(m_middleTier->user().createDir(requester, dirPath));
+
+  {
+    DirIterator itor;
+
+    ASSERT_NO_THROW(itor = m_middleTier->user().getDirContents(requester, "/"));
+
+    ASSERT_TRUE(itor.hasMore());
+
+    DirEntry entry;
+
+    ASSERT_NO_THROW(entry = itor.next());
+
+    ASSERT_EQ(std::string("grandparent"), entry.getName());
+  }
+
+  ASSERT_NO_THROW(m_middleTier->user().deleteDir(requester, "/grandparent"));
+
+  {
+    DirIterator itor;
+  
+    ASSERT_NO_THROW(itor = m_middleTier->user().getDirContents(requester, "/"));
+  
+    ASSERT_FALSE(itor.hasMore());
+  }
+}
+
+TEST_P(MiddleTierAbstractTest,
+  user_deleteDir_non_empty_top_level) {
+  using namespace cta;
+
+  std::auto_ptr<localMiddleTier> m_middleTier(GetParam()->allocateLocalMiddleTier());
+  const SecurityIdentity requester;
+
+  {
+    const std::string topLevelDirPath = "/grandparent";
+
+    ASSERT_NO_THROW(m_middleTier->user().createDir(requester, topLevelDirPath));
+
+    DirIterator itor;
+
+    ASSERT_NO_THROW(itor = m_middleTier->user().getDirContents(requester, "/"));
+
+    ASSERT_TRUE(itor.hasMore());
+
+    DirEntry entry;
+
+    ASSERT_NO_THROW(entry = itor.next());
+
+    ASSERT_EQ(std::string("grandparent"), entry.getName());
+  }
+
+  {
+    const std::string secondLevelDirPath = "/grandparent/parent";
+
+    ASSERT_NO_THROW(m_middleTier->user().createDir(requester, secondLevelDirPath));
+
+    DirIterator itor;
+
+    ASSERT_NO_THROW(itor = m_middleTier->user().getDirContents(requester, "/"));
+
+    ASSERT_TRUE(itor.hasMore());
+
+    DirEntry entry;
+
+    ASSERT_NO_THROW(entry = itor.next());
+
+    ASSERT_EQ(std::string("grandparent"), entry.getName());
+  }
+
+  {
+    DirIterator itor;
+
+    ASSERT_NO_THROW(itor = m_middleTier->user().getDirContents(requester, "/grandparent"));
+
+    ASSERT_TRUE(itor.hasMore());
+
+    DirEntry entry;
+
+    ASSERT_NO_THROW(entry = itor.next());
+
+    ASSERT_EQ(std::string("parent"), entry.getName());
+  }
+
+  ASSERT_THROW(m_middleTier->user().deleteDir(requester, "/grandparent"), std::exception);
+
+  {
+    DirIterator itor;
+
+    ASSERT_NO_THROW(itor = m_middleTier->user().getDirContents(requester, "/grandparent"));
+
+    ASSERT_TRUE(itor.hasMore());
+
+    DirEntry entry;
+
+    ASSERT_NO_THROW(entry = itor.next());
+
+    ASSERT_EQ(std::string("parent"), entry.getName());
+  }
+}
+
+TEST_P(MiddleTierAbstractTest,
+  user_deleteDir_non_existing_top_level) {
+  using namespace cta;
+  
+  std::auto_ptr<localMiddleTier> m_middleTier(GetParam()->allocateLocalMiddleTier());
+  const SecurityIdentity requester;
+
+  ASSERT_THROW(m_middleTier->user().deleteDir(requester, "/grandparent"), std::exception);
+}
+
+TEST_P(MiddleTierAbstractTest, user_setDirStorageClass_top_level) {
+  using namespace cta;
+
+  std::auto_ptr<localMiddleTier> m_middleTier(GetParam()->allocateLocalMiddleTier());
+  const SecurityIdentity requester;
+  const std::string dirPath = "/grandparent";
+
+  ASSERT_NO_THROW(m_middleTier->user().createDir(requester, dirPath));
+
+  DirIterator itor;
+
+  ASSERT_NO_THROW(itor = m_middleTier->user().getDirContents(requester, "/"));
+
+  ASSERT_TRUE(itor.hasMore());
+
+  DirEntry entry;
+
+  ASSERT_NO_THROW(entry = itor.next());
+
+  ASSERT_EQ(std::string("grandparent"), entry.getName());
+
+  {
+    std::string name;
+    ASSERT_NO_THROW(name = m_middleTier->user().getDirStorageClass(requester, dirPath));
+    ASSERT_TRUE(name.empty());
+  }
+
+  const std::string storageClassName = "TestStorageClass";
+  const uint16_t nbCopies = 2;
+    const std::string comment = "Comment";
+  {
+    ASSERT_NO_THROW(m_middleTier->admin().createStorageClass(requester, storageClassName,
+      nbCopies, comment));
+  }
+
+  ASSERT_NO_THROW(m_middleTier->user().setDirStorageClass(requester, dirPath,
+    storageClassName));
+
+  {
+    std::string name;
+    ASSERT_NO_THROW(name = m_middleTier->user().getDirStorageClass(requester, dirPath));
+    ASSERT_EQ(storageClassName, name);
+  }
+}
+
+TEST_P(MiddleTierAbstractTest,
+  user_clearDirStorageClass_top_level) {
+  using namespace cta;
+
+  std::auto_ptr<localMiddleTier> m_middleTier(GetParam()->allocateLocalMiddleTier());
+  const SecurityIdentity requester;
+  const std::string dirPath = "/grandparent";
+
+  ASSERT_NO_THROW(m_middleTier->user().createDir(requester, dirPath));
+
+  DirIterator itor;
+
+  ASSERT_NO_THROW(itor = m_middleTier->user().getDirContents(requester, "/"));
+
+  ASSERT_TRUE(itor.hasMore());
+
+  DirEntry entry;
+
+  ASSERT_NO_THROW(entry = itor.next());
+
+  ASSERT_EQ(std::string("grandparent"), entry.getName());
+
+  {
+    std::string name;
+    ASSERT_NO_THROW(name = m_middleTier->user().getDirStorageClass(requester, dirPath));
+    ASSERT_TRUE(name.empty());
+  }
+
+  const std::string storageClassName = "TestStorageClass";
+  const uint16_t nbCopies = 2;
+  const std::string comment = "Comment";
+  ASSERT_NO_THROW(m_middleTier->admin().createStorageClass(requester, storageClassName,
+    nbCopies, comment));
+
+  ASSERT_NO_THROW(m_middleTier->user().setDirStorageClass(requester, dirPath,
+    storageClassName));
+
+  {
+    std::string name;
+    ASSERT_NO_THROW(name = m_middleTier->user().getDirStorageClass(requester, dirPath));
+    ASSERT_EQ(storageClassName, name);
+  }
+
+  ASSERT_THROW(m_middleTier->admin().deleteStorageClass(requester, storageClassName),
+    std::exception);
+
+  ASSERT_NO_THROW(m_middleTier->user().clearDirStorageClass(requester, dirPath));
+
+  {
+    std::string name;
+    ASSERT_NO_THROW(name = m_middleTier->user().getDirStorageClass(requester, dirPath));
+    ASSERT_TRUE(name.empty());
+  }
+
+  ASSERT_NO_THROW(m_middleTier->admin().deleteStorageClass(requester, storageClassName));
+}
+
+TEST_P(MiddleTierAbstractTest, user_archive_to_new_file) {
+  using namespace cta;
+
+  std::auto_ptr<localMiddleTier> m_middleTier(GetParam()->allocateLocalMiddleTier());
+  const SecurityIdentity requester;
+
+  const std::string storageClassName = "TestStorageClass";
+  const uint16_t nbCopies = 1;
+  const std::string storageClassComment = "Storage-class comment";
+  ASSERT_NO_THROW(m_middleTier->admin().createStorageClass(requester, storageClassName,
+    nbCopies, storageClassComment));
+
+  const std::string dirPath = "/grandparent";
+  ASSERT_NO_THROW(m_middleTier->user().createDir(requester, dirPath));
+  ASSERT_NO_THROW(m_middleTier->user().setDirStorageClass(requester, dirPath,
+    storageClassName));
+
+  const std::string tapePoolName = "TestTapePool";
+  const uint16_t nbPartialTapes = 1;
+  const std::string tapePoolComment = "Tape-pool comment";
+  ASSERT_NO_THROW(m_middleTier->admin().createTapePool(requester, tapePoolName,
+    nbPartialTapes, tapePoolComment));
+
+  const uint16_t copyNb = 1;
+  const std::string archivalRouteComment = "Archival-route comment";
+  ASSERT_NO_THROW(m_middleTier->admin().createArchivalRoute(requester, storageClassName,
+    copyNb, tapePoolName, archivalRouteComment));
+
+  std::list<std::string> srcUrls;
+  srcUrls.push_back("diskUrl");
+  const std::string dstPath  = "/grandparent/parent_file";
+  ASSERT_NO_THROW(m_middleTier->user().archive(requester, srcUrls, dstPath));
+
+  {
+    DirIterator itor;
+    ASSERT_NO_THROW(itor = m_middleTier->user().getDirContents(requester, "/"));
+    ASSERT_TRUE(itor.hasMore());
+    DirEntry entry;
+    ASSERT_NO_THROW(entry = itor.next());
+    ASSERT_EQ(std::string("grandparent"), entry.getName());
+    ASSERT_EQ(DirEntry::ENTRYTYPE_DIRECTORY, entry.getType());
+    ASSERT_EQ(storageClassName, entry.getStorageClassName());
+  }
+
+  {
+    DirIterator itor;
+    ASSERT_NO_THROW(itor = m_middleTier->user().getDirContents(requester,
+      "/grandparent"));
+    ASSERT_TRUE(itor.hasMore());
+    DirEntry entry;
+    ASSERT_NO_THROW(entry = itor.next());
+    ASSERT_EQ(std::string("parent_file"), entry.getName());
+    ASSERT_EQ(DirEntry::ENTRYTYPE_FILE, entry.getType());
+    ASSERT_EQ(storageClassName, entry.getStorageClassName());
+  }
+
+  {
+    DirEntry entry;
+    ASSERT_NO_THROW(entry = m_middleTier->user().stat(requester, dstPath));
+    ASSERT_EQ(DirEntry::ENTRYTYPE_FILE, entry.getType());
+    ASSERT_EQ(storageClassName, entry.getStorageClassName());
+  }
+
+  {
+    const std::map<TapePool, std::list<ArchivalJob> > allJobs =
+      m_middleTier->user().getArchivalJobs(requester);
+    ASSERT_EQ(1, allJobs.size());
+    std::map<TapePool, std::list<ArchivalJob> >::const_iterator
+      poolItor = allJobs.begin();
+    ASSERT_FALSE(poolItor == allJobs.end());
+    const TapePool &pool = poolItor->first;
+    ASSERT_TRUE(tapePoolName == pool.getName());
+    const std::list<ArchivalJob> &poolJobs = poolItor->second;
+    ASSERT_EQ(1, poolJobs.size());
+    std::set<std::string> srcUrls;
+    std::set<std::string> dstPaths;
+    for(std::list<ArchivalJob>::const_iterator jobItor = poolJobs.begin();
+      jobItor != poolJobs.end(); jobItor++) {
+      ASSERT_EQ(ArchivalJobState::PENDING, jobItor->getState());
+      srcUrls.insert(jobItor->getSrcUrl());
+      dstPaths.insert(jobItor->getDstPath());
+    }
+    ASSERT_EQ(1, srcUrls.size());
+    ASSERT_FALSE(srcUrls.find("diskUrl") == srcUrls.end());
+    ASSERT_EQ(1, dstPaths.size());
+    ASSERT_FALSE(dstPaths.find("/grandparent/parent_file") == dstPaths.end());
+  }
+
+  {
+    const std::list<ArchivalJob> poolJobs = m_middleTier->user().getArchivalJobs(requester,
+      tapePoolName);
+    ASSERT_EQ(1, poolJobs.size());
+    std::set<std::string> srcUrls;
+    std::set<std::string> dstPaths;
+    for(std::list<ArchivalJob>::const_iterator jobItor = poolJobs.begin();
+      jobItor != poolJobs.end(); jobItor++) {
+      ASSERT_EQ(ArchivalJobState::PENDING, jobItor->getState());
+      srcUrls.insert(jobItor->getSrcUrl());
+      dstPaths.insert(jobItor->getDstPath());
+    }
+    ASSERT_EQ(1, srcUrls.size());
+    ASSERT_FALSE(srcUrls.find("diskUrl") == srcUrls.end());
+    ASSERT_EQ(1, dstPaths.size());
+    ASSERT_FALSE(dstPaths.find("/grandparent/parent_file") == dstPaths.end());
+  }
+}
+
+TEST_P(MiddleTierAbstractTest,
+  user_archive_to_new_file_with_no_storage_class) {
+  using namespace cta;
+
+  std::auto_ptr<localMiddleTier> m_middleTier(GetParam()->allocateLocalMiddleTier());
+  const SecurityIdentity requester;
+
+  const std::string dirPath = "/grandparent";
+  ASSERT_NO_THROW(m_middleTier->user().createDir(requester, dirPath));
+
+  std::list<std::string> srcUrls;
+  srcUrls.push_back("diskUrl");
+  const std::string dstPath  = "/grandparent/parent_file";
+  ASSERT_THROW(m_middleTier->user().archive(requester, srcUrls, dstPath), std::exception);
+}
+
+TEST_P(MiddleTierAbstractTest,
+  user_archive_to_new_file_with_zero_copy_storage_class) {
+  using namespace cta;
+
+  std::auto_ptr<localMiddleTier> m_middleTier(GetParam()->allocateLocalMiddleTier());
+  const SecurityIdentity requester;
+
+  const std::string storageClassName = "TestStorageClass";
+  const uint16_t nbCopies = 0;
+  const std::string storageClassComment = "Storage-class comment";
+  ASSERT_NO_THROW(m_middleTier->admin().createStorageClass(requester, storageClassName,
+    nbCopies, storageClassComment));
+
+  const std::string dirPath = "/grandparent";
+  ASSERT_NO_THROW(m_middleTier->user().createDir(requester, dirPath));
+  ASSERT_NO_THROW(m_middleTier->user().setDirStorageClass(requester, dirPath,
+    storageClassName));
+
+  std::list<std::string> srcUrls;
+  srcUrls.push_back("diskUrl");
+  const std::string dstPath  = "/grandparent/parent_file";
+  ASSERT_THROW(m_middleTier->user().archive(requester, srcUrls, dstPath), std::exception);
+}
+
+TEST_P(MiddleTierAbstractTest, user_archive_to_new_file_with_no_route) {
+  using namespace cta;
+
+  std::auto_ptr<localMiddleTier> m_middleTier(GetParam()->allocateLocalMiddleTier());
+  const SecurityIdentity requester;
+
+  const std::string storageClassName = "TestStorageClass";
+  const uint16_t nbCopies = 1;
+  const std::string storageClassComment = "Storage-class comment";
+  ASSERT_NO_THROW(m_middleTier->admin().createStorageClass(requester, storageClassName,
+    nbCopies, storageClassComment));
+
+  const std::string dirPath = "/grandparent";
+  ASSERT_NO_THROW(m_middleTier->user().createDir(requester, dirPath));
+  ASSERT_NO_THROW(m_middleTier->user().setDirStorageClass(requester, dirPath,
+    storageClassName));
+
+  const std::string tapePoolName = "TestTapePool";
+  const uint16_t nbPartialTapes = 1;
+  const std::string tapePoolComment = "Tape-pool comment";
+  ASSERT_NO_THROW(m_middleTier->admin().createTapePool(requester, tapePoolName,
+    nbPartialTapes, tapePoolComment));
+
+  std::list<std::string> srcUrls;
+  srcUrls.push_back("diskUrl");
+  const std::string dstPath  = "/grandparent/parent_file";
+  ASSERT_THROW(m_middleTier->user().archive(requester, srcUrls, dstPath), std::exception);
+}
+
+TEST_P(MiddleTierAbstractTest,
+  user_archive_to_new_file_with_incomplete_routing) {
+  using namespace cta;
+
+  std::auto_ptr<localMiddleTier> m_middleTier(GetParam()->allocateLocalMiddleTier());
+  const SecurityIdentity requester;
+
+  const std::string storageClassName = "TestStorageClass";
+  const uint16_t nbCopies = 2;
+  const std::string storageClassComment = "Storage-class comment";
+  ASSERT_NO_THROW(m_middleTier->admin().createStorageClass(requester, storageClassName,
+    nbCopies, storageClassComment));
+
+  const std::string dirPath = "/grandparent";
+  ASSERT_NO_THROW(m_middleTier->user().createDir(requester, dirPath));
+  ASSERT_NO_THROW(m_middleTier->user().setDirStorageClass(requester, dirPath,
+    storageClassName));
+
+  const std::string tapePoolName = "TestTapePool";
+  const uint16_t nbPartialTapes = 1;
+  const std::string tapePoolComment = "Tape-pool comment";
+  ASSERT_NO_THROW(m_middleTier->admin().createTapePool(requester, tapePoolName,
+    nbPartialTapes, tapePoolComment));
+
+  const uint16_t copyNb = 1;
+  const std::string archivalRouteComment = "Archival-route comment";
+  ASSERT_NO_THROW(m_middleTier->admin().createArchivalRoute(requester, storageClassName,
+    copyNb, tapePoolName, archivalRouteComment));
+
+  std::list<std::string> srcUrls;
+  srcUrls.push_back("diskUrl");
+  const std::string dstPath  = "/grandparent/parent_file";
+  ASSERT_THROW(m_middleTier->user().archive(requester, srcUrls, dstPath), std::exception);
+}
+
+TEST_P(MiddleTierAbstractTest, user_archive_to_directory) {
+  using namespace cta;
+
+  std::auto_ptr<localMiddleTier> m_middleTier(GetParam()->allocateLocalMiddleTier());
+  const SecurityIdentity requester;
+
+  const std::string storageClassName = "TestStorageClass";
+  const uint16_t nbCopies = 1;
+  const std::string storageClassComment = "Storage-class comment";
+  ASSERT_NO_THROW(m_middleTier->admin().createStorageClass(requester, storageClassName,
+    nbCopies, storageClassComment));
+
+  const std::string dirPath = "/grandparent";
+  ASSERT_NO_THROW(m_middleTier->user().createDir(requester, dirPath));
+  ASSERT_NO_THROW(m_middleTier->user().setDirStorageClass(requester, dirPath,
+    storageClassName));
+
+  const std::string tapePoolName = "TestTapePool";
+  const uint16_t nbPartialTapes = 1;
+  const std::string tapePoolComment = "Tape-pool comment";
+  ASSERT_NO_THROW(m_middleTier->admin().createTapePool(requester, tapePoolName,
+    nbPartialTapes, tapePoolComment));
+
+  const uint16_t copyNb = 1;
+  const std::string archivalRouteComment = "Archival-route comment";
+  ASSERT_NO_THROW(m_middleTier->admin().createArchivalRoute(requester, storageClassName,
+    copyNb, tapePoolName, archivalRouteComment));
+
+  std::list<std::string> srcUrls;
+  srcUrls.push_back("diskUrl1");
+  srcUrls.push_back("diskUrl2");
+  srcUrls.push_back("diskUrl3");
+  srcUrls.push_back("diskUrl4");
+  const std::string dstPath  = "/grandparent";
+  ASSERT_NO_THROW(m_middleTier->user().archive(requester, srcUrls, dstPath));
+
+  {
+    DirIterator itor;
+    ASSERT_NO_THROW(itor = m_middleTier->user().getDirContents(requester, "/"));
+    ASSERT_TRUE(itor.hasMore());
+    DirEntry entry;
+    ASSERT_NO_THROW(entry = itor.next());
+    ASSERT_EQ(std::string("grandparent"), entry.getName());
+    ASSERT_EQ(DirEntry::ENTRYTYPE_DIRECTORY, entry.getType());
+    ASSERT_EQ(storageClassName, entry.getStorageClassName());
+  }
+
+  {
+    std::set<std::string> archiveFileNames;
+    DirIterator itor;
+    ASSERT_NO_THROW(itor = m_middleTier->user().getDirContents(requester,
+      "/grandparent"));
+    while(itor.hasMore()) {
+      const DirEntry entry = itor.next();
+      archiveFileNames.insert(entry.getName());
+    }
+    ASSERT_EQ(4, archiveFileNames.size());
+    ASSERT_TRUE(archiveFileNames.find("diskUrl1") != archiveFileNames.end());
+    ASSERT_TRUE(archiveFileNames.find("diskUrl2") != archiveFileNames.end());
+    ASSERT_TRUE(archiveFileNames.find("diskUrl3") != archiveFileNames.end());
+    ASSERT_TRUE(archiveFileNames.find("diskUrl4") != archiveFileNames.end());
+  }
+
+  {
+    const std::map<TapePool, std::list<ArchivalJob> > allJobs =
+      m_middleTier->user().getArchivalJobs(requester);
+    ASSERT_EQ(1, allJobs.size());
+    std::map<TapePool, std::list<ArchivalJob> >::const_iterator
+      poolItor = allJobs.begin();
+    ASSERT_FALSE(poolItor == allJobs.end());
+    const TapePool &pool = poolItor->first;
+    ASSERT_TRUE(tapePoolName == pool.getName());
+    const std::list<ArchivalJob> &poolJobs = poolItor->second;
+    ASSERT_EQ(4, poolJobs.size());
+    std::set<std::string> srcUrls;
+    std::set<std::string> dstPaths;
+    for(std::list<ArchivalJob>::const_iterator jobItor = poolJobs.begin();
+      jobItor != poolJobs.end(); jobItor++) {
+      ASSERT_EQ(ArchivalJobState::PENDING, jobItor->getState());
+      srcUrls.insert(jobItor->getSrcUrl());
+      dstPaths.insert(jobItor->getDstPath());
+    }
+    ASSERT_EQ(4, srcUrls.size());
+    ASSERT_FALSE(srcUrls.find("diskUrl1") == srcUrls.end());
+    ASSERT_FALSE(srcUrls.find("diskUrl2") == srcUrls.end());
+    ASSERT_FALSE(srcUrls.find("diskUrl3") == srcUrls.end());
+    ASSERT_FALSE(srcUrls.find("diskUrl4") == srcUrls.end());
+    ASSERT_EQ(4, dstPaths.size());
+    ASSERT_FALSE(dstPaths.find("/grandparent/diskUrl1") == srcUrls.end());
+    ASSERT_FALSE(dstPaths.find("/grandparent/diskUrl2") == srcUrls.end());
+    ASSERT_FALSE(dstPaths.find("/grandparent/diskUrl3") == srcUrls.end());
+    ASSERT_FALSE(dstPaths.find("/grandparent/diskUrl4") == srcUrls.end());
+  }
+
+  {
+    const std::list<ArchivalJob> poolJobs = m_middleTier->user().getArchivalJobs(requester,
+      tapePoolName);
+    ASSERT_EQ(4, poolJobs.size());
+    std::set<std::string> srcUrls;
+    std::set<std::string> dstPaths;
+    for(std::list<ArchivalJob>::const_iterator jobItor = poolJobs.begin();
+      jobItor != poolJobs.end(); jobItor++) {
+      ASSERT_EQ(ArchivalJobState::PENDING, jobItor->getState());
+      srcUrls.insert(jobItor->getSrcUrl());
+      dstPaths.insert(jobItor->getDstPath());
+    }
+    ASSERT_EQ(4, srcUrls.size());
+    ASSERT_FALSE(srcUrls.find("diskUrl1") == srcUrls.end());
+    ASSERT_FALSE(srcUrls.find("diskUrl2") == srcUrls.end());
+    ASSERT_FALSE(srcUrls.find("diskUrl3") == srcUrls.end());
+    ASSERT_FALSE(srcUrls.find("diskUrl4") == srcUrls.end());
+    ASSERT_EQ(4, dstPaths.size());
+    ASSERT_FALSE(dstPaths.find("/grandparent/diskUrl1") == srcUrls.end());
+    ASSERT_FALSE(dstPaths.find("/grandparent/diskUrl2") == srcUrls.end());
+    ASSERT_FALSE(dstPaths.find("/grandparent/diskUrl3") == srcUrls.end());
+    ASSERT_FALSE(dstPaths.find("/grandparent/diskUrl4") == srcUrls.end());
+  }
+}
+
+TEST_P(MiddleTierAbstractTest,
+  user_archive_to_directory_without_storage_class) {
+  using namespace cta;
+
+  std::auto_ptr<localMiddleTier> m_middleTier(GetParam()->allocateLocalMiddleTier());
+  const SecurityIdentity requester;
+
+  const std::string dirPath = "/grandparent";
+  ASSERT_NO_THROW(m_middleTier->user().createDir(requester, dirPath));
+
+  std::list<std::string> srcUrls;
+  srcUrls.push_back("diskUrl1");
+  srcUrls.push_back("diskUrl2");
+  srcUrls.push_back("diskUrl3");
+  srcUrls.push_back("diskUrl4");
+  const std::string dstPath  = "/grandparent";
+  ASSERT_THROW(m_middleTier->user().archive(requester, srcUrls, dstPath), std::exception);
+}
+
+TEST_P(MiddleTierAbstractTest,
+  user_archive_to_directory_with_zero_copy_storage_class) {
+  using namespace cta;
+
+  std::auto_ptr<localMiddleTier> m_middleTier(GetParam()->allocateLocalMiddleTier());
+  const SecurityIdentity requester;
+
+  const std::string storageClassName = "TestStorageClass";
+  const uint16_t nbCopies = 0;
+  const std::string storageClassComment = "Storage-class comment";
+  ASSERT_NO_THROW(m_middleTier->admin().createStorageClass(requester, storageClassName,
+    nbCopies, storageClassComment));
+
+  const std::string dirPath = "/grandparent";
+  ASSERT_NO_THROW(m_middleTier->user().createDir(requester, dirPath));
+  ASSERT_NO_THROW(m_middleTier->user().setDirStorageClass(requester, dirPath,
+    storageClassName));
+
+  std::list<std::string> srcUrls;
+  srcUrls.push_back("diskUrl1");
+  srcUrls.push_back("diskUrl2");
+  srcUrls.push_back("diskUrl3");
+  srcUrls.push_back("diskUrl4");
+  const std::string dstPath  = "/grandparent";
+  ASSERT_THROW(m_middleTier->user().archive(requester, srcUrls, dstPath), std::exception);
+}
+
+TEST_P(MiddleTierAbstractTest, user_archive_to_directory_with_no_route) {
+  using namespace cta;
+
+  std::auto_ptr<localMiddleTier> m_middleTier(GetParam()->allocateLocalMiddleTier());
+  const SecurityIdentity requester;
+
+  const std::string storageClassName = "TestStorageClass";
+  const uint16_t nbCopies = 1;
+  const std::string storageClassComment = "Storage-class comment";
+  ASSERT_NO_THROW(m_middleTier->admin().createStorageClass(requester, storageClassName,
+    nbCopies, storageClassComment));
+
+  const std::string dirPath = "/grandparent";
+  ASSERT_NO_THROW(m_middleTier->user().createDir(requester, dirPath));
+  ASSERT_NO_THROW(m_middleTier->user().setDirStorageClass(requester, dirPath,
+    storageClassName));
+
+  const std::string tapePoolName = "TestTapePool";
+  const uint16_t nbPartialTapes = 1;
+  const std::string tapePoolComment = "Tape-pool comment";
+  ASSERT_NO_THROW(m_middleTier->admin().createTapePool(requester, tapePoolName,
+    nbPartialTapes, tapePoolComment));
+
+  std::list<std::string> srcUrls;
+  srcUrls.push_back("diskUrl1");
+  srcUrls.push_back("diskUrl2");
+  srcUrls.push_back("diskUrl3");
+  srcUrls.push_back("diskUrl4");
+  const std::string dstPath  = "/grandparent";
+  ASSERT_THROW(m_middleTier->user().archive(requester, srcUrls, dstPath), std::exception);
+}
+
+TEST_P(MiddleTierAbstractTest,
+  user_archive_to_directory_with_incomplete_routing) {
+  using namespace cta;
+
+  std::auto_ptr<localMiddleTier> m_middleTier(GetParam()->allocateLocalMiddleTier());
+  const SecurityIdentity requester;
+
+  const std::string storageClassName = "TestStorageClass";
+  const uint16_t nbCopies = 2;
+  const std::string storageClassComment = "Storage-class comment";
+  ASSERT_NO_THROW(m_middleTier->admin().createStorageClass(requester, storageClassName,
+    nbCopies, storageClassComment));
+
+  const std::string dirPath = "/grandparent";
+  ASSERT_NO_THROW(m_middleTier->user().createDir(requester, dirPath));
+  ASSERT_NO_THROW(m_middleTier->user().setDirStorageClass(requester, dirPath,
+    storageClassName));
+
+  const std::string tapePoolName = "TestTapePool";
+  const uint16_t nbPartialTapes = 1;
+  const std::string tapePoolComment = "Tape-pool comment";
+  ASSERT_NO_THROW(m_middleTier->admin().createTapePool(requester, tapePoolName,
+    nbPartialTapes, tapePoolComment));
+
+  const uint16_t copyNb = 1;
+  const std::string archivalRouteComment = "Archival-route comment";
+  ASSERT_NO_THROW(m_middleTier->admin().createArchivalRoute(requester, storageClassName,
+    copyNb, tapePoolName, archivalRouteComment));
+
+  std::list<std::string> srcUrls;
+  srcUrls.push_back("diskUrl1");
+  srcUrls.push_back("diskUrl2");
+  srcUrls.push_back("diskUrl3");
+  srcUrls.push_back("diskUrl4");
+  const std::string dstPath  = "/grandparent";
+  ASSERT_THROW(m_middleTier->user().archive(requester, srcUrls, dstPath), std::exception);
+}
+
+} // namespace unitTests