diff --git a/middletier/CMakeLists.txt b/middletier/CMakeLists.txt
index ef90cf3377bc857e0c814c1787aa6bb4959a448b..e2f4ade8012c6d5ac524665c608a653405e4a4d3 100644
--- a/middletier/CMakeLists.txt
+++ b/middletier/CMakeLists.txt
@@ -83,5 +83,5 @@ include_directories(${CMAKE_BINARY_DIR})
 add_library(ctamiddletiersqliteobjectstore
   objectstore/ObjectStoreMiddleTierAdmin.cpp)
 
-#add_library (ctamiddletiersqliteobjectstoreunittests SHARED
-#  objectstore/ObjectStoreMiddleTierTest.cpp)
+add_library (ctamiddletiersqliteobjectstoreunittests SHARED
+  objectstore/ObjectStoreMiddleTierTest.cpp)
diff --git a/middletier/objectstore/ObjectStoreMiddleTierAdmin.cpp b/middletier/objectstore/ObjectStoreMiddleTierAdmin.cpp
index c24022a8746e92d25b7fc6dea4f9fe488f989761..ccb7934664b033cc7e08795ac51557535c512f52 100644
--- a/middletier/objectstore/ObjectStoreMiddleTierAdmin.cpp
+++ b/middletier/objectstore/ObjectStoreMiddleTierAdmin.cpp
@@ -62,4 +62,137 @@ void OStoreMiddleTierAdmin::createAdminUser(
   aul.commit();
 }
 
+void OStoreMiddleTierAdmin::deleteAdminUser(
+  const SecurityIdentity& requester, 
+  const UserIdentity& user) {
+  // Authz is not handled in this layer. We hence store the new admin user
+  // without checks.
+  objectstore::RootEntry re(m_backend);
+  objectstore::ScopedSharedLock reLock(re);
+  re.fetch();
+  objectstore::AdminUsersList aul(re.getAdminUsersList(), m_backend);
+  reLock.release();
+  objectstore::ScopedExclusiveLock aulLock(aul);
+  aul.fetch();
+  aul.remove(user.getUid(), user.getGid());
+  aul.commit();
+  }
+
+std::list<AdminUser> OStoreMiddleTierAdmin::getAdminUsers(
+  const SecurityIdentity& requester) const {
+  std::list<AdminUser> ret;
+  return ret;
+}
+
+void OStoreMiddleTierAdmin::createAdminHost(
+  const SecurityIdentity& requester,
+  const std::string& hostName,
+  const std::string& comment) {
+}
+
+void OStoreMiddleTierAdmin::deleteAdminHost(
+  const SecurityIdentity& requester,
+  const std::string& hostName) {
+}
+
+std::list<AdminHost> OStoreMiddleTierAdmin::getAdminHosts(
+  const SecurityIdentity& requester) const {
+  std::list<AdminHost> ret;
+  return ret;
+}
+
+void OStoreMiddleTierAdmin::createStorageClass(
+  const SecurityIdentity &requester,
+  const std::string &name,
+  const uint16_t nbCopies,
+  const std::string &comment) {
+}
+
+void OStoreMiddleTierAdmin::deleteStorageClass(
+  const SecurityIdentity& requester,
+  const std::string& name) { 
+
+}
+
+std::list<StorageClass> OStoreMiddleTierAdmin::getStorageClasses(
+  const SecurityIdentity& requester) const {
+  std::list<StorageClass> ret;
+  return ret;
+}
+
+void OStoreMiddleTierAdmin::createTapePool(
+  const SecurityIdentity& requester,
+  const std::string& name,
+  const uint16_t nbDrives,
+  const uint32_t nbPartialTapes,
+  const std::string& comment) {
+}
+
+void OStoreMiddleTierAdmin::deleteTapePool(
+  const SecurityIdentity& requester,
+  const std::string& name) {
+}
+
+std::list<TapePool> OStoreMiddleTierAdmin::getTapePools(
+  const SecurityIdentity& requester) const {
+  std::list<TapePool> ret;
+  return ret;
+}
+
+void OStoreMiddleTierAdmin::createArchivalRoute(
+  const SecurityIdentity &requester,
+  const std::string &storageClassName,
+  const uint16_t copyNb,
+  const std::string &tapePoolName,
+  const std::string &comment) {
+}
+
+void OStoreMiddleTierAdmin::deleteArchivalRoute(
+  const SecurityIdentity &requester,
+  const std::string &storageClassName,
+  const uint16_t copyNb) {
+}
+
+std::list<ArchivalRoute> OStoreMiddleTierAdmin::getArchivalRoutes(
+  const SecurityIdentity& requester) const {
+  std::list<ArchivalRoute> ret;
+  return ret;
+}
+
+void OStoreMiddleTierAdmin::createLogicalLibrary(
+  const SecurityIdentity& requester,
+  const std::string& name,
+  const std::string& comment) {
+}
+
+void OStoreMiddleTierAdmin::deleteLogicalLibrary(
+  const SecurityIdentity& requester,
+  const std::string& name) {
+}
+
+std::list<LogicalLibrary> OStoreMiddleTierAdmin::getLogicalLibraries(
+  const SecurityIdentity& requester) const {
+  std::list<LogicalLibrary> ret;
+  return ret;
+}
+
+void OStoreMiddleTierAdmin::createTape(
+  const SecurityIdentity& requester,
+  const std::string& vid,
+  const std::string& logicalLibraryName,
+  const std::string& tapePoolName, const uint64_t capacityInBytes, const std::string& comment) {
+}
+
+
+void OStoreMiddleTierAdmin::deleteTape(
+  const SecurityIdentity& requester,
+  const std::string& vid) {
+}
+
+std::list<Tape> OStoreMiddleTierAdmin::getTapes(
+  const SecurityIdentity& requester) const {
+  std::list<Tape> ret;
+  return ret;
+}
+
 }
diff --git a/middletier/objectstore/ObjectStoreMiddleTierAdmin.hpp b/middletier/objectstore/ObjectStoreMiddleTierAdmin.hpp
index 00dccf4a401c59b2956fb362b6d70ba9997c9f34..e662f118171c5877921ede8a5bd3018aaeff5a7b 100644
--- a/middletier/objectstore/ObjectStoreMiddleTierAdmin.hpp
+++ b/middletier/objectstore/ObjectStoreMiddleTierAdmin.hpp
@@ -122,7 +122,7 @@ public:
   virtual void createStorageClass(
     const SecurityIdentity &requester,
     const std::string &name,
-    const uint8_t nbCopies,
+    const uint16_t nbCopies,
     const std::string &comment);
 
   /**
@@ -145,6 +145,22 @@ public:
   virtual std::list<StorageClass> getStorageClasses(
     const SecurityIdentity &requester) const;
 
+  /**
+   * Creates a tape pool with the specifed name.
+   *
+   * @param requester The identity of the user requesting the creation of the
+   * tape pool.
+   * @param name The name of the tape pool.
+   * @param nbPartialTapes The maximum number of tapes that can be partially
+   * full at any moment in time.
+   * @param comment The comment describing the tape pool.
+   */
+  virtual void createTapePool(
+    const SecurityIdentity &requester,
+    const std::string &name,
+    const uint32_t nbPartialTapes,
+    const std::string &comment);
+
   /**
    * Creates a tape pool with the specifed name.
    *
@@ -186,28 +202,28 @@ public:
     const SecurityIdentity &requester) const;
 
   /**
-   * Creates the specified archive route.
+   * Creates the specified archival route.
    *
    * @param requester The identity of the user requesting the creation of the
-   * archive route.
+   * archival route.
    * @param storageClassName The name of the storage class that identifies the
    * source disk files.
    * @param copyNb The tape copy number.
    * @param tapePoolName The name of the destination tape pool.
-   * @param comment The comment describing the archive route.
+   * @param comment The comment describing the archival route.
    */
   virtual void createArchivalRoute(
     const SecurityIdentity &requester,
     const std::string &storageClassName,
-    const uint8_t copyNb,
+    const uint16_t copyNb,
     const std::string &tapePoolName,
     const std::string &comment);
 
   /**
-   * Deletes the specified archive route.
+   * Deletes the specified archival route.
    *
    * @param requester The identity of the user requesting the deletion of the
-   * archive route.
+   * archival route.
    * @param storageClassName The name of the storage class that identifies the
    * source disk files.
    * @param copyNb The tape copy number.
@@ -215,7 +231,7 @@ public:
   virtual void deleteArchivalRoute(
     const SecurityIdentity &requester,
     const std::string &storageClassName,
-    const uint8_t copyNb);
+    const uint16_t copyNb);
 
   /**
    * Gets the current list of archive routes.
diff --git a/middletier/objectstore/ObjectStoreMiddleTierTest.cpp b/middletier/objectstore/ObjectStoreMiddleTierTest.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..82d2c88f151306088ec3cf5ba63dbe283c115c63
--- /dev/null
+++ b/middletier/objectstore/ObjectStoreMiddleTierTest.cpp
@@ -0,0 +1,51 @@
+/*
+ * 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 "middletier/sharedtest/MiddleTierAbstractTest.hpp"
+#include "middletier/interface/MiddleTierAdmin.hpp"
+#include "middletier/interface/MiddleTierUser.hpp"
+#include "middletier/objectstore/ObjectStoreMiddleTierAdmin.hpp"
+#include "objectstore/BackendVFS.hpp"
+
+namespace unitTests {
+
+class OStoreVfsMiddleTier: public localMiddleTier {
+public:
+  OStoreVfsMiddleTier(): m_vfs(), m_admin(m_vfs) {}
+  virtual cta::MiddleTierAdmin & admin () { return m_admin; }
+  //virtual cta::MiddleTierUser & user () { return m_user; }
+private:
+  cta::objectstore::BackendVFS m_vfs;
+  cta::OStoreMiddleTierAdmin m_admin;
+  //cta::OStoreMiddleTierUser m_user;
+};
+
+class SQLiteMiddleTierFactory: public MiddleTierFactory {
+public:
+  SQLiteMiddleTierFactory() {
+    m_localMiddleTier = allocateLocalMiddleTier();
+  }
+  virtual localMiddleTier * allocateLocalMiddleTier() { 
+    return new OStoreVfsMiddleTier; }
+} g_SQLiteMiddleTierFactory;
+
+// Macro chokes on implicit casting of pointer so we have to do it ourselves
+INSTANTIATE_TEST_CASE_P(MiddleTierSQL, MiddleTierAbstractTest, ::testing::Values(
+    (MiddleTierFactory*)&g_SQLiteMiddleTierFactory));
+
+}
\ No newline at end of file
diff --git a/objectstore/AdminUsersList.cpp b/objectstore/AdminUsersList.cpp
index fb2a51f88601ae3ec87f029381d2eca0ef4de633..d0bde42dd6ddef22844497bf53f1552118afdcbd 100644
--- a/objectstore/AdminUsersList.cpp
+++ b/objectstore/AdminUsersList.cpp
@@ -46,4 +46,22 @@ void AdminUsersList::add(const cta::AdminUser& adminUser) {
   newEntry->set_comment(adminUser.getComment());
 }
 
+void AdminUsersList::remove(uint32_t uid, uint32_t gid) {
+  ::google::protobuf::RepeatedPtrField<serializers::AdminUser>* list =
+      m_payload.mutable_element();
+  bool found;
+  do {
+    found = false;
+    for (size_t i=0; i<(size_t)list->size(); i++) {
+      if (uid == list->Get(i).user().uid() && 
+          gid == list->Get(i).user().gid()) {
+        found = true;
+        list->SwapElements(i, list->size()-1);
+        list->RemoveLast();
+        break;
+      }
+    }
+  } while (found);
+}
+
 }}
\ No newline at end of file
diff --git a/objectstore/AdminUsersList.hpp b/objectstore/AdminUsersList.hpp
index 29e74c7937a307feb3fe33ee4674c52db0629f72..f55fa5b0f9706a62c3a5be6fca03a5ae67c4a632 100644
--- a/objectstore/AdminUsersList.hpp
+++ b/objectstore/AdminUsersList.hpp
@@ -35,6 +35,8 @@ public:
   AdminUsersList(const std::string & name, Backend & os);
   
   void add(const cta::AdminUser & adminUser);
+  
+  void remove(uint32_t uid, uint32_t gid);
 };
 
 }}