diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 0fb084669321bbcc822ae30918940570657966e0..52e2e24928d9dd8a9ddfc58891b0bb0a1bef651e 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -13,6 +13,8 @@ before_script:
   - echo "Exporting CTA_BUILD_ID=${CTA_BUILD_ID}"
   - test -n "${CI_COMMIT_TAG}" && export TAG_VERSION=$(echo ${CI_COMMIT_TAG} | sed -e 's/^v//;s/-.*$//')
   - test -n "${CI_COMMIT_TAG}" && export TAG_RELEASE=$(echo ${CI_COMMIT_TAG} | sed -e 's/^[^-]*-//')
+  - echo "Removing protectbase from all repos (same as Puppet)"
+  - sed -i '/^protect=/d' /etc/yum.repos.d/* 
 
 cta_srpm:
   stage: build:srpm
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 0c63df723e6d11e5845b6407bbb13483fee6c4e4..1b17823566d5f878c2549dce761ed8d9233480c0 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -72,14 +72,6 @@ endif (NOT DEFINED SKIP_UNIT_TESTS)
 #Load version information in all cases.
 include(cmake/CTAVersions.cmake)
 
-if (DEFINED NoACS)
-  message (STATUS "Running CMake without support for ACS")
-  set (use_manually_specified_variable ${NoACS})
-else (DEFINED NoACS)
-  message (STATUS "Running CMake with support for ACS")
-  message (STATUS "Override with -DNoACS:Bool=true")
-endif (DEFINED NoACS)
-
 IF(DEFINED PackageOnly)
   message (STATUS "Running CMake in package-only mode")
    set(COMPILE_PACKAGING "1") 
diff --git a/catalogue/ArchiveFileRow.cpp b/catalogue/ArchiveFileRow.cpp
index 520779af7de44b74eb9e41a6417e42e8d95349ee..d6bdeb287985a6a8650e7d74a6b82b796d3ac806 100644
--- a/catalogue/ArchiveFileRow.cpp
+++ b/catalogue/ArchiveFileRow.cpp
@@ -40,7 +40,6 @@ bool ArchiveFileRow::operator==(const ArchiveFileRow &rhs) const {
     diskFilePath == rhs.diskFilePath &&
     diskFileUser == rhs.diskFileUser &&
     diskFileGroup == rhs.diskFileGroup &&
-    diskFileRecoveryBlob == rhs.diskFileRecoveryBlob &&
     size == rhs.size &&
     checksumType == rhs.checksumType &&
     checksumValue == rhs.checksumValue &&
@@ -59,7 +58,6 @@ std::ostream &operator<<(std::ostream &os, const ArchiveFileRow &obj) {
   "diskFilePath=" << obj.diskFilePath <<
   "diskFileUser=" << obj.diskFileUser <<
   "diskFileGroup=" << obj.diskFileGroup <<
-  "diskFileRecoveryBlob=" << obj.diskFileRecoveryBlob <<
   "size=" << obj.size <<
   "checksumType=" << obj.checksumType << "checksumValue=" << obj.checksumValue <<
   "storageClassName=" << obj.storageClassName <<
diff --git a/catalogue/ArchiveFileRow.hpp b/catalogue/ArchiveFileRow.hpp
index 3b2218bd723058a187880a60c04d4233567ad6b2..3e3a92600f90af1ff37f0a51982bf6b3f389dd94 100644
--- a/catalogue/ArchiveFileRow.hpp
+++ b/catalogue/ArchiveFileRow.hpp
@@ -78,13 +78,6 @@ struct ArchiveFileRow {
    */
   std::string diskFileGroup;
 
-  /**
-   * Opaque blob containing the metadata of the source disk file within its host
-   * disk system.  This blob can be used in a disaster recovery scenario to
-   * contribute to reconstructing the namespace of the host disk system.
-   */
-  std::string diskFileRecoveryBlob;
-
   /**
    * The uncompressed size of the tape file in bytes.
    */
diff --git a/catalogue/CMakeLists.txt b/catalogue/CMakeLists.txt
index d6d4b5490c71b35056707de331546cc1ec3dbeab..b46717c56fa40107568986b89929423588cee423 100644
--- a/catalogue/CMakeLists.txt
+++ b/catalogue/CMakeLists.txt
@@ -38,6 +38,7 @@ set (CATALOGUE_LIB_SRC_FILES
   MysqlCatalogueSchema.cpp
   OracleCatalogue.cpp
   OracleCatalogueFactory.cpp
+  PostgresCatalogue.cpp
   PostgresqlCatalogueFactory.cpp
   SqliteCatalogueSchema.cpp
   TapeFileWritten.cpp
@@ -78,7 +79,7 @@ target_link_libraries (ctacatalogue
   ctacommon
   ctardbms)
 
-add_custom_command (OUTPUT sqlite_catalogue_schema.sql mysql_catalogue_schema.sql oracle_catalogue_schema.sql
+add_custom_command (OUTPUT sqlite_catalogue_schema.sql mysql_catalogue_schema.sql oracle_catalogue_schema.sql postgres_catalogue_schema.sql
   COMMAND cat
     ${CMAKE_CURRENT_SOURCE_DIR}/sqlite_catalogue_schema_header.sql
     ${CMAKE_CURRENT_SOURCE_DIR}/common_catalogue_schema.sql
@@ -96,12 +97,19 @@ add_custom_command (OUTPUT sqlite_catalogue_schema.sql mysql_catalogue_schema.sq
     ${CMAKE_CURRENT_SOURCE_DIR}/oracle_catalogue_schema_trailer.sql
     | sed 's/VARCHAR/VARCHAR2/g'
     > oracle_catalogue_schema.sql
+  COMMAND cat
+    ${CMAKE_CURRENT_SOURCE_DIR}/postgres_catalogue_schema_header.sql
+    ${CMAKE_CURRENT_SOURCE_DIR}/common_catalogue_schema.sql
+    ${CMAKE_CURRENT_SOURCE_DIR}/postgres_catalogue_schema_trailer.sql
+    > postgres_catalogue_schema.sql
   DEPENDS
     ${CMAKE_CURRENT_SOURCE_DIR}/common_catalogue_schema.sql
     ${CMAKE_CURRENT_SOURCE_DIR}/sqlite_catalogue_schema_header.sql
     ${CMAKE_CURRENT_SOURCE_DIR}/sqlite_catalogue_schema_trailer.sql
     ${CMAKE_CURRENT_SOURCE_DIR}/mysql_catalogue_schema_header.sql
     ${CMAKE_CURRENT_SOURCE_DIR}/mysql_catalogue_schema_trailer.sql
+    ${CMAKE_CURRENT_SOURCE_DIR}/postgres_catalogue_schema_header.sql
+    ${CMAKE_CURRENT_SOURCE_DIR}/postgres_catalogue_schema_trailer.sql
     ${CMAKE_CURRENT_SOURCE_DIR}/oracle_catalogue_schema_header.sql
     ${CMAKE_CURRENT_SOURCE_DIR}/oracle_catalogue_schema_trailer.sql)
 
@@ -127,6 +135,15 @@ add_custom_command(OUTPUT MysqlCatalogueSchema.cpp
   COMMAND sed -e '/CTA_SQL_SCHEMA/r mysql_catalogue_schema.cpp' -e '/CTA_SQL_TRIGGER/r mysql_catalogue_schema_trigger.cpp' ${CMAKE_CURRENT_SOURCE_DIR}/MysqlCatalogueSchema.before_SQL.cpp > MysqlCatalogueSchema.cpp
   DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/MysqlCatalogueSchema.before_SQL.cpp mysql_catalogue_schema.cpp mysql_catalogue_schema_trigger.cpp)
 
+# For Postgres
+add_custom_command(OUTPUT postgres_catalogue_schema.cpp
+  COMMAND sed 's/^/\ \ \"/' postgres_catalogue_schema.sql | sed 's/$$/\"/' > postgres_catalogue_schema.cpp
+  DEPENDS postgres_catalogue_schema.sql)
+
+add_custom_command(OUTPUT PostgresCatalogueSchema.cpp
+  COMMAND sed -e '/CTA_SQL_SCHEMA/r postgres_catalogue_schema.cpp' ${CMAKE_CURRENT_SOURCE_DIR}/PostgresCatalogueSchema.before_SQL.cpp > PostgresCatalogueSchema.cpp
+  DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/PostgresCatalogueSchema.before_SQL.cpp postgres_catalogue_schema.cpp)
+
 
 set(IN_MEMORY_CATALOGUE_UNIT_TESTS_LIB_SRC_FILES
   CatalogueTest.cpp
@@ -175,6 +192,7 @@ add_executable(cta-catalogue-schema-create
   CreateSchemaCmdMain.cpp
   OracleCatalogueSchema.cpp
   SqliteCatalogueSchema.cpp
+  PostgresCatalogueSchema.cpp
   MysqlCatalogueSchema.cpp)
 
 target_link_libraries (cta-catalogue-schema-create
diff --git a/catalogue/Catalogue.hpp b/catalogue/Catalogue.hpp
index d7d692b6ff7b8109212aa9983f7a83fb0101e0d6..318cdbbd28a535f9a2a63e8ede471daec275d593 100644
--- a/catalogue/Catalogue.hpp
+++ b/catalogue/Catalogue.hpp
@@ -92,9 +92,8 @@ public:
    *
    * @param vid The volume identifier of the tape.
    * @param drive The name of tape drive that was used to label the tape.
-   * @param lbpIsOn Set to true if Logical Block Protection (LBP) was enabled.
    */
-  virtual void tapeLabelled(const std::string &vid, const std::string &drive, const bool lbpIsOn) = 0;
+  virtual void tapeLabelled(const std::string &vid, const std::string &drive) = 0;
 
   /**
    * Checks the specified archival could take place and returns a new and
diff --git a/catalogue/CatalogueRetryWrapper.hpp b/catalogue/CatalogueRetryWrapper.hpp
index b88f30c1719b7885ca8f0064d5ac59c9e18de490..e192baafca0798bc3585bc5c5a82030818adae67 100644
--- a/catalogue/CatalogueRetryWrapper.hpp
+++ b/catalogue/CatalogueRetryWrapper.hpp
@@ -64,8 +64,8 @@ public:
    */
   CatalogueRetryWrapper &operator=(const CatalogueRetryWrapper &) = delete;
 
-  void tapeLabelled(const std::string &vid, const std::string &drive, const bool lbpIsOn) override {
-    return retryOnLostConnection(m_log, [&]{return m_catalogue->tapeLabelled(vid, drive, lbpIsOn);}, m_maxTriesToConnect);
+  void tapeLabelled(const std::string &vid, const std::string &drive) override {
+    return retryOnLostConnection(m_log, [&]{return m_catalogue->tapeLabelled(vid, drive);}, m_maxTriesToConnect);
   }
 
   uint64_t checkAndGetNextArchiveFileId(const std::string &diskInstanceName, const std::string &storageClassName, const common::dataStructures::UserIdentity &user) override {
diff --git a/catalogue/CatalogueTest.cpp b/catalogue/CatalogueTest.cpp
index cb2c4b478e03356e76be6d1255778227d3d4c7dc..0d00662d71a4aebbb94a60a7becf4fa59a5afa0a 100644
--- a/catalogue/CatalogueTest.cpp
+++ b/catalogue/CatalogueTest.cpp
@@ -41,6 +41,9 @@
 #include "rdbms/wrapper/ConnFactoryFactory.hpp"
 #include "rdbms/Conn.hpp"
 #include "rdbms/ConnPool.hpp"
+#include "common/threading/Thread.hpp"
+#include "common/threading/Mutex.hpp"
+#include "common/threading/MutexLocker.hpp"
 
 #include <algorithm>
 #include <gtest/gtest.h>
@@ -2103,7 +2106,6 @@ TEST_P(cta_catalogue_CatalogueTest, createTape) {
     ASSERT_EQ(capacityInBytes, tape.capacityInBytes);
     ASSERT_TRUE(disabledValue == tape.disabled);
     ASSERT_TRUE(fullValue == tape.full);
-    ASSERT_FALSE(tape.lbp);
     ASSERT_EQ(comment, tape.comment);
     ASSERT_FALSE(tape.labelLog);
     ASSERT_FALSE(tape.lastReadLog);
@@ -2479,7 +2481,6 @@ TEST_P(cta_catalogue_CatalogueTest, createTape_9_exabytes_capacity) {
     ASSERT_EQ(capacityInBytes, tape.capacityInBytes);
     ASSERT_TRUE(disabledValue == tape.disabled);
     ASSERT_TRUE(fullValue == tape.full);
-    ASSERT_FALSE(tape.lbp);
     ASSERT_EQ(comment, tape.comment);
     ASSERT_FALSE(tape.labelLog);
     ASSERT_FALSE(tape.lastReadLog);
@@ -2884,7 +2885,6 @@ TEST_P(cta_catalogue_CatalogueTest, createTape_1_tape_with_write_log_1_tape_with
     ASSERT_EQ(capacityInBytes, tape.capacityInBytes);
     ASSERT_TRUE(disabledValue == tape.disabled);
     ASSERT_TRUE(fullValue == tape.full);
-    ASSERT_FALSE(tape.lbp);
     ASSERT_EQ(comment, tape.comment);
     ASSERT_FALSE(tape.labelLog);
     ASSERT_FALSE(tape.lastReadLog);
@@ -2924,7 +2924,6 @@ TEST_P(cta_catalogue_CatalogueTest, createTape_1_tape_with_write_log_1_tape_with
     file1Written.diskFilePath         = "/public_dir/public_file";
     file1Written.diskFileUser         = "public_disk_user";
     file1Written.diskFileGroup        = "public_disk_group";
-    file1Written.diskFileRecoveryBlob = "opaque_disk_file_recovery_contents";
     file1Written.size                 = fileSize;
     file1Written.checksumType         = "checksum_type";
     file1Written.checksumValue        = "checksum_value";
@@ -2970,7 +2969,6 @@ TEST_P(cta_catalogue_CatalogueTest, createTape_1_tape_with_write_log_1_tape_with
     ASSERT_EQ(capacityInBytes, tape.capacityInBytes);
     ASSERT_TRUE(disabledValue == tape.disabled);
     ASSERT_TRUE(fullValue == tape.full);
-    ASSERT_FALSE(tape.lbp);
     ASSERT_EQ(comment, tape.comment);
     ASSERT_FALSE(tape.labelLog);
     ASSERT_FALSE(tape.lastReadLog);
@@ -3037,7 +3035,6 @@ TEST_P(cta_catalogue_CatalogueTest, deleteTape) {
   ASSERT_EQ(capacityInBytes, tape.capacityInBytes);
   ASSERT_TRUE(disabledValue == tape.disabled);
   ASSERT_TRUE(fullValue == tape.full);
-  ASSERT_FALSE(tape.lbp);
   ASSERT_EQ(comment, tape.comment);
   ASSERT_FALSE(tape.labelLog);
   ASSERT_FALSE(tape.lastReadLog);
@@ -3100,7 +3097,6 @@ TEST_P(cta_catalogue_CatalogueTest, deleteNonEmptyTape) {
     ASSERT_EQ(0, tape.dataOnTapeInBytes);
     ASSERT_TRUE(disabledValue == tape.disabled);
     ASSERT_TRUE(fullValue == tape.full);
-    ASSERT_FALSE(tape.lbp);
     ASSERT_EQ(comment, tape.comment);
     ASSERT_FALSE(tape.labelLog);
     ASSERT_FALSE(tape.lastReadLog);
@@ -3127,7 +3123,6 @@ TEST_P(cta_catalogue_CatalogueTest, deleteNonEmptyTape) {
     file1Written.diskFilePath         = "/public_dir/public_file";
     file1Written.diskFileUser         = "public_disk_user";
     file1Written.diskFileGroup        = "public_disk_group";
-    file1Written.diskFileRecoveryBlob = "opaque_disk_file_recovery_contents";
     file1Written.size                 = fileSize;
     file1Written.checksumType         = "checksum_type";
     file1Written.checksumValue        = "checksum_value";
@@ -3157,7 +3152,6 @@ TEST_P(cta_catalogue_CatalogueTest, deleteNonEmptyTape) {
     ASSERT_EQ(fileSize, tape.dataOnTapeInBytes);
     ASSERT_TRUE(disabledValue == tape.disabled);
     ASSERT_TRUE(fullValue == tape.full);
-    ASSERT_FALSE(tape.lbp);
     ASSERT_EQ(comment, tape.comment);
     ASSERT_FALSE(tape.labelLog);
     ASSERT_FALSE(tape.lastReadLog);
@@ -3221,7 +3215,6 @@ TEST_P(cta_catalogue_CatalogueTest, modifyTapeMediaType) {
     ASSERT_EQ(capacityInBytes, tape.capacityInBytes);
     ASSERT_TRUE(disabledValue == tape.disabled);
     ASSERT_TRUE(fullValue == tape.full);
-    ASSERT_FALSE(tape.lbp);
     ASSERT_EQ(comment, tape.comment);
     ASSERT_FALSE(tape.labelLog);
     ASSERT_FALSE(tape.lastReadLog);
@@ -3251,7 +3244,6 @@ TEST_P(cta_catalogue_CatalogueTest, modifyTapeMediaType) {
     ASSERT_EQ(capacityInBytes, tape.capacityInBytes);
     ASSERT_TRUE(disabledValue == tape.disabled);
     ASSERT_TRUE(fullValue == tape.full);
-    ASSERT_FALSE(tape.lbp);
     ASSERT_EQ(comment, tape.comment);
     ASSERT_FALSE(tape.labelLog);
     ASSERT_FALSE(tape.lastReadLog);
@@ -3301,7 +3293,6 @@ TEST_P(cta_catalogue_CatalogueTest, modifyTapeVendor) {
     ASSERT_EQ(capacityInBytes, tape.capacityInBytes);
     ASSERT_TRUE(disabledValue == tape.disabled);
     ASSERT_TRUE(fullValue == tape.full);
-    ASSERT_FALSE(tape.lbp);
     ASSERT_EQ(comment, tape.comment);
     ASSERT_FALSE(tape.labelLog);
     ASSERT_FALSE(tape.lastReadLog);
@@ -3332,7 +3323,6 @@ TEST_P(cta_catalogue_CatalogueTest, modifyTapeVendor) {
     ASSERT_EQ(capacityInBytes, tape.capacityInBytes);
     ASSERT_TRUE(disabledValue == tape.disabled);
     ASSERT_TRUE(fullValue == tape.full);
-    ASSERT_FALSE(tape.lbp);
     ASSERT_EQ(comment, tape.comment);
     ASSERT_FALSE(tape.labelLog);
     ASSERT_FALSE(tape.lastReadLog);
@@ -3383,7 +3373,6 @@ TEST_P(cta_catalogue_CatalogueTest, modifyTapeLogicalLibraryName) {
     ASSERT_EQ(capacityInBytes, tape.capacityInBytes);
     ASSERT_TRUE(disabledValue == tape.disabled);
     ASSERT_TRUE(fullValue == tape.full);
-    ASSERT_FALSE(tape.lbp);
     ASSERT_EQ(comment, tape.comment);
     ASSERT_FALSE(tape.labelLog);
     ASSERT_FALSE(tape.lastReadLog);
@@ -3414,7 +3403,6 @@ TEST_P(cta_catalogue_CatalogueTest, modifyTapeLogicalLibraryName) {
     ASSERT_EQ(capacityInBytes, tape.capacityInBytes);
     ASSERT_TRUE(disabledValue == tape.disabled);
     ASSERT_TRUE(fullValue == tape.full);
-    ASSERT_FALSE(tape.lbp);
     ASSERT_EQ(comment, tape.comment);
     ASSERT_FALSE(tape.labelLog);
     ASSERT_FALSE(tape.lastReadLog);
@@ -3479,7 +3467,6 @@ TEST_P(cta_catalogue_CatalogueTest, modifyTapeTapePoolName) {
     ASSERT_EQ(capacityInBytes, tape.capacityInBytes);
     ASSERT_TRUE(disabledValue == tape.disabled);
     ASSERT_TRUE(fullValue == tape.full);
-    ASSERT_FALSE(tape.lbp);
     ASSERT_EQ(comment, tape.comment);
     ASSERT_FALSE(tape.labelLog);
     ASSERT_FALSE(tape.lastReadLog);
@@ -3510,7 +3497,6 @@ TEST_P(cta_catalogue_CatalogueTest, modifyTapeTapePoolName) {
     ASSERT_EQ(capacityInBytes, tape.capacityInBytes);
     ASSERT_TRUE(disabledValue == tape.disabled);
     ASSERT_TRUE(fullValue == tape.full);
-    ASSERT_FALSE(tape.lbp);
     ASSERT_EQ(comment, tape.comment);
     ASSERT_FALSE(tape.labelLog);
     ASSERT_FALSE(tape.lastReadLog);
@@ -3576,7 +3562,6 @@ TEST_P(cta_catalogue_CatalogueTest, modifyTapeCapacityInBytes) {
     ASSERT_EQ(capacityInBytes, tape.capacityInBytes);
     ASSERT_TRUE(disabledValue == tape.disabled);
     ASSERT_TRUE(fullValue == tape.full);
-    ASSERT_FALSE(tape.lbp);
     ASSERT_EQ(comment, tape.comment);
     ASSERT_FALSE(tape.labelLog);
     ASSERT_FALSE(tape.lastReadLog);
@@ -3608,7 +3593,6 @@ TEST_P(cta_catalogue_CatalogueTest, modifyTapeCapacityInBytes) {
     ASSERT_EQ(modifiedCapacityInBytes, tape.capacityInBytes);
     ASSERT_TRUE(disabledValue == tape.disabled);
     ASSERT_TRUE(fullValue == tape.full);
-    ASSERT_FALSE(tape.lbp);
     ASSERT_EQ(comment, tape.comment);
     ASSERT_FALSE(tape.labelLog);
     ASSERT_FALSE(tape.lastReadLog);
@@ -3669,7 +3653,6 @@ TEST_P(cta_catalogue_CatalogueTest, modifyTapeEncryptionKey) {
     ASSERT_EQ(capacityInBytes, tape.capacityInBytes);
     ASSERT_TRUE(disabledValue == tape.disabled);
     ASSERT_TRUE(fullValue == tape.full);
-    ASSERT_FALSE(tape.lbp);
     ASSERT_EQ(comment, tape.comment);
     ASSERT_FALSE(tape.labelLog);
     ASSERT_FALSE(tape.lastReadLog);
@@ -3702,7 +3685,6 @@ TEST_P(cta_catalogue_CatalogueTest, modifyTapeEncryptionKey) {
     ASSERT_EQ(capacityInBytes, tape.capacityInBytes);
     ASSERT_TRUE(disabledValue == tape.disabled);
     ASSERT_TRUE(fullValue == tape.full);
-    ASSERT_FALSE(tape.lbp);
     ASSERT_EQ(comment, tape.comment);
     ASSERT_FALSE(tape.labelLog);
     ASSERT_FALSE(tape.lastReadLog);
@@ -3763,7 +3745,6 @@ TEST_P(cta_catalogue_CatalogueTest, tapeLabelled) {
     ASSERT_EQ(capacityInBytes, tape.capacityInBytes);
     ASSERT_TRUE(disabledValue == tape.disabled);
     ASSERT_TRUE(fullValue == tape.full);
-    ASSERT_FALSE(tape.lbp);
     ASSERT_EQ(comment, tape.comment);
     ASSERT_FALSE(tape.labelLog);
     ASSERT_FALSE(tape.lastReadLog);
@@ -3778,8 +3759,7 @@ TEST_P(cta_catalogue_CatalogueTest, tapeLabelled) {
   }
 
   const std::string labelDrive = "labelling_drive";
-  const bool lbpIsOn = true;
-  m_catalogue->tapeLabelled(vid, labelDrive, lbpIsOn);
+  m_catalogue->tapeLabelled(vid, labelDrive);
 
   {
     const std::list<common::dataStructures::Tape> tapes = m_catalogue->getTapes();
@@ -3796,8 +3776,6 @@ TEST_P(cta_catalogue_CatalogueTest, tapeLabelled) {
     ASSERT_EQ(capacityInBytes, tape.capacityInBytes);
     ASSERT_TRUE(disabledValue == tape.disabled);
     ASSERT_TRUE(fullValue == tape.full);
-    ASSERT_TRUE((bool)tape.lbp);
-    ASSERT_TRUE(tape.lbp.value());
     ASSERT_EQ(comment, tape.comment);
     ASSERT_TRUE((bool)tape.labelLog);
     ASSERT_EQ(labelDrive, tape.labelLog.value().drive);
@@ -3817,9 +3795,8 @@ TEST_P(cta_catalogue_CatalogueTest, tapeLabelled_nonExistentTape) {
 
   const std::string vid = "vid";
   const std::string labelDrive = "drive";
-  const bool lbpIsOn = true;
 
-  ASSERT_THROW(m_catalogue->tapeLabelled(vid, labelDrive, lbpIsOn), exception::UserError);
+  ASSERT_THROW(m_catalogue->tapeLabelled(vid, labelDrive), exception::UserError);
 }
 
 TEST_P(cta_catalogue_CatalogueTest, tapeMountedForArchive) {
@@ -3860,7 +3837,6 @@ TEST_P(cta_catalogue_CatalogueTest, tapeMountedForArchive) {
     ASSERT_EQ(capacityInBytes, tape.capacityInBytes);
     ASSERT_TRUE(disabledValue == tape.disabled);
     ASSERT_TRUE(fullValue == tape.full);
-    ASSERT_FALSE(tape.lbp);
     ASSERT_EQ(comment, tape.comment);
     ASSERT_FALSE(tape.labelLog);
     ASSERT_FALSE(tape.lastReadLog);
@@ -3892,7 +3868,6 @@ TEST_P(cta_catalogue_CatalogueTest, tapeMountedForArchive) {
     ASSERT_EQ(capacityInBytes, tape.capacityInBytes);
     ASSERT_TRUE(disabledValue == tape.disabled);
     ASSERT_TRUE(fullValue == tape.full);
-    ASSERT_FALSE(tape.lbp);
     ASSERT_EQ(comment, tape.comment);
     ASSERT_FALSE(tape.labelLog);
     ASSERT_FALSE(tape.lastReadLog);
@@ -3954,7 +3929,6 @@ TEST_P(cta_catalogue_CatalogueTest, tapeMountedForRetrieve) {
     ASSERT_EQ(capacityInBytes, tape.capacityInBytes);
     ASSERT_TRUE(disabledValue == tape.disabled);
     ASSERT_TRUE(fullValue == tape.full);
-    ASSERT_FALSE(tape.lbp);
     ASSERT_EQ(comment, tape.comment);
     ASSERT_FALSE(tape.labelLog);
     ASSERT_FALSE(tape.lastReadLog);
@@ -3986,7 +3960,6 @@ TEST_P(cta_catalogue_CatalogueTest, tapeMountedForRetrieve) {
     ASSERT_EQ(capacityInBytes, tape.capacityInBytes);
     ASSERT_TRUE(disabledValue == tape.disabled);
     ASSERT_TRUE(fullValue == tape.full);
-    ASSERT_FALSE(tape.lbp);
     ASSERT_EQ(comment, tape.comment);
     ASSERT_FALSE(tape.labelLog);
     ASSERT_TRUE((bool)tape.lastReadLog);
@@ -4048,7 +4021,6 @@ TEST_P(cta_catalogue_CatalogueTest, setTapeFull) {
     ASSERT_EQ(capacityInBytes, tape.capacityInBytes);
     ASSERT_TRUE(disabledValue == tape.disabled);
     ASSERT_TRUE(fullValue == tape.full);
-    ASSERT_FALSE(tape.lbp);
     ASSERT_EQ(comment, tape.comment);
     ASSERT_FALSE(tape.labelLog);
     ASSERT_FALSE(tape.lastReadLog);
@@ -4138,7 +4110,6 @@ TEST_P(cta_catalogue_CatalogueTest, noSpaceLeftOnTape) {
     ASSERT_EQ(capacityInBytes, tape.capacityInBytes);
     ASSERT_TRUE(disabledValue == tape.disabled);
     ASSERT_TRUE(fullValue == tape.full);
-    ASSERT_FALSE(tape.lbp);
     ASSERT_EQ(comment, tape.comment);
     ASSERT_FALSE(tape.labelLog);
     ASSERT_FALSE(tape.lastReadLog);
@@ -4228,7 +4199,6 @@ TEST_P(cta_catalogue_CatalogueTest, setTapeDisabled) {
     ASSERT_EQ(capacityInBytes, tape.capacityInBytes);
     ASSERT_TRUE(disabledValue == tape.disabled);
     ASSERT_TRUE(fullValue == tape.full);
-    ASSERT_FALSE(tape.lbp);
     ASSERT_EQ(comment, tape.comment);
     ASSERT_FALSE(tape.labelLog);
     ASSERT_FALSE(tape.lastReadLog);
@@ -4300,8 +4270,7 @@ TEST_P(cta_catalogue_CatalogueTest, getTapesForWriting) {
   m_catalogue->createTapePool(m_admin, tapePoolName, vo, 2, true, "Create tape pool");
   m_catalogue->createTape(m_admin, vid, mediaType, vendor, logicalLibraryName, tapePoolName, capacityInBytes,
    disabledValue, fullValue, comment);
-  const bool lbpIsOn = true;
-  m_catalogue->tapeLabelled(vid, "tape_drive", lbpIsOn);
+  m_catalogue->tapeLabelled(vid, "tape_drive");
 
   const std::list<catalogue::TapeForWriting> tapes = m_catalogue->getTapesForWriting(logicalLibraryName);
 
@@ -6386,7 +6355,6 @@ TEST_P(cta_catalogue_CatalogueTest, prepareToRetrieveFileUsingArchiveFileId) {
     ASSERT_EQ(capacityInBytes, tape.capacityInBytes);
     ASSERT_TRUE(disabledValue == tape.disabled);
     ASSERT_TRUE(fullValue == tape.full);
-    ASSERT_FALSE(tape.lbp);
     ASSERT_EQ(createTapeComment, tape.comment);
     ASSERT_FALSE(tape.labelLog);
     ASSERT_FALSE(tape.lastReadLog);
@@ -6412,7 +6380,6 @@ TEST_P(cta_catalogue_CatalogueTest, prepareToRetrieveFileUsingArchiveFileId) {
     ASSERT_EQ(capacityInBytes, tape.capacityInBytes);
     ASSERT_TRUE(disabledValue == tape.disabled);
     ASSERT_TRUE(fullValue == tape.full);
-    ASSERT_FALSE(tape.lbp);
     ASSERT_EQ(createTapeComment, tape.comment);
     ASSERT_FALSE(tape.labelLog);
     ASSERT_FALSE(tape.lastReadLog);
@@ -6454,7 +6421,6 @@ TEST_P(cta_catalogue_CatalogueTest, prepareToRetrieveFileUsingArchiveFileId) {
   file1Written.diskFilePath         = "/public_dir/public_file";
   file1Written.diskFileUser         = "public_disk_user";
   file1Written.diskFileGroup        = "public_disk_group";
-  file1Written.diskFileRecoveryBlob = "opaque_disk_file_recovery_contents";
   file1Written.size                 = archiveFileSize;
   file1Written.checksumType         = checksumType;
   file1Written.checksumValue        = checksumValue;
@@ -6481,7 +6447,6 @@ TEST_P(cta_catalogue_CatalogueTest, prepareToRetrieveFileUsingArchiveFileId) {
     ASSERT_EQ(file1Written.diskFilePath, archiveFile.diskFileInfo.path);
     ASSERT_EQ(file1Written.diskFileUser, archiveFile.diskFileInfo.owner);
     ASSERT_EQ(file1Written.diskFileGroup, archiveFile.diskFileInfo.group);
-    ASSERT_EQ(file1Written.diskFileRecoveryBlob, archiveFile.diskFileInfo.recoveryBlob);
 
     ASSERT_EQ(1, archiveFile.tapeFiles.size());
     auto copyNbToTapeFile1Itor = archiveFile.tapeFiles.find(1);
@@ -6506,7 +6471,6 @@ TEST_P(cta_catalogue_CatalogueTest, prepareToRetrieveFileUsingArchiveFileId) {
   file2Written.diskFilePath         = file1Written.diskFilePath;
   file2Written.diskFileUser         = file1Written.diskFileUser;
   file2Written.diskFileGroup        = file1Written.diskFileGroup;
-  file2Written.diskFileRecoveryBlob = file1Written.diskFileRecoveryBlob;
   file2Written.size                 = archiveFileSize;
   file2Written.checksumType         = checksumType;
   file2Written.checksumValue        = checksumValue;
@@ -6533,7 +6497,6 @@ TEST_P(cta_catalogue_CatalogueTest, prepareToRetrieveFileUsingArchiveFileId) {
     ASSERT_EQ(file2Written.diskFilePath, archiveFile.diskFileInfo.path);
     ASSERT_EQ(file2Written.diskFileUser, archiveFile.diskFileInfo.owner);
     ASSERT_EQ(file2Written.diskFileGroup, archiveFile.diskFileInfo.group);
-    ASSERT_EQ(file2Written.diskFileRecoveryBlob, archiveFile.diskFileInfo.recoveryBlob);
 
     ASSERT_EQ(2, archiveFile.tapeFiles.size());
 
@@ -6650,7 +6613,6 @@ TEST_P(cta_catalogue_CatalogueTest, prepareToRetrieveFileUsingArchiveFileId_disa
     ASSERT_EQ(capacityInBytes, tape.capacityInBytes);
     ASSERT_TRUE(disabledValue == tape.disabled);
     ASSERT_TRUE(fullValue == tape.full);
-    ASSERT_FALSE(tape.lbp);
     ASSERT_EQ(createTapeComment, tape.comment);
     ASSERT_FALSE(tape.labelLog);
     ASSERT_FALSE(tape.lastReadLog);
@@ -6676,7 +6638,6 @@ TEST_P(cta_catalogue_CatalogueTest, prepareToRetrieveFileUsingArchiveFileId_disa
     ASSERT_EQ(capacityInBytes, tape.capacityInBytes);
     ASSERT_TRUE(disabledValue == tape.disabled);
     ASSERT_TRUE(fullValue == tape.full);
-    ASSERT_FALSE(tape.lbp);
     ASSERT_EQ(createTapeComment, tape.comment);
     ASSERT_FALSE(tape.labelLog);
     ASSERT_FALSE(tape.lastReadLog);
@@ -6717,7 +6678,6 @@ TEST_P(cta_catalogue_CatalogueTest, prepareToRetrieveFileUsingArchiveFileId_disa
   file1Written.diskFilePath         = "/public_dir/public_file";
   file1Written.diskFileUser         = "public_disk_user";
   file1Written.diskFileGroup        = "public_disk_group";
-  file1Written.diskFileRecoveryBlob = "opaque_disk_file_recovery_contents";
   file1Written.size                 = archiveFileSize;
   file1Written.checksumType         = checksumType;
   file1Written.checksumValue        = checksumValue;
@@ -6744,7 +6704,6 @@ TEST_P(cta_catalogue_CatalogueTest, prepareToRetrieveFileUsingArchiveFileId_disa
     ASSERT_EQ(file1Written.diskFilePath, archiveFile.diskFileInfo.path);
     ASSERT_EQ(file1Written.diskFileUser, archiveFile.diskFileInfo.owner);
     ASSERT_EQ(file1Written.diskFileGroup, archiveFile.diskFileInfo.group);
-    ASSERT_EQ(file1Written.diskFileRecoveryBlob, archiveFile.diskFileInfo.recoveryBlob);
 
     ASSERT_EQ(1, archiveFile.tapeFiles.size());
     auto copyNbToTapeFile1Itor = archiveFile.tapeFiles.find(1);
@@ -6769,7 +6728,6 @@ TEST_P(cta_catalogue_CatalogueTest, prepareToRetrieveFileUsingArchiveFileId_disa
   file2Written.diskFilePath         = file1Written.diskFilePath;
   file2Written.diskFileUser         = file1Written.diskFileUser;
   file2Written.diskFileGroup        = file1Written.diskFileGroup;
-  file2Written.diskFileRecoveryBlob = file1Written.diskFileRecoveryBlob;
   file2Written.size                 = archiveFileSize;
   file2Written.checksumType         = checksumType;
   file2Written.checksumValue        = checksumValue;
@@ -6796,7 +6754,6 @@ TEST_P(cta_catalogue_CatalogueTest, prepareToRetrieveFileUsingArchiveFileId_disa
     ASSERT_EQ(file2Written.diskFilePath, archiveFile.diskFileInfo.path);
     ASSERT_EQ(file2Written.diskFileUser, archiveFile.diskFileInfo.owner);
     ASSERT_EQ(file2Written.diskFileGroup, archiveFile.diskFileInfo.group);
-    ASSERT_EQ(file2Written.diskFileRecoveryBlob, archiveFile.diskFileInfo.recoveryBlob);
 
     ASSERT_EQ(2, archiveFile.tapeFiles.size());
 
@@ -7202,7 +7159,6 @@ TEST_P(cta_catalogue_CatalogueTest, filesWrittenToTape_many_archive_files) {
       ASSERT_EQ(capacityInBytes, tape.capacityInBytes);
       ASSERT_TRUE(disabledValue == tape.disabled);
       ASSERT_TRUE(fullValue == tape.full);
-      ASSERT_FALSE(tape.lbp);
       ASSERT_EQ(comment, tape.comment);
       ASSERT_FALSE(tape.labelLog);
       ASSERT_FALSE(tape.lastReadLog);
@@ -7229,7 +7185,6 @@ TEST_P(cta_catalogue_CatalogueTest, filesWrittenToTape_many_archive_files) {
       ASSERT_EQ(capacityInBytes, tape.capacityInBytes);
       ASSERT_TRUE(disabledValue == tape.disabled);
       ASSERT_TRUE(fullValue == tape.full);
-      ASSERT_FALSE(tape.lbp);
       ASSERT_EQ(comment, tape.comment);
       ASSERT_FALSE(tape.labelLog);
       ASSERT_FALSE(tape.lastReadLog);
@@ -7276,7 +7231,6 @@ TEST_P(cta_catalogue_CatalogueTest, filesWrittenToTape_many_archive_files) {
     fileWritten.diskFilePath = diskFilePath.str();
     fileWritten.diskFileUser = "public_disk_user";
     fileWritten.diskFileGroup = "public_disk_group";
-    fileWritten.diskFileRecoveryBlob = "opaque_disk_file_recovery_contents";
     fileWritten.size = archiveFileSize;
     fileWritten.checksumType = checksumType;
     fileWritten.checksumValue = checksumValue;
@@ -7340,7 +7294,6 @@ TEST_P(cta_catalogue_CatalogueTest, filesWrittenToTape_many_archive_files) {
     fileWritten.diskFilePath = diskFilePath.str();
     fileWritten.diskFileUser = "public_disk_user";
     fileWritten.diskFileGroup = "public_disk_group";
-    fileWritten.diskFileRecoveryBlob = "opaque_disk_file_recovery_contents";
     fileWritten.size = archiveFileSize;
     fileWritten.checksumType = checksumType;
     fileWritten.checksumValue = checksumValue;
@@ -7437,7 +7390,6 @@ TEST_P(cta_catalogue_CatalogueTest, filesWrittenToTape_many_archive_files) {
       fileWritten1.diskFilePath = diskFilePath.str();
       fileWritten1.diskFileUser = "public_disk_user";
       fileWritten1.diskFileGroup = "public_disk_group";
-      fileWritten1.diskFileRecoveryBlob = "opaque_disk_file_recovery_contents";
       fileWritten1.size = archiveFileSize;
       fileWritten1.checksumType = checksumType;
       fileWritten1.checksumValue = checksumValue;
@@ -7461,7 +7413,6 @@ TEST_P(cta_catalogue_CatalogueTest, filesWrittenToTape_many_archive_files) {
       ASSERT_EQ(fileWritten1.diskFilePath, archiveFile.diskFileInfo.path);
       ASSERT_EQ(fileWritten1.diskFileUser, archiveFile.diskFileInfo.owner);
       ASSERT_EQ(fileWritten1.diskFileGroup, archiveFile.diskFileInfo.group);
-      ASSERT_EQ(fileWritten1.diskFileRecoveryBlob, archiveFile.diskFileInfo.recoveryBlob);
       ASSERT_EQ(fileWritten1.size, archiveFile.fileSize);
       ASSERT_EQ(fileWritten1.checksumType, archiveFile.checksumType);
       ASSERT_EQ(fileWritten1.checksumValue, archiveFile.checksumValue);
@@ -7517,7 +7468,6 @@ TEST_P(cta_catalogue_CatalogueTest, filesWrittenToTape_many_archive_files) {
       fileWritten1.diskFilePath = diskFilePath.str();
       fileWritten1.diskFileUser = "public_disk_user";
       fileWritten1.diskFileGroup = "public_disk_group";
-      fileWritten1.diskFileRecoveryBlob = "opaque_disk_file_recovery_contents";
       fileWritten1.size = archiveFileSize;
       fileWritten1.checksumType = checksumType;
       fileWritten1.checksumValue = checksumValue;
@@ -7541,7 +7491,6 @@ TEST_P(cta_catalogue_CatalogueTest, filesWrittenToTape_many_archive_files) {
       ASSERT_EQ(fileWritten1.diskFilePath, archiveFile.diskFileInfo.path);
       ASSERT_EQ(fileWritten1.diskFileUser, archiveFile.diskFileInfo.owner);
       ASSERT_EQ(fileWritten1.diskFileGroup, archiveFile.diskFileInfo.group);
-      ASSERT_EQ(fileWritten1.diskFileRecoveryBlob, archiveFile.diskFileInfo.recoveryBlob);
       ASSERT_EQ(fileWritten1.size, archiveFile.fileSize);
       ASSERT_EQ(fileWritten1.checksumType, archiveFile.checksumType);
       ASSERT_EQ(fileWritten1.checksumValue, archiveFile.checksumValue);
@@ -7599,7 +7548,6 @@ TEST_P(cta_catalogue_CatalogueTest, filesWrittenToTape_many_archive_files) {
       fileWritten.diskFilePath = diskFilePath.str();
       fileWritten.diskFileUser = "public_disk_user";
       fileWritten.diskFileGroup = "public_disk_group";
-      fileWritten.diskFileRecoveryBlob = "opaque_disk_file_recovery_contents";
       fileWritten.size = archiveFileSize;
       fileWritten.checksumType = checksumType;
       fileWritten.checksumValue = checksumValue;
@@ -7619,7 +7567,6 @@ TEST_P(cta_catalogue_CatalogueTest, filesWrittenToTape_many_archive_files) {
       ASSERT_EQ(fileWritten.diskFilePath, archiveFile.diskFileInfo.path);
       ASSERT_EQ(fileWritten.diskFileUser, archiveFile.diskFileInfo.owner);
       ASSERT_EQ(fileWritten.diskFileGroup, archiveFile.diskFileInfo.group);
-      ASSERT_EQ(fileWritten.diskFileRecoveryBlob, archiveFile.diskFileInfo.recoveryBlob);
       ASSERT_EQ(fileWritten.size, archiveFile.fileSize);
       ASSERT_EQ(fileWritten.checksumType, archiveFile.checksumType);
       ASSERT_EQ(fileWritten.checksumValue, archiveFile.checksumValue);
@@ -7665,7 +7612,6 @@ TEST_P(cta_catalogue_CatalogueTest, filesWrittenToTape_many_archive_files) {
       fileWritten.diskFilePath = diskFilePath.str();
       fileWritten.diskFileUser = "public_disk_user";
       fileWritten.diskFileGroup = "public_disk_group";
-      fileWritten.diskFileRecoveryBlob = "opaque_disk_file_recovery_contents";
       fileWritten.size = archiveFileSize;
       fileWritten.checksumType = checksumType;
       fileWritten.checksumValue = checksumValue;
@@ -7685,7 +7631,6 @@ TEST_P(cta_catalogue_CatalogueTest, filesWrittenToTape_many_archive_files) {
       ASSERT_EQ(fileWritten.diskFilePath, archiveFile.diskFileInfo.path);
       ASSERT_EQ(fileWritten.diskFileUser, archiveFile.diskFileInfo.owner);
       ASSERT_EQ(fileWritten.diskFileGroup, archiveFile.diskFileInfo.group);
-      ASSERT_EQ(fileWritten.diskFileRecoveryBlob, archiveFile.diskFileInfo.recoveryBlob);
       ASSERT_EQ(fileWritten.size, archiveFile.fileSize);
       ASSERT_EQ(fileWritten.checksumType, archiveFile.checksumType);
       ASSERT_EQ(fileWritten.checksumValue, archiveFile.checksumValue);
@@ -7731,7 +7676,6 @@ TEST_P(cta_catalogue_CatalogueTest, filesWrittenToTape_many_archive_files) {
       fileWritten.diskFilePath = diskFilePath.str();
       fileWritten.diskFileUser = "public_disk_user";
       fileWritten.diskFileGroup = "public_disk_group";
-      fileWritten.diskFileRecoveryBlob = "opaque_disk_file_recovery_contents";
       fileWritten.size = archiveFileSize;
       fileWritten.checksumType = checksumType;
       fileWritten.checksumValue = checksumValue;
@@ -7751,7 +7695,983 @@ TEST_P(cta_catalogue_CatalogueTest, filesWrittenToTape_many_archive_files) {
       ASSERT_EQ(fileWritten.diskFilePath, archiveFile.diskFileInfo.path);
       ASSERT_EQ(fileWritten.diskFileUser, archiveFile.diskFileInfo.owner);
       ASSERT_EQ(fileWritten.diskFileGroup, archiveFile.diskFileInfo.group);
-      ASSERT_EQ(fileWritten.diskFileRecoveryBlob, archiveFile.diskFileInfo.recoveryBlob);
+      ASSERT_EQ(fileWritten.size, archiveFile.fileSize);
+      ASSERT_EQ(fileWritten.checksumType, archiveFile.checksumType);
+      ASSERT_EQ(fileWritten.checksumValue, archiveFile.checksumValue);
+      ASSERT_EQ(fileWritten.storageClassName, archiveFile.storageClass);
+
+      // There is only one tape copy because repack only want the tape file on a
+      // single tape
+      ASSERT_EQ(1, archiveFile.tapeFiles.size());
+
+      {
+        const auto it = archiveFile.tapeFiles.find(copyNb);
+        ASSERT_NE(archiveFile.tapeFiles.end(), it);
+        ASSERT_EQ(fileWritten.vid, it->second.vid);
+        ASSERT_EQ(fileWritten.fSeq, it->second.fSeq);
+        ASSERT_EQ(fileWritten.blockId, it->second.blockId);
+        ASSERT_EQ(fileWritten.compressedSize, it->second.compressedSize);
+        ASSERT_EQ(fileWritten.checksumType, it->second.checksumType);
+        ASSERT_EQ(fileWritten.checksumValue, it->second.checksumValue);
+        ASSERT_EQ(fileWritten.copyNb, it->second.copyNb);
+        ASSERT_EQ(fileWritten.copyNb, it->first);
+      }
+    }
+  }
+
+  {
+    catalogue::TapeFileSearchCriteria searchCriteria;
+    searchCriteria.archiveFileId = 10;
+    auto archiveFileItor = m_catalogue->getArchiveFilesItor(searchCriteria);
+    const auto m = archiveFileItorToMap(archiveFileItor);
+    ASSERT_EQ(1, m.size());
+    ASSERT_EQ(10, m.begin()->first);
+    ASSERT_EQ(10, m.begin()->second.archiveFileID);
+
+    const common::dataStructures::ArchiveFileSummary summary = m_catalogue->getTapeFileSummary(searchCriteria);
+    ASSERT_EQ(storageClass.nbCopies * archiveFileSize, summary.totalBytes);
+    ASSERT_EQ(storageClass.nbCopies * compressedFileSize, summary.totalCompressedBytes);
+    ASSERT_EQ(storageClass.nbCopies, summary.totalFiles);
+  }
+
+  {
+    catalogue::TapeFileSearchCriteria searchCriteria;
+    searchCriteria.diskInstance = storageClass.diskInstance;
+    auto archiveFileItor = m_catalogue->getArchiveFilesItor(searchCriteria);
+    const auto m = archiveFileItorToMap(archiveFileItor);
+    ASSERT_EQ(nbArchiveFiles, m.size());
+
+    const common::dataStructures::ArchiveFileSummary summary = m_catalogue->getTapeFileSummary(searchCriteria);
+    ASSERT_EQ(nbArchiveFiles * storageClass.nbCopies * archiveFileSize, summary.totalBytes);
+    ASSERT_EQ(nbArchiveFiles * storageClass.nbCopies * compressedFileSize, summary.totalCompressedBytes);
+    ASSERT_EQ(nbArchiveFiles * storageClass.nbCopies, summary.totalFiles);
+  }
+
+  {
+    catalogue::TapeFileSearchCriteria searchCriteria;
+    searchCriteria.diskInstance = storageClass.diskInstance;
+    searchCriteria.diskFileId = "12345687";
+    auto archiveFileItor = m_catalogue->getArchiveFilesItor(searchCriteria);
+    const auto m = archiveFileItorToMap(archiveFileItor);
+    ASSERT_EQ(1, m.size());
+    ASSERT_EQ("12345687", m.begin()->second.diskFileId);
+
+    const common::dataStructures::ArchiveFileSummary summary = m_catalogue->getTapeFileSummary(searchCriteria);
+    ASSERT_EQ(storageClass.nbCopies * archiveFileSize, summary.totalBytes);
+    ASSERT_EQ(storageClass.nbCopies * compressedFileSize, summary.totalCompressedBytes);
+    ASSERT_EQ(storageClass.nbCopies, summary.totalFiles);
+  }
+
+  {
+    catalogue::TapeFileSearchCriteria searchCriteria;
+    searchCriteria.diskInstance = storageClass.diskInstance;
+    searchCriteria.diskFilePath = "/public_dir/public_file_10";
+    auto archiveFileItor = m_catalogue->getArchiveFilesItor(searchCriteria);
+    const auto m = archiveFileItorToMap(archiveFileItor);
+    ASSERT_EQ(1, m.size());
+    ASSERT_EQ("/public_dir/public_file_10", m.begin()->second.diskFileInfo.path);
+
+    const common::dataStructures::ArchiveFileSummary summary = m_catalogue->getTapeFileSummary(searchCriteria);
+    ASSERT_EQ(storageClass.nbCopies * archiveFileSize, summary.totalBytes);
+    ASSERT_EQ(storageClass.nbCopies * compressedFileSize, summary.totalCompressedBytes);
+    ASSERT_EQ(storageClass.nbCopies, summary.totalFiles);
+  }
+
+  {
+    catalogue::TapeFileSearchCriteria searchCriteria;
+    searchCriteria.diskInstance = storageClass.diskInstance;
+    searchCriteria.diskFileUser = "public_disk_user";
+    auto archiveFileItor = m_catalogue->getArchiveFilesItor(searchCriteria);
+    const auto m = archiveFileItorToMap(archiveFileItor);
+    ASSERT_EQ(nbArchiveFiles, m.size());
+
+    const common::dataStructures::ArchiveFileSummary summary = m_catalogue->getTapeFileSummary(searchCriteria);
+    ASSERT_EQ(nbArchiveFiles * storageClass.nbCopies * archiveFileSize, summary.totalBytes);
+    ASSERT_EQ(nbArchiveFiles * storageClass.nbCopies * compressedFileSize, summary.totalCompressedBytes);
+    ASSERT_EQ(nbArchiveFiles * storageClass.nbCopies, summary.totalFiles);
+  }
+
+  {
+    catalogue::TapeFileSearchCriteria searchCriteria;
+    searchCriteria.diskInstance = storageClass.diskInstance;
+    searchCriteria.diskFileGroup = "public_disk_group";
+    auto archiveFileItor = m_catalogue->getArchiveFilesItor(searchCriteria);
+    const auto m = archiveFileItorToMap(archiveFileItor);
+    ASSERT_EQ(nbArchiveFiles, m.size());
+
+    const common::dataStructures::ArchiveFileSummary summary = m_catalogue->getTapeFileSummary(searchCriteria);
+    ASSERT_EQ(nbArchiveFiles * storageClass.nbCopies * archiveFileSize, summary.totalBytes);
+    ASSERT_EQ(nbArchiveFiles * storageClass.nbCopies * compressedFileSize, summary.totalCompressedBytes);
+    ASSERT_EQ(nbArchiveFiles * storageClass.nbCopies, summary.totalFiles);
+  }
+
+  {
+    catalogue::TapeFileSearchCriteria searchCriteria;
+    searchCriteria.diskInstance = storageClass.diskInstance;
+    searchCriteria.storageClass = storageClass.name;
+    auto archiveFileItor = m_catalogue->getArchiveFilesItor(searchCriteria);
+    const auto m = archiveFileItorToMap(archiveFileItor);
+    ASSERT_EQ(nbArchiveFiles, m.size());
+
+    const common::dataStructures::ArchiveFileSummary summary = m_catalogue->getTapeFileSummary(searchCriteria);
+    ASSERT_EQ(nbArchiveFiles * storageClass.nbCopies * archiveFileSize, summary.totalBytes);
+    ASSERT_EQ(nbArchiveFiles * storageClass.nbCopies * compressedFileSize, summary.totalCompressedBytes);
+    ASSERT_EQ(nbArchiveFiles * storageClass.nbCopies, summary.totalFiles);
+  }
+
+  {
+    catalogue::TapeFileSearchCriteria searchCriteria;
+    auto archiveFileItor = m_catalogue->getArchiveFilesItor(searchCriteria);
+    const auto m = archiveFileItorToMap(archiveFileItor);
+    ASSERT_EQ(nbArchiveFiles, m.size());
+
+    const common::dataStructures::ArchiveFileSummary summary = m_catalogue->getTapeFileSummary(searchCriteria);
+    ASSERT_EQ(nbArchiveFiles * storageClass.nbCopies * archiveFileSize, summary.totalBytes);
+    ASSERT_EQ(nbArchiveFiles * storageClass.nbCopies * compressedFileSize, summary.totalCompressedBytes);
+    ASSERT_EQ(nbArchiveFiles * storageClass.nbCopies, summary.totalFiles);
+  }
+
+  {
+    catalogue::TapeFileSearchCriteria searchCriteria;
+    searchCriteria.vid = vid1;
+    auto archiveFileItor = m_catalogue->getArchiveFilesItor(searchCriteria);
+    const auto m = archiveFileItorToMap(archiveFileItor);
+    ASSERT_EQ(nbArchiveFiles, m.size());
+
+    const common::dataStructures::ArchiveFileSummary summary = m_catalogue->getTapeFileSummary(searchCriteria);
+    ASSERT_EQ(nbArchiveFiles * archiveFileSize, summary.totalBytes);
+    ASSERT_EQ(nbArchiveFiles * compressedFileSize, summary.totalCompressedBytes);
+    ASSERT_EQ(nbArchiveFiles, summary.totalFiles);
+  }
+
+  {
+    catalogue::TapeFileSearchCriteria searchCriteria;
+    searchCriteria.tapeFileCopyNb = 1;
+    auto archiveFileItor = m_catalogue->getArchiveFilesItor(searchCriteria);
+    const auto m = archiveFileItorToMap(archiveFileItor);
+    ASSERT_EQ(nbArchiveFiles, m.size());
+
+    const common::dataStructures::ArchiveFileSummary summary = m_catalogue->getTapeFileSummary(searchCriteria);
+    ASSERT_EQ(nbArchiveFiles * archiveFileSize, summary.totalBytes);
+    ASSERT_EQ(nbArchiveFiles * compressedFileSize, summary.totalCompressedBytes);
+    ASSERT_EQ(nbArchiveFiles, summary.totalFiles);
+  }
+
+  {
+    catalogue::TapeFileSearchCriteria searchCriteria;
+    searchCriteria.tapePool = tapePoolName1;
+    auto archiveFileItor = m_catalogue->getArchiveFilesItor(searchCriteria);
+    const auto m = archiveFileItorToMap(archiveFileItor);
+    ASSERT_EQ(nbArchiveFiles, m.size());
+
+    const common::dataStructures::ArchiveFileSummary summary = m_catalogue->getTapeFileSummary(searchCriteria);
+    ASSERT_EQ(nbArchiveFiles * archiveFileSize, summary.totalBytes);
+    ASSERT_EQ(nbArchiveFiles * compressedFileSize, summary.totalCompressedBytes);
+    ASSERT_EQ(nbArchiveFiles, summary.totalFiles);
+  }
+
+  {
+    catalogue::TapeFileSearchCriteria searchCriteria;
+    searchCriteria.tapePool = tapePoolName2;
+    auto archiveFileItor = m_catalogue->getArchiveFilesItor(searchCriteria);
+    const auto m = archiveFileItorToMap(archiveFileItor);
+    ASSERT_EQ(nbArchiveFiles, m.size());
+
+    const common::dataStructures::ArchiveFileSummary summary = m_catalogue->getTapeFileSummary(searchCriteria);
+    ASSERT_EQ(nbArchiveFiles * archiveFileSize, summary.totalBytes);
+    ASSERT_EQ(nbArchiveFiles * compressedFileSize, summary.totalCompressedBytes);
+    ASSERT_EQ(nbArchiveFiles, summary.totalFiles);
+  }
+
+  {
+    catalogue::TapeFileSearchCriteria searchCriteria;
+    searchCriteria.archiveFileId = nbArchiveFiles + 1234;
+    ASSERT_THROW(m_catalogue->getArchiveFilesItor(searchCriteria), exception::UserError);
+
+    const common::dataStructures::ArchiveFileSummary summary = m_catalogue->getTapeFileSummary(searchCriteria);
+    ASSERT_EQ(0, summary.totalBytes);
+    ASSERT_EQ(0, summary.totalCompressedBytes);
+    ASSERT_EQ(0, summary.totalFiles);
+  }
+}
+
+TEST_P(cta_catalogue_CatalogueTest, DISABLED_concurrent_filesWrittenToTape_many_archive_files) {
+  using namespace cta;
+
+  std::unique_ptr<cta::catalogue::Catalogue> catalogue2;
+
+  try {
+    catalogue::CatalogueFactory *const *const catalogueFactoryPtrPtr = GetParam();
+
+    if(nullptr == catalogueFactoryPtrPtr) {
+      throw exception::Exception("Global pointer to the catalogue factory pointer for unit-tests in null");
+    }
+
+    if(nullptr == (*catalogueFactoryPtrPtr)) {
+      throw exception::Exception("Global pointer to the catalogue factoryfor unit-tests in null");
+    }
+
+    catalogue2 = (*catalogueFactoryPtrPtr)->create();
+
+  } catch(exception::Exception &ex) {
+    throw exception::Exception(std::string(__FUNCTION__) + " failed: " + ex.getMessage().str());
+  }
+
+  class Barrier {
+  public:
+    Barrier(unsigned int count) : m_exited(false) {
+      pthread_barrier_init(&m_barrier, nullptr, count);
+    }
+    ~Barrier() {
+      pthread_barrier_destroy(&m_barrier);
+    }
+    void wait() {
+      pthread_barrier_wait(&m_barrier);
+    }
+    void exit() {
+      threading::MutexLocker lock(m_mtx);
+      m_exited = true;
+    }
+
+    bool hasExited() {
+      threading::MutexLocker lock(m_mtx);
+      return m_exited;
+    }
+
+    threading::Mutex m_mtx;
+    pthread_barrier_t m_barrier;
+    bool m_exited;
+  };
+
+  class filesWrittenThread : public threading::Thread {
+  public:
+    filesWrittenThread(
+        cta::catalogue::Catalogue *const cat,
+        Barrier &barrier,
+        const uint64_t nbArchiveFiles,
+        const uint64_t batchSize,
+        const common::dataStructures::StorageClass &storageClass,
+        const uint64_t &archiveFileSize,
+        const std::string &checksumType,
+        const std::string &checksumValue,
+        const std::string &vid,
+        const uint64_t &compressedFileSize,
+        const uint64_t &copyNb,
+        const std::string &tapeDrive) :
+          m_cat(cat), m_barrier(barrier), m_nbArchiveFiles(nbArchiveFiles), m_batchSize(batchSize), m_storageClass(storageClass), m_archiveFileSize(archiveFileSize),
+          m_checksumType(checksumType), m_checksumValue(checksumValue), m_vid(vid), m_compressedFileSize(compressedFileSize), m_copyNb(copyNb), m_tapeDrive(tapeDrive) { }
+
+    void run() override {
+      for(uint64_t batch=0;batch< 1 + (m_nbArchiveFiles-1)/m_batchSize;++batch) {
+        uint64_t bs = m_nbArchiveFiles - (m_batchSize*batch);
+        if (bs> m_batchSize) {
+          bs = m_batchSize;
+        }
+        std::set<catalogue::TapeItemWrittenPointer> tapeFilesWritten;
+        for(uint64_t i= 0 ; i < bs; i++) {
+          // calculate this file's archive_file_id and fseq numbers
+          const uint64_t fn_afid = 1 + m_batchSize*batch + i;
+          const uint64_t fn_seq = (m_copyNb == 1) ? fn_afid : 1 + m_batchSize*batch + (bs-i-1);
+          std::ostringstream diskFileId;
+          diskFileId << (12345677 + fn_afid);
+          std::ostringstream diskFilePath;
+          diskFilePath << "/public_dir/public_file_" << fn_afid;
+
+          // Tape this batch to tape
+          auto fileWrittenUP=cta::make_unique<cta::catalogue::TapeFileWritten>();
+          auto & fileWritten = *fileWrittenUP;
+          fileWritten.archiveFileId = fn_afid;
+          fileWritten.diskInstance = m_storageClass.diskInstance;
+          fileWritten.diskFileId = diskFileId.str();
+          fileWritten.diskFilePath = diskFilePath.str();
+          fileWritten.diskFileUser = "public_disk_user";
+          fileWritten.diskFileGroup = "public_disk_group";
+          fileWritten.size = m_archiveFileSize;
+          fileWritten.checksumType = m_checksumType;
+          fileWritten.checksumValue = m_checksumValue;
+          fileWritten.storageClassName = m_storageClass.name;
+          fileWritten.vid = m_vid;
+          fileWritten.fSeq = fn_seq;
+          fileWritten.blockId = fn_seq * 100;
+          fileWritten.compressedSize = m_compressedFileSize;
+          fileWritten.copyNb = m_copyNb;
+          fileWritten.tapeDrive = m_tapeDrive;
+          tapeFilesWritten.emplace(fileWrittenUP.release());
+        }
+        m_barrier.wait();
+        try {
+          m_cat->filesWrittenToTape(tapeFilesWritten);
+        } catch(std::exception &) {
+          m_barrier.exit();
+          m_barrier.wait();
+          throw;
+        }
+        m_barrier.wait();
+        if (m_barrier.hasExited()) {
+          return;
+        }
+      }
+    }
+
+    cta::catalogue::Catalogue *const m_cat;
+    Barrier &m_barrier;
+    const uint64_t m_nbArchiveFiles;
+    const uint64_t m_batchSize;
+    const common::dataStructures::StorageClass m_storageClass;
+    const uint64_t m_archiveFileSize;
+    const std::string m_checksumType;
+    const std::string m_checksumValue;
+    const std::string m_vid;
+    const uint64_t m_compressedFileSize;
+    const uint64_t m_copyNb;
+    const std::string m_tapeDrive;
+  };
+
+  class filesWrittenRunner {
+  public:
+    filesWrittenRunner(filesWrittenThread &th) : m_th(th), m_waited(false) { m_th.start(); }
+    ~filesWrittenRunner() {
+      if (!m_waited) {
+        try {
+          m_th.wait();
+        } catch(...) {
+          // nothing
+        }
+      }
+    }
+    void wait() {
+      m_waited = true;
+      m_th.wait();
+    }
+    filesWrittenThread &m_th;
+    bool m_waited;
+  };
+
+  const std::string vid1 = "VID123";
+  const std::string vid2 = "VID456";
+  const std::string mediaType = "media_type";
+  const std::string vendor = "vendor";
+  const std::string logicalLibraryName = "logical_library_name";
+  const std::string tapePoolName1 = "tape_pool_name_1";
+  const std::string tapePoolName2 = "tape_pool_name_2";
+  const std::string vo = "vo";
+  const uint64_t capacityInBytes = (uint64_t)10 * 1000 * 1000 * 1000 * 1000;
+  const bool disabledValue = true;
+  const bool fullValue = false;
+  const std::string comment = "Create tape";
+
+  m_catalogue->createLogicalLibrary(m_admin, logicalLibraryName, "Create logical library");
+
+  m_catalogue->createTapePool(m_admin, tapePoolName1, vo, 1, true, "Create tape pool");
+  {
+    const auto pools = m_catalogue->getTapePools();
+    ASSERT_EQ(1, pools.size());
+
+    auto tapePoolMap = tapePoolListToMap(pools);
+    auto tapePoolMapItor = tapePoolMap.find(tapePoolName1);
+    ASSERT_NE(tapePoolMapItor, tapePoolMap.end());
+    const auto &pool = tapePoolMapItor->second;
+
+    ASSERT_EQ(tapePoolName1, pool.name);
+    ASSERT_EQ(0, pool.nbTapes);
+    ASSERT_EQ(0, pool.capacityBytes);
+    ASSERT_EQ(0, pool.dataBytes);
+    ASSERT_EQ(0, pool.nbPhysicalFiles);
+  }
+
+  m_catalogue->createTapePool(m_admin, tapePoolName2, vo, 1, true, "Create tape pool");
+  {
+    const auto pools = m_catalogue->getTapePools();
+    ASSERT_EQ(2, pools.size());
+
+    auto tapePoolMap = tapePoolListToMap(pools);
+    auto tapePoolMapItor = tapePoolMap.find(tapePoolName2);
+    ASSERT_NE(tapePoolMapItor, tapePoolMap.end());
+    const auto &pool = tapePoolMapItor->second;
+
+    ASSERT_EQ(tapePoolName2, pool.name);
+    ASSERT_EQ(0, pool.nbTapes);
+    ASSERT_EQ(0, pool.capacityBytes);
+    ASSERT_EQ(0, pool.dataBytes);
+    ASSERT_EQ(0, pool.nbPhysicalFiles);
+  }
+
+  m_catalogue->createTape(m_admin, vid1, mediaType, vendor, logicalLibraryName, tapePoolName1, capacityInBytes,
+    disabledValue, fullValue, comment);
+  {
+    const auto pools = m_catalogue->getTapePools();
+    ASSERT_EQ(2, pools.size());
+
+    auto tapePoolMap = tapePoolListToMap(pools);
+    auto tapePoolMapItor = tapePoolMap.find(tapePoolName1);
+    ASSERT_NE(tapePoolMapItor, tapePoolMap.end());
+    const auto &pool = tapePoolMapItor->second;
+
+    ASSERT_EQ(tapePoolName1, pool.name);
+    ASSERT_EQ(1, pool.nbTapes);
+    ASSERT_EQ(capacityInBytes, pool.capacityBytes);
+    ASSERT_EQ(0, pool.dataBytes);
+    ASSERT_EQ(0, pool.nbPhysicalFiles);
+  }
+
+  m_catalogue->createTape(m_admin, vid2, mediaType, vendor, logicalLibraryName, tapePoolName2, capacityInBytes,
+    disabledValue, fullValue, comment);
+  {
+    const auto pools = m_catalogue->getTapePools();
+    ASSERT_EQ(2, pools.size());
+
+    auto tapePoolMap = tapePoolListToMap(pools);
+    auto tapePoolMapItor = tapePoolMap.find(tapePoolName2);
+    ASSERT_NE(tapePoolMapItor, tapePoolMap.end());
+    const auto &pool = tapePoolMapItor->second;
+
+    ASSERT_EQ(tapePoolName2, pool.name);
+    ASSERT_EQ(1, pool.nbTapes);
+    ASSERT_EQ(capacityInBytes, pool.capacityBytes);
+    ASSERT_EQ(0, pool.dataBytes);
+    ASSERT_EQ(0, pool.nbPhysicalFiles);
+  }
+
+  {
+    const auto tapes = m_catalogue->getTapes();
+
+    ASSERT_EQ(2, tapes.size());
+
+    const auto vidToTape = tapeListToMap(tapes);
+    {
+      auto it = vidToTape.find(vid1);
+      ASSERT_NE(vidToTape.end(), it);
+      const common::dataStructures::Tape &tape = it->second;
+      ASSERT_EQ(vid1, tape.vid);
+      ASSERT_EQ(mediaType, tape.mediaType);
+      ASSERT_EQ(vendor, tape.vendor);
+      ASSERT_EQ(logicalLibraryName, tape.logicalLibraryName);
+      ASSERT_EQ(tapePoolName1, tape.tapePoolName);
+      ASSERT_EQ(vo, tape.vo);
+      ASSERT_EQ(capacityInBytes, tape.capacityInBytes);
+      ASSERT_TRUE(disabledValue == tape.disabled);
+      ASSERT_TRUE(fullValue == tape.full);
+      ASSERT_EQ(comment, tape.comment);
+      ASSERT_FALSE(tape.labelLog);
+      ASSERT_FALSE(tape.lastReadLog);
+      ASSERT_FALSE(tape.lastWriteLog);
+
+      const common::dataStructures::EntryLog creationLog = tape.creationLog;
+      ASSERT_EQ(m_admin.username, creationLog.username);
+      ASSERT_EQ(m_admin.host, creationLog.host);
+
+      const common::dataStructures::EntryLog lastModificationLog =
+        tape.lastModificationLog;
+      ASSERT_EQ(creationLog, lastModificationLog);
+    }
+    {
+      auto it = vidToTape.find(vid2);
+      ASSERT_NE(vidToTape.end(), it);
+      const auto &tape = it->second;
+      ASSERT_EQ(vid2, tape.vid);
+      ASSERT_EQ(mediaType, tape.mediaType);
+      ASSERT_EQ(vendor, tape.vendor);
+      ASSERT_EQ(logicalLibraryName, tape.logicalLibraryName);
+      ASSERT_EQ(tapePoolName2, tape.tapePoolName);
+      ASSERT_EQ(vo, tape.vo);
+      ASSERT_EQ(capacityInBytes, tape.capacityInBytes);
+      ASSERT_TRUE(disabledValue == tape.disabled);
+      ASSERT_TRUE(fullValue == tape.full);
+      ASSERT_EQ(comment, tape.comment);
+      ASSERT_FALSE(tape.labelLog);
+      ASSERT_FALSE(tape.lastReadLog);
+      ASSERT_FALSE(tape.lastWriteLog);
+
+      const auto creationLog = tape.creationLog;
+      ASSERT_EQ(m_admin.username, creationLog.username);
+      ASSERT_EQ(m_admin.host, creationLog.host);
+
+      const auto lastModificationLog = tape.lastModificationLog;
+      ASSERT_EQ(creationLog, lastModificationLog);
+    }
+  }
+
+  common::dataStructures::StorageClass storageClass;
+  storageClass.diskInstance = "disk_instance";
+  storageClass.name = "storage_class";
+  storageClass.nbCopies = 2;
+  storageClass.comment = "Create storage class";
+  m_catalogue->createStorageClass(m_admin, storageClass);
+
+  const std::string checksumType = "checksum_type";
+  const std::string checksumValue = "checksum_value";
+  const std::string tapeDrive1 = "tape_drive1";
+  const std::string tapeDrive2 = "tape_drive2";
+
+  ASSERT_FALSE(m_catalogue->getArchiveFilesItor().hasMore());
+  const uint64_t nbArchiveFiles = 200; // Must be a multiple of batchsize for this test
+  const uint64_t archiveFileSize = 2 * 1000 * 1000 * 1000;
+  const uint64_t compressedFileSize = archiveFileSize;
+
+  const uint64_t batchsize = 20;
+
+  {
+    Barrier barrier(2);
+    filesWrittenThread a(m_catalogue.get(), barrier, nbArchiveFiles, batchsize, storageClass, archiveFileSize, checksumType, checksumValue, vid1, compressedFileSize, 1, tapeDrive1);
+    filesWrittenThread b(catalogue2.get(), barrier, nbArchiveFiles, batchsize, storageClass, archiveFileSize, checksumType, checksumValue, vid2, compressedFileSize, 2, tapeDrive2);
+
+    filesWrittenRunner r1(a);
+    filesWrittenRunner r2(b);
+    r1.wait();
+    r2.wait();
+  }
+
+  {
+    const auto pools = m_catalogue->getTapePools();
+    ASSERT_EQ(2, pools.size());
+
+    const auto tapePoolMap = tapePoolListToMap(pools);
+    auto tapePoolMapItor = tapePoolMap.find(tapePoolName1);
+    ASSERT_NE(tapePoolMapItor, tapePoolMap.end());
+    const auto &pool = tapePoolMapItor->second;
+
+    ASSERT_EQ(tapePoolName1, pool.name);
+    ASSERT_EQ(1, pool.nbTapes);
+    ASSERT_EQ(capacityInBytes, pool.capacityBytes);
+    ASSERT_EQ(nbArchiveFiles * compressedFileSize, pool.dataBytes);
+    ASSERT_EQ(nbArchiveFiles, pool.nbPhysicalFiles);
+  }
+
+  {
+    const std::list<common::dataStructures::Tape> tapes = m_catalogue->getTapes();
+    const std::map<std::string, common::dataStructures::Tape> vidToTape = tapeListToMap(tapes);
+    ASSERT_EQ(2, tapes.size());
+    {
+      auto it = vidToTape.find(vid1);
+      ASSERT_NE(vidToTape.end(), it);
+      ASSERT_EQ(vid1, it->second.vid);
+      ASSERT_EQ(nbArchiveFiles, it->second.lastFSeq);
+    }
+    {
+      auto it = vidToTape.find(vid2);
+      ASSERT_NE(vidToTape.end(), it);
+      ASSERT_EQ(vid2, it->second.vid);
+      ASSERT_EQ(nbArchiveFiles, it->second.lastFSeq);
+    }
+  }
+
+  {
+    const auto pools = m_catalogue->getTapePools();
+    ASSERT_EQ(2, pools.size());
+
+    const auto tapePoolMap = tapePoolListToMap(pools);
+    auto tapePoolMapItor = tapePoolMap.find(tapePoolName2);
+    ASSERT_NE(tapePoolMapItor, tapePoolMap.end());
+    const auto &pool = tapePoolMapItor->second;
+
+    ASSERT_EQ(tapePoolName2, pool.name);
+    ASSERT_EQ(1, pool.nbTapes);
+    ASSERT_EQ(capacityInBytes, pool.capacityBytes);
+    ASSERT_EQ(nbArchiveFiles * compressedFileSize, pool.dataBytes);
+    ASSERT_EQ(nbArchiveFiles, pool.nbPhysicalFiles);
+  }
+
+  {
+    const std::list<common::dataStructures::Tape> tapes = m_catalogue->getTapes();
+    const std::map<std::string, common::dataStructures::Tape> vidToTape = tapeListToMap(tapes);
+    ASSERT_EQ(2, tapes.size());
+    {
+      auto it = vidToTape.find(vid1);
+      ASSERT_NE(vidToTape.end(), it);
+      ASSERT_EQ(vid1, it->second.vid);
+      ASSERT_EQ(nbArchiveFiles, it->second.lastFSeq);
+    }
+    {
+      auto it = vidToTape.find(vid2);
+      ASSERT_NE(vidToTape.end(), it);
+      ASSERT_EQ(vid2, it->second.vid);
+      ASSERT_EQ(nbArchiveFiles, it->second.lastFSeq);
+    }
+  }
+
+  {
+    catalogue::TapeFileSearchCriteria searchCriteria;
+    searchCriteria.archiveFileId = 1;
+    searchCriteria.diskInstance = storageClass.diskInstance;
+    searchCriteria.diskFileId = std::to_string(12345678);
+    searchCriteria.diskFilePath = "/public_dir/public_file_1";
+    searchCriteria.diskFileUser = "public_disk_user";
+    searchCriteria.diskFileGroup = "public_disk_group";
+    searchCriteria.storageClass = storageClass.name;
+    searchCriteria.vid = vid1;
+    searchCriteria.tapeFileCopyNb = 1;
+    searchCriteria.tapePool = tapePoolName1;
+
+    auto archiveFileItor = m_catalogue->getArchiveFilesItor(searchCriteria);
+    std::map<uint64_t, common::dataStructures::ArchiveFile> m = archiveFileItorToMap(archiveFileItor);
+    ASSERT_EQ(1, m.size());
+
+    const auto idAndFile = m.find(1);
+    ASSERT_FALSE(m.end() == idAndFile);
+    const common::dataStructures::ArchiveFile archiveFile = idAndFile->second;
+    ASSERT_EQ(searchCriteria.archiveFileId, archiveFile.archiveFileID);
+    ASSERT_EQ(searchCriteria.diskInstance, archiveFile.diskInstance);
+    ASSERT_EQ(searchCriteria.diskFileId, archiveFile.diskFileId);
+    ASSERT_EQ(searchCriteria.diskFilePath, archiveFile.diskFileInfo.path);
+    ASSERT_EQ(searchCriteria.diskFileUser, archiveFile.diskFileInfo.owner);
+    ASSERT_EQ(searchCriteria.diskFileGroup, archiveFile.diskFileInfo.group);
+    ASSERT_EQ(searchCriteria.storageClass, archiveFile.storageClass);
+    ASSERT_EQ(1, archiveFile.tapeFiles.size());
+    ASSERT_EQ(searchCriteria.vid, archiveFile.tapeFiles.begin()->second.vid);
+  }
+
+  auto afidToSeq = [](const uint64_t l_nbTot, const uint64_t l_batchsize, const uint64_t l_afid, uint64_t &l_seq1, uint64_t &l_seq2) {
+    l_seq1 = l_afid;
+    uint64_t batch = (l_afid-1)/l_batchsize;
+    uint64_t bidx = (l_afid-1)%l_batchsize;
+    uint64_t bs = l_nbTot - batch*l_batchsize;
+    if (bs>l_batchsize) {
+      bs = l_batchsize;
+    }
+    l_seq2 = batch*l_batchsize + (bs-bidx);
+  };
+
+  {
+    auto archiveFileItor = m_catalogue->getArchiveFilesItor();
+    std::map<uint64_t, common::dataStructures::ArchiveFile> m = archiveFileItorToMap(archiveFileItor);
+    ASSERT_EQ(nbArchiveFiles, m.size());
+
+    for(uint64_t i = 1; i <= nbArchiveFiles; i++) {
+      uint64_t seq1,seq2;
+      afidToSeq(nbArchiveFiles, batchsize, i, seq1, seq2);
+
+      std::ostringstream diskFileId;
+      diskFileId << (12345677 + i);
+      std::ostringstream diskFilePath;
+      diskFilePath << "/public_dir/public_file_" << i;
+
+      catalogue::TapeFileWritten fileWritten1;
+      fileWritten1.archiveFileId = i;
+      fileWritten1.diskInstance = storageClass.diskInstance;
+      fileWritten1.diskFileId = diskFileId.str();
+      fileWritten1.diskFilePath = diskFilePath.str();
+      fileWritten1.diskFileUser = "public_disk_user";
+      fileWritten1.diskFileGroup = "public_disk_group";
+      fileWritten1.size = archiveFileSize;
+      fileWritten1.checksumType = checksumType;
+      fileWritten1.checksumValue = checksumValue;
+      fileWritten1.storageClassName = storageClass.name;
+      fileWritten1.vid = vid1;
+      fileWritten1.fSeq = seq1;
+      fileWritten1.blockId = seq1 * 100;
+      fileWritten1.compressedSize = compressedFileSize;
+      fileWritten1.copyNb = 1;
+
+      catalogue::TapeFileWritten fileWritten2 = fileWritten1;
+      fileWritten2.vid = vid2;
+      fileWritten2.fSeq = seq2;
+      fileWritten2.blockId = seq2 * 100;
+      fileWritten2.copyNb = 2;
+
+      const auto idAndFile = m.find(i);
+      ASSERT_FALSE(m.end() == idAndFile);
+      const common::dataStructures::ArchiveFile archiveFile = idAndFile->second;
+      ASSERT_EQ(fileWritten1.archiveFileId, archiveFile.archiveFileID);
+      ASSERT_EQ(fileWritten1.diskInstance, archiveFile.diskInstance);
+      ASSERT_EQ(fileWritten1.diskFileId, archiveFile.diskFileId);
+      ASSERT_EQ(fileWritten1.diskFilePath, archiveFile.diskFileInfo.path);
+      ASSERT_EQ(fileWritten1.diskFileUser, archiveFile.diskFileInfo.owner);
+      ASSERT_EQ(fileWritten1.diskFileGroup, archiveFile.diskFileInfo.group);
+      ASSERT_EQ(fileWritten1.size, archiveFile.fileSize);
+      ASSERT_EQ(fileWritten1.checksumType, archiveFile.checksumType);
+      ASSERT_EQ(fileWritten1.checksumValue, archiveFile.checksumValue);
+      ASSERT_EQ(fileWritten1.storageClassName, archiveFile.storageClass);
+      ASSERT_EQ(storageClass.nbCopies, archiveFile.tapeFiles.size());
+
+      // Tape copy 1
+      {
+        const auto it = archiveFile.tapeFiles.find(1);
+        ASSERT_NE(archiveFile.tapeFiles.end(), it);
+        ASSERT_EQ(fileWritten1.vid, it->second.vid);
+        ASSERT_EQ(fileWritten1.fSeq, it->second.fSeq);
+        ASSERT_EQ(fileWritten1.blockId, it->second.blockId);
+        ASSERT_EQ(fileWritten1.compressedSize, it->second.compressedSize);
+        ASSERT_EQ(fileWritten1.checksumType, it->second.checksumType);
+        ASSERT_EQ(fileWritten1.checksumValue, it->second.checksumValue);
+        ASSERT_EQ(fileWritten1.copyNb, it->second.copyNb);
+        ASSERT_EQ(fileWritten1.copyNb, it->first);
+      }
+
+      // Tape copy 2
+      {
+        const auto it = archiveFile.tapeFiles.find(2);
+        ASSERT_NE(archiveFile.tapeFiles.end(), it);
+        ASSERT_EQ(fileWritten2.vid, it->second.vid);
+        ASSERT_EQ(fileWritten2.fSeq, it->second.fSeq);
+        ASSERT_EQ(fileWritten2.blockId, it->second.blockId);
+        ASSERT_EQ(fileWritten2.compressedSize, it->second.compressedSize);
+        ASSERT_EQ(fileWritten2.checksumType, it->second.checksumType);
+        ASSERT_EQ(fileWritten2.checksumValue, it->second.checksumValue);
+        ASSERT_EQ(fileWritten2.copyNb, it->second.copyNb);
+        ASSERT_EQ(fileWritten2.copyNb, it->first);
+      }
+    }
+  }
+
+  {
+    const uint64_t startFseq = 1;
+    auto archiveFileItor = m_catalogue->getArchiveFilesForRepackItor(vid1, startFseq);
+    const auto m = archiveFileItorToMap(archiveFileItor);
+    ASSERT_EQ(nbArchiveFiles, m.size());
+
+    for(uint64_t i = 1; i <= nbArchiveFiles; i++) {
+      uint64_t seq1,seq2;
+      afidToSeq(nbArchiveFiles, batchsize, i, seq1, seq2);
+      std::ostringstream diskFileId;
+      diskFileId << (12345677 + i);
+      std::ostringstream diskFilePath;
+      diskFilePath << "/public_dir/public_file_" << i;
+
+      catalogue::TapeFileWritten fileWritten1;
+      fileWritten1.archiveFileId = i;
+      fileWritten1.diskInstance = storageClass.diskInstance;
+      fileWritten1.diskFileId = diskFileId.str();
+      fileWritten1.diskFilePath = diskFilePath.str();
+      fileWritten1.diskFileUser = "public_disk_user";
+      fileWritten1.diskFileGroup = "public_disk_group";
+      fileWritten1.size = archiveFileSize;
+      fileWritten1.checksumType = checksumType;
+      fileWritten1.checksumValue = checksumValue;
+      fileWritten1.storageClassName = storageClass.name;
+      fileWritten1.vid = vid1;
+      fileWritten1.fSeq = seq1;
+      fileWritten1.blockId = seq1 * 100;
+      fileWritten1.compressedSize = compressedFileSize;
+      fileWritten1.copyNb = 1;
+
+      catalogue::TapeFileWritten fileWritten2 = fileWritten1;
+      fileWritten2.vid = vid2;
+      fileWritten2.fSeq = seq2;
+      fileWritten2.blockId = seq2 * 100;
+      fileWritten2.copyNb = 2;
+
+      const auto idAndFile = m.find(i);
+      ASSERT_FALSE(m.end() == idAndFile);
+      const common::dataStructures::ArchiveFile archiveFile = idAndFile->second;
+      ASSERT_EQ(fileWritten1.archiveFileId, archiveFile.archiveFileID);
+      ASSERT_EQ(fileWritten1.diskInstance, archiveFile.diskInstance);
+      ASSERT_EQ(fileWritten1.diskFileId, archiveFile.diskFileId);
+      ASSERT_EQ(fileWritten1.diskFilePath, archiveFile.diskFileInfo.path);
+      ASSERT_EQ(fileWritten1.diskFileUser, archiveFile.diskFileInfo.owner);
+      ASSERT_EQ(fileWritten1.diskFileGroup, archiveFile.diskFileInfo.group);
+      ASSERT_EQ(fileWritten1.size, archiveFile.fileSize);
+      ASSERT_EQ(fileWritten1.checksumType, archiveFile.checksumType);
+      ASSERT_EQ(fileWritten1.checksumValue, archiveFile.checksumValue);
+      ASSERT_EQ(fileWritten1.storageClassName, archiveFile.storageClass);
+      ASSERT_EQ(storageClass.nbCopies, archiveFile.tapeFiles.size());
+
+      // Tape copy 1
+      {
+        const auto it = archiveFile.tapeFiles.find(1);
+        ASSERT_NE(archiveFile.tapeFiles.end(), it);
+        ASSERT_EQ(fileWritten1.vid, it->second.vid);
+        ASSERT_EQ(fileWritten1.fSeq, it->second.fSeq);
+        ASSERT_EQ(fileWritten1.blockId, it->second.blockId);
+        ASSERT_EQ(fileWritten1.compressedSize, it->second.compressedSize);
+        ASSERT_EQ(fileWritten1.checksumType, it->second.checksumType);
+        ASSERT_EQ(fileWritten1.checksumValue, it->second.checksumValue);
+        ASSERT_EQ(fileWritten1.copyNb, it->second.copyNb);
+        ASSERT_EQ(fileWritten1.copyNb, it->first);
+      }
+
+      // Tape copy 2
+      {
+        const auto it = archiveFile.tapeFiles.find(2);
+        ASSERT_NE(archiveFile.tapeFiles.end(), it);
+        ASSERT_EQ(fileWritten2.vid, it->second.vid);
+        ASSERT_EQ(fileWritten2.fSeq, it->second.fSeq);
+        ASSERT_EQ(fileWritten2.blockId, it->second.blockId);
+        ASSERT_EQ(fileWritten2.compressedSize, it->second.compressedSize);
+        ASSERT_EQ(fileWritten2.checksumType, it->second.checksumType);
+        ASSERT_EQ(fileWritten2.checksumValue, it->second.checksumValue);
+        ASSERT_EQ(fileWritten2.copyNb, it->second.copyNb);
+        ASSERT_EQ(fileWritten2.copyNb, it->first);
+      }
+    }
+  }
+
+  for(uint64_t copyNb = 1; copyNb <= 2; copyNb++) {
+    const std::string vid = copyNb == 1 ? vid1 : vid2;
+    const uint64_t startFseq = 1;
+    const uint64_t maxNbFiles = nbArchiveFiles;
+    const auto archiveFiles = m_catalogue->getFilesForRepack(vid, startFseq, maxNbFiles);
+    const auto m = archiveFileListToMap(archiveFiles);
+    ASSERT_EQ(nbArchiveFiles, m.size());
+
+    for(uint64_t i = 1; i <= nbArchiveFiles; i++) {
+      uint64_t seq1,seq2;
+      afidToSeq(nbArchiveFiles, batchsize, i, seq1, seq2);
+      uint64_t seq = (copyNb==1) ? seq1 : seq2;
+      std::ostringstream diskFileId;
+      diskFileId << (12345677 + i);
+      std::ostringstream diskFilePath;
+      diskFilePath << "/public_dir/public_file_" << i;
+
+      catalogue::TapeFileWritten fileWritten;
+      fileWritten.archiveFileId = i;
+      fileWritten.diskInstance = storageClass.diskInstance;
+      fileWritten.diskFileId = diskFileId.str();
+      fileWritten.diskFilePath = diskFilePath.str();
+      fileWritten.diskFileUser = "public_disk_user";
+      fileWritten.diskFileGroup = "public_disk_group";
+      fileWritten.size = archiveFileSize;
+      fileWritten.checksumType = checksumType;
+      fileWritten.checksumValue = checksumValue;
+      fileWritten.storageClassName = storageClass.name;
+      fileWritten.vid = vid;
+      fileWritten.fSeq = seq;
+      fileWritten.blockId = seq * 100;
+      fileWritten.compressedSize = compressedFileSize;
+      fileWritten.copyNb = copyNb;
+
+      const auto idAndFile = m.find(i);
+      ASSERT_FALSE(m.end() == idAndFile);
+      const common::dataStructures::ArchiveFile archiveFile = idAndFile->second;
+      ASSERT_EQ(fileWritten.archiveFileId, archiveFile.archiveFileID);
+      ASSERT_EQ(fileWritten.diskInstance, archiveFile.diskInstance);
+      ASSERT_EQ(fileWritten.diskFileId, archiveFile.diskFileId);
+      ASSERT_EQ(fileWritten.diskFilePath, archiveFile.diskFileInfo.path);
+      ASSERT_EQ(fileWritten.diskFileUser, archiveFile.diskFileInfo.owner);
+      ASSERT_EQ(fileWritten.diskFileGroup, archiveFile.diskFileInfo.group);
+      ASSERT_EQ(fileWritten.size, archiveFile.fileSize);
+      ASSERT_EQ(fileWritten.checksumType, archiveFile.checksumType);
+      ASSERT_EQ(fileWritten.checksumValue, archiveFile.checksumValue);
+      ASSERT_EQ(fileWritten.storageClassName, archiveFile.storageClass);
+
+      // There is only one tape copy because repack only want the tape file on a
+      // single tape
+      ASSERT_EQ(1, archiveFile.tapeFiles.size());
+
+      {
+        const auto it = archiveFile.tapeFiles.find(copyNb);
+        ASSERT_NE(archiveFile.tapeFiles.end(), it);
+        ASSERT_EQ(fileWritten.vid, it->second.vid);
+        ASSERT_EQ(fileWritten.fSeq, it->second.fSeq);
+        ASSERT_EQ(fileWritten.blockId, it->second.blockId);
+        ASSERT_EQ(fileWritten.compressedSize, it->second.compressedSize);
+        ASSERT_EQ(fileWritten.checksumType, it->second.checksumType);
+        ASSERT_EQ(fileWritten.checksumValue, it->second.checksumValue);
+        ASSERT_EQ(fileWritten.copyNb, it->second.copyNb);
+        ASSERT_EQ(fileWritten.copyNb, it->first);
+      }
+    }
+  }
+
+  for(uint64_t copyNb = 1; copyNb <= 2; copyNb++) {
+    const std::string vid = copyNb == 1 ? vid1 : vid2;
+    const uint64_t startFseq = 1;
+    const uint64_t maxNbFiles = nbArchiveFiles / 2;
+    const auto archiveFiles = m_catalogue->getFilesForRepack(vid, startFseq, maxNbFiles);
+    const auto m = archiveFileListToMap(archiveFiles);
+    ASSERT_EQ(nbArchiveFiles / 2, m.size());
+
+    for(uint64_t i = 1; i <= nbArchiveFiles / 2; i++) {
+      uint64_t seq1,seq2;
+      afidToSeq(nbArchiveFiles, batchsize, i, seq1, seq2);
+      uint64_t seq = (copyNb==1) ? seq1 : seq2;
+      std::ostringstream diskFileId;
+      diskFileId << (12345677 + i);
+      std::ostringstream diskFilePath;
+      diskFilePath << "/public_dir/public_file_" << i;
+
+      catalogue::TapeFileWritten fileWritten;
+      fileWritten.archiveFileId = i;
+      fileWritten.diskInstance = storageClass.diskInstance;
+      fileWritten.diskFileId = diskFileId.str();
+      fileWritten.diskFilePath = diskFilePath.str();
+      fileWritten.diskFileUser = "public_disk_user";
+      fileWritten.diskFileGroup = "public_disk_group";
+      fileWritten.size = archiveFileSize;
+      fileWritten.checksumType = checksumType;
+      fileWritten.checksumValue = checksumValue;
+      fileWritten.storageClassName = storageClass.name;
+      fileWritten.vid = vid;
+      fileWritten.fSeq = seq;
+      fileWritten.blockId = seq * 100;
+      fileWritten.compressedSize = compressedFileSize;
+      fileWritten.copyNb = copyNb;
+
+      const auto idAndFile = m.find(i);
+      ASSERT_FALSE(m.end() == idAndFile);
+      const common::dataStructures::ArchiveFile archiveFile = idAndFile->second;
+      ASSERT_EQ(fileWritten.archiveFileId, archiveFile.archiveFileID);
+      ASSERT_EQ(fileWritten.diskInstance, archiveFile.diskInstance);
+      ASSERT_EQ(fileWritten.diskFileId, archiveFile.diskFileId);
+      ASSERT_EQ(fileWritten.diskFilePath, archiveFile.diskFileInfo.path);
+      ASSERT_EQ(fileWritten.diskFileUser, archiveFile.diskFileInfo.owner);
+      ASSERT_EQ(fileWritten.diskFileGroup, archiveFile.diskFileInfo.group);
+      ASSERT_EQ(fileWritten.size, archiveFile.fileSize);
+      ASSERT_EQ(fileWritten.checksumType, archiveFile.checksumType);
+      ASSERT_EQ(fileWritten.checksumValue, archiveFile.checksumValue);
+      ASSERT_EQ(fileWritten.storageClassName, archiveFile.storageClass);
+
+      // There is only one tape copy because repack only want the tape file on a
+      // single tape
+      ASSERT_EQ(1, archiveFile.tapeFiles.size());
+
+      {
+        const auto it = archiveFile.tapeFiles.find(copyNb);
+        ASSERT_NE(archiveFile.tapeFiles.end(), it);
+        ASSERT_EQ(fileWritten.vid, it->second.vid);
+        ASSERT_EQ(fileWritten.fSeq, it->second.fSeq);
+        ASSERT_EQ(fileWritten.blockId, it->second.blockId);
+        ASSERT_EQ(fileWritten.compressedSize, it->second.compressedSize);
+        ASSERT_EQ(fileWritten.checksumType, it->second.checksumType);
+        ASSERT_EQ(fileWritten.checksumValue, it->second.checksumValue);
+        ASSERT_EQ(fileWritten.copyNb, it->second.copyNb);
+        ASSERT_EQ(fileWritten.copyNb, it->first);
+      }
+    }
+  }
+
+  for(uint64_t copyNb = 1; copyNb <= 2; copyNb++) {
+    const std::string vid = copyNb == 1 ? vid1 : vid2;
+    const uint64_t startFseq = nbArchiveFiles / 2 + 1;
+    const uint64_t maxNbFiles = nbArchiveFiles / 2;
+    const auto archiveFiles = m_catalogue->getFilesForRepack(vid, startFseq, maxNbFiles);
+    const auto m = archiveFileListToMap(archiveFiles);
+    ASSERT_EQ(nbArchiveFiles / 2, m.size());
+
+    for(uint64_t i = nbArchiveFiles / 2 + 1; i <= nbArchiveFiles; i++) {
+      uint64_t seq1,seq2;
+      afidToSeq(nbArchiveFiles, batchsize, i, seq1, seq2);
+      uint64_t seq = (copyNb==1) ? seq1 : seq2;
+      std::ostringstream diskFileId;
+      diskFileId << (12345677 + i);
+      std::ostringstream diskFilePath;
+      diskFilePath << "/public_dir/public_file_" << i;
+
+      catalogue::TapeFileWritten fileWritten;
+      fileWritten.archiveFileId = i;
+      fileWritten.diskInstance = storageClass.diskInstance;
+      fileWritten.diskFileId = diskFileId.str();
+      fileWritten.diskFilePath = diskFilePath.str();
+      fileWritten.diskFileUser = "public_disk_user";
+      fileWritten.diskFileGroup = "public_disk_group";
+      fileWritten.size = archiveFileSize;
+      fileWritten.checksumType = checksumType;
+      fileWritten.checksumValue = checksumValue;
+      fileWritten.storageClassName = storageClass.name;
+      fileWritten.vid = vid;
+      fileWritten.fSeq = seq;
+      fileWritten.blockId = seq * 100;
+      fileWritten.compressedSize = compressedFileSize;
+      fileWritten.copyNb = copyNb;
+
+      const auto idAndFile = m.find(i);
+      ASSERT_FALSE(m.end() == idAndFile);
+      const common::dataStructures::ArchiveFile archiveFile = idAndFile->second;
+      ASSERT_EQ(fileWritten.archiveFileId, archiveFile.archiveFileID);
+      ASSERT_EQ(fileWritten.diskInstance, archiveFile.diskInstance);
+      ASSERT_EQ(fileWritten.diskFileId, archiveFile.diskFileId);
+      ASSERT_EQ(fileWritten.diskFilePath, archiveFile.diskFileInfo.path);
+      ASSERT_EQ(fileWritten.diskFileUser, archiveFile.diskFileInfo.owner);
+      ASSERT_EQ(fileWritten.diskFileGroup, archiveFile.diskFileInfo.group);
       ASSERT_EQ(fileWritten.size, archiveFile.fileSize);
       ASSERT_EQ(fileWritten.checksumType, archiveFile.checksumType);
       ASSERT_EQ(fileWritten.checksumValue, archiveFile.checksumValue);
@@ -7992,7 +8912,6 @@ TEST_P(cta_catalogue_CatalogueTest, filesWrittenToTape_1_archive_file_2_tape_cop
       ASSERT_EQ(capacityInBytes, tape.capacityInBytes);
       ASSERT_TRUE(disabledValue == tape.disabled);
       ASSERT_TRUE(fullValue == tape.full);
-      ASSERT_FALSE(tape.lbp);
       ASSERT_EQ(comment, tape.comment);
       ASSERT_FALSE(tape.labelLog);
       ASSERT_FALSE(tape.lastReadLog);
@@ -8018,7 +8937,6 @@ TEST_P(cta_catalogue_CatalogueTest, filesWrittenToTape_1_archive_file_2_tape_cop
       ASSERT_EQ(capacityInBytes, tape.capacityInBytes);
       ASSERT_TRUE(disabledValue == tape.disabled);
       ASSERT_TRUE(fullValue == tape.full);
-      ASSERT_FALSE(tape.lbp);
       ASSERT_EQ(comment, tape.comment);
       ASSERT_FALSE(tape.labelLog);
       ASSERT_FALSE(tape.lastReadLog);
@@ -8061,7 +8979,6 @@ TEST_P(cta_catalogue_CatalogueTest, filesWrittenToTape_1_archive_file_2_tape_cop
   file1Written.diskFilePath         = "/public_dir/public_file";
   file1Written.diskFileUser         = "public_disk_user";
   file1Written.diskFileGroup        = "public_disk_group";
-  file1Written.diskFileRecoveryBlob = "opaque_disk_file_recovery_contents";
   file1Written.size                 = archiveFileSize;
   file1Written.checksumType         = checksumType;
   file1Written.checksumValue        = checksumValue;
@@ -8097,7 +9014,6 @@ TEST_P(cta_catalogue_CatalogueTest, filesWrittenToTape_1_archive_file_2_tape_cop
     ASSERT_EQ(file1Written.diskFilePath, archiveFile.diskFileInfo.path);
     ASSERT_EQ(file1Written.diskFileUser, archiveFile.diskFileInfo.owner);
     ASSERT_EQ(file1Written.diskFileGroup, archiveFile.diskFileInfo.group);
-    ASSERT_EQ(file1Written.diskFileRecoveryBlob, archiveFile.diskFileInfo.recoveryBlob);
 
     ASSERT_EQ(1, archiveFile.tapeFiles.size());
     auto copyNbToTapeFile1Itor = archiveFile.tapeFiles.find(1);
@@ -8122,7 +9038,6 @@ TEST_P(cta_catalogue_CatalogueTest, filesWrittenToTape_1_archive_file_2_tape_cop
   file2Written.diskFilePath         = file1Written.diskFilePath;
   file2Written.diskFileUser         = file1Written.diskFileUser;
   file2Written.diskFileGroup        = file1Written.diskFileGroup;
-  file2Written.diskFileRecoveryBlob = file1Written.diskFileRecoveryBlob;
   file2Written.size                 = archiveFileSize;
   file2Written.checksumType         = checksumType;
   file2Written.checksumValue        = checksumValue;
@@ -8159,7 +9074,6 @@ TEST_P(cta_catalogue_CatalogueTest, filesWrittenToTape_1_archive_file_2_tape_cop
     ASSERT_EQ(file2Written.diskFilePath, archiveFile.diskFileInfo.path);
     ASSERT_EQ(file2Written.diskFileUser, archiveFile.diskFileInfo.owner);
     ASSERT_EQ(file2Written.diskFileGroup, archiveFile.diskFileInfo.group);
-    ASSERT_EQ(file2Written.diskFileRecoveryBlob, archiveFile.diskFileInfo.recoveryBlob);
 
     ASSERT_EQ(2, archiveFile.tapeFiles.size());
 
@@ -8227,7 +9141,6 @@ TEST_P(cta_catalogue_CatalogueTest, filesWrittenToTape_1_archive_file_2_tape_cop
       ASSERT_EQ(capacityInBytes, tape.capacityInBytes);
       ASSERT_TRUE(disabledValue == tape.disabled);
       ASSERT_TRUE(fullValue == tape.full);
-      ASSERT_FALSE(tape.lbp);
       ASSERT_EQ(comment, tape.comment);
       ASSERT_FALSE(tape.labelLog);
       ASSERT_FALSE(tape.lastReadLog);
@@ -8253,7 +9166,6 @@ TEST_P(cta_catalogue_CatalogueTest, filesWrittenToTape_1_archive_file_2_tape_cop
       ASSERT_EQ(capacityInBytes, tape.capacityInBytes);
       ASSERT_TRUE(disabledValue == tape.disabled);
       ASSERT_TRUE(fullValue == tape.full);
-      ASSERT_FALSE(tape.lbp);
       ASSERT_EQ(comment, tape.comment);
       ASSERT_FALSE(tape.labelLog);
       ASSERT_FALSE(tape.lastReadLog);
@@ -8296,7 +9208,6 @@ TEST_P(cta_catalogue_CatalogueTest, filesWrittenToTape_1_archive_file_2_tape_cop
   file1Written.diskFilePath         = "/public_dir/public_file";
   file1Written.diskFileUser         = "public_disk_user";
   file1Written.diskFileGroup        = "public_disk_group";
-  file1Written.diskFileRecoveryBlob = "opaque_disk_file_recovery_contents";
   file1Written.size                 = archiveFileSize;
   file1Written.checksumType         = checksumType;
   file1Written.checksumValue        = checksumValue;
@@ -8332,7 +9243,6 @@ TEST_P(cta_catalogue_CatalogueTest, filesWrittenToTape_1_archive_file_2_tape_cop
     ASSERT_EQ(file1Written.diskFilePath, archiveFile.diskFileInfo.path);
     ASSERT_EQ(file1Written.diskFileUser, archiveFile.diskFileInfo.owner);
     ASSERT_EQ(file1Written.diskFileGroup, archiveFile.diskFileInfo.group);
-    ASSERT_EQ(file1Written.diskFileRecoveryBlob, archiveFile.diskFileInfo.recoveryBlob);
 
     ASSERT_EQ(1, archiveFile.tapeFiles.size());
     auto copyNbToTapeFile1Itor = archiveFile.tapeFiles.find(1);
@@ -8357,7 +9267,6 @@ TEST_P(cta_catalogue_CatalogueTest, filesWrittenToTape_1_archive_file_2_tape_cop
   file2Written.diskFilePath         = file1Written.diskFilePath;
   file2Written.diskFileUser         = file1Written.diskFileUser;
   file2Written.diskFileGroup        = file1Written.diskFileGroup;
-  file2Written.diskFileRecoveryBlob = file1Written.diskFileRecoveryBlob;
   file2Written.size                 = archiveFileSize;
   file2Written.checksumType         = checksumType;
   file2Written.checksumValue        = checksumValue;
@@ -8394,7 +9303,6 @@ TEST_P(cta_catalogue_CatalogueTest, filesWrittenToTape_1_archive_file_2_tape_cop
     ASSERT_EQ(file2Written.diskFilePath, archiveFile.diskFileInfo.path);
     ASSERT_EQ(file2Written.diskFileUser, archiveFile.diskFileInfo.owner);
     ASSERT_EQ(file2Written.diskFileGroup, archiveFile.diskFileInfo.group);
-    ASSERT_EQ(file2Written.diskFileRecoveryBlob, archiveFile.diskFileInfo.recoveryBlob);
 
     // If there are two or more tape copies with the same copy number then
     // only the last one read out by the database is returned by
@@ -8456,7 +9364,6 @@ TEST_P(cta_catalogue_CatalogueTest, filesWrittenToTape_1_archive_file_2_tape_cop
       ASSERT_EQ(capacityInBytes, tape.capacityInBytes);
       ASSERT_TRUE(disabledValue == tape.disabled);
       ASSERT_TRUE(fullValue == tape.full);
-      ASSERT_FALSE(tape.lbp);
       ASSERT_EQ(comment, tape.comment);
       ASSERT_FALSE(tape.labelLog);
       ASSERT_FALSE(tape.lastReadLog);
@@ -8499,7 +9406,6 @@ TEST_P(cta_catalogue_CatalogueTest, filesWrittenToTape_1_archive_file_2_tape_cop
   file1Written.diskFilePath         = "/public_dir/public_file";
   file1Written.diskFileUser         = "public_disk_user";
   file1Written.diskFileGroup        = "public_disk_group";
-  file1Written.diskFileRecoveryBlob = "opaque_disk_file_recovery_contents";
   file1Written.size                 = archiveFileSize;
   file1Written.checksumType         = checksumType;
   file1Written.checksumValue        = checksumValue;
@@ -8535,7 +9441,6 @@ TEST_P(cta_catalogue_CatalogueTest, filesWrittenToTape_1_archive_file_2_tape_cop
     ASSERT_EQ(file1Written.diskFilePath, archiveFile.diskFileInfo.path);
     ASSERT_EQ(file1Written.diskFileUser, archiveFile.diskFileInfo.owner);
     ASSERT_EQ(file1Written.diskFileGroup, archiveFile.diskFileInfo.group);
-    ASSERT_EQ(file1Written.diskFileRecoveryBlob, archiveFile.diskFileInfo.recoveryBlob);
 
     ASSERT_EQ(1, archiveFile.tapeFiles.size());
     auto copyNbToTapeFile1Itor = archiveFile.tapeFiles.find(1);
@@ -8560,7 +9465,6 @@ TEST_P(cta_catalogue_CatalogueTest, filesWrittenToTape_1_archive_file_2_tape_cop
   file2Written.diskFilePath         = file1Written.diskFilePath;
   file2Written.diskFileUser         = file1Written.diskFileUser;
   file2Written.diskFileGroup        = file1Written.diskFileGroup;
-  file2Written.diskFileRecoveryBlob = file1Written.diskFileRecoveryBlob;
   file2Written.size                 = archiveFileSize;
   file2Written.checksumType         = checksumType;
   file2Written.checksumValue        = checksumValue;
@@ -8597,7 +9501,6 @@ TEST_P(cta_catalogue_CatalogueTest, filesWrittenToTape_1_archive_file_2_tape_cop
     ASSERT_EQ(file2Written.diskFilePath, archiveFile.diskFileInfo.path);
     ASSERT_EQ(file2Written.diskFileUser, archiveFile.diskFileInfo.owner);
     ASSERT_EQ(file2Written.diskFileGroup, archiveFile.diskFileInfo.group);
-    ASSERT_EQ(file2Written.diskFileRecoveryBlob, archiveFile.diskFileInfo.recoveryBlob);
 
     // If there are two or more tape copies with the same copy number then
     // only the last one read out by the database is returned by
@@ -8662,7 +9565,6 @@ TEST_P(cta_catalogue_CatalogueTest, filesWrittenToTape_1_archive_file_2_tape_cop
       ASSERT_EQ(capacityInBytes, tape.capacityInBytes);
       ASSERT_TRUE(disabledValue == tape.disabled);
       ASSERT_TRUE(fullValue == tape.full);
-      ASSERT_FALSE(tape.lbp);
       ASSERT_EQ(comment, tape.comment);
       ASSERT_FALSE(tape.labelLog);
       ASSERT_FALSE(tape.lastReadLog);
@@ -8688,7 +9590,6 @@ TEST_P(cta_catalogue_CatalogueTest, filesWrittenToTape_1_archive_file_2_tape_cop
       ASSERT_EQ(capacityInBytes, tape.capacityInBytes);
       ASSERT_TRUE(disabledValue == tape.disabled);
       ASSERT_TRUE(fullValue == tape.full);
-      ASSERT_FALSE(tape.lbp);
       ASSERT_EQ(comment, tape.comment);
       ASSERT_FALSE(tape.labelLog);
       ASSERT_FALSE(tape.lastReadLog);
@@ -8731,7 +9632,6 @@ TEST_P(cta_catalogue_CatalogueTest, filesWrittenToTape_1_archive_file_2_tape_cop
   file1Written.diskFilePath         = "/public_dir/public_file";
   file1Written.diskFileUser         = "public_disk_user";
   file1Written.diskFileGroup        = "public_disk_group";
-  file1Written.diskFileRecoveryBlob = "opaque_disk_file_recovery_contents";
   file1Written.size                 = archiveFileSize1;
   file1Written.checksumType         = checksumType;
   file1Written.checksumValue        = checksumValue;
@@ -8767,7 +9667,6 @@ TEST_P(cta_catalogue_CatalogueTest, filesWrittenToTape_1_archive_file_2_tape_cop
     ASSERT_EQ(file1Written.diskFilePath, archiveFile.diskFileInfo.path);
     ASSERT_EQ(file1Written.diskFileUser, archiveFile.diskFileInfo.owner);
     ASSERT_EQ(file1Written.diskFileGroup, archiveFile.diskFileInfo.group);
-    ASSERT_EQ(file1Written.diskFileRecoveryBlob, archiveFile.diskFileInfo.recoveryBlob);
 
     ASSERT_EQ(1, archiveFile.tapeFiles.size());
     auto copyNbToTapeFile1Itor = archiveFile.tapeFiles.find(1);
@@ -8794,7 +9693,6 @@ TEST_P(cta_catalogue_CatalogueTest, filesWrittenToTape_1_archive_file_2_tape_cop
   file2Written.diskFilePath         = file1Written.diskFilePath;
   file2Written.diskFileUser         = file1Written.diskFileUser;
   file2Written.diskFileGroup        = file1Written.diskFileGroup;
-  file2Written.diskFileRecoveryBlob = file1Written.diskFileRecoveryBlob;
   file2Written.size                 = archiveFileSize2;
   file2Written.checksumType         = checksumType;
   file2Written.checksumValue        = checksumValue;
@@ -8849,7 +9747,6 @@ TEST_P(cta_catalogue_CatalogueTest, filesWrittenToTape_1_archive_file_2_tape_cop
       ASSERT_EQ(capacityInBytes, tape.capacityInBytes);
       ASSERT_TRUE(disabledValue == tape.disabled);
       ASSERT_TRUE(fullValue == tape.full);
-      ASSERT_FALSE(tape.lbp);
       ASSERT_EQ(comment, tape.comment);
       ASSERT_FALSE(tape.labelLog);
       ASSERT_FALSE(tape.lastReadLog);
@@ -8875,7 +9772,6 @@ TEST_P(cta_catalogue_CatalogueTest, filesWrittenToTape_1_archive_file_2_tape_cop
       ASSERT_EQ(capacityInBytes, tape.capacityInBytes);
       ASSERT_TRUE(disabledValue == tape.disabled);
       ASSERT_TRUE(fullValue == tape.full);
-      ASSERT_FALSE(tape.lbp);
       ASSERT_EQ(comment, tape.comment);
       ASSERT_FALSE(tape.labelLog);
       ASSERT_FALSE(tape.lastReadLog);
@@ -8918,7 +9814,6 @@ TEST_P(cta_catalogue_CatalogueTest, filesWrittenToTape_1_archive_file_2_tape_cop
   file1Written.diskFilePath         = "/public_dir/public_file";
   file1Written.diskFileUser         = "public_disk_user";
   file1Written.diskFileGroup        = "public_disk_group";
-  file1Written.diskFileRecoveryBlob = "opaque_disk_file_recovery_contents";
   file1Written.size                 = archiveFileSize;
   file1Written.checksumType         = checksumType1;
   file1Written.checksumValue        = checksumValue;
@@ -8954,7 +9849,6 @@ TEST_P(cta_catalogue_CatalogueTest, filesWrittenToTape_1_archive_file_2_tape_cop
     ASSERT_EQ(file1Written.diskFilePath, archiveFile.diskFileInfo.path);
     ASSERT_EQ(file1Written.diskFileUser, archiveFile.diskFileInfo.owner);
     ASSERT_EQ(file1Written.diskFileGroup, archiveFile.diskFileInfo.group);
-    ASSERT_EQ(file1Written.diskFileRecoveryBlob, archiveFile.diskFileInfo.recoveryBlob);
 
     ASSERT_EQ(1, archiveFile.tapeFiles.size());
     auto copyNbToTapeFile1Itor = archiveFile.tapeFiles.find(1);
@@ -8981,7 +9875,6 @@ TEST_P(cta_catalogue_CatalogueTest, filesWrittenToTape_1_archive_file_2_tape_cop
   file2Written.diskFilePath         = file1Written.diskFilePath;
   file2Written.diskFileUser         = file1Written.diskFileUser;
   file2Written.diskFileGroup        = file1Written.diskFileGroup;
-  file2Written.diskFileRecoveryBlob = file1Written.diskFileRecoveryBlob;
   file2Written.size                 = archiveFileSize;
   file2Written.checksumType         = checksumType2;
   file2Written.checksumValue        = checksumValue;
@@ -9036,7 +9929,6 @@ TEST_P(cta_catalogue_CatalogueTest, filesWrittenToTape_1_archive_file_2_tape_cop
       ASSERT_EQ(capacityInBytes, tape.capacityInBytes);
       ASSERT_TRUE(disabledValue == tape.disabled);
       ASSERT_TRUE(fullValue == tape.full);
-      ASSERT_FALSE(tape.lbp);
       ASSERT_EQ(comment, tape.comment);
       ASSERT_FALSE(tape.labelLog);
       ASSERT_FALSE(tape.lastReadLog);
@@ -9062,7 +9954,6 @@ TEST_P(cta_catalogue_CatalogueTest, filesWrittenToTape_1_archive_file_2_tape_cop
       ASSERT_EQ(capacityInBytes, tape.capacityInBytes);
       ASSERT_TRUE(disabledValue == tape.disabled);
       ASSERT_TRUE(fullValue == tape.full);
-      ASSERT_FALSE(tape.lbp);
       ASSERT_EQ(comment, tape.comment);
       ASSERT_FALSE(tape.labelLog);
       ASSERT_FALSE(tape.lastReadLog);
@@ -9105,7 +9996,6 @@ TEST_P(cta_catalogue_CatalogueTest, filesWrittenToTape_1_archive_file_2_tape_cop
   file1Written.diskFilePath         = "/public_dir/public_file";
   file1Written.diskFileUser         = "public_disk_user";
   file1Written.diskFileGroup        = "public_disk_group";
-  file1Written.diskFileRecoveryBlob = "opaque_disk_file_recovery_contents";
   file1Written.size                 = archiveFileSize;
   file1Written.checksumType         = checksumType;
   file1Written.checksumValue        = checksumValue1;
@@ -9141,7 +10031,6 @@ TEST_P(cta_catalogue_CatalogueTest, filesWrittenToTape_1_archive_file_2_tape_cop
     ASSERT_EQ(file1Written.diskFilePath, archiveFile.diskFileInfo.path);
     ASSERT_EQ(file1Written.diskFileUser, archiveFile.diskFileInfo.owner);
     ASSERT_EQ(file1Written.diskFileGroup, archiveFile.diskFileInfo.group);
-    ASSERT_EQ(file1Written.diskFileRecoveryBlob, archiveFile.diskFileInfo.recoveryBlob);
 
     ASSERT_EQ(1, archiveFile.tapeFiles.size());
     auto copyNbToTapeFile1Itor = archiveFile.tapeFiles.find(1);
@@ -9168,7 +10057,6 @@ TEST_P(cta_catalogue_CatalogueTest, filesWrittenToTape_1_archive_file_2_tape_cop
   file2Written.diskFilePath         = file1Written.diskFilePath;
   file2Written.diskFileUser         = file1Written.diskFileUser;
   file2Written.diskFileGroup        = file1Written.diskFileGroup;
-  file2Written.diskFileRecoveryBlob = file1Written.diskFileRecoveryBlob;
   file2Written.size                 = archiveFileSize;
   file2Written.checksumType         = checksumType;
   file2Written.checksumValue        = checksumValue2;
@@ -9223,7 +10111,6 @@ TEST_P(cta_catalogue_CatalogueTest, deleteArchiveFile) {
       ASSERT_EQ(capacityInBytes, tape.capacityInBytes);
       ASSERT_TRUE(disabledValue == tape.disabled);
       ASSERT_TRUE(fullValue == tape.full);
-      ASSERT_FALSE(tape.lbp);
       ASSERT_EQ(comment, tape.comment);
       ASSERT_FALSE(tape.labelLog);
       ASSERT_FALSE(tape.lastReadLog);
@@ -9249,7 +10136,6 @@ TEST_P(cta_catalogue_CatalogueTest, deleteArchiveFile) {
       ASSERT_EQ(capacityInBytes, tape.capacityInBytes);
       ASSERT_TRUE(disabledValue == tape.disabled);
       ASSERT_TRUE(fullValue == tape.full);
-      ASSERT_FALSE(tape.lbp);
       ASSERT_EQ(comment, tape.comment);
       ASSERT_FALSE(tape.labelLog);
       ASSERT_FALSE(tape.lastReadLog);
@@ -9292,7 +10178,6 @@ TEST_P(cta_catalogue_CatalogueTest, deleteArchiveFile) {
   file1Written.diskFilePath         = "/public_dir/public_file";
   file1Written.diskFileUser         = "public_disk_user";
   file1Written.diskFileGroup        = "public_disk_group";
-  file1Written.diskFileRecoveryBlob = "opaque_disk_file_recovery_contents";
   file1Written.size                 = archiveFileSize;
   file1Written.checksumType         = checksumType;
   file1Written.checksumValue        = checksumValue;
@@ -9334,7 +10219,6 @@ TEST_P(cta_catalogue_CatalogueTest, deleteArchiveFile) {
     ASSERT_EQ(file1Written.diskFilePath, archiveFile.diskFileInfo.path);
     ASSERT_EQ(file1Written.diskFileUser, archiveFile.diskFileInfo.owner);
     ASSERT_EQ(file1Written.diskFileGroup, archiveFile.diskFileInfo.group);
-    ASSERT_EQ(file1Written.diskFileRecoveryBlob, archiveFile.diskFileInfo.recoveryBlob);
 
     ASSERT_EQ(1, archiveFile.tapeFiles.size());
     auto copyNbToTapeFile1Itor = archiveFile.tapeFiles.find(1);
@@ -9363,7 +10247,6 @@ TEST_P(cta_catalogue_CatalogueTest, deleteArchiveFile) {
     ASSERT_EQ(file1Written.diskFilePath, archiveFile.diskFileInfo.path);
     ASSERT_EQ(file1Written.diskFileUser, archiveFile.diskFileInfo.owner);
     ASSERT_EQ(file1Written.diskFileGroup, archiveFile.diskFileInfo.group);
-    ASSERT_EQ(file1Written.diskFileRecoveryBlob, archiveFile.diskFileInfo.recoveryBlob);
 
     ASSERT_EQ(1, archiveFile.tapeFiles.size());
     auto copyNbToTapeFile1Itor = archiveFile.tapeFiles.find(1);
@@ -9388,7 +10271,6 @@ TEST_P(cta_catalogue_CatalogueTest, deleteArchiveFile) {
   file2Written.diskFilePath         = file1Written.diskFilePath;
   file2Written.diskFileUser         = file1Written.diskFileUser;
   file2Written.diskFileGroup        = file1Written.diskFileGroup;
-  file2Written.diskFileRecoveryBlob = file1Written.diskFileRecoveryBlob;
   file2Written.size                 = archiveFileSize;
   file2Written.checksumType         = checksumType;
   file2Written.checksumValue        = checksumValue;
@@ -9433,7 +10315,6 @@ TEST_P(cta_catalogue_CatalogueTest, deleteArchiveFile) {
       ASSERT_EQ(file2Written.diskFilePath, archiveFile.diskFileInfo.path);
       ASSERT_EQ(file2Written.diskFileUser, archiveFile.diskFileInfo.owner);
       ASSERT_EQ(file2Written.diskFileGroup, archiveFile.diskFileInfo.group);
-      ASSERT_EQ(file2Written.diskFileRecoveryBlob, archiveFile.diskFileInfo.recoveryBlob);
 
       ASSERT_EQ(2, archiveFile.tapeFiles.size());
 
@@ -9475,7 +10356,6 @@ TEST_P(cta_catalogue_CatalogueTest, deleteArchiveFile) {
     ASSERT_EQ(file2Written.diskFilePath, archiveFile.diskFileInfo.path);
     ASSERT_EQ(file2Written.diskFileUser, archiveFile.diskFileInfo.owner);
     ASSERT_EQ(file2Written.diskFileGroup, archiveFile.diskFileInfo.group);
-    ASSERT_EQ(file2Written.diskFileRecoveryBlob, archiveFile.diskFileInfo.recoveryBlob);
 
     ASSERT_EQ(2, archiveFile.tapeFiles.size());
 
@@ -9548,7 +10428,6 @@ TEST_P(cta_catalogue_CatalogueTest, deleteArchiveFile_by_archive_file_id_of_anot
       ASSERT_EQ(capacityInBytes, tape.capacityInBytes);
       ASSERT_TRUE(disabledValue == tape.disabled);
       ASSERT_TRUE(fullValue == tape.full);
-      ASSERT_FALSE(tape.lbp);
       ASSERT_EQ(comment, tape.comment);
       ASSERT_FALSE(tape.labelLog);
       ASSERT_FALSE(tape.lastReadLog);
@@ -9574,7 +10453,6 @@ TEST_P(cta_catalogue_CatalogueTest, deleteArchiveFile_by_archive_file_id_of_anot
       ASSERT_EQ(capacityInBytes, tape.capacityInBytes);
       ASSERT_TRUE(disabledValue == tape.disabled);
       ASSERT_TRUE(fullValue == tape.full);
-      ASSERT_FALSE(tape.lbp);
       ASSERT_EQ(comment, tape.comment);
       ASSERT_FALSE(tape.labelLog);
       ASSERT_FALSE(tape.lastReadLog);
@@ -9617,7 +10495,6 @@ TEST_P(cta_catalogue_CatalogueTest, deleteArchiveFile_by_archive_file_id_of_anot
   file1Written.diskFilePath         = "/public_dir/public_file";
   file1Written.diskFileUser         = "public_disk_user";
   file1Written.diskFileGroup        = "public_disk_group";
-  file1Written.diskFileRecoveryBlob = "opaque_disk_file_recovery_contents";
   file1Written.size                 = archiveFileSize;
   file1Written.checksumType         = checksumType;
   file1Written.checksumValue        = checksumValue;
@@ -9659,7 +10536,6 @@ TEST_P(cta_catalogue_CatalogueTest, deleteArchiveFile_by_archive_file_id_of_anot
     ASSERT_EQ(file1Written.diskFilePath, archiveFile.diskFileInfo.path);
     ASSERT_EQ(file1Written.diskFileUser, archiveFile.diskFileInfo.owner);
     ASSERT_EQ(file1Written.diskFileGroup, archiveFile.diskFileInfo.group);
-    ASSERT_EQ(file1Written.diskFileRecoveryBlob, archiveFile.diskFileInfo.recoveryBlob);
 
     ASSERT_EQ(1, archiveFile.tapeFiles.size());
     auto copyNbToTapeFile1Itor = archiveFile.tapeFiles.find(1);
@@ -9688,7 +10564,6 @@ TEST_P(cta_catalogue_CatalogueTest, deleteArchiveFile_by_archive_file_id_of_anot
     ASSERT_EQ(file1Written.diskFilePath, archiveFile.diskFileInfo.path);
     ASSERT_EQ(file1Written.diskFileUser, archiveFile.diskFileInfo.owner);
     ASSERT_EQ(file1Written.diskFileGroup, archiveFile.diskFileInfo.group);
-    ASSERT_EQ(file1Written.diskFileRecoveryBlob, archiveFile.diskFileInfo.recoveryBlob);
 
     ASSERT_EQ(1, archiveFile.tapeFiles.size());
     auto copyNbToTapeFile1Itor = archiveFile.tapeFiles.find(1);
@@ -9713,7 +10588,6 @@ TEST_P(cta_catalogue_CatalogueTest, deleteArchiveFile_by_archive_file_id_of_anot
   file2Written.diskFilePath         = file1Written.diskFilePath;
   file2Written.diskFileUser         = file1Written.diskFileUser;
   file2Written.diskFileGroup        = file1Written.diskFileGroup;
-  file2Written.diskFileRecoveryBlob = file1Written.diskFileRecoveryBlob;
   file2Written.size                 = archiveFileSize;
   file2Written.checksumType         = checksumType;
   file2Written.checksumValue        = checksumValue;
@@ -9758,7 +10632,6 @@ TEST_P(cta_catalogue_CatalogueTest, deleteArchiveFile_by_archive_file_id_of_anot
       ASSERT_EQ(file2Written.diskFilePath, archiveFile.diskFileInfo.path);
       ASSERT_EQ(file2Written.diskFileUser, archiveFile.diskFileInfo.owner);
       ASSERT_EQ(file2Written.diskFileGroup, archiveFile.diskFileInfo.group);
-      ASSERT_EQ(file2Written.diskFileRecoveryBlob, archiveFile.diskFileInfo.recoveryBlob);
 
       ASSERT_EQ(2, archiveFile.tapeFiles.size());
 
@@ -9800,7 +10673,6 @@ TEST_P(cta_catalogue_CatalogueTest, deleteArchiveFile_by_archive_file_id_of_anot
     ASSERT_EQ(file2Written.diskFilePath, archiveFile.diskFileInfo.path);
     ASSERT_EQ(file2Written.diskFileUser, archiveFile.diskFileInfo.owner);
     ASSERT_EQ(file2Written.diskFileGroup, archiveFile.diskFileInfo.group);
-    ASSERT_EQ(file2Written.diskFileRecoveryBlob, archiveFile.diskFileInfo.recoveryBlob);
 
     ASSERT_EQ(2, archiveFile.tapeFiles.size());
 
@@ -9950,7 +10822,6 @@ TEST_P(cta_catalogue_CatalogueTest, reclaimTape_full_lastFSeq_0_no_tape_files) {
     ASSERT_EQ(capacityInBytes, tape.capacityInBytes);
     ASSERT_TRUE(disabledValue == tape.disabled);
     ASSERT_TRUE(fullValue == tape.full);
-    ASSERT_FALSE(tape.lbp);
     ASSERT_EQ(comment, tape.comment);
     ASSERT_FALSE(tape.labelLog);
     ASSERT_FALSE(tape.lastReadLog);
@@ -9984,7 +10855,6 @@ TEST_P(cta_catalogue_CatalogueTest, reclaimTape_full_lastFSeq_0_no_tape_files) {
     ASSERT_EQ(capacityInBytes, tape.capacityInBytes);
     ASSERT_TRUE(disabledValue == tape.disabled);
     ASSERT_FALSE(tape.full);
-    ASSERT_FALSE(tape.lbp);
     ASSERT_EQ(comment, tape.comment);
     ASSERT_FALSE(tape.labelLog);
     ASSERT_FALSE(tape.lastReadLog);
@@ -10034,7 +10904,6 @@ TEST_P(cta_catalogue_CatalogueTest, reclaimTape_not_full_lastFSeq_0_no_tape_file
     ASSERT_EQ(capacityInBytes, tape.capacityInBytes);
     ASSERT_TRUE(disabledValue == tape.disabled);
     ASSERT_TRUE(fullValue == tape.full);
-    ASSERT_FALSE(tape.lbp);
     ASSERT_EQ(comment, tape.comment);
     ASSERT_FALSE(tape.labelLog);
     ASSERT_FALSE(tape.lastReadLog);
@@ -10092,7 +10961,6 @@ TEST_P(cta_catalogue_CatalogueTest, reclaimTape_full_lastFSeq_1_no_tape_files) {
     ASSERT_EQ(capacityInBytes, tape.capacityInBytes);
     ASSERT_TRUE(disabledValue == tape.disabled);
     ASSERT_TRUE(fullValue == tape.full);
-    ASSERT_FALSE(tape.lbp);
     ASSERT_EQ(createTapeComment, tape.comment);
     ASSERT_FALSE(tape.labelLog);
     ASSERT_FALSE(tape.lastReadLog);
@@ -10134,7 +11002,6 @@ TEST_P(cta_catalogue_CatalogueTest, reclaimTape_full_lastFSeq_1_no_tape_files) {
   file1Written.diskFilePath         = "/public_dir/public_file";
   file1Written.diskFileUser         = "public_disk_user";
   file1Written.diskFileGroup        = "public_disk_group";
-  file1Written.diskFileRecoveryBlob = "opaque_disk_file_recovery_contents";
   file1Written.size                 = archiveFileSize;
   file1Written.checksumType         = checksumType;
   file1Written.checksumValue        = checksumValue;
@@ -10161,7 +11028,6 @@ TEST_P(cta_catalogue_CatalogueTest, reclaimTape_full_lastFSeq_1_no_tape_files) {
     ASSERT_EQ(file1Written.diskFilePath, archiveFile.diskFileInfo.path);
     ASSERT_EQ(file1Written.diskFileUser, archiveFile.diskFileInfo.owner);
     ASSERT_EQ(file1Written.diskFileGroup, archiveFile.diskFileInfo.group);
-    ASSERT_EQ(file1Written.diskFileRecoveryBlob, archiveFile.diskFileInfo.recoveryBlob);
 
     ASSERT_EQ(1, archiveFile.tapeFiles.size());
     auto copyNbToTapeFile1Itor = archiveFile.tapeFiles.find(1);
@@ -10193,7 +11059,6 @@ TEST_P(cta_catalogue_CatalogueTest, reclaimTape_full_lastFSeq_1_no_tape_files) {
     ASSERT_EQ(capacityInBytes, tape.capacityInBytes);
     ASSERT_TRUE(disabledValue == tape.disabled);
     ASSERT_TRUE(fullValue == tape.full);
-    ASSERT_FALSE(tape.lbp);
     ASSERT_EQ(createTapeComment, tape.comment);
     ASSERT_FALSE(tape.labelLog);
     ASSERT_FALSE(tape.lastReadLog);
@@ -10231,7 +11096,6 @@ TEST_P(cta_catalogue_CatalogueTest, reclaimTape_full_lastFSeq_1_no_tape_files) {
     ASSERT_EQ(capacityInBytes, tape.capacityInBytes);
     ASSERT_TRUE(disabledValue == tape.disabled);
     ASSERT_TRUE(fullValue == tape.full);
-    ASSERT_FALSE(tape.lbp);
     ASSERT_EQ(createTapeComment, tape.comment);
     ASSERT_FALSE(tape.labelLog);
     ASSERT_FALSE(tape.lastReadLog);
@@ -10267,7 +11131,6 @@ TEST_P(cta_catalogue_CatalogueTest, reclaimTape_full_lastFSeq_1_no_tape_files) {
     ASSERT_EQ(capacityInBytes, tape.capacityInBytes);
     ASSERT_TRUE(disabledValue == tape.disabled);
     ASSERT_TRUE(fullValue == tape.full);
-    ASSERT_FALSE(tape.lbp);
     ASSERT_EQ(createTapeComment, tape.comment);
     ASSERT_FALSE(tape.labelLog);
     ASSERT_FALSE(tape.lastReadLog);
@@ -10321,7 +11184,6 @@ TEST_P(cta_catalogue_CatalogueTest, reclaimTape_full_lastFSeq_1_one_tape_file) {
     ASSERT_EQ(capacityInBytes, tape.capacityInBytes);
     ASSERT_TRUE(disabledValue == tape.disabled);
     ASSERT_TRUE(fullValue == tape.full);
-    ASSERT_FALSE(tape.lbp);
     ASSERT_EQ(createTapeComment, tape.comment);
     ASSERT_FALSE(tape.labelLog);
     ASSERT_FALSE(tape.lastReadLog);
@@ -10363,7 +11225,6 @@ TEST_P(cta_catalogue_CatalogueTest, reclaimTape_full_lastFSeq_1_one_tape_file) {
   file1Written.diskFilePath         = "/public_dir/public_file";
   file1Written.diskFileUser         = "public_disk_user";
   file1Written.diskFileGroup        = "public_disk_group";
-  file1Written.diskFileRecoveryBlob = "opaque_disk_file_recovery_contents";
   file1Written.size                 = archiveFileSize;
   file1Written.checksumType         = checksumType;
   file1Written.checksumValue        = checksumValue;
@@ -10390,7 +11251,6 @@ TEST_P(cta_catalogue_CatalogueTest, reclaimTape_full_lastFSeq_1_one_tape_file) {
     ASSERT_EQ(file1Written.diskFilePath, archiveFile.diskFileInfo.path);
     ASSERT_EQ(file1Written.diskFileUser, archiveFile.diskFileInfo.owner);
     ASSERT_EQ(file1Written.diskFileGroup, archiveFile.diskFileInfo.group);
-    ASSERT_EQ(file1Written.diskFileRecoveryBlob, archiveFile.diskFileInfo.recoveryBlob);
 
     ASSERT_EQ(1, archiveFile.tapeFiles.size());
     auto copyNbToTapeFile1Itor = archiveFile.tapeFiles.find(1);
@@ -10423,7 +11283,6 @@ TEST_P(cta_catalogue_CatalogueTest, reclaimTape_full_lastFSeq_1_one_tape_file) {
     ASSERT_EQ(capacityInBytes, tape.capacityInBytes);
     ASSERT_TRUE(disabledValue == tape.disabled);
     ASSERT_TRUE(fullValue == tape.full);
-    ASSERT_FALSE(tape.lbp);
     ASSERT_EQ(createTapeComment, tape.comment);
     ASSERT_FALSE(tape.labelLog);
     ASSERT_FALSE(tape.lastReadLog);
diff --git a/catalogue/CreateSchemaCmd.cpp b/catalogue/CreateSchemaCmd.cpp
index 62c1f897914cd0d6e2c1d88c739fb4f1a61a3f15..c23111e5369946909223a3bcdef0eec8f6816f5e 100644
--- a/catalogue/CreateSchemaCmd.cpp
+++ b/catalogue/CreateSchemaCmd.cpp
@@ -1,6 +1,6 @@
 /*
  * The CERN Tape Archive (CTA) project
- * Copyright (C) 2015  CERN
+ * Copyright (C) 2019  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
@@ -20,6 +20,7 @@
 #include "catalogue/CreateSchemaCmdLineArgs.hpp"
 #include "catalogue/MysqlCatalogueSchema.hpp"
 #include "catalogue/OracleCatalogueSchema.hpp"
+#include "catalogue/PostgresCatalogueSchema.hpp"
 #include "catalogue/SqliteCatalogueSchema.hpp"
 #include "common/exception/Exception.hpp"
 #include "rdbms/ConnPool.hpp"
@@ -73,6 +74,12 @@ int CreateSchemaCmd::exceptionThrowingMain(const int argc, char *const *const ar
        conn.executeNonQueries(schema.sql);
     }
     break;
+  case rdbms::Login::DBTYPE_POSTGRESQL:
+    {
+       PostgresCatalogueSchema schema;
+       conn.executeNonQueries(schema.sql);
+    }
+    break;
   case rdbms::Login::DBTYPE_MYSQL:
     {
        MysqlCatalogueSchema schema;
diff --git a/catalogue/DropSchemaCmd.cpp b/catalogue/DropSchemaCmd.cpp
index 4e49093c36944c260a7eeae25ff876af55ea6281..db265369e6ebbad67b12358b110a3271e46c3d9d 100644
--- a/catalogue/DropSchemaCmd.cpp
+++ b/catalogue/DropSchemaCmd.cpp
@@ -1,6 +1,6 @@
 /*
  * The CERN Tape Archive (CTA) project
- * Copyright (C) 2015  CERN
+ * Copyright (C) 2019  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
@@ -106,6 +106,9 @@ void DropSchemaCmd::dropCatalogueSchema(const rdbms::Login::DbType &dbType, rdbm
     case rdbms::Login::DBTYPE_MYSQL:
       dropMysqlCatalogueSchema(conn);
       break;
+    case rdbms::Login::DBTYPE_POSTGRESQL:
+      dropPostgresCatalogueSchema(conn);
+      break;
     case rdbms::Login::DBTYPE_ORACLE:
       dropOracleCatalogueSchema(conn);
       break;
@@ -243,6 +246,37 @@ void DropSchemaCmd::dropOracleCatalogueSchema(rdbms::Conn &conn) {
   }
 }
 
+//------------------------------------------------------------------------------
+// dropPostgresCatalogueSchema
+//------------------------------------------------------------------------------
+void DropSchemaCmd::dropPostgresCatalogueSchema(rdbms::Conn &conn) {
+  try {
+    std::list<std::string> tablesInDb = conn.getTableNames();
+    std::list<std::string> tablesToDrop = {
+      "CTA_CATALOGUE",
+      "ARCHIVE_ROUTE",
+      "TAPE_FILE",
+      "ARCHIVE_FILE",
+      "TAPE",
+      "REQUESTER_MOUNT_RULE",
+      "REQUESTER_GROUP_MOUNT_RULE",
+      "ADMIN_USER",
+      "ADMIN_HOST",
+      "STORAGE_CLASS",
+      "TAPE_POOL",
+      "LOGICAL_LIBRARY",
+      "MOUNT_POLICY"
+    };
+
+    dropDatabaseTables(conn, tablesToDrop);
+
+    std::list<std::string> sequencesToDrop = {"ARCHIVE_FILE_ID_SEQ", "STORAGE_CLASS_ID_SEQ"};
+    dropDatabaseSequences(conn, sequencesToDrop);
+  } catch(exception::Exception &ex) {
+    throw exception::Exception(std::string(__FUNCTION__) + " failed: " + ex.getMessage().str());
+  }
+}
+
 //------------------------------------------------------------------------------
 // dropDatabaseSequences
 //------------------------------------------------------------------------------
diff --git a/catalogue/DropSchemaCmd.hpp b/catalogue/DropSchemaCmd.hpp
index 669c98d5cae4a66fdb3a8b9d3c65b4a8ede14111..54da56020581ff5c69cb7537b190d73cafbe5343 100644
--- a/catalogue/DropSchemaCmd.hpp
+++ b/catalogue/DropSchemaCmd.hpp
@@ -98,6 +98,14 @@ private:
    */
   void dropMysqlCatalogueSchema(rdbms::Conn &conn);
 
+  /**
+   * Unconditionally drops the schema of the catalogue database associated with
+   * the specified database connection.
+   *
+   * @param conn The database connection.
+   */
+  void dropPostgresCatalogueSchema(rdbms::Conn &conn);
+
   /**
    * Drops the database tables with the specified names.
    *
diff --git a/catalogue/DummyCatalogue.hpp b/catalogue/DummyCatalogue.hpp
index 6bf982b5f5d56f1a5905c7c37d22bf990b37ca38..60c7bd35a0838b2ce26372b901544c820eac74b2 100644
--- a/catalogue/DummyCatalogue.hpp
+++ b/catalogue/DummyCatalogue.hpp
@@ -109,7 +109,7 @@ public:
   void setTapeFull(const common::dataStructures::SecurityIdentity& admin, const std::string& vid, const bool fullValue) override { throw exception::Exception(std::string("In ")+__PRETTY_FUNCTION__+": not implemented"); }
   void setTapePoolEncryption(const common::dataStructures::SecurityIdentity& admin, const std::string& name, const bool encryptionValue) override { throw exception::Exception(std::string("In ")+__PRETTY_FUNCTION__+": not implemented"); }
   bool tapeExists(const std::string& vid) const { throw exception::Exception(std::string("In ")+__PRETTY_FUNCTION__+": not implemented"); }
-  void tapeLabelled(const std::string& vid, const std::string& drive, const bool lbpIsOn) override { throw exception::Exception(std::string("In ")+__PRETTY_FUNCTION__+": not implemented"); }
+  void tapeLabelled(const std::string& vid, const std::string& drive) override { throw exception::Exception(std::string("In ")+__PRETTY_FUNCTION__+": not implemented"); }
   void tapeMountedForArchive(const std::string& vid, const std::string& drive) override { throw exception::Exception(std::string("In ")+__PRETTY_FUNCTION__+": not implemented"); }
   void tapeMountedForRetrieve(const std::string& vid, const std::string& drive) override { throw exception::Exception(std::string("In ")+__PRETTY_FUNCTION__+": not implemented"); }
   bool tapePoolExists(const std::string& tapePoolName) const { throw exception::Exception(std::string("In ")+__PRETTY_FUNCTION__+": not implemented"); }
diff --git a/catalogue/MysqlCatalogue.cpp b/catalogue/MysqlCatalogue.cpp
index d73876e6a36899ffd576c483688db0a9aaba0e46..e947f024afdf02bcc6de7d50b79effef7743586f 100644
--- a/catalogue/MysqlCatalogue.cpp
+++ b/catalogue/MysqlCatalogue.cpp
@@ -156,7 +156,6 @@ common::dataStructures::Tape MysqlCatalogue::selectTapeForUpdate(rdbms::Conn &co
       "LAST_FSEQ AS LAST_FSEQ,"
       "IS_DISABLED AS IS_DISABLED,"
       "IS_FULL AS IS_FULL,"
-      "LBP_IS_ON AS LBP_IS_ON,"
 
       "LABEL_DRIVE AS LABEL_DRIVE,"
       "LABEL_TIME AS LABEL_TIME,"
@@ -199,7 +198,6 @@ common::dataStructures::Tape MysqlCatalogue::selectTapeForUpdate(rdbms::Conn &co
     tape.lastFSeq = rset.columnUint64("LAST_FSEQ");
     tape.disabled = rset.columnBool("IS_DISABLED");
     tape.full = rset.columnBool("IS_FULL");
-    tape.lbp = rset.columnOptionalBool("LBP_IS_ON");
 
     tape.labelLog = getTapeLogFromRset(rset, "LABEL_DRIVE", "LABEL_TIME");
     tape.lastReadLog = getTapeLogFromRset(rset, "LAST_READ_DRIVE", "LAST_READ_TIME");
@@ -324,7 +322,6 @@ void MysqlCatalogue::fileWrittenToTape(rdbms::Conn &conn, const TapeFileWritten
       row.diskFilePath = event.diskFilePath;
       row.diskFileUser = event.diskFileUser;
       row.diskFileGroup = event.diskFileGroup;
-      row.diskFileRecoveryBlob = event.diskFileRecoveryBlob;
       insertArchiveFile(conn, row);
     } catch(exception::DatabasePrimaryKeyError &) {
       // Ignore this error
@@ -398,7 +395,6 @@ void MysqlCatalogue::deleteArchiveFile(const std::string &diskInstanceName, cons
         "ARCHIVE_FILE.DISK_FILE_PATH AS DISK_FILE_PATH,"
         "ARCHIVE_FILE.DISK_FILE_USER AS DISK_FILE_USER,"
         "ARCHIVE_FILE.DISK_FILE_GROUP AS DISK_FILE_GROUP,"
-        "ARCHIVE_FILE.DISK_FILE_RECOVERY_BLOB AS DISK_FILE_RECOVERY_BLOB,"
         "ARCHIVE_FILE.SIZE_IN_BYTES AS SIZE_IN_BYTES,"
         "ARCHIVE_FILE.CHECKSUM_TYPE AS CHECKSUM_TYPE,"
         "ARCHIVE_FILE.CHECKSUM_VALUE AS CHECKSUM_VALUE,"
@@ -441,7 +437,6 @@ void MysqlCatalogue::deleteArchiveFile(const std::string &diskInstanceName, cons
         archiveFile->diskFileInfo.path = selectRset.columnString("DISK_FILE_PATH");
         archiveFile->diskFileInfo.owner = selectRset.columnString("DISK_FILE_USER");
         archiveFile->diskFileInfo.group = selectRset.columnString("DISK_FILE_GROUP");
-        archiveFile->diskFileInfo.recoveryBlob = selectRset.columnString("DISK_FILE_RECOVERY_BLOB");
         archiveFile->fileSize = selectRset.columnUint64("SIZE_IN_BYTES");
         archiveFile->checksumType = selectRset.columnString("CHECKSUM_TYPE");
         archiveFile->checksumValue = selectRset.columnString("CHECKSUM_VALUE");
diff --git a/catalogue/OracleCatalogue.cpp b/catalogue/OracleCatalogue.cpp
index 0dda1e40a9e350bd8ba440a69aa8f54dde4e87ed..687d8f53eef26872cc5bd2762663c93768577c5c 100644
--- a/catalogue/OracleCatalogue.cpp
+++ b/catalogue/OracleCatalogue.cpp
@@ -82,7 +82,6 @@ namespace {
     rdbms::wrapper::OcciColumn diskFilePath;
     rdbms::wrapper::OcciColumn diskFileUser;
     rdbms::wrapper::OcciColumn diskFileGroup;
-    rdbms::wrapper::OcciColumn diskFileRecoveryBlob;
     rdbms::wrapper::OcciColumn size;
     rdbms::wrapper::OcciColumn checksumType;
     rdbms::wrapper::OcciColumn checksumValue;
@@ -103,7 +102,6 @@ namespace {
       diskFilePath("DISK_FILE_PATH", nbRows),
       diskFileUser("DISK_FILE_USER", nbRows),
       diskFileGroup("DISK_FILE_GROUP", nbRows),
-      diskFileRecoveryBlob("DISK_FILE_RECOVERY_BLOB", nbRows),
       size("SIZE_IN_BYTES", nbRows),
       checksumType("CHECKSUM_TYPE", nbRows),
       checksumValue("CHECKSUM_VALUE", nbRows),
@@ -222,7 +220,6 @@ common::dataStructures::Tape OracleCatalogue::selectTapeForUpdate(rdbms::Conn &c
         "LAST_FSEQ AS LAST_FSEQ,"
         "IS_DISABLED AS IS_DISABLED,"
         "IS_FULL AS IS_FULL,"
-        "LBP_IS_ON AS LBP_IS_ON,"
 
         "LABEL_DRIVE AS LABEL_DRIVE,"
         "LABEL_TIME AS LABEL_TIME,"
@@ -265,7 +262,6 @@ common::dataStructures::Tape OracleCatalogue::selectTapeForUpdate(rdbms::Conn &c
     tape.lastFSeq = rset.columnUint64("LAST_FSEQ");
     tape.disabled = rset.columnBool("IS_DISABLED");
     tape.full = rset.columnBool("IS_FULL");
-    tape.lbp = rset.columnOptionalBool("LBP_IS_ON");
 
     tape.labelLog = getTapeLogFromRset(rset, "LABEL_DRIVE", "LABEL_TIME");
     tape.lastReadLog = getTapeLogFromRset(rset, "LAST_READ_DRIVE", "LAST_READ_TIME");
@@ -525,7 +521,6 @@ void OracleCatalogue::idempotentBatchInsertArchiveFiles(rdbms::Conn &conn, const
       archiveFileBatch.diskFilePath.setFieldLenToValueLen(i, event.diskFilePath);
       archiveFileBatch.diskFileUser.setFieldLenToValueLen(i, event.diskFileUser);
       archiveFileBatch.diskFileGroup.setFieldLenToValueLen(i, event.diskFileGroup);
-      archiveFileBatch.diskFileRecoveryBlob.setFieldLenToValueLen(i, event.diskFileRecoveryBlob);
       archiveFileBatch.size.setFieldLenToValueLen(i, event.size);
       archiveFileBatch.checksumType.setFieldLenToValueLen(i, event.checksumType);
       archiveFileBatch.checksumValue.setFieldLenToValueLen(i, event.checksumValue);
@@ -544,7 +539,6 @@ void OracleCatalogue::idempotentBatchInsertArchiveFiles(rdbms::Conn &conn, const
       archiveFileBatch.diskFilePath.setFieldValue(i, event.diskFilePath);
       archiveFileBatch.diskFileUser.setFieldValue(i, event.diskFileUser);
       archiveFileBatch.diskFileGroup.setFieldValue(i, event.diskFileGroup);
-      archiveFileBatch.diskFileRecoveryBlob.setFieldValue(i, event.diskFileRecoveryBlob);
       archiveFileBatch.size.setFieldValue(i, event.size);
       archiveFileBatch.checksumType.setFieldValue(i, event.checksumType);
       archiveFileBatch.checksumValue.setFieldValue(i, event.checksumValue);
@@ -562,7 +556,6 @@ void OracleCatalogue::idempotentBatchInsertArchiveFiles(rdbms::Conn &conn, const
         "DISK_FILE_PATH,"
         "DISK_FILE_USER,"
         "DISK_FILE_GROUP,"
-        "DISK_FILE_RECOVERY_BLOB,"
         "SIZE_IN_BYTES,"
         "CHECKSUM_TYPE,"
         "CHECKSUM_VALUE,"
@@ -576,7 +569,6 @@ void OracleCatalogue::idempotentBatchInsertArchiveFiles(rdbms::Conn &conn, const
         ":DISK_FILE_PATH,"
         ":DISK_FILE_USER,"
         ":DISK_FILE_GROUP,"
-        ":DISK_FILE_RECOVERY_BLOB,"
         ":SIZE_IN_BYTES,"
         ":CHECKSUM_TYPE,"
         ":CHECKSUM_VALUE,"
@@ -598,7 +590,6 @@ void OracleCatalogue::idempotentBatchInsertArchiveFiles(rdbms::Conn &conn, const
     occiStmt.setColumn(archiveFileBatch.diskFilePath);
     occiStmt.setColumn(archiveFileBatch.diskFileUser);
     occiStmt.setColumn(archiveFileBatch.diskFileGroup);
-    occiStmt.setColumn(archiveFileBatch.diskFileRecoveryBlob);
     occiStmt.setColumn(archiveFileBatch.size);
     occiStmt.setColumn(archiveFileBatch.checksumType);
     occiStmt.setColumn(archiveFileBatch.checksumValue);
@@ -770,7 +761,6 @@ void OracleCatalogue::deleteArchiveFile(const std::string &diskInstanceName, con
         "ARCHIVE_FILE.DISK_FILE_PATH AS DISK_FILE_PATH,"
         "ARCHIVE_FILE.DISK_FILE_USER AS DISK_FILE_USER,"
         "ARCHIVE_FILE.DISK_FILE_GROUP AS DISK_FILE_GROUP,"
-        "ARCHIVE_FILE.DISK_FILE_RECOVERY_BLOB AS DISK_FILE_RECOVERY_BLOB,"
         "ARCHIVE_FILE.SIZE_IN_BYTES AS SIZE_IN_BYTES,"
         "ARCHIVE_FILE.CHECKSUM_TYPE AS CHECKSUM_TYPE,"
         "ARCHIVE_FILE.CHECKSUM_VALUE AS CHECKSUM_VALUE,"
@@ -817,7 +807,6 @@ void OracleCatalogue::deleteArchiveFile(const std::string &diskInstanceName, con
         archiveFile->diskFileInfo.path = selectRset.columnString("DISK_FILE_PATH");
         archiveFile->diskFileInfo.owner = selectRset.columnString("DISK_FILE_USER");
         archiveFile->diskFileInfo.group = selectRset.columnString("DISK_FILE_GROUP");
-        archiveFile->diskFileInfo.recoveryBlob = selectRset.columnString("DISK_FILE_RECOVERY_BLOB");
         archiveFile->fileSize = selectRset.columnUint64("SIZE_IN_BYTES");
         archiveFile->checksumType = selectRset.columnString("CHECKSUM_TYPE");
         archiveFile->checksumValue = selectRset.columnString("CHECKSUM_VALUE");
diff --git a/catalogue/PostgresCatalogue.cpp b/catalogue/PostgresCatalogue.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..56f078add90c36dc471b582c7238e683f467a082
--- /dev/null
+++ b/catalogue/PostgresCatalogue.cpp
@@ -0,0 +1,900 @@
+/*
+ * The CERN Tape Archive(CTA) project
+ * Copyright(C) 2019  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 "catalogue/ArchiveFileRow.hpp"
+#include "catalogue/ChecksumTypeMismatch.hpp"
+#include "catalogue/ChecksumValueMismatch.hpp"
+#include "catalogue/FileSizeMismatch.hpp"
+#include "catalogue/PostgresCatalogue.hpp"
+#include "catalogue/retryOnLostConnection.hpp"
+#include "common/exception/Exception.hpp"
+#include "common/exception/LostDatabaseConnection.hpp"
+#include "common/exception/UserError.hpp"
+#include "common/make_unique.hpp"
+#include "common/Timer.hpp"
+#include "common/utils/utils.hpp"
+#include "rdbms/AutoRollback.hpp"
+#include "rdbms/rdbms.hpp"
+#include "rdbms/wrapper/PostgresColumn.hpp"
+#include "rdbms/wrapper/PostgresStmt.hpp"
+#include <algorithm>
+
+namespace cta {
+namespace catalogue {
+
+namespace {
+  /**
+   * Structure used to assemble a batch of rows to insert into the TAPE_FILE
+   * table.
+   */
+  struct TapeFileBatch {
+    size_t nbRows;
+    rdbms::wrapper::PostgresColumn vid;
+    rdbms::wrapper::PostgresColumn fSeq;
+    rdbms::wrapper::PostgresColumn blockId;
+    rdbms::wrapper::PostgresColumn compressedSize;
+    rdbms::wrapper::PostgresColumn copyNb;
+    rdbms::wrapper::PostgresColumn creationTime;
+    rdbms::wrapper::PostgresColumn archiveFileId;
+
+    /**
+     * Constructor.
+     *
+     * @param nbRowsValue  The Number of rows to be inserted.
+     */
+    TapeFileBatch(const size_t nbRowsValue):
+      nbRows(nbRowsValue),
+      vid("VID", nbRows),
+      fSeq("FSEQ", nbRows),
+      blockId("BLOCK_ID", nbRows),
+      compressedSize("COMPRESSED_SIZE_IN_BYTES", nbRows),
+      copyNb("COPY_NB", nbRows),
+      creationTime("CREATION_TIME", nbRows),
+      archiveFileId("ARCHIVE_FILE_ID", nbRows) {
+    }
+  }; // struct TapeFileBatch
+
+  /**
+   * Structure used to assemble a batch of rows to insert into the TEMP_ARCHIVE_FILE_BATCH
+   * table.
+   */
+  struct ArchiveFileBatch {
+    size_t nbRows;
+    rdbms::wrapper::PostgresColumn archiveFileId;
+    rdbms::wrapper::PostgresColumn diskInstance;
+    rdbms::wrapper::PostgresColumn diskFileId;
+    rdbms::wrapper::PostgresColumn diskFilePath;
+    rdbms::wrapper::PostgresColumn diskFileUser;
+    rdbms::wrapper::PostgresColumn diskFileGroup;
+    rdbms::wrapper::PostgresColumn size;
+    rdbms::wrapper::PostgresColumn checksumType;
+    rdbms::wrapper::PostgresColumn checksumValue;
+    rdbms::wrapper::PostgresColumn storageClassName;
+    rdbms::wrapper::PostgresColumn creationTime;
+    rdbms::wrapper::PostgresColumn reconciliationTime;
+
+    /**
+     * Constructor.
+     *
+     * @param nbRowsValue  The Number of rows to be inserted.
+     */
+    ArchiveFileBatch(const size_t nbRowsValue):
+      nbRows(nbRowsValue),
+      archiveFileId("ARCHIVE_FILE_ID", nbRows),
+      diskInstance("DISK_INSTANCE_NAME", nbRows),
+      diskFileId("DISK_FILE_ID", nbRows),
+      diskFilePath("DISK_FILE_PATH", nbRows),
+      diskFileUser("DISK_FILE_USER", nbRows),
+      diskFileGroup("DISK_FILE_GROUP", nbRows),
+      size("SIZE_IN_BYTES", nbRows),
+      checksumType("CHECKSUM_TYPE", nbRows),
+      checksumValue("CHECKSUM_VALUE", nbRows),
+      storageClassName("STORAGE_CLASS_NAME", nbRows),
+      creationTime("CREATION_TIME", nbRows),
+      reconciliationTime("RECONCILIATION_TIME", nbRows) {
+    }
+  }; // struct ArchiveFileBatch
+
+  /**
+   * Structure used to assemble a batch of rows to insert into the
+   * TAPE_FILE_BATCH temporary table.
+   */
+  struct TempTapeFileBatch {
+    size_t nbRows;
+    rdbms::wrapper::PostgresColumn archiveFileId;
+
+    /**
+     * Constructor.
+     *
+     * @param nbRowsValue  The Number of rows to be inserted.
+     */
+    TempTapeFileBatch(const size_t nbRowsValue):
+      nbRows(nbRowsValue),
+      archiveFileId("ARCHIVE_FILE_ID", nbRows) {
+    }
+  }; // struct TempTapeFileBatch
+} // anonymous namespace
+
+//------------------------------------------------------------------------------
+// constructor
+//------------------------------------------------------------------------------
+PostgresCatalogue::PostgresCatalogue(
+  log::Logger &log,
+  const rdbms::Login &login,
+  const uint64_t nbConns,
+  const uint64_t nbArchiveFileListingConns):
+  RdbmsCatalogue(
+    log,
+    rdbms::Login(rdbms::Login::DBTYPE_POSTGRESQL,
+                 login.username, login.password, login.database,
+                 login.hostname, login.port),
+    nbConns,
+    nbArchiveFileListingConns) {
+}
+
+//------------------------------------------------------------------------------
+// destructor
+//------------------------------------------------------------------------------
+PostgresCatalogue::~PostgresCatalogue() {
+}
+
+//------------------------------------------------------------------------------
+// getNextArchiveFileId
+//------------------------------------------------------------------------------
+uint64_t PostgresCatalogue::getNextArchiveFileId(rdbms::Conn &conn) {
+  try {
+    const char *const sql =
+      "select NEXTVAL('ARCHIVE_FILE_ID_SEQ') AS ARCHIVE_FILE_ID";
+    auto stmt = conn.createStmt(sql);
+    auto rset = stmt.executeQuery();
+    if(!rset.next()) {
+      throw exception::Exception("Result set is unexpectedly empty");
+    }
+    return rset.columnUint64("ARCHIVE_FILE_ID");
+  } catch(exception::UserError &) {
+    throw;
+  } catch(exception::Exception &ex) {
+    ex.getMessage().str(std::string(__FUNCTION__) + ": " + ex.getMessage().str());
+    throw;
+  }
+}
+
+//------------------------------------------------------------------------------
+// getNextStorageClassId
+//------------------------------------------------------------------------------
+uint64_t PostgresCatalogue::getNextStorageClassId(rdbms::Conn &conn) {
+  try {
+    const char *const sql =
+      "select NEXTVAL('STORAGE_CLASS_ID_SEQ') AS STORAGE_CLASS_ID";
+    auto stmt = conn.createStmt(sql);
+    auto rset = stmt.executeQuery();
+    if(!rset.next()) {
+      throw exception::Exception("Result set is unexpectedly empty");
+    }
+    return rset.columnUint64("STORAGE_CLASS_ID");
+  } catch(exception::UserError &) {
+    throw;
+  } catch(exception::Exception &ex) {
+    ex.getMessage().str(std::string(__FUNCTION__) + ": " + ex.getMessage().str());
+    throw;
+  }
+}
+
+//------------------------------------------------------------------------------
+// selectTapeForUpdate
+//------------------------------------------------------------------------------
+common::dataStructures::Tape PostgresCatalogue::selectTapeForUpdate(rdbms::Conn &conn, const std::string &vid) const {
+  try {
+    const char *const sql =
+      "SELECT "
+        "VID AS VID,"
+        "LOGICAL_LIBRARY_NAME AS LOGICAL_LIBRARY_NAME,"
+        "TAPE_POOL_NAME AS TAPE_POOL_NAME,"
+        "ENCRYPTION_KEY AS ENCRYPTION_KEY,"
+        "CAPACITY_IN_BYTES AS CAPACITY_IN_BYTES,"
+        "DATA_IN_BYTES AS DATA_IN_BYTES,"
+        "LAST_FSEQ AS LAST_FSEQ,"
+        "IS_DISABLED AS IS_DISABLED,"
+        "IS_FULL AS IS_FULL,"
+
+        "LABEL_DRIVE AS LABEL_DRIVE,"
+        "LABEL_TIME AS LABEL_TIME,"
+
+        "LAST_READ_DRIVE AS LAST_READ_DRIVE,"
+        "LAST_READ_TIME AS LAST_READ_TIME,"
+
+        "LAST_WRITE_DRIVE AS LAST_WRITE_DRIVE,"
+        "LAST_WRITE_TIME AS LAST_WRITE_TIME,"
+
+        "USER_COMMENT AS USER_COMMENT,"
+
+        "CREATION_LOG_USER_NAME AS CREATION_LOG_USER_NAME,"
+        "CREATION_LOG_HOST_NAME AS CREATION_LOG_HOST_NAME,"
+        "CREATION_LOG_TIME AS CREATION_LOG_TIME,"
+
+        "LAST_UPDATE_USER_NAME AS LAST_UPDATE_USER_NAME,"
+        "LAST_UPDATE_HOST_NAME AS LAST_UPDATE_HOST_NAME,"
+        "LAST_UPDATE_TIME AS LAST_UPDATE_TIME "
+      "FROM "
+        "TAPE "
+      "WHERE "
+        "VID = :VID "
+      "FOR UPDATE";
+    auto stmt = conn.createStmt(sql);
+    stmt.bindString(":VID", vid);
+    auto rset = stmt.executeQuery();
+    if (!rset.next()) {
+      throw exception::Exception(std::string("The tape with VID " + vid + " does not exist"));
+    }
+
+    common::dataStructures::Tape tape;
+
+    tape.vid = rset.columnString("VID");
+    tape.logicalLibraryName = rset.columnString("LOGICAL_LIBRARY_NAME");
+    tape.tapePoolName = rset.columnString("TAPE_POOL_NAME");
+    tape.encryptionKey = rset.columnOptionalString("ENCRYPTION_KEY");
+    tape.capacityInBytes = rset.columnUint64("CAPACITY_IN_BYTES");
+    tape.dataOnTapeInBytes = rset.columnUint64("DATA_IN_BYTES");
+    tape.lastFSeq = rset.columnUint64("LAST_FSEQ");
+    tape.disabled = rset.columnBool("IS_DISABLED");
+    tape.full = rset.columnBool("IS_FULL");
+
+    tape.labelLog = getTapeLogFromRset(rset, "LABEL_DRIVE", "LABEL_TIME");
+    tape.lastReadLog = getTapeLogFromRset(rset, "LAST_READ_DRIVE", "LAST_READ_TIME");
+    tape.lastWriteLog = getTapeLogFromRset(rset, "LAST_WRITE_DRIVE", "LAST_WRITE_TIME");
+
+    tape.comment = rset.columnString("USER_COMMENT");
+
+    common::dataStructures::UserIdentity creatorUI;
+    creatorUI.name = rset.columnString("CREATION_LOG_USER_NAME");
+
+    common::dataStructures::EntryLog creationLog;
+    creationLog.username = rset.columnString("CREATION_LOG_USER_NAME");
+    creationLog.host = rset.columnString("CREATION_LOG_HOST_NAME");
+    creationLog.time = rset.columnUint64("CREATION_LOG_TIME");
+
+    tape.creationLog = creationLog;
+
+    common::dataStructures::UserIdentity updaterUI;
+    updaterUI.name = rset.columnString("LAST_UPDATE_USER_NAME");
+
+    common::dataStructures::EntryLog updateLog;
+    updateLog.username = rset.columnString("LAST_UPDATE_USER_NAME");
+    updateLog.host = rset.columnString("LAST_UPDATE_HOST_NAME");
+    updateLog.time = rset.columnUint64("LAST_UPDATE_TIME");
+
+    tape.lastModificationLog = updateLog;
+
+    return tape;
+  } catch(exception::UserError &) {
+    throw;
+  } catch(exception::Exception &ex) {
+    ex.getMessage().str(std::string(__FUNCTION__) + ": " + ex.getMessage().str());
+    throw;
+  }
+}
+
+//------------------------------------------------------------------------------
+// filesWrittenToTape
+//------------------------------------------------------------------------------
+void PostgresCatalogue::filesWrittenToTape(const std::set<TapeItemWrittenPointer> &events) {
+  try {
+    if (events.empty()) {
+      return;
+    }
+
+    auto firstEventItor = events.begin();
+    const auto &firstEvent = **firstEventItor;
+    checkTapeItemWrittenFieldsAreSet(__FUNCTION__, firstEvent);
+    const time_t now = time(nullptr);
+    auto conn = m_connPool.getConn();
+    rdbms::AutoRollback autoRollback(conn);
+
+    // Start DB transaction and create temporary tables TEMP_ARCHIVE_FILE_BATCH and TEMP_TAPE_FILE_BATCH.
+    // These two tables will exist only for the duration of the transaction.
+    // Set deferrable for second (disk instance, disk file id) constraint of the ARCHIVE_FILE table
+    // to avoid violation in the case of concurrent inserts of a previously not existing archive file.
+    beginCreateTemporarySetDeferred(conn);
+
+    const auto tape = selectTapeForUpdate(conn, firstEvent.vid);
+    uint64_t expectedFSeq = tape.lastFSeq + 1;
+    uint64_t totalCompressedBytesWritten = 0;
+
+    // We have a mix of files and items. Only files will be recorded, but items
+    // allow checking fSeq coherency.
+    // determine the number of files
+    size_t filesCount=std::count_if(events.cbegin(), events.cend(), 
+        [](const TapeItemWrittenPointer &e){return typeid(*e)==typeid(TapeFileWritten);});
+    TapeFileBatch tapeFileBatch(filesCount);
+    
+    std::set<TapeFileWritten> fileEvents;
+
+    for (const auto &eventP: events) {
+      // Check for all item types.
+      const auto &event = *eventP;
+      checkTapeItemWrittenFieldsAreSet(__FUNCTION__, event);
+
+      if (event.vid != firstEvent.vid) {
+        throw exception::Exception(std::string("VID mismatch: expected=") + firstEvent.vid + " actual=" + event.vid);
+      }
+      
+      if (expectedFSeq != event.fSeq) {
+        exception::Exception ex;
+        ex.getMessage() << "FSeq mismatch for tape " << firstEvent.vid << ": expected=" << expectedFSeq << " actual=" <<
+          event.fSeq;
+        throw ex;
+      }
+      expectedFSeq++;
+      
+      try {
+        // If this is a file (as opposed to a placeholder), do the full processing.
+        const auto &fileEvent=dynamic_cast<const TapeFileWritten &>(event);
+
+        checkTapeFileWrittenFieldsAreSet(__FUNCTION__, fileEvent);
+        
+        totalCompressedBytesWritten += fileEvent.compressedSize;
+        
+        fileEvents.insert(fileEvent);
+      } catch (std::bad_cast&) {}
+    }
+
+    // Update the tape because all the necessary information is now available
+    auto lastEventItor = events.cend();
+    lastEventItor--;
+    const TapeItemWritten &lastEvent = **lastEventItor;
+    updateTape(conn, lastEvent.vid, lastEvent.fSeq, totalCompressedBytesWritten,
+      lastEvent.tapeDrive);
+
+    // If we had only placeholders and no file recorded, we are done.
+    if (fileEvents.empty()) return;
+
+    // Create the archive file entries, skipping those that already exist
+    // However we don't currently lock existing rows, so this transaction may
+    // still fail later, in the face of certain concurrent modifications such
+    // as the deletion of one of the existing archive files for which we are
+    // inserting another tape file.
+    idempotentBatchInsertArchiveFiles(conn, fileEvents);
+
+    insertTapeFileBatchIntoTempTable(conn, fileEvents);
+
+    // Verify that the archive file entries in the catalogue database agree with
+    // the tape file written events
+    const auto fileSizesAndChecksums = selectArchiveFileSizesAndChecksums(conn, fileEvents);
+    for (const auto &event: fileEvents) {
+      const auto fileSizeAndChecksumItor = fileSizesAndChecksums.find(event.archiveFileId);
+
+      std::ostringstream fileContext;
+      fileContext << "archiveFileId=" << event.archiveFileId << ", diskInstanceName=" << event.diskInstance <<
+        ", diskFileId=" << event.diskFileId << ", diskFilePath=" << event.diskFilePath;
+
+      // This should never happen
+      if(fileSizesAndChecksums.end() == fileSizeAndChecksumItor) {
+        exception::Exception ex;
+        ex.getMessage() << __FUNCTION__ << ": Failed to find archive file entry in the catalogue: " << fileContext.str();
+        throw ex;
+      }
+
+      const auto &fileSizeAndChecksum = fileSizeAndChecksumItor->second;
+
+      if(fileSizeAndChecksum.fileSize != event.size) {
+        catalogue::FileSizeMismatch ex;
+        ex.getMessage() << __FUNCTION__ << ": File size mismatch: expected=" << fileSizeAndChecksum.fileSize <<
+          ", actual=" << event.size << ": " << fileContext.str();
+        throw ex;
+      }
+
+      if(fileSizeAndChecksum.checksumType != event.checksumType) {
+        catalogue::ChecksumTypeMismatch ex;
+        ex.getMessage() << __FUNCTION__ << ": Checksum type mismatch: expected=" << fileSizeAndChecksum.checksumType <<
+          ", actual=" << event.checksumType << ": " << fileContext.str();
+        throw ex;
+      }
+
+      if(fileSizeAndChecksum.checksumValue != event.checksumValue) {
+        catalogue::ChecksumValueMismatch ex;
+        ex.getMessage() << __FUNCTION__ << ": Checksum value mismatch: expected=" << fileSizeAndChecksum.checksumValue
+          << ", actual=" << event.checksumValue << ": " << fileContext.str();
+        throw ex;
+      }
+    }
+
+    // Store the value of each field
+    uint32_t i = 0;
+    for (const auto &event: fileEvents) {
+      tapeFileBatch.vid.setFieldValue(i, event.vid);
+      tapeFileBatch.fSeq.setFieldValue(i, event.fSeq);
+      tapeFileBatch.blockId.setFieldValue(i, event.blockId);
+      tapeFileBatch.compressedSize.setFieldValue(i, event.compressedSize);
+      tapeFileBatch.copyNb.setFieldValue(i, event.copyNb);
+      tapeFileBatch.creationTime.setFieldValue(i, now);
+      tapeFileBatch.archiveFileId.setFieldValue(i, event.archiveFileId);
+      i++;
+    }
+
+    const char *const sql =
+      "COPY TAPE_FILE("
+        "VID,"
+        "FSEQ,"
+        "BLOCK_ID,"
+        "COMPRESSED_SIZE_IN_BYTES,"
+        "COPY_NB,"
+        "CREATION_TIME,"
+        "ARCHIVE_FILE_ID) "
+      "FROM STDIN --"
+        ":VID,"
+        ":FSEQ,"
+        ":BLOCK_ID,"
+        ":COMPRESSED_SIZE_IN_BYTES,"
+        ":COPY_NB,"
+        ":CREATION_TIME,"
+        ":ARCHIVE_FILE_ID";
+
+    auto stmt = conn.createStmt(sql);
+    rdbms::wrapper::PostgresStmt &postgresStmt = dynamic_cast<rdbms::wrapper::PostgresStmt &>(stmt.getStmt());
+    postgresStmt.setColumn(tapeFileBatch.vid);
+    postgresStmt.setColumn(tapeFileBatch.fSeq);
+    postgresStmt.setColumn(tapeFileBatch.blockId);
+    postgresStmt.setColumn(tapeFileBatch.compressedSize);
+    postgresStmt.setColumn(tapeFileBatch.copyNb);
+    postgresStmt.setColumn(tapeFileBatch.creationTime);
+    postgresStmt.setColumn(tapeFileBatch.archiveFileId);
+    
+    postgresStmt.executeCopyInsert(tapeFileBatch.nbRows);
+
+    conn.commit();
+    autoRollback.cancel();
+  } catch(exception::UserError &) {
+    throw;
+  } catch(exception::Exception &ex) {
+    ex.getMessage().str(std::string(__FUNCTION__) + ": " + ex.getMessage().str());
+    throw;
+  }
+}
+
+//------------------------------------------------------------------------------
+// idempotentBatchInsertArchiveFiles
+//------------------------------------------------------------------------------
+void PostgresCatalogue::idempotentBatchInsertArchiveFiles(rdbms::Conn &conn,
+   const std::set<TapeFileWritten> &events) const {
+  try {
+    ArchiveFileBatch archiveFileBatch(events.size());
+    const time_t now = time(nullptr);
+
+    // Store the value of each field
+    uint32_t i = 0;
+    for (const auto &event: events) {
+      archiveFileBatch.archiveFileId.setFieldValue(i, event.archiveFileId);
+      archiveFileBatch.diskInstance.setFieldValue(i, event.diskInstance);
+      archiveFileBatch.diskFileId.setFieldValue(i, event.diskFileId);
+      archiveFileBatch.diskFilePath.setFieldValue(i, event.diskFilePath);
+      archiveFileBatch.diskFileUser.setFieldValue(i, event.diskFileUser);
+      archiveFileBatch.diskFileGroup.setFieldValue(i, event.diskFileGroup);
+      archiveFileBatch.size.setFieldValue(i, event.size);
+      archiveFileBatch.checksumType.setFieldValue(i, event.checksumType);
+      archiveFileBatch.checksumValue.setFieldValue(i, event.checksumValue);
+      archiveFileBatch.storageClassName.setFieldValue(i, event.storageClassName);
+      archiveFileBatch.creationTime.setFieldValue(i, now);
+      archiveFileBatch.reconciliationTime.setFieldValue(i, now);
+      i++;
+    }
+
+    const char *const sql =
+      "COPY TEMP_ARCHIVE_FILE_BATCH("
+        "ARCHIVE_FILE_ID,"
+        "DISK_INSTANCE_NAME,"
+        "DISK_FILE_ID,"
+        "DISK_FILE_PATH,"
+        "DISK_FILE_USER,"
+        "DISK_FILE_GROUP,"
+        "SIZE_IN_BYTES,"
+        "CHECKSUM_TYPE,"
+        "CHECKSUM_VALUE,"
+        "STORAGE_CLASS_NAME,"
+        "CREATION_TIME,"
+        "RECONCILIATION_TIME) "
+      "FROM STDIN --"
+        ":ARCHIVE_FILE_ID,"
+        ":DISK_INSTANCE_NAME,"
+        ":DISK_FILE_ID,"
+        ":DISK_FILE_PATH,"
+        ":DISK_FILE_USER,"
+        ":DISK_FILE_GROUP,"
+        ":SIZE_IN_BYTES,"
+        ":CHECKSUM_TYPE,"
+        ":CHECKSUM_VALUE,"
+        ":STORAGE_CLASS_NAME,"
+        ":CREATION_TIME,"
+        ":RECONCILIATION_TIME";
+
+    auto stmt = conn.createStmt(sql);
+    rdbms::wrapper::PostgresStmt &postgresStmt = dynamic_cast<rdbms::wrapper::PostgresStmt &>(stmt.getStmt());
+
+    postgresStmt.setColumn(archiveFileBatch.archiveFileId);
+    postgresStmt.setColumn(archiveFileBatch.diskInstance);
+    postgresStmt.setColumn(archiveFileBatch.diskFileId);
+    postgresStmt.setColumn(archiveFileBatch.diskFilePath);
+    postgresStmt.setColumn(archiveFileBatch.diskFileUser);
+    postgresStmt.setColumn(archiveFileBatch.diskFileGroup);
+    postgresStmt.setColumn(archiveFileBatch.size);
+    postgresStmt.setColumn(archiveFileBatch.checksumType);
+    postgresStmt.setColumn(archiveFileBatch.checksumValue);
+    postgresStmt.setColumn(archiveFileBatch.storageClassName);
+    postgresStmt.setColumn(archiveFileBatch.creationTime);
+    postgresStmt.setColumn(archiveFileBatch.reconciliationTime);
+
+    postgresStmt.executeCopyInsert(archiveFileBatch.nbRows);
+
+    const char *const sql_insert =
+      "INSERT INTO ARCHIVE_FILE("
+        "ARCHIVE_FILE_ID,"
+  	"DISK_INSTANCE_NAME,"
+        "DISK_FILE_ID,"
+        "DISK_FILE_PATH,"
+        "DISK_FILE_USER,"
+        "DISK_FILE_GROUP,"
+        "SIZE_IN_BYTES,"
+        "CHECKSUM_TYPE,"
+        "CHECKSUM_VALUE,"
+        "STORAGE_CLASS_ID,"
+        "CREATION_TIME,"
+        "RECONCILIATION_TIME) "
+      "SELECT "
+        "A.ARCHIVE_FILE_ID,"
+        "A.DISK_INSTANCE_NAME,"
+        "A.DISK_FILE_ID,"
+        "A.DISK_FILE_PATH,"
+        "A.DISK_FILE_USER,"
+        "A.DISK_FILE_GROUP,"
+        "A.SIZE_IN_BYTES,"
+        "A.CHECKSUM_TYPE," 
+  	    "A.CHECKSUM_VALUE,"
+        "S.STORAGE_CLASS_ID,"
+        "A.CREATION_TIME,"
+        "A.RECONCILIATION_TIME "
+      "FROM TEMP_ARCHIVE_FILE_BATCH AS A, STORAGE_CLASS AS S "
+        "WHERE A.DISK_INSTANCE_NAME = S.DISK_INSTANCE_NAME AND "
+        "A.STORAGE_CLASS_NAME = S.STORAGE_CLASS_NAME "
+      "ORDER BY A.ARCHIVE_FILE_ID "
+      "ON CONFLICT (ARCHIVE_FILE_ID) DO NOTHING";
+
+    // Concerns for bulk insertion in archive_file: deadlock with concurrent
+    // inserts of previously not-existing entry for the same archive file,
+    // hence insert with ORDER BY to define an update order.
+
+    auto stmt_insert = conn.createStmt(sql_insert);
+    stmt_insert.executeNonQuery();
+
+  } catch(exception::UserError &) {
+    throw;
+  } catch(exception::Exception &ex) {
+    ex.getMessage().str(std::string(__FUNCTION__) + ": " + ex.getMessage().str());
+    throw;
+  }
+}
+
+//------------------------------------------------------------------------------
+// selectArchiveFileSizeAndChecksum
+//------------------------------------------------------------------------------
+std::map<uint64_t, PostgresCatalogue::FileSizeAndChecksum> PostgresCatalogue::selectArchiveFileSizesAndChecksums(
+  rdbms::Conn &conn, const std::set<TapeFileWritten> &events) const {
+  try {
+    std::vector<uint64_t> archiveFileIdList(events.size());
+    for (const auto &event: events) {
+      archiveFileIdList.push_back(event.archiveFileId);
+    }
+
+    const char *const sql =
+      "SELECT "
+        "ARCHIVE_FILE.ARCHIVE_FILE_ID AS ARCHIVE_FILE_ID,"
+        "ARCHIVE_FILE.SIZE_IN_BYTES AS SIZE_IN_BYTES,"
+        "ARCHIVE_FILE.CHECKSUM_TYPE AS CHECKSUM_TYPE,"
+        "ARCHIVE_FILE.CHECKSUM_VALUE AS CHECKSUM_VALUE "
+      "FROM "
+        "ARCHIVE_FILE "
+      "INNER JOIN TEMP_TAPE_FILE_BATCH ON "
+        "ARCHIVE_FILE.ARCHIVE_FILE_ID = TEMP_TAPE_FILE_BATCH.ARCHIVE_FILE_ID";
+    auto stmt = conn.createStmt(sql);
+
+    auto rset = stmt.executeQuery();
+
+    std::map<uint64_t, FileSizeAndChecksum> fileSizesAndChecksums;
+    while (rset.next()) {
+      const uint64_t archiveFileId = rset.columnUint64("ARCHIVE_FILE_ID");
+
+      if (fileSizesAndChecksums.end() != fileSizesAndChecksums.find(archiveFileId)) {
+        exception::Exception ex;
+        ex.getMessage() << __FUNCTION__ << " failed: "
+          "Found duplicate archive file identifier in batch of files written to tape: archiveFileId=" << archiveFileId;
+        throw ex;
+      }
+
+      FileSizeAndChecksum fileSizeAndChecksum;
+      fileSizeAndChecksum.fileSize = rset.columnUint64("SIZE_IN_BYTES");
+      fileSizeAndChecksum.checksumType = rset.columnString("CHECKSUM_TYPE");
+      fileSizeAndChecksum.checksumValue = rset.columnString("CHECKSUM_VALUE");
+
+      fileSizesAndChecksums[archiveFileId] = fileSizeAndChecksum;
+    }
+
+    return fileSizesAndChecksums;
+  } catch(exception::UserError &) {
+    throw;
+  } catch(exception::Exception &ex) {
+    ex.getMessage().str(std::string(__FUNCTION__) + ": " + ex.getMessage().str());
+    throw;
+  }
+}
+
+//------------------------------------------------------------------------------
+// insertArchiveFilesIntoTempTable
+//------------------------------------------------------------------------------
+void PostgresCatalogue::insertTapeFileBatchIntoTempTable(rdbms::Conn &conn,
+   const std::set<TapeFileWritten> &events) const {
+  try {
+    TempTapeFileBatch tempTapeFileBatch(events.size());
+
+    // Store the value of each field
+    uint32_t i = 0;
+    for (const auto &event: events) {
+      tempTapeFileBatch.archiveFileId.setFieldValue(i, event.archiveFileId);
+      i++;
+    }
+
+    const char *const sql =
+      "COPY TEMP_TAPE_FILE_BATCH("
+        "ARCHIVE_FILE_ID) "
+      "FROM STDIN --"
+        ":ARCHIVE_FILE_ID";
+
+    auto stmt = conn.createStmt(sql);
+    rdbms::wrapper::PostgresStmt &postgresStmt = dynamic_cast<rdbms::wrapper::PostgresStmt &>(stmt.getStmt());
+
+    postgresStmt.setColumn(tempTapeFileBatch.archiveFileId);
+    postgresStmt.executeCopyInsert(tempTapeFileBatch.nbRows);
+  } catch(exception::UserError &) {
+    throw;
+  } catch(exception::Exception &ex) {
+    ex.getMessage().str(std::string(__FUNCTION__) + ": " + ex.getMessage().str());
+    throw;
+  }
+}
+
+//------------------------------------------------------------------------------
+// deleteArchiveFile
+//------------------------------------------------------------------------------
+void PostgresCatalogue::deleteArchiveFile(const std::string &diskInstanceName, const uint64_t archiveFileId,
+  log::LogContext &lc) {
+  try {
+    const char *selectSql =
+      "SELECT "
+        "ARCHIVE_FILE.ARCHIVE_FILE_ID AS ARCHIVE_FILE_ID,"
+        "ARCHIVE_FILE.DISK_INSTANCE_NAME AS DISK_INSTANCE_NAME,"
+        "ARCHIVE_FILE.DISK_FILE_ID AS DISK_FILE_ID,"
+        "ARCHIVE_FILE.DISK_FILE_PATH AS DISK_FILE_PATH,"
+        "ARCHIVE_FILE.DISK_FILE_USER AS DISK_FILE_USER,"
+        "ARCHIVE_FILE.DISK_FILE_GROUP AS DISK_FILE_GROUP,"
+        "ARCHIVE_FILE.SIZE_IN_BYTES AS SIZE_IN_BYTES,"
+        "ARCHIVE_FILE.CHECKSUM_TYPE AS CHECKSUM_TYPE,"
+        "ARCHIVE_FILE.CHECKSUM_VALUE AS CHECKSUM_VALUE,"
+        "STORAGE_CLASS.STORAGE_CLASS_NAME AS STORAGE_CLASS_NAME,"
+        "ARCHIVE_FILE.CREATION_TIME AS ARCHIVE_FILE_CREATION_TIME,"
+        "ARCHIVE_FILE.RECONCILIATION_TIME AS RECONCILIATION_TIME,"
+        "TAPE_FILE.VID AS VID,"
+        "TAPE_FILE.FSEQ AS FSEQ,"
+        "TAPE_FILE.BLOCK_ID AS BLOCK_ID,"
+        "TAPE_FILE.COMPRESSED_SIZE_IN_BYTES AS COMPRESSED_SIZE_IN_BYTES,"
+        "TAPE_FILE.COPY_NB AS COPY_NB,"
+        "TAPE_FILE.CREATION_TIME AS TAPE_FILE_CREATION_TIME "
+      "FROM "
+        "ARCHIVE_FILE "
+      "INNER JOIN STORAGE_CLASS ON "
+        "ARCHIVE_FILE.STORAGE_CLASS_ID = STORAGE_CLASS.STORAGE_CLASS_ID "
+      "LEFT OUTER JOIN TAPE_FILE ON "
+        "ARCHIVE_FILE.ARCHIVE_FILE_ID = TAPE_FILE.ARCHIVE_FILE_ID "
+      "WHERE "
+        "ARCHIVE_FILE.ARCHIVE_FILE_ID = :ARCHIVE_FILE_ID "
+      "FOR UPDATE OF ARCHIVE_FILE";
+    utils::Timer t;
+    auto conn = m_connPool.getConn();
+    rdbms::AutoRollback autoRollback(conn);
+    conn.executeNonQuery("BEGIN");
+
+    const auto getConnTime = t.secs(utils::Timer::resetCounter);
+    auto selectStmt = conn.createStmt(selectSql);
+    const auto createStmtTime = t.secs();
+    selectStmt.bindUint64(":ARCHIVE_FILE_ID", archiveFileId);
+    t.reset();
+    rdbms::Rset selectRset = selectStmt.executeQuery();
+    const auto selectFromArchiveFileTime = t.secs();
+    std::unique_ptr<common::dataStructures::ArchiveFile> archiveFile;
+    while(selectRset.next()) {
+      if(nullptr == archiveFile.get()) {
+        archiveFile = cta::make_unique<common::dataStructures::ArchiveFile>();
+
+        archiveFile->archiveFileID = selectRset.columnUint64("ARCHIVE_FILE_ID");
+        archiveFile->diskInstance = selectRset.columnString("DISK_INSTANCE_NAME");
+        archiveFile->diskFileId = selectRset.columnString("DISK_FILE_ID");
+        archiveFile->diskFileInfo.path = selectRset.columnString("DISK_FILE_PATH");
+        archiveFile->diskFileInfo.owner = selectRset.columnString("DISK_FILE_USER");
+        archiveFile->diskFileInfo.group = selectRset.columnString("DISK_FILE_GROUP");
+        archiveFile->fileSize = selectRset.columnUint64("SIZE_IN_BYTES");
+        archiveFile->checksumType = selectRset.columnString("CHECKSUM_TYPE");
+        archiveFile->checksumValue = selectRset.columnString("CHECKSUM_VALUE");
+        archiveFile->storageClass = selectRset.columnString("STORAGE_CLASS_NAME");
+        archiveFile->creationTime = selectRset.columnUint64("ARCHIVE_FILE_CREATION_TIME");
+        archiveFile->reconciliationTime = selectRset.columnUint64("RECONCILIATION_TIME");
+      }
+
+      // If there is a tape file
+      if(!selectRset.columnIsNull("VID")) {
+        // Add the tape file to the archive file's in-memory structure
+        common::dataStructures::TapeFile tapeFile;
+        tapeFile.vid = selectRset.columnString("VID");
+        tapeFile.fSeq = selectRset.columnUint64("FSEQ");
+        tapeFile.blockId = selectRset.columnUint64("BLOCK_ID");
+        tapeFile.compressedSize = selectRset.columnUint64("COMPRESSED_SIZE_IN_BYTES");
+        tapeFile.copyNb = selectRset.columnUint64("COPY_NB");
+        tapeFile.creationTime = selectRset.columnUint64("TAPE_FILE_CREATION_TIME");
+        tapeFile.checksumType = archiveFile->checksumType; // Duplicated for convenience
+        tapeFile.checksumValue = archiveFile->checksumValue; // Duplicated for convenience
+
+        archiveFile->tapeFiles[selectRset.columnUint64("COPY_NB")] = tapeFile;
+      }
+    }
+
+    if(nullptr == archiveFile.get()) {
+      log::ScopedParamContainer spc(lc);
+      spc.add("fileId", archiveFileId);
+      lc.log(log::WARNING, "Ignoring request to delete archive file because it does not exist in the catalogue");
+      return;
+    }
+
+    if(diskInstanceName != archiveFile->diskInstance) {
+      log::ScopedParamContainer spc(lc);
+      spc.add("fileId", std::to_string(archiveFile->archiveFileID))
+         .add("diskInstance", archiveFile->diskInstance)
+         .add("requestDiskInstance", diskInstanceName)
+         .add("diskFileId", archiveFile->diskFileId)
+         .add("diskFileInfo.path", archiveFile->diskFileInfo.path)
+         .add("diskFileInfo.owner", archiveFile->diskFileInfo.owner)
+         .add("diskFileInfo.group", archiveFile->diskFileInfo.group)
+         .add("fileSize", std::to_string(archiveFile->fileSize))
+         .add("checksumType", archiveFile->checksumType)
+         .add("checksumValue", archiveFile->checksumValue)
+         .add("creationTime", std::to_string(archiveFile->creationTime))
+         .add("reconciliationTime", std::to_string(archiveFile->reconciliationTime))
+         .add("storageClass", archiveFile->storageClass)
+         .add("getConnTime", getConnTime)
+         .add("createStmtTime", createStmtTime)
+         .add("selectFromArchiveFileTime", selectFromArchiveFileTime);
+      for(auto it=archiveFile->tapeFiles.begin(); it!=archiveFile->tapeFiles.end(); it++) {
+        std::stringstream tapeCopyLogStream;
+        tapeCopyLogStream << "copy number: " << it->first
+          << " vid: " << it->second.vid
+          << " fSeq: " << it->second.fSeq
+          << " blockId: " << it->second.blockId
+          << " creationTime: " << it->second.creationTime
+          << " compressedSize: " << it->second.compressedSize
+          << " checksumType: " << it->second.checksumType //this shouldn't be here: repeated field
+          << " checksumValue: " << it->second.checksumValue //this shouldn't be here: repeated field
+          << " copyNb: " << it->second.copyNb; //this shouldn't be here: repeated field
+        spc.add("TAPE FILE", tapeCopyLogStream.str());
+      }
+      lc.log(log::WARNING, "Failed to delete archive file because the disk instance of the request does not match that "
+        "of the archived file");
+
+      exception::UserError ue;
+      ue.getMessage() << "Failed to delete archive file with ID " << archiveFileId << " because the disk instance of "
+        "the request does not match that of the archived file: archiveFileId=" << archiveFileId << " path=" <<
+        archiveFile->diskFileInfo.path << " requestDiskInstance=" << diskInstanceName << " archiveFileDiskInstance=" <<
+        archiveFile->diskInstance;
+      throw ue;
+    }
+
+    t.reset();
+    {
+      const char *const sql = "DELETE FROM TAPE_FILE WHERE ARCHIVE_FILE_ID = :ARCHIVE_FILE_ID";
+      auto stmt = conn.createStmt(sql);
+      stmt.bindUint64(":ARCHIVE_FILE_ID", archiveFileId);
+      stmt.executeNonQuery();
+    }
+    const auto deleteFromTapeFileTime = t.secs(utils::Timer::resetCounter);
+
+    {
+      const char *const sql = "DELETE FROM ARCHIVE_FILE WHERE ARCHIVE_FILE_ID = :ARCHIVE_FILE_ID";
+      auto stmt = conn.createStmt(sql);
+      stmt.bindUint64(":ARCHIVE_FILE_ID", archiveFileId);
+      stmt.executeNonQuery();
+    }
+    const auto deleteFromArchiveFileTime = t.secs(utils::Timer::resetCounter);
+
+    conn.commit();
+    autoRollback.cancel();
+    const auto commitTime = t.secs();
+
+    log::ScopedParamContainer spc(lc);
+    spc.add("fileId", std::to_string(archiveFile->archiveFileID))
+       .add("diskInstance", archiveFile->diskInstance)
+       .add("diskFileId", archiveFile->diskFileId)
+       .add("diskFileInfo.path", archiveFile->diskFileInfo.path)
+       .add("diskFileInfo.owner", archiveFile->diskFileInfo.owner)
+       .add("diskFileInfo.group", archiveFile->diskFileInfo.group)
+       .add("fileSize", std::to_string(archiveFile->fileSize))
+       .add("checksumType", archiveFile->checksumType)
+       .add("checksumValue", archiveFile->checksumValue)
+       .add("creationTime", std::to_string(archiveFile->creationTime))
+       .add("reconciliationTime", std::to_string(archiveFile->reconciliationTime))
+       .add("storageClass", archiveFile->storageClass)
+       .add("getConnTime", getConnTime)
+       .add("createStmtTime", createStmtTime)
+       .add("selectFromArchiveFileTime", selectFromArchiveFileTime)
+       .add("deleteFromTapeFileTime", deleteFromTapeFileTime)
+       .add("deleteFromArchiveFileTime", deleteFromArchiveFileTime)
+       .add("commitTime", commitTime);
+    for(auto it=archiveFile->tapeFiles.begin(); it!=archiveFile->tapeFiles.end(); it++) {
+      std::stringstream tapeCopyLogStream;
+      tapeCopyLogStream << "copy number: " << it->first
+        << " vid: " << it->second.vid
+        << " fSeq: " << it->second.fSeq
+        << " blockId: " << it->second.blockId
+        << " creationTime: " << it->second.creationTime
+        << " compressedSize: " << it->second.compressedSize
+        << " checksumType: " << it->second.checksumType //this shouldn't be here: repeated field
+        << " checksumValue: " << it->second.checksumValue //this shouldn't be here: repeated field
+        << " copyNb: " << it->second.copyNb; //this shouldn't be here: repeated field
+      spc.add("TAPE FILE", tapeCopyLogStream.str());
+    }
+    lc.log(log::INFO, "Archive file deleted from CTA catalogue");
+  } catch(exception::UserError &) {
+    throw;
+  } catch(exception::Exception &ex) {
+    ex.getMessage().str(std::string(__FUNCTION__) + ": " + ex.getMessage().str());
+    throw;
+  }
+}
+
+//------------------------------------------------------------------------------
+// createTemporaryTables
+//------------------------------------------------------------------------------
+void PostgresCatalogue::beginCreateTemporarySetDeferred(rdbms::Conn &conn) const {
+  const char *const sql_temptables =
+    "BEGIN;"
+    "CREATE TEMPORARY TABLE TEMP_ARCHIVE_FILE_BATCH ("
+      "LIKE ARCHIVE_FILE) "
+      "ON COMMIT DROP;"
+    "ALTER TABLE TEMP_ARCHIVE_FILE_BATCH "
+      "ADD COLUMN STORAGE_CLASS_NAME VARCHAR(100);"
+    "ALTER TABLE TEMP_ARCHIVE_FILE_BATCH "
+      "ALTER COLUMN STORAGE_CLASS_ID DROP NOT NULL;"
+    "CREATE INDEX TEMP_A_F_B_ARCHIVE_FILE_ID_I ON "
+      "TEMP_ARCHIVE_FILE_BATCH(ARCHIVE_FILE_ID);"
+    "CREATE INDEX TEMP_A_F_B_DIN_SCN_I ON "
+      "TEMP_ARCHIVE_FILE_BATCH(DISK_INSTANCE_NAME, STORAGE_CLASS_NAME);"
+    "CREATE TEMPORARY TABLE TEMP_TAPE_FILE_BATCH("
+      "ARCHIVE_FILE_ID NUMERIC(20,0)) "
+      "ON COMMIT DROP;"
+    "CREATE INDEX TEMP_T_F_B_ARCHIVE_FILE_ID_I ON "
+      "TEMP_TAPE_FILE_BATCH(ARCHIVE_FILE_ID);"
+    "SET CONSTRAINTS ARCHIVE_FILE_DIN_DFI_UN DEFERRED";
+
+  conn.executeNonQuery(sql_temptables);
+}
+
+
+} // namespace catalogue
+} // namespace cta
diff --git a/catalogue/PostgresCatalogue.hpp b/catalogue/PostgresCatalogue.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..b5daec4f5a557ad8125810beae4ecdaa7e87051c
--- /dev/null
+++ b/catalogue/PostgresCatalogue.hpp
@@ -0,0 +1,184 @@
+/*
+ * The CERN Tape Archive(CTA) project
+ * Copyright(C) 2019  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/>.
+ */
+
+#pragma once
+
+#include "catalogue/RdbmsCatalogue.hpp"
+#include "rdbms/Conn.hpp"
+
+namespace cta {
+namespace catalogue {
+
+/**
+ * An Postgres based implementation of the CTA catalogue.
+ */
+class PostgresCatalogue: public RdbmsCatalogue {
+public:
+
+  /**
+   * Constructor.
+   *
+   * @param log Object representing the API to the CTA logging system.
+   * @param username The database username.
+   * @param password The database password.
+   * @param database The database name.
+   * @param nbConns The maximum number of concurrent connections to the
+   * underlying relational database for all operations accept listing archive
+   * files which can be relatively long operations.
+   * @param nbArchiveFileListingConns The maximum number of concurrent
+   * connections to the underlying relational database for the sole purpose of
+   * listing archive files.
+   */
+  PostgresCatalogue(
+    log::Logger &log,
+    const rdbms::Login &login,
+    const uint64_t nbConns,
+    const uint64_t nbArchiveFileListingConns);
+
+  /**
+   * Destructor.
+   */
+  ~PostgresCatalogue() override;
+
+  /**
+   * Deletes the specified archive file and its associated tape copies from the
+   * catalogue.
+   *
+   * Please note that the name of the disk instance is specified in order to
+   * prevent a disk instance deleting an archive file that belongs to another
+   * disk instance.
+   *
+   * Please note that this method is idempotent.  If the file to be deleted does
+   * not exist in the CTA catalogue then this method returns without error.
+   *
+   * @param instanceName The name of the instance from where the deletion request
+   * originated
+   * @param archiveFileId The unique identifier of the archive file.
+   * @param lc The log context.
+   * @return The metadata of the deleted archive file including the metadata of
+   * the associated and also deleted tape copies.
+   */
+  void deleteArchiveFile(const std::string &instanceName, const uint64_t archiveFileId,
+    log::LogContext &lc) override;
+
+  /**
+   * Notifies the catalogue that the specified files have been written to tape.
+   *
+   * @param events The tape file written events.
+   */
+  void filesWrittenToTape(const std::set<TapeItemWrittenPointer> &events) override;
+
+  /**
+   * Returns a unique archive ID that can be used by a new archive file within
+   * the catalogue.
+   *
+   * This method must be implemented by the sub-classes of RdbmsCatalogue
+   * because different database technologies propose different solution to the
+   * problem of generating ever increasing numeric identifiers.
+   *
+   * @param conn The database connection.
+   * @return A unique archive ID that can be used by a new archive file within
+   * the catalogue.
+   */
+  uint64_t getNextArchiveFileId(rdbms::Conn &conn) override;
+
+  /**
+   * Returns a unique storage class ID that can be used by a new storage class
+   * within the catalogue.
+   *
+   * This method must be implemented by the sub-classes of RdbmsCatalogue
+   * because different database technologies propose different solution to the
+   * problem of generating ever increasing numeric identifiers.
+   *
+   * @param conn The database connection.
+   * @return a unique archive ID that can be used by a new archive file within
+   * within the catalogue.
+   */
+  uint64_t getNextStorageClassId(rdbms::Conn &conn) override;
+
+
+private:
+
+  /**
+   * Start a database transaction and then create the temporary
+   * tables TEMP_ARCHIVE_FILE_BATCH and TEMP_TAPE_FILE_BATCH.
+   * Sets deferred mode for one of the db constraints to avoid
+   * violations during concurrent bulk insert.
+   *
+   * @parm conn The database connection.
+   */
+  void beginCreateTemporarySetDeferred(rdbms::Conn &conn) const;
+
+  /**
+   * Selects the specified tape within the Tape table for update.
+   *
+   * @param conn The database connection.
+   * @param vid The volume identifier of the tape.
+   */
+  common::dataStructures::Tape selectTapeForUpdate(rdbms::Conn &conn, const std::string &vid) const;
+
+  /**
+   * Batch inserts rows into the ARCHIVE_FILE table that correspond to the
+   * specified TapeFileWritten events.
+   *
+   * This method has idempotent behaviour in the case where an ARCHIVE_FILE
+   * already exists.  Such a situation will occur when a file has more than one
+   * copy on tape.  The first tape copy will cause two successful inserts, one
+   * into the ARCHIVE_FILE table and one into the  TAPE_FILE table.  The second
+   * tape copy will try to do the same, but the insert into the ARCHIVE_FILE
+   * table will fail or simply bounce as the row will already exists.  The
+   * insert into the TABLE_FILE table will succeed because the two TAPE_FILE
+   * rows will be unique.
+   *
+   * @param conn The database connection.
+   * @param events The tape file written events.
+   */
+  void idempotentBatchInsertArchiveFiles(rdbms::Conn &conn, const std::set<TapeFileWritten> &events) const;
+
+  /**
+   * The size and checksum of a file.
+   */
+  struct FileSizeAndChecksum {
+    uint64_t fileSize;
+    std::string checksumType;
+    std::string checksumValue;
+  };
+
+  /**
+   * Returns the sizes and checksums of the specified archive files.
+   *
+   * @param conn The database connection.
+   * @param events The tape file written events that identify the archive files.
+   * @return A map from the identifier of each archive file to its size and checksum.
+   */
+  std::map<uint64_t, FileSizeAndChecksum> selectArchiveFileSizesAndChecksums(rdbms::Conn &conn,
+    const std::set<TapeFileWritten> &events) const;
+
+  /**
+   * Batch inserts rows into the TAPE_FILE_BATCH temporary table that correspond
+   * to the specified TapeFileWritten events.
+   *
+   * @param conn The database connection.
+   * @param events The tape file written events.
+   */
+  void insertTapeFileBatchIntoTempTable(rdbms::Conn &conn, const std::set<TapeFileWritten> &events) const;
+
+}; // class PostgresCatalogue
+
+} // namespace catalogue
+} // namespace cta
diff --git a/catalogue/PostgresCatalogueSchema.before_SQL.cpp b/catalogue/PostgresCatalogueSchema.before_SQL.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..c13c19a7dd3d6b2884652c6a048ed1c105651058
--- /dev/null
+++ b/catalogue/PostgresCatalogueSchema.before_SQL.cpp
@@ -0,0 +1,33 @@
+/*
+ * The CERN Tape Archive (CTA) project
+ * Copyright (C) 2019  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 "catalogue/PostgresCatalogueSchema.hpp"
+
+namespace cta {
+namespace catalogue {
+
+//------------------------------------------------------------------------------
+// constructor
+//------------------------------------------------------------------------------
+PostgresCatalogueSchema::PostgresCatalogueSchema(): sql(
+  // CTA_SQL_SCHEMA - The contents of postgres_catalogue_schema.cpp go here
+  ) {
+}
+
+} // namespace catalogue
+} // namespace cta
diff --git a/catalogue/PostgresCatalogueSchema.hpp b/catalogue/PostgresCatalogueSchema.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..a7c4d07ab21af556b414867a4b33596a58713bdd
--- /dev/null
+++ b/catalogue/PostgresCatalogueSchema.hpp
@@ -0,0 +1,54 @@
+/*
+ * The CERN Tape Archive (CTA) project
+ * Copyright (C) 2019  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/>.
+ */
+
+#pragma once
+
+#include <string>
+
+namespace cta {
+namespace catalogue {
+
+/**
+ * Structure containing the SQL to create the schema of the in memory CTA
+ * database.
+ *
+ * The CMakeLists.txt file of this directory instructs cmake to generate
+ * PostgresCatalogueSchema.cpp from:
+ *   - PostgresCatalogueSchema.before_SQL.cpp
+ *   - postgres_catalogue_schema.sql
+ *
+ * The PostgresSchema.before_SQL.cpp file is not compilable and is therefore
+ * difficult for Integrated Developent Environments (IDEs) to handle.
+ *
+ * The purpose of this class is to help IDEs by isolating the "non-compilable"
+ * issues into a small cpp file.
+ */
+struct PostgresCatalogueSchema {
+  /**
+   * Constructor.
+   */
+  PostgresCatalogueSchema();
+
+  /**
+   * The schema.
+   */
+  const std::string sql;
+};
+
+} // namespace catalogue
+} // namespace cta
diff --git a/catalogue/PostgresqlCatalogueFactory.cpp b/catalogue/PostgresqlCatalogueFactory.cpp
index 6f38aafbd7a8d6663bd6a7f311d9da9df7f7b7c2..4b4e82393e5543e844f045357745c60e88af2e28 100644
--- a/catalogue/PostgresqlCatalogueFactory.cpp
+++ b/catalogue/PostgresqlCatalogueFactory.cpp
@@ -18,6 +18,7 @@
 
 #include "catalogue/CatalogueRetryWrapper.hpp"
 #include "catalogue/PostgresqlCatalogueFactory.hpp"
+#include "catalogue/PostgresCatalogue.hpp"
 #include "common/exception/Exception.hpp"
 #include "common/make_unique.hpp"
 
@@ -50,7 +51,12 @@ PostgresqlCatalogueFactory::PostgresqlCatalogueFactory(
 // create
 //------------------------------------------------------------------------------
 std::unique_ptr<Catalogue> PostgresqlCatalogueFactory::create() {
-  throw exception::Exception(std::string(__FUNCTION__) + ": Not implemented");
+  try {
+    auto c = cta::make_unique<PostgresCatalogue>(m_log, m_login, m_nbConns, m_nbArchiveFileListingConns);
+    return cta::make_unique<CatalogueRetryWrapper>(m_log, std::move(c), m_maxTriesToConnect);
+  } catch(exception::Exception &ex) {
+    throw exception::Exception(std::string(__FUNCTION__) + " failed: " + ex.getMessage().str());
+  }
 }
 
 } // namespace catalogue
diff --git a/catalogue/RdbmsCatalogue.cpp b/catalogue/RdbmsCatalogue.cpp
index 4d2eccc1af63b5fee7e5a0922cd996f93b6b7ff8..85c73d1bf35e561be9c5e3dccc82b43ffa628d7b 100644
--- a/catalogue/RdbmsCatalogue.cpp
+++ b/catalogue/RdbmsCatalogue.cpp
@@ -1862,7 +1862,6 @@ std::list<common::dataStructures::Tape> RdbmsCatalogue::getTapes(rdbms::Conn &co
         "TAPE.LAST_FSEQ AS LAST_FSEQ,"
         "TAPE.IS_DISABLED AS IS_DISABLED,"
         "TAPE.IS_FULL AS IS_FULL,"
-        "TAPE.LBP_IS_ON AS LBP_IS_ON,"
 
         "TAPE.LABEL_DRIVE AS LABEL_DRIVE,"
         "TAPE.LABEL_TIME AS LABEL_TIME,"
@@ -1895,8 +1894,7 @@ std::list<common::dataStructures::Tape> RdbmsCatalogue::getTapes(rdbms::Conn &co
        searchCriteria.vo ||
        searchCriteria.capacityInBytes ||
        searchCriteria.disabled ||
-       searchCriteria.full ||
-       searchCriteria.lbp) {
+       searchCriteria.full) {
       sql += " WHERE ";
     }
 
@@ -1946,10 +1944,6 @@ std::list<common::dataStructures::Tape> RdbmsCatalogue::getTapes(rdbms::Conn &co
       sql += " TAPE.IS_FULL = :IS_FULL";
       addedAWhereConstraint = true;
     }
-    if(searchCriteria.lbp) {
-      if(addedAWhereConstraint) sql += " AND ";
-      sql += " TAPE.LBP_IS_ON = :LBP_IS_ON";
-    }
 
     sql += " ORDER BY TAPE.VID";
 
@@ -1964,7 +1958,6 @@ std::list<common::dataStructures::Tape> RdbmsCatalogue::getTapes(rdbms::Conn &co
     if(searchCriteria.capacityInBytes) stmt.bindUint64(":CAPACITY_IN_BYTES", searchCriteria.capacityInBytes.value());
     if(searchCriteria.disabled) stmt.bindBool(":IS_DISABLED", searchCriteria.disabled.value());
     if(searchCriteria.full) stmt.bindBool(":IS_FULL", searchCriteria.full.value());
-    if(searchCriteria.lbp) stmt.bindBool(":LBP_IS_ON", searchCriteria.lbp.value());
 
     auto rset = stmt.executeQuery();
     while (rset.next()) {
@@ -1982,7 +1975,6 @@ std::list<common::dataStructures::Tape> RdbmsCatalogue::getTapes(rdbms::Conn &co
       tape.lastFSeq = rset.columnUint64("LAST_FSEQ");
       tape.disabled = rset.columnBool("IS_DISABLED");
       tape.full = rset.columnBool("IS_FULL");
-      tape.lbp = rset.columnOptionalBool("LBP_IS_ON");
 
       tape.labelLog = getTapeLogFromRset(rset, "LABEL_DRIVE", "LABEL_TIME");
       tape.lastReadLog = getTapeLogFromRset(rset, "LAST_READ_DRIVE", "LAST_READ_TIME");
@@ -2028,7 +2020,6 @@ common::dataStructures::VidToTapeMap RdbmsCatalogue::getTapesByVid(const std::se
         "TAPE.LAST_FSEQ AS LAST_FSEQ,"
         "TAPE.IS_DISABLED AS IS_DISABLED,"
         "TAPE.IS_FULL AS IS_FULL,"
-        "TAPE.LBP_IS_ON AS LBP_IS_ON,"
 
         "TAPE.LABEL_DRIVE AS LABEL_DRIVE,"
         "TAPE.LABEL_TIME AS LABEL_TIME,"
@@ -2096,7 +2087,6 @@ common::dataStructures::VidToTapeMap RdbmsCatalogue::getTapesByVid(const std::se
       tape.lastFSeq = rset.columnUint64("LAST_FSEQ");
       tape.disabled = rset.columnBool("IS_DISABLED");
       tape.full = rset.columnBool("IS_FULL");
-      tape.lbp = rset.columnOptionalBool("LBP_IS_ON");
 
       tape.labelLog = getTapeLogFromRset(rset, "LABEL_DRIVE", "LABEL_TIME");
       tape.lastReadLog = getTapeLogFromRset(rset, "LAST_READ_DRIVE", "LAST_READ_TIME");
@@ -2146,7 +2136,6 @@ common::dataStructures::VidToTapeMap RdbmsCatalogue::getAllTapes() const {
         "TAPE.LAST_FSEQ AS LAST_FSEQ,"
         "TAPE.IS_DISABLED AS IS_DISABLED,"
         "TAPE.IS_FULL AS IS_FULL,"
-        "TAPE.LBP_IS_ON AS LBP_IS_ON,"
 
         "TAPE.LABEL_DRIVE AS LABEL_DRIVE,"
         "TAPE.LABEL_TIME AS LABEL_TIME,"
@@ -2190,7 +2179,6 @@ common::dataStructures::VidToTapeMap RdbmsCatalogue::getAllTapes() const {
       tape.lastFSeq = rset.columnUint64("LAST_FSEQ");
       tape.disabled = rset.columnBool("IS_DISABLED");
       tape.full = rset.columnBool("IS_FULL");
-      tape.lbp = rset.columnOptionalBool("LBP_IS_ON");
 
       tape.labelLog = getTapeLogFromRset(rset, "LABEL_DRIVE", "LABEL_TIME");
       tape.lastReadLog = getTapeLogFromRset(rset, "LAST_READ_DRIVE", "LAST_READ_TIME");
@@ -2226,13 +2214,13 @@ void RdbmsCatalogue::reclaimTape(const common::dataStructures::SecurityIdentity
       "UPDATE TAPE SET "
         "DATA_IN_BYTES = 0,"
         "LAST_FSEQ = 0,"
-        "IS_FULL = 0,"
+        "IS_FULL = '0',"
         "LAST_UPDATE_USER_NAME = :LAST_UPDATE_USER_NAME,"
         "LAST_UPDATE_HOST_NAME = :LAST_UPDATE_HOST_NAME,"
         "LAST_UPDATE_TIME = :LAST_UPDATE_TIME "
       "WHERE "
         "VID = :UPDATE_VID AND "
-        "IS_FULL != 0 AND "
+        "IS_FULL != '0' AND "
         "NOT EXISTS (SELECT VID FROM TAPE_FILE WHERE VID = :SELECT_VID)";
     auto conn = m_connPool.getConn();
     auto stmt = conn.createStmt(sql);
@@ -2621,7 +2609,7 @@ void RdbmsCatalogue::noSpaceLeftOnTape(const std::string &vid) {
   try {
     const char *const sql =
       "UPDATE TAPE SET "
-        "IS_FULL = 1 "
+        "IS_FULL = '1' "
       "WHERE "
         "VID = :VID";
     auto conn = m_connPool.getConn();
@@ -3864,7 +3852,6 @@ void RdbmsCatalogue::insertArchiveFile(rdbms::Conn &conn, const ArchiveFileRow &
         "DISK_FILE_PATH,"
         "DISK_FILE_USER,"
         "DISK_FILE_GROUP,"
-        "DISK_FILE_RECOVERY_BLOB,"
         "SIZE_IN_BYTES,"
         "CHECKSUM_TYPE,"
         "CHECKSUM_VALUE,"
@@ -3878,7 +3865,6 @@ void RdbmsCatalogue::insertArchiveFile(rdbms::Conn &conn, const ArchiveFileRow &
         ":DISK_FILE_PATH,"
         ":DISK_FILE_USER,"
         ":DISK_FILE_GROUP,"
-        ":DISK_FILE_RECOVERY_BLOB,"
         ":SIZE_IN_BYTES,"
         ":CHECKSUM_TYPE,"
         ":CHECKSUM_VALUE,"
@@ -3898,7 +3884,6 @@ void RdbmsCatalogue::insertArchiveFile(rdbms::Conn &conn, const ArchiveFileRow &
     stmt.bindString(":DISK_FILE_PATH", row.diskFilePath);
     stmt.bindString(":DISK_FILE_USER", row.diskFileUser);
     stmt.bindString(":DISK_FILE_GROUP", row.diskFileGroup);
-    stmt.bindString(":DISK_FILE_RECOVERY_BLOB", row.diskFileRecoveryBlob);
     stmt.bindUint64(":SIZE_IN_BYTES", row.size);
     stmt.bindString(":CHECKSUM_TYPE", row.checksumType);
     stmt.bindString(":CHECKSUM_VALUE", row.checksumValue);
@@ -4036,7 +4021,6 @@ std::list<common::dataStructures::ArchiveFile> RdbmsCatalogue::getFilesForRepack
         "ARCHIVE_FILE.DISK_FILE_PATH AS DISK_FILE_PATH,"
         "ARCHIVE_FILE.DISK_FILE_USER AS DISK_FILE_USER,"
         "ARCHIVE_FILE.DISK_FILE_GROUP AS DISK_FILE_GROUP,"
-        "ARCHIVE_FILE.DISK_FILE_RECOVERY_BLOB AS DISK_FILE_RECOVERY_BLOB,"
         "ARCHIVE_FILE.SIZE_IN_BYTES AS SIZE_IN_BYTES,"
         "ARCHIVE_FILE.CHECKSUM_TYPE AS CHECKSUM_TYPE,"
         "ARCHIVE_FILE.CHECKSUM_VALUE AS CHECKSUM_VALUE,"
@@ -4079,7 +4063,6 @@ std::list<common::dataStructures::ArchiveFile> RdbmsCatalogue::getFilesForRepack
       archiveFile.diskFileInfo.path = rset.columnString("DISK_FILE_PATH");
       archiveFile.diskFileInfo.owner = rset.columnString("DISK_FILE_USER");
       archiveFile.diskFileInfo.group = rset.columnString("DISK_FILE_GROUP");
-      archiveFile.diskFileInfo.recoveryBlob = rset.columnString("DISK_FILE_RECOVERY_BLOB");
       archiveFile.fileSize = rset.columnUint64("SIZE_IN_BYTES");
       archiveFile.checksumType = rset.columnString("CHECKSUM_TYPE");
       archiveFile.checksumValue = rset.columnString("CHECKSUM_VALUE");
@@ -4289,21 +4272,19 @@ common::dataStructures::ArchiveFile RdbmsCatalogue::getArchiveFileById(const uin
 //------------------------------------------------------------------------------
 // tapeLabelled
 //------------------------------------------------------------------------------
-void RdbmsCatalogue::tapeLabelled(const std::string &vid, const std::string &drive, const bool lbpIsOn) {
+void RdbmsCatalogue::tapeLabelled(const std::string &vid, const std::string &drive) {
   try {
     const time_t now = time(nullptr);
     const char *const sql =
       "UPDATE TAPE SET "
         "LABEL_DRIVE = :LABEL_DRIVE,"
-        "LABEL_TIME = :LABEL_TIME,"
-        "LBP_IS_ON = :LBP_IS_ON "
+        "LABEL_TIME = :LABEL_TIME "
       "WHERE "
         "VID = :VID";
     auto conn = m_connPool.getConn();
     auto stmt = conn.createStmt(sql);
     stmt.bindString(":LABEL_DRIVE", drive);
     stmt.bindUint64(":LABEL_TIME", now);
-    stmt.bindBool(":LBP_IS_ON", lbpIsOn);
     stmt.bindString(":VID", vid);
     stmt.executeNonQuery();
 
@@ -4806,11 +4787,10 @@ std::list<TapeForWriting> RdbmsCatalogue::getTapesForWriting(const std::string &
       "INNER JOIN TAPE_POOL ON "
         "TAPE.TAPE_POOL_NAME = TAPE_POOL.TAPE_POOL_NAME "
       "WHERE "
-//      "LBP_IS_ON IS NOT NULL AND "   // Set when the tape has been labelled
 //      "LABEL_DRIVE IS NOT NULL AND " // Set when the tape has been labelled
 //      "LABEL_TIME IS NOT NULL AND "  // Set when the tape has been labelled
-        "IS_DISABLED = 0 AND "
-        "IS_FULL = 0 AND "
+        "IS_DISABLED = '0' AND "
+        "IS_FULL = '0' AND "
         "LOGICAL_LIBRARY_NAME = :LOGICAL_LIBRARY_NAME";
 
     auto conn = m_connPool.getConn();
@@ -4958,7 +4938,6 @@ std::unique_ptr<common::dataStructures::ArchiveFile> RdbmsCatalogue::getArchiveF
         "ARCHIVE_FILE.DISK_FILE_PATH AS DISK_FILE_PATH,"
         "ARCHIVE_FILE.DISK_FILE_USER AS DISK_FILE_USER,"
         "ARCHIVE_FILE.DISK_FILE_GROUP AS DISK_FILE_GROUP,"
-        "ARCHIVE_FILE.DISK_FILE_RECOVERY_BLOB AS DISK_FILE_RECOVERY_BLOB,"
         "ARCHIVE_FILE.SIZE_IN_BYTES AS SIZE_IN_BYTES,"
         "ARCHIVE_FILE.CHECKSUM_TYPE AS CHECKSUM_TYPE,"
         "ARCHIVE_FILE.CHECKSUM_VALUE AS CHECKSUM_VALUE,"
@@ -4995,7 +4974,6 @@ std::unique_ptr<common::dataStructures::ArchiveFile> RdbmsCatalogue::getArchiveF
         archiveFile->diskFileInfo.path = rset.columnString("DISK_FILE_PATH");
         archiveFile->diskFileInfo.owner = rset.columnString("DISK_FILE_USER");
         archiveFile->diskFileInfo.group = rset.columnString("DISK_FILE_GROUP");
-        archiveFile->diskFileInfo.recoveryBlob = rset.columnString("DISK_FILE_RECOVERY_BLOB");
         archiveFile->fileSize = rset.columnUint64("SIZE_IN_BYTES");
         archiveFile->checksumType = rset.columnString("CHECKSUM_TYPE");
         archiveFile->checksumValue = rset.columnString("CHECKSUM_VALUE");
@@ -5044,7 +5022,6 @@ std::unique_ptr<common::dataStructures::ArchiveFile> RdbmsCatalogue::getArchiveF
         "ARCHIVE_FILE.DISK_FILE_PATH AS DISK_FILE_PATH,"
         "ARCHIVE_FILE.DISK_FILE_USER AS DISK_FILE_USER,"
         "ARCHIVE_FILE.DISK_FILE_GROUP AS DISK_FILE_GROUP,"
-        "ARCHIVE_FILE.DISK_FILE_RECOVERY_BLOB AS DISK_FILE_RECOVERY_BLOB,"
         "ARCHIVE_FILE.SIZE_IN_BYTES AS SIZE_IN_BYTES,"
         "ARCHIVE_FILE.CHECKSUM_TYPE AS CHECKSUM_TYPE,"
         "ARCHIVE_FILE.CHECKSUM_VALUE AS CHECKSUM_VALUE,"
@@ -5067,7 +5044,7 @@ std::unique_ptr<common::dataStructures::ArchiveFile> RdbmsCatalogue::getArchiveF
         "TAPE_FILE.VID = TAPE.VID "
       "WHERE "
         "ARCHIVE_FILE.ARCHIVE_FILE_ID = :ARCHIVE_FILE_ID AND "
-        "TAPE.IS_DISABLED = 0 "
+        "TAPE.IS_DISABLED = '0' "
       "ORDER BY "
         "TAPE_FILE.CREATION_TIME ASC";
     auto stmt = conn.createStmt(sql);
@@ -5084,7 +5061,6 @@ std::unique_ptr<common::dataStructures::ArchiveFile> RdbmsCatalogue::getArchiveF
         archiveFile->diskFileInfo.path = rset.columnString("DISK_FILE_PATH");
         archiveFile->diskFileInfo.owner = rset.columnString("DISK_FILE_USER");
         archiveFile->diskFileInfo.group = rset.columnString("DISK_FILE_GROUP");
-        archiveFile->diskFileInfo.recoveryBlob = rset.columnString("DISK_FILE_RECOVERY_BLOB");
         archiveFile->fileSize = rset.columnUint64("SIZE_IN_BYTES");
         archiveFile->checksumType = rset.columnString("CHECKSUM_TYPE");
         archiveFile->checksumValue = rset.columnString("CHECKSUM_VALUE");
@@ -5135,7 +5111,6 @@ std::unique_ptr<common::dataStructures::ArchiveFile> RdbmsCatalogue::getArchiveF
         "ARCHIVE_FILE.DISK_FILE_PATH AS DISK_FILE_PATH,"
         "ARCHIVE_FILE.DISK_FILE_USER AS DISK_FILE_USER,"
         "ARCHIVE_FILE.DISK_FILE_GROUP AS DISK_FILE_GROUP,"
-        "ARCHIVE_FILE.DISK_FILE_RECOVERY_BLOB AS DISK_FILE_RECOVERY_BLOB,"
         "ARCHIVE_FILE.SIZE_IN_BYTES AS SIZE_IN_BYTES,"
         "ARCHIVE_FILE.CHECKSUM_TYPE AS CHECKSUM_TYPE,"
         "ARCHIVE_FILE.CHECKSUM_VALUE AS CHECKSUM_VALUE,"
@@ -5174,7 +5149,6 @@ std::unique_ptr<common::dataStructures::ArchiveFile> RdbmsCatalogue::getArchiveF
         archiveFile->diskFileInfo.path = rset.columnString("DISK_FILE_PATH");
         archiveFile->diskFileInfo.owner = rset.columnString("DISK_FILE_USER");
         archiveFile->diskFileInfo.group = rset.columnString("DISK_FILE_GROUP");
-        archiveFile->diskFileInfo.recoveryBlob = rset.columnString("DISK_FILE_RECOVERY_BLOB");
         archiveFile->fileSize = rset.columnUint64("SIZE_IN_BYTES");
         archiveFile->checksumType = rset.columnString("CHECKSUM_TYPE");
         archiveFile->checksumValue = rset.columnString("CHECKSUM_VALUE");
@@ -5225,7 +5199,6 @@ std::unique_ptr<common::dataStructures::ArchiveFile> RdbmsCatalogue::getArchiveF
         "ARCHIVE_FILE.DISK_FILE_PATH AS DISK_FILE_PATH,"
         "ARCHIVE_FILE.DISK_FILE_USER AS DISK_FILE_USER,"
         "ARCHIVE_FILE.DISK_FILE_GROUP AS DISK_FILE_GROUP,"
-        "ARCHIVE_FILE.DISK_FILE_RECOVERY_BLOB AS DISK_FILE_RECOVERY_BLOB,"
         "ARCHIVE_FILE.SIZE_IN_BYTES AS SIZE_IN_BYTES,"
         "ARCHIVE_FILE.CHECKSUM_TYPE AS CHECKSUM_TYPE,"
         "ARCHIVE_FILE.CHECKSUM_VALUE AS CHECKSUM_VALUE,"
@@ -5249,7 +5222,7 @@ std::unique_ptr<common::dataStructures::ArchiveFile> RdbmsCatalogue::getArchiveF
       "WHERE "
         "ARCHIVE_FILE.DISK_INSTANCE_NAME = :DISK_INSTANCE_NAME AND "
         "ARCHIVE_FILE.DISK_FILE_ID = :DISK_FILE_ID AND "
-        "TAPE.IS_DISABLED = 0 "
+        "TAPE.IS_DISABLED = '0' "
       "ORDER BY "
         "TAPE_FILE.CREATION_TIME ASC";
     auto stmt = conn.createStmt(sql);
@@ -5267,7 +5240,6 @@ std::unique_ptr<common::dataStructures::ArchiveFile> RdbmsCatalogue::getArchiveF
         archiveFile->diskFileInfo.path = rset.columnString("DISK_FILE_PATH");
         archiveFile->diskFileInfo.owner = rset.columnString("DISK_FILE_USER");
         archiveFile->diskFileInfo.group = rset.columnString("DISK_FILE_GROUP");
-        archiveFile->diskFileInfo.recoveryBlob = rset.columnString("DISK_FILE_RECOVERY_BLOB");
         archiveFile->fileSize = rset.columnUint64("SIZE_IN_BYTES");
         archiveFile->checksumType = rset.columnString("CHECKSUM_TYPE");
         archiveFile->checksumValue = rset.columnString("CHECKSUM_VALUE");
@@ -5328,7 +5300,7 @@ std::list<std::string> RdbmsCatalogue::getTableNames() const {
 }
 
 //------------------------------------------------------------------------------
-// checkTapeWrittenFilesAreSet
+// checkTapeFileWrittenFieldsAreSet
 //------------------------------------------------------------------------------
 void RdbmsCatalogue::checkTapeFileWrittenFieldsAreSet(const std::string &callingFunc, const TapeFileWritten &event)
   const {
@@ -5338,7 +5310,6 @@ void RdbmsCatalogue::checkTapeFileWrittenFieldsAreSet(const std::string &calling
     if(event.diskFilePath.empty()) throw exception::Exception("diskFilePath is an empty string");
     if(event.diskFileUser.empty()) throw exception::Exception("diskFileUser is an empty string");
     if(event.diskFileGroup.empty()) throw exception::Exception("diskFileGroup is an empty string");
-    if(event.diskFileRecoveryBlob.empty()) throw exception::Exception("diskFileRecoveryBlob is an empty string");
     if(0 == event.size) throw exception::Exception("size is 0");
     if(event.checksumType.empty()) throw exception::Exception("checksumType is an empty string");
     if(event.checksumValue.empty()) throw exception::Exception("checksumValue is an empty string");
diff --git a/catalogue/RdbmsCatalogue.hpp b/catalogue/RdbmsCatalogue.hpp
index 04854b7c47d3b29c65ca05703150295153268600..779e7ca789cdf358b58a512cb7b639086a6921c9 100644
--- a/catalogue/RdbmsCatalogue.hpp
+++ b/catalogue/RdbmsCatalogue.hpp
@@ -94,9 +94,8 @@ public:
    *
    * @param vid The volume identifier of the tape.
    * @param drive The name of tape drive that was used to label the tape.
-   * @param lbpIsOn Set to true if Logical Block Protection (LBP) was enabled.
    */
-  void tapeLabelled(const std::string &vid, const std::string &drive, const bool lbpIsOn) override;
+  void tapeLabelled(const std::string &vid, const std::string &drive) override;
 
   /**
    * Checks the specified archival could take place and returns a new and
diff --git a/catalogue/RdbmsCatalogueGetArchiveFilesForRepackItor.cpp b/catalogue/RdbmsCatalogueGetArchiveFilesForRepackItor.cpp
index d207690f3e6ea066a15f37a77f468c1c4cb54c01..c3895566e4b60acff18889aa11f01b86156d3b77 100644
--- a/catalogue/RdbmsCatalogueGetArchiveFilesForRepackItor.cpp
+++ b/catalogue/RdbmsCatalogueGetArchiveFilesForRepackItor.cpp
@@ -46,7 +46,6 @@ namespace {
     archiveFile.diskFileInfo.path = rset.columnString("DISK_FILE_PATH");
     archiveFile.diskFileInfo.owner = rset.columnString("DISK_FILE_USER");
     archiveFile.diskFileInfo.group = rset.columnString("DISK_FILE_GROUP");
-    archiveFile.diskFileInfo.recoveryBlob = rset.columnString("DISK_FILE_RECOVERY_BLOB");
     archiveFile.fileSize = rset.columnUint64("SIZE_IN_BYTES");
     archiveFile.checksumType = rset.columnString("CHECKSUM_TYPE");
     archiveFile.checksumValue = rset.columnString("CHECKSUM_VALUE");
@@ -95,7 +94,6 @@ RdbmsCatalogueGetArchiveFilesForRepackItor::RdbmsCatalogueGetArchiveFilesForRepa
         "ARCHIVE_FILE.DISK_FILE_PATH AS DISK_FILE_PATH,"
         "ARCHIVE_FILE.DISK_FILE_USER AS DISK_FILE_USER,"
         "ARCHIVE_FILE.DISK_FILE_GROUP AS DISK_FILE_GROUP,"
-        "ARCHIVE_FILE.DISK_FILE_RECOVERY_BLOB AS DISK_FILE_RECOVERY_BLOB,"
         "ARCHIVE_FILE.SIZE_IN_BYTES AS SIZE_IN_BYTES,"
         "ARCHIVE_FILE.CHECKSUM_TYPE AS CHECKSUM_TYPE,"
         "ARCHIVE_FILE.CHECKSUM_VALUE AS CHECKSUM_VALUE,"
diff --git a/catalogue/RdbmsCatalogueGetArchiveFilesItor.cpp b/catalogue/RdbmsCatalogueGetArchiveFilesItor.cpp
index 9002096da79c241af0cb011ef810d34f5a899eb1..7d3ad9a7cff3d541b536cc47164c934f39b1ae99 100644
--- a/catalogue/RdbmsCatalogueGetArchiveFilesItor.cpp
+++ b/catalogue/RdbmsCatalogueGetArchiveFilesItor.cpp
@@ -46,7 +46,6 @@ namespace {
     archiveFile.diskFileInfo.path = rset.columnString("DISK_FILE_PATH");
     archiveFile.diskFileInfo.owner = rset.columnString("DISK_FILE_USER");
     archiveFile.diskFileInfo.group = rset.columnString("DISK_FILE_GROUP");
-    archiveFile.diskFileInfo.recoveryBlob = rset.columnString("DISK_FILE_RECOVERY_BLOB");
     archiveFile.fileSize = rset.columnUint64("SIZE_IN_BYTES");
     archiveFile.checksumType = rset.columnString("CHECKSUM_TYPE");
     archiveFile.checksumValue = rset.columnString("CHECKSUM_VALUE");
@@ -95,7 +94,6 @@ RdbmsCatalogueGetArchiveFilesItor::RdbmsCatalogueGetArchiveFilesItor(
         "ARCHIVE_FILE.DISK_FILE_PATH AS DISK_FILE_PATH,"
         "ARCHIVE_FILE.DISK_FILE_USER AS DISK_FILE_USER,"
         "ARCHIVE_FILE.DISK_FILE_GROUP AS DISK_FILE_GROUP,"
-        "ARCHIVE_FILE.DISK_FILE_RECOVERY_BLOB AS DISK_FILE_RECOVERY_BLOB,"
         "ARCHIVE_FILE.SIZE_IN_BYTES AS SIZE_IN_BYTES,"
         "ARCHIVE_FILE.CHECKSUM_TYPE AS CHECKSUM_TYPE,"
         "ARCHIVE_FILE.CHECKSUM_VALUE AS CHECKSUM_VALUE,"
diff --git a/catalogue/SqliteCatalogue.cpp b/catalogue/SqliteCatalogue.cpp
index c12aac427a9e84c7c53447b08e5cb10d6a5efd40..47a8e48aa3dff02cdb027f01e0ff2c17f40a8d9d 100644
--- a/catalogue/SqliteCatalogue.cpp
+++ b/catalogue/SqliteCatalogue.cpp
@@ -259,7 +259,6 @@ common::dataStructures::Tape SqliteCatalogue::selectTape(rdbms::Conn &conn, cons
         "LAST_FSEQ AS LAST_FSEQ,"
         "IS_DISABLED AS IS_DISABLED,"
         "IS_FULL AS IS_FULL,"
-        "LBP_IS_ON AS LBP_IS_ON,"
 
         "LABEL_DRIVE AS LABEL_DRIVE,"
         "LABEL_TIME AS LABEL_TIME,"
@@ -302,7 +301,6 @@ common::dataStructures::Tape SqliteCatalogue::selectTape(rdbms::Conn &conn, cons
     tape.lastFSeq = rset.columnUint64("LAST_FSEQ");
     tape.disabled = rset.columnBool("IS_DISABLED");
     tape.full = rset.columnBool("IS_FULL");
-    tape.lbp = rset.columnOptionalBool("LBP_IS_ON");
 
     tape.labelLog = getTapeLogFromRset(rset, "LABEL_DRIVE", "LABEL_TIME");
     tape.lastReadLog = getTapeLogFromRset(rset, "LAST_READ_DRIVE", "LAST_READ_TIME");
@@ -430,7 +428,6 @@ void SqliteCatalogue::fileWrittenToTape(rdbms::Conn &conn, const TapeFileWritten
       row.diskFilePath = event.diskFilePath;
       row.diskFileUser = event.diskFileUser;
       row.diskFileGroup = event.diskFileGroup;
-      row.diskFileRecoveryBlob = event.diskFileRecoveryBlob;
       insertArchiveFile(conn, row);
     } catch(exception::DatabasePrimaryKeyError &) {
       // Ignore this error
diff --git a/catalogue/TapeFileWritten.cpp b/catalogue/TapeFileWritten.cpp
index 900df52cfdabc827f1f9eeaa2c786a0c8187f4c7..086073095bce61ec77b6ef3ec63da78cfab8944e 100644
--- a/catalogue/TapeFileWritten.cpp
+++ b/catalogue/TapeFileWritten.cpp
@@ -44,7 +44,6 @@ bool TapeFileWritten::operator==(const TapeFileWritten &rhs) const {
     diskFilePath == rhs.diskFilePath &&
     diskFileUser == rhs.diskFileUser &&
     diskFileGroup == rhs.diskFileGroup &&
-    diskFileRecoveryBlob == rhs.diskFileRecoveryBlob &&
     size == rhs.size &&
     checksumType == rhs.checksumType &&
     checksumValue == rhs.checksumValue &&
@@ -67,7 +66,6 @@ std::ostream &operator<<(std::ostream &os, const TapeFileWritten &obj) {
   "diskFilePath=" << obj.diskFilePath << ","
   "diskFileUser=" << obj.diskFileUser << ","
   "diskFileGroup=" << obj.diskFileGroup << ","
-  "diskFileRecoveryBlob=" << obj.diskFileRecoveryBlob << ","
   "size=" << obj.size << ","
   "checksumType=" << obj.checksumType << "checksumValue=" << obj.checksumValue << ","
   "storageClassName=" << obj.storageClassName << ","
diff --git a/catalogue/TapeFileWritten.hpp b/catalogue/TapeFileWritten.hpp
index 09856cec75cc6d81d90f5dea562fbe3462f09c82..93f3c5379e868f30e6e52f88c97410bba242dbcd 100644
--- a/catalogue/TapeFileWritten.hpp
+++ b/catalogue/TapeFileWritten.hpp
@@ -78,13 +78,6 @@ struct TapeFileWritten: public TapeItemWritten {
    */
   std::string diskFileGroup;
 
-  /**
-   * Opaque blob containing the metadata of the source disk file within its host
-   * disk system.  This blob can be used in a disaster recovery scenario to
-   * contribute to reconstructing the namespace of the host disk system.
-   */
-  std::string diskFileRecoveryBlob;
-
   /**
    * The uncompressed size of the tape file in bytes.
    */
diff --git a/catalogue/TapeSearchCriteria.hpp b/catalogue/TapeSearchCriteria.hpp
index 3a00bcbf1b0f128188304279f120de159180124b..898ddbeffc29a5929bb8a94c9f169113d2b4aeaf 100644
--- a/catalogue/TapeSearchCriteria.hpp
+++ b/catalogue/TapeSearchCriteria.hpp
@@ -81,11 +81,6 @@ struct TapeSearchCriteria {
    */
   optional<bool> full;
 
-  /**
-   * Set to true if searching for tapes with logical block protection enabled.
-   */
-  optional<bool> lbp;
-
 }; // struct TapeSearchCriteria
 
 } // namespace catalogue
diff --git a/catalogue/common_catalogue_schema.sql b/catalogue/common_catalogue_schema.sql
index 664ba6a74e6a289e4b8d9af752fba63cb999f986..a52e1f3c6eb861a387e84b122f2d7adb75ec52d3 100644
--- a/catalogue/common_catalogue_schema.sql
+++ b/catalogue/common_catalogue_schema.sql
@@ -32,7 +32,7 @@ CREATE TABLE TAPE_POOL(
   TAPE_POOL_NAME          VARCHAR(100)    CONSTRAINT TAPE_POOL_TPN_NN  NOT NULL,
   VO                      VARCHAR(100)    CONSTRAINT TAPE_POOL_VO_NN   NOT NULL,
   NB_PARTIAL_TAPES        NUMERIC(20, 0)  CONSTRAINT TAPE_POOL_NPT_NN  NOT NULL,
-  IS_ENCRYPTED            NUMERIC(20, 0)  CONSTRAINT TAPE_POOL_IE_NN   NOT NULL,
+  IS_ENCRYPTED            CHAR(1)         CONSTRAINT TAPE_POOL_IE_NN   NOT NULL,
   USER_COMMENT            VARCHAR(1000)   CONSTRAINT TAPE_POOL_UC_NN   NOT NULL,
   CREATION_LOG_USER_NAME  VARCHAR(100)    CONSTRAINT TAPE_POOL_CLUN_NN NOT NULL,
   CREATION_LOG_HOST_NAME  VARCHAR(100)    CONSTRAINT TAPE_POOL_CLHN_NN NOT NULL,
@@ -41,7 +41,7 @@ CREATE TABLE TAPE_POOL(
   LAST_UPDATE_HOST_NAME   VARCHAR(100)    CONSTRAINT TAPE_POOL_LUHN_NN NOT NULL,
   LAST_UPDATE_TIME        NUMERIC(20, 0)  CONSTRAINT TAPE_POOL_LUT_NN  NOT NULL,
   CONSTRAINT TAPE_POOL_PK PRIMARY KEY(TAPE_POOL_NAME),
-  CONSTRAINT TAPE_POOL_IS_ENCRYPTED_BOOL_CK CHECK(IS_ENCRYPTED IN (0, 1))
+  CONSTRAINT TAPE_POOL_IS_ENCRYPTED_BOOL_CK CHECK(IS_ENCRYPTED IN ('0', '1'))
 );
 CREATE TABLE ARCHIVE_ROUTE(
   STORAGE_CLASS_ID        NUMERIC(20, 0)  CONSTRAINT ARCHIVE_ROUTE_SCI_NN  NOT NULL,
@@ -81,9 +81,8 @@ CREATE TABLE TAPE(
   CAPACITY_IN_BYTES       NUMERIC(20, 0)  CONSTRAINT TAPE_CIB_UN  NOT NULL,
   DATA_IN_BYTES           NUMERIC(20, 0)  CONSTRAINT TAPE_DIB_UN  NOT NULL,
   LAST_FSEQ               NUMERIC(20, 0)  CONSTRAINT TAPE_LF_UN   NOT NULL,
-  IS_DISABLED             NUMERIC(20, 0)  CONSTRAINT TAPE_ID_UN   NOT NULL,
-  IS_FULL                 NUMERIC(20, 0)  CONSTRAINT TAPE_IF_UN   NOT NULL,
-  LBP_IS_ON               NUMERIC(20, 0),
+  IS_DISABLED             CHAR(1)         CONSTRAINT TAPE_ID_UN   NOT NULL,
+  IS_FULL                 CHAR(1)         CONSTRAINT TAPE_IF_UN   NOT NULL,
   LABEL_DRIVE             VARCHAR(100),
   LABEL_TIME              NUMERIC(20, 0),
   LAST_READ_DRIVE         VARCHAR(100),
@@ -102,9 +101,8 @@ CREATE TABLE TAPE(
     REFERENCES LOGICAL_LIBRARY(LOGICAL_LIBRARY_NAME),
   CONSTRAINT TAPE_TAPE_POOL_FK FOREIGN KEY(TAPE_POOL_NAME)
     REFERENCES TAPE_POOL(TAPE_POOL_NAME),
-  CONSTRAINT TAPE_IS_DISABLED_BOOL_CK CHECK(IS_DISABLED = 0 OR IS_DISABLED = 1),
-  CONSTRAINT TAPE_IS_FULL_BOOL_CK CHECK(IS_FULL = 0 OR IS_FULL = 1),
-  CONSTRAINT TAPE_LBP_IS_ON_BOOL_CK CHECK(LBP_IS_ON = 0 OR LBP_IS_ON = 1)
+  CONSTRAINT TAPE_IS_DISABLED_BOOL_CK CHECK(IS_DISABLED IN ('0', '1')),
+  CONSTRAINT TAPE_IS_FULL_BOOL_CK CHECK(IS_FULL IN ('0', '1'))
 );
 CREATE INDEX TAPE_TAPE_POOL_NAME_IDX ON TAPE(TAPE_POOL_NAME);
 CREATE TABLE MOUNT_POLICY(
@@ -160,7 +158,6 @@ CREATE TABLE ARCHIVE_FILE(
   DISK_FILE_PATH          VARCHAR(2000)   CONSTRAINT ARCHIVE_FILE_DFP_NN  NOT NULL,
   DISK_FILE_USER          VARCHAR(100)    CONSTRAINT ARCHIVE_FILE_DFU_NN  NOT NULL,
   DISK_FILE_GROUP         VARCHAR(100)    CONSTRAINT ARCHIVE_FILE_DFG_NN  NOT NULL,
-  DISK_FILE_RECOVERY_BLOB VARCHAR(4000)   CONSTRAINT ARCHIVE_FILE_DFRB_NN NOT NULL,
   SIZE_IN_BYTES           NUMERIC(20, 0)  CONSTRAINT ARCHIVE_FILE_SIB_NN  NOT NULL,
   CHECKSUM_TYPE           VARCHAR(100)    CONSTRAINT ARCHIVE_FILE_CT1_NN  NOT NULL,
   CHECKSUM_VALUE          VARCHAR(100)    CONSTRAINT ARCHIVE_FILE_CV_NN   NOT NULL,
diff --git a/catalogue/mysql_catalogue_schema_trigger.sql b/catalogue/mysql_catalogue_schema_trigger.sql
index 9daca2ea23122c196dccbe54f60190de8fb78a2b..694c27a8800727de03dd306bee20cd9670a4418f 100644
--- a/catalogue/mysql_catalogue_schema_trigger.sql
+++ b/catalogue/mysql_catalogue_schema_trigger.sql
@@ -1,7 +1,7 @@
 CREATE TRIGGER `TAPE_POOL_IS_ENCRYPTED_BOOL_CK_BEFORE_INSERT` BEFORE INSERT ON `TAPE_POOL`
   FOR EACH ROW
   BEGIN
-    IF new.IS_ENCRYPTED NOT IN (0,1) THEN
+    IF new.IS_ENCRYPTED NOT IN ('0','1') THEN
       SIGNAL SQLSTATE '45000'
       SET MESSAGE_TEXT = 'TAPE_POOL.IS_ENCRYPTED should be 0 or 1';
     END IF;
@@ -10,7 +10,7 @@ CREATE TRIGGER `TAPE_POOL_IS_ENCRYPTED_BOOL_CK_BEFORE_INSERT` BEFORE INSERT ON `
 CREATE TRIGGER `TAPE_POOL_IS_ENCRYPTED_BOOL_CK_BEFORE_UPDATE` BEFORE UPDATE ON `TAPE_POOL`
   FOR EACH ROW
   BEGIN
-    IF new.IS_ENCRYPTED NOT IN (0,1) THEN
+    IF new.IS_ENCRYPTED NOT IN ('0','1') THEN
       SIGNAL SQLSTATE '45000'
       SET MESSAGE_TEXT = 'TAPE_POOL.IS_ENCRYPTED should be 0 or 1';
     END IF;
@@ -37,35 +37,27 @@ CREATE TRIGGER `ARCHIVE_ROUTE_COPY_NB_GT_ZERO_BEFORE_UPDATE` BEFORE UPDATE ON `A
 CREATE TRIGGER `CHECK_TAPE_BEFORE_INSERT` BEFORE INSERT ON `TAPE`
   FOR EACH ROW
   BEGIN
-    IF new.IS_DISABLED not in (0,1) THEN
+    IF new.IS_DISABLED not in ('0','1') THEN
       SIGNAL SQLSTATE '45000'
       SET MESSAGE_TEXT = 'TAPE.IS_DISABLED should be 0 or 1';       
     END IF;
-    IF new.IS_FULL not in (0,1) THEN
+    IF new.IS_FULL not in ('0','1') THEN
       SIGNAL SQLSTATE '45000'
       SET MESSAGE_TEXT = 'TAPE.IS_FULL should be 0 or 1';       
     END IF;
-    IF new.LBP_IS_ON not in (0,1) THEN
-      SIGNAL SQLSTATE '45000'
-      SET MESSAGE_TEXT = 'TAPE.LBP_IS_ON should be 0 or 1';       
-    END IF;
   END;
 
 CREATE TRIGGER `CHECK_TAPE_BEFORE_UPDATE` BEFORE UPDATE ON `TAPE`
   FOR EACH ROW
   BEGIN
-    IF new.IS_DISABLED not in (0,1) THEN
+    IF new.IS_DISABLED not in ('0','1') THEN
       SIGNAL SQLSTATE '45000'
       SET MESSAGE_TEXT = 'TAPE.IS_DISABLED should be 0 or 1';       
     END IF;
-    IF new.IS_FULL not in (0,1) THEN
+    IF new.IS_FULL not in ('0','1') THEN
       SIGNAL SQLSTATE '45000'
       SET MESSAGE_TEXT = 'TAPE.IS_FULL should be 0 or 1';       
     END IF;
-    IF new.LBP_IS_ON not in (0,1) THEN
-      SIGNAL SQLSTATE '45000'
-      SET MESSAGE_TEXT = 'TAPE.LBP_IS_ON should be 0 or 1';       
-    END IF;
   END;
 
 CREATE TRIGGER `TAPE_FILE_COPY_NB_GT_ZERO_BEFORE_INSERT` BEFORE INSERT ON `TAPE_FILE`
diff --git a/catalogue/postgres_catalogue_schema_header.sql b/catalogue/postgres_catalogue_schema_header.sql
new file mode 100644
index 0000000000000000000000000000000000000000..c46162e86fb2108df0c916183eb1c6978848c868
--- /dev/null
+++ b/catalogue/postgres_catalogue_schema_header.sql
@@ -0,0 +1,14 @@
+CREATE SEQUENCE ARCHIVE_FILE_ID_SEQ
+  INCREMENT BY 1
+  START WITH 1
+  NO MAXVALUE
+  MINVALUE 1
+  NO CYCLE
+  CACHE 20;
+CREATE SEQUENCE STORAGE_CLASS_ID_SEQ
+  INCREMENT BY 1
+  START WITH 1
+  NO MAXVALUE
+  MINVALUE 1
+  NO CYCLE
+  CACHE 20;
diff --git a/catalogue/postgres_catalogue_schema_trailer.sql b/catalogue/postgres_catalogue_schema_trailer.sql
new file mode 100644
index 0000000000000000000000000000000000000000..02931d98022756729cb725de9525f392488c7599
--- /dev/null
+++ b/catalogue/postgres_catalogue_schema_trailer.sql
@@ -0,0 +1,4 @@
+ALTER TABLE ARCHIVE_FILE DROP CONSTRAINT
+  ARCHIVE_FILE_DIN_DFI_UN;
+ALTER TABLE ARCHIVE_FILE ADD CONSTRAINT
+  ARCHIVE_FILE_DIN_DFI_UN UNIQUE(DISK_INSTANCE_NAME, DISK_FILE_ID) DEFERRABLE INITIALLY IMMEDIATE;
diff --git a/cmake/Findstk.cmake b/cmake/Findpostgres.cmake
similarity index 63%
rename from cmake/Findstk.cmake
rename to cmake/Findpostgres.cmake
index f954e63bb23370884f5dd9148448cf126e319ff3..0aaf507df0648db4a4cb65a7b3d237c466de8002 100644
--- a/cmake/Findstk.cmake
+++ b/cmake/Findpostgres.cmake
@@ -1,6 +1,5 @@
-
 # The CERN Tape Archive(CTA) project
-# Copyright(C) 2015  CERN
+# Copyright(C) 2018  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
@@ -14,25 +13,25 @@
 #
 # You should have received a copy of the GNU General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
 # This module will set the following variables:
-#     STK_FOUND
-#     STK_LIBRARIES
-#     STK_INCLUDE_DIR
+#     POSTGRES_FOUND
+#     POSTGRES_INCLUDE_DIRS
+#     POSTGRES_LIBRARIES
 
-find_library (STK_LIBRARIES
-  stk-ssi
-  PATHS /usr/lib64/CDK /usr/lib/CDK
+find_path(POSTGRES_INCLUDE_DIRS
+  libpq-fe.h
+  PATHS /usr/include
   NO_DEFAULT_PATH)
 
-find_path (STK_INCLUDE_DIRS
-  acssys.h
-  PATHS /usr/include/CDK
+find_library(POSTGRES_LIBRARIES
+  NAME pq
+  PATHS /usr/lib64/
   NO_DEFAULT_PATH)
 
-message (STATUS "STK_LIBRARIES=${STK_LIBRARIES}")
-message (STATUS "STK_INCLUDE_DIRS=${STK_INCLUDE_DIRS}")
+message (STATUS "POSTGRES_INCLUDE_DIRS = ${POSTGRES_INCLUDE_DIRS}")
+message (STATUS "POSTGRES_LIBRARIES    = ${POSTGRES_LIBRARIES}")
 
 include(FindPackageHandleStandardArgs)
-find_package_handle_standard_args(stk DEFAULT_MSG
-  STK_LIBRARIES
-  STK_INCLUDE_DIRS)
+find_package_handle_standard_args(mysql DEFAULT_MSG
+  POSTGRES_INCLUDE_DIRS POSTGRES_LIBRARIES)
diff --git a/cmdline/CtaAdminCmdParse.hpp b/cmdline/CtaAdminCmdParse.hpp
index 86f84322857efff5bf067daed203fa9e4ba9ec07..1164672e7e65531a1030f3ee1a489ca711e19872 100644
--- a/cmdline/CtaAdminCmdParse.hpp
+++ b/cmdline/CtaAdminCmdParse.hpp
@@ -253,7 +253,6 @@ const std::map<std::string, OptionBoolean::Key> boolOptions = {
    { "--encrypted",             OptionBoolean::ENCRYPTED },
    { "--force",                 OptionBoolean::FORCE },
    { "--full",                  OptionBoolean::FULL },
-   { "--lbp",                   OptionBoolean::LBP },
 
    // hasOption options
    { "--checkchecksum",         OptionBoolean::CHECK_CHECKSUM },
diff --git a/common/dataStructures/ArchiveFileTest.cpp b/common/dataStructures/ArchiveFileTest.cpp
index bab2b13fa6b7ceef410c19ee5acdb9e0050bd9bb..2ba848c0035793a5e5da5ac791998e9abe0a5257 100644
--- a/common/dataStructures/ArchiveFileTest.cpp
+++ b/common/dataStructures/ArchiveFileTest.cpp
@@ -48,7 +48,6 @@ TEST_F(cta_common_dataStructures_ArchiveFileTest, copy_constructor) {
   archiveFile1.diskFileInfo.path = "recovery_path";
   archiveFile1.diskFileInfo.owner = "recovery_owner";
   archiveFile1.diskFileInfo.group = "recovery_group";
-  archiveFile1.diskFileInfo.recoveryBlob = "recovery_blob";
 
   TapeFile tapeFile1;
   tapeFile1.vid = "VID1";
@@ -85,7 +84,6 @@ TEST_F(cta_common_dataStructures_ArchiveFileTest, copy_constructor) {
   ASSERT_EQ(archiveFile1.diskFileInfo.path, archiveFile2.diskFileInfo.path);
   ASSERT_EQ(archiveFile1.diskFileInfo.owner, archiveFile2.diskFileInfo.owner);
   ASSERT_EQ(archiveFile1.diskFileInfo.group, archiveFile2.diskFileInfo.group);
-  ASSERT_EQ(archiveFile1.diskFileInfo.recoveryBlob, archiveFile2.diskFileInfo.recoveryBlob);
 
   ASSERT_EQ(2, archiveFile2.tapeFiles.size());
 
diff --git a/common/dataStructures/DiskFileInfo.cpp b/common/dataStructures/DiskFileInfo.cpp
index 5fc73cb01dbd00252882391cb93e132826044389..948572716611eb82be1e0822234e2dc3999c957c 100644
--- a/common/dataStructures/DiskFileInfo.cpp
+++ b/common/dataStructures/DiskFileInfo.cpp
@@ -35,8 +35,7 @@ DiskFileInfo::DiskFileInfo() {}
 bool DiskFileInfo::operator==(const DiskFileInfo &rhs) const {
   return path==rhs.path
       && owner==rhs.owner
-      && group==rhs.group
-      && recoveryBlob==rhs.recoveryBlob;
+      && group==rhs.group;
 }
 
 //------------------------------------------------------------------------------
@@ -52,8 +51,7 @@ bool DiskFileInfo::operator!=(const DiskFileInfo &rhs) const {
 std::ostream &operator<<(std::ostream &os, const DiskFileInfo &obj) {
   os << "(path=" << obj.path
      << " owner=" << obj.owner
-     << " group=" << obj.group
-     << " recoveryBlob=" << obj.recoveryBlob << ")";
+     << " group=" << obj.group << ")";
   return os;
 }
 
diff --git a/common/dataStructures/DiskFileInfo.hpp b/common/dataStructures/DiskFileInfo.hpp
index c92ebac9a7ca4748db676739b88ed38488842e86..d0395d55404676cce04fa126068ba91e5c08792f 100644
--- a/common/dataStructures/DiskFileInfo.hpp
+++ b/common/dataStructures/DiskFileInfo.hpp
@@ -43,7 +43,6 @@ struct DiskFileInfo {
   std::string path;
   std::string owner;
   std::string group;
-  std::string recoveryBlob;
 
 }; // struct DiskFileInfo
 
diff --git a/common/dataStructures/Tape.cpp b/common/dataStructures/Tape.cpp
index dcaaed5b9df0ec967c30a947ab3b99e0600dc6c9..78886b1436673f984855569706e8ba054ae952a3 100644
--- a/common/dataStructures/Tape.cpp
+++ b/common/dataStructures/Tape.cpp
@@ -43,7 +43,6 @@ bool Tape::operator==(const Tape &rhs) const {
       && capacityInBytes==rhs.capacityInBytes
       && dataOnTapeInBytes==rhs.dataOnTapeInBytes
       && encryptionKey==rhs.encryptionKey
-      && lbp==rhs.lbp
       && full==rhs.full
       && disabled==rhs.disabled
       && creationLog==rhs.creationLog
@@ -72,7 +71,6 @@ std::ostream &operator<<(std::ostream &os, const Tape &obj) {
      << " capacityInBytes=" << obj.capacityInBytes
      << " dataOnTapeInBytes=" << obj.dataOnTapeInBytes
      << " encryptionKey=" << (obj.encryptionKey ? obj.encryptionKey.value() : "null")
-     << " lbp=" << (obj.lbp ? (obj.lbp.value() ? "true" : "false") : "null")
      << " full=" << obj.full
      << " disabled=" << obj.disabled
      << " creationLog=" << obj.creationLog
diff --git a/common/dataStructures/Tape.hpp b/common/dataStructures/Tape.hpp
index acb845e40acb2613ec2f7013b5e433d6bf47b799..436e4040af58953145e45c5f7c829dbc032ee8e5 100644
--- a/common/dataStructures/Tape.hpp
+++ b/common/dataStructures/Tape.hpp
@@ -60,13 +60,6 @@ struct Tape {
    */
   optional<std::string> encryptionKey;
 
-  /**
-   * Specifies whether or not the tape has Logical Block Protection (LBP)
-   * enabled.  This value is not set until the tape is either labelled or
-   * imported as a tape containing pre-existing files.
-   */
-  optional<bool> lbp;
-
   bool full;
   bool disabled;
   EntryLog creationLog;
diff --git a/continuousintegration/docker/ctafrontend/cc7/buildtree-stage1-rpms/Dockerfile b/continuousintegration/docker/ctafrontend/cc7/buildtree-stage1-rpms/Dockerfile
index 0932335a69295571bf8abd4dd276a3384a145bf9..290ed77b5e7bbd0d9e9cf053c9c046034e950aa9 100644
--- a/continuousintegration/docker/ctafrontend/cc7/buildtree-stage1-rpms/Dockerfile
+++ b/continuousintegration/docker/ctafrontend/cc7/buildtree-stage1-rpms/Dockerfile
@@ -86,6 +86,7 @@ RUN yum-config-manager --enable epel --setopt="epel.priority=4" \
       sudo \
       zeromq \
       mariadb-devel \
+      postgresql-libs \
   && \
     yum clean all \
   && \
diff --git a/continuousintegration/docker/ctafrontend/cc7/etc/yum.repos.d/castor.repo b/continuousintegration/docker/ctafrontend/cc7/etc/yum.repos.d/castor.repo
index 2b4bc73103ca9b8b811f7ca1e25692a7d93dbf88..1a0bd6a90c9a1491dbfb280a7e578746e73d7f69 100644
--- a/continuousintegration/docker/ctafrontend/cc7/etc/yum.repos.d/castor.repo
+++ b/continuousintegration/docker/ctafrontend/cc7/etc/yum.repos.d/castor.repo
@@ -1,7 +1,6 @@
 [castor]
 name=CASTOR Repositories in LINUXSOFT
 baseurl=http://linuxsoft.cern.ch/internal/repos/castor7-testing/$basearch/os
-protected=1
 priority=2
 enabled=0
 gpgcheck=0
diff --git a/continuousintegration/docker/ctafrontend/cc7/etc/yum.repos.d/cta-ci.repo b/continuousintegration/docker/ctafrontend/cc7/etc/yum.repos.d/cta-ci.repo
index e72fe33f9408b92e0a4e616925e9d0ebe05e60f0..9d6003a5c1e799c7eae7a6b45812e6b7917ebf27 100644
--- a/continuousintegration/docker/ctafrontend/cc7/etc/yum.repos.d/cta-ci.repo
+++ b/continuousintegration/docker/ctafrontend/cc7/etc/yum.repos.d/cta-ci.repo
@@ -1,7 +1,6 @@
 [cta-ci-castor]
 name=CTA CI repo castor cache
 baseurl=https://cta-ci-repo.web.cern.ch/cta-ci-repo/castor/
-protected=1
 priority=2
 gpgcheck=0
 enabled=1
@@ -9,7 +8,6 @@ enabled=1
 [cta-ci-ceph]
 name=CTA CI repo ceph cache
 baseurl=https://cta-ci-repo.web.cern.ch/cta-ci-repo/ceph/
-protected=1
 priority=3
 gpgcheck=0
 enabled=1
@@ -24,7 +22,6 @@ enabled=1
 [cta-ci-eos]
 name=CTA CI repo eos cache
 baseurl=https://cta-ci-repo.web.cern.ch/cta-ci-repo/eos/
-protected=1
 priority=4
 gpgcheck=0
 enabled=1
@@ -32,7 +29,6 @@ enabled=1
 [cta-ci-others]
 name=CTA CI repo any additional needed RPM cache
 baseurl=https://cta-ci-repo.web.cern.ch/cta-ci-repo/others/
-protected=1
 priority=4
 gpgcheck=0
 enabled=1
@@ -40,7 +36,6 @@ enabled=1
 [cta-ci-xroot]
 name=CTA CI repo xroot cache
 baseurl=https://cta-ci-repo.web.cern.ch/cta-ci-repo/xroot/
-protected=1
 priority=4
 gpgcheck=0
 enabled=1
diff --git a/continuousintegration/docker/ctafrontend/cc7/etc/yum/pluginconf.d/versionlock.list b/continuousintegration/docker/ctafrontend/cc7/etc/yum/pluginconf.d/versionlock.list
index 5a9caaca7d7a51f376b04b2980076b2ea7f9c188..b61b0c3c7978ca63f1921e77db973e6afd5fcfd0 100644
--- a/continuousintegration/docker/ctafrontend/cc7/etc/yum/pluginconf.d/versionlock.list
+++ b/continuousintegration/docker/ctafrontend/cc7/etc/yum/pluginconf.d/versionlock.list
@@ -1,34 +1,34 @@
-0:eos-archive-4.4.20-20190125160957gitfec7ad8.el7.cern.x86_64
-0:eos-cleanup-4.4.20-20190125160957gitfec7ad8.el7.cern.x86_64
-0:eos-client-4.4.20-20190125160957gitfec7ad8.el7.cern.x86_64
-0:eos-debuginfo-4.4.20-20190125160957gitfec7ad8.el7.cern.x86_64
-0:eos-fuse-4.4.20-20190125160957gitfec7ad8.el7.cern.x86_64
-0:eos-fuse-core-4.4.20-20190125160957gitfec7ad8.el7.cern.x86_64
-0:eos-fuse-sysv-4.4.20-20190125160957gitfec7ad8.el7.cern.x86_64
-0:eos-fusex-4.4.20-20190125160957gitfec7ad8.el7.cern.x86_64
-0:eos-fusex-core-4.4.20-20190125160957gitfec7ad8.el7.cern.x86_64
-0:eos-fusex-selinux-4.4.20-20190125160957gitfec7ad8.el7.cern.x86_64
-0:eos-server-4.4.20-20190125160957gitfec7ad8.el7.cern.x86_64
-0:eos-srm-4.4.20-20190125160957gitfec7ad8.el7.cern.x86_64
-0:eos-test-4.4.20-20190125160957gitfec7ad8.el7.cern.x86_64
-0:eos-testkeytab-4.4.20-20190125160957gitfec7ad8.el7.cern.x86_64
-1:python2-xrootd-4.9.0-0.rc5.el7.*
-1:python3-xrootd-4.9.0-0.rc5.el7.*
-1:xrootd-4.9.0-0.rc5.el7.*
-1:xrootd-client-4.9.0-0.rc5.el7.*
-1:xrootd-client-devel-4.9.0-0.rc5.el7.*
-1:xrootd-client-libs-4.9.0-0.rc5.el7.*
-1:xrootd-debuginfo-4.9.0-0.rc5.el7.*
-1:xrootd-devel-4.9.0-0.rc5.el7.*
-1:xrootd-doc-4.9.0-0.rc5.el7.*
-1:xrootd-fuse-4.9.0-0.rc5.el7.*
-1:xrootd-libs-4.9.0-0.rc5.el7.*
-1:xrootd-private-devel-4.9.0-0.rc5.el7.*
-1:xrootd-selinux-4.9.0-0.rc5.el7.*
-1:xrootd-server-4.9.0-0.rc5.el7.*
-1:xrootd-server-devel-4.9.0-0.rc5.el7.*
-1:xrootd-server-libs-4.9.0-0.rc5.el7.*
-1:xrootd-tests-4.9.0-0.rc5.el7.*
+0:eos-archive-4.4.30-1.el7.cern.x86_64
+0:eos-cleanup-4.4.30-1.el7.cern.x86_64
+0:eos-client-4.4.30-1.el7.cern.x86_64
+0:eos-debuginfo-4.4.30-1.el7.cern.x86_64
+0:eos-fuse-4.4.30-1.el7.cern.x86_64
+0:eos-fuse-core-4.4.30-1.el7.cern.x86_64
+0:eos-fuse-sysv-4.4.30-1.el7.cern.x86_64
+0:eos-fusex-4.4.30-1.el7.cern.x86_64
+0:eos-fusex-core-4.4.30-1.el7.cern.x86_64
+0:eos-fusex-selinux-4.4.30-1.el7.cern.x86_64
+0:eos-server-4.4.30-1.el7.cern.x86_64
+0:eos-srm-4.4.30-1.el7.cern.x86_64
+0:eos-test-4.4.30-1.el7.cern.x86_64
+0:eos-testkeytab-4.4.30-1.el7.cern.x86_64
+1:python2-xrootd-4.9.0-1.el7.*
+1:python3-xrootd-4.9.0-1.el7.*
+1:xrootd-4.9.0-1.el7.*
+1:xrootd-client-4.9.0-1.el7.*
+1:xrootd-client-devel-4.9.0-1.el7.*
+1:xrootd-client-libs-4.9.0-1.el7.*
+1:xrootd-debuginfo-4.9.0-1.el7.*
+1:xrootd-devel-4.9.0-1.el7.*
+1:xrootd-doc-4.9.0-1.el7.*
+1:xrootd-fuse-4.9.0-1.el7.*
+1:xrootd-libs-4.9.0-1.el7.*
+1:xrootd-private-devel-4.9.0-1.el7.*
+1:xrootd-selinux-4.9.0-1.el7.*
+1:xrootd-server-4.9.0-1.el7.*
+1:xrootd-server-devel-4.9.0-1.el7.*
+1:xrootd-server-libs-4.9.0-1.el7.*
+1:xrootd-tests-4.9.0-1.el7.*
 2:ceph-12.2.2-0.el7.x86_64
 2:ceph-base-12.2.2-0.el7.x86_64
 2:ceph-common-12.2.2-0.el7.x86_64
diff --git a/continuousintegration/docker/ctafrontend/cc7/opt/run/bin/ctaeos-mgm.sh b/continuousintegration/docker/ctafrontend/cc7/opt/run/bin/ctaeos-mgm.sh
index c9b4da28c7964e394d9704e0c5427f874524d856..8dbcb75f99493c57d1ca85a68904396e10360a78 100755
--- a/continuousintegration/docker/ctafrontend/cc7/opt/run/bin/ctaeos-mgm.sh
+++ b/continuousintegration/docker/ctafrontend/cc7/opt/run/bin/ctaeos-mgm.sh
@@ -9,7 +9,7 @@ if [ ! -e /etc/buildtreeRunner ]; then
   yum-config-manager --enable eos-citrine
 
   # Install missing RPMs
-  yum -y install eos-client eos-server xrootd-client xrootd-debuginfo xrootd-server cta-cli cta-debuginfo sudo
+  yum -y install eos-client eos-server xrootd-client xrootd-debuginfo xrootd-server cta-cli cta-debuginfo sudo logrotate
 fi
 
 # create local users as the mgm is the only one doing the uid/user/group mapping in the full infrastructure
diff --git a/continuousintegration/docker/ctafrontend/cc7/opt/run/bin/init.sh b/continuousintegration/docker/ctafrontend/cc7/opt/run/bin/init.sh
index ae052099815a701a57c3c758024a52b5d5b8c55f..501b6feeb028b490eb24caf294c81425c1d219f7 100755
--- a/continuousintegration/docker/ctafrontend/cc7/opt/run/bin/init.sh
+++ b/continuousintegration/docker/ctafrontend/cc7/opt/run/bin/init.sh
@@ -58,12 +58,15 @@ if [ "$KEEP_DATABASE" == "0" ]; then
     mkdir -p $(dirname $(echo ${DATABASEURL} | cut -d: -f2))
     cta-catalogue-schema-create /etc/cta/cta-catalogue.conf
     chmod -R 777 $(dirname $(echo ${DATABASEURL} | cut -d: -f2)) # needed?
-  else
-    # Oracle DB
+  elif [ "$DATABASETYPE" == "oracle" ]; then
     echo "Purging Oracle recycle bin"
     test -f ${ORACLE_SQLPLUS} || echo "ERROR: ORACLE SQLPLUS client is not present, cannot purge recycle bin: ${ORACLE_SQLPLUS}"
     LD_LIBRARY_PATH=$(readlink ${ORACLE_SQLPLUS} | sed -e 's;/bin/[^/]\+;/lib;') ${ORACLE_SQLPLUS} $(echo $DATABASEURL | sed -e 's/oracle://') @/opt/ci/init/purge_recyclebin.ext
     cta-catalogue-schema-create /etc/cta/cta-catalogue.conf
+  elif [ "$DATABASETYPE" == "postgres" ]; then
+    cta-catalogue-schema-create /etc/cta/cta-catalogue.conf
+  else
+    echo "${DATABASETYPE}: Unsupported database type."
   fi
 else
   echo "Reusing database (no check)"
diff --git a/continuousintegration/docker/ctafrontend/cc7/opt/run/bin/init_database.sh b/continuousintegration/docker/ctafrontend/cc7/opt/run/bin/init_database.sh
index 0434e4d507ade04e6fa8cae828e1e27654637500..4d42899a0a0df8be1ad1fd3c2b769e22c5353208 100755
--- a/continuousintegration/docker/ctafrontend/cc7/opt/run/bin/init_database.sh
+++ b/continuousintegration/docker/ctafrontend/cc7/opt/run/bin/init_database.sh
@@ -28,6 +28,11 @@ case "$(get_conf database.type)" in
     DATABASETYPE=oracle
     DATABASEURL=oracle:$(get_conf database.oracle.username)/$(get_conf database.oracle.password)@$(get_conf database.oracle.database)
   ;;
+  "postgres")
+     echo "Configuring postgres database"
+     DATABASETYPE=postgres
+     DATABASEURL=postgresql:postgresql://$(get_conf database.postgres.username):$(get_conf database.postgres.password)@$(get_conf database.postgres.server)/$(get_conf database.postgres.database)
+  ;;
   *)
     echo "Error unknown database type: $(get_conf database.type)"
     exit 1
diff --git a/continuousintegration/docker/ctafrontend/cc7/opt/run/bin/init_pod.sh b/continuousintegration/docker/ctafrontend/cc7/opt/run/bin/init_pod.sh
index 86c9118fad671dcb1e639a807de8d88633b12245..ba1881a5da145599535546fb384c46bea1e69cfb 100755
--- a/continuousintegration/docker/ctafrontend/cc7/opt/run/bin/init_pod.sh
+++ b/continuousintegration/docker/ctafrontend/cc7/opt/run/bin/init_pod.sh
@@ -29,9 +29,9 @@ sed -i -c "s/^\($(hostname -i)\)\s\+.*$/\1 $(hostname -s).$(grep search /etc/res
 echo "DONE"
 
 # Not needed anymore, keep it in case it comes back
-#echo -n "Yum should resolve names using IPv4 DNS: "
-#echo "ip_resolve=IPv4" >> /etc/yum.conf
-#echo "DONE"
+echo -n "Yum should resolve names using IPv4 DNS: "
+echo "ip_resolve=IPv4" >> /etc/yum.conf
+echo "DONE"
 
 # defining CI_CONTEXT
 # possible values are "systemd" and "nosystemd"
diff --git a/continuousintegration/orchestration/README_postgres.md b/continuousintegration/orchestration/README_postgres.md
new file mode 100644
index 0000000000000000000000000000000000000000..1403100bd218d3be16962cc90f29fed774253275
--- /dev/null
+++ b/continuousintegration/orchestration/README_postgres.md
@@ -0,0 +1,18 @@
+# Running with `postgres`
+
+## External postgres instance:
+
+Modify `database-postgres-sample.yaml` file to suit your configuration and submit it to `./run_systemtest.sh` using the `-d` option for example:
+```
+[root@ctadevjulien orchestration]# (postgres_CI) ./run_systemtest.sh -S -O -d database_postgres_dbod.yaml -s tests/archive_retrieve.sh -n toto -k
+```
+
+## Internal postgres instance:
+
+In this case the postgres instance is launched in a `postgres` pod in the namespace.
+This configuration allows developers to launch a standalone offline instance that does not require any externally configured database.
+`internal_postgres.yaml` contains everything needed to launch an internal postgres instance, contact it with namespace DNS and configure CTA accordingly.
+Here is an instanciation example of a standalone postgres DB instance with a local objectstore:
+```
+[root@ctadevjulien orchestration]# (postgres_CI) ./run_systemtest.sh -S -d internal_postgres.yaml -s tests/archive_retrieve.sh -n toto -k
+```
diff --git a/continuousintegration/orchestration/create_instance.sh b/continuousintegration/orchestration/create_instance.sh
index dab70ca3b5f778d7208b443e111203274e405919..1e6281ec7b9fffee8a3ab7f962f73289355d6023 100755
--- a/continuousintegration/orchestration/create_instance.sh
+++ b/continuousintegration/orchestration/create_instance.sh
@@ -25,7 +25,7 @@ keepobjectstore=1
 
 usage() { cat <<EOF 1>&2
 Usage: $0 -n <namespace> [-o <objectstore_configmap>] [-d <database_configmap>] \
-      [-e <eos_configmap>] \
+      [-e <eos_configmap>] [-a <additional_k8_resources>]\
       [-p <gitlab pipeline ID> | -b <build tree base> -B <build tree subdir> ]  \
       [-S] [-D] [-O] [-m [mhvtl|ibm]]
 
@@ -36,13 +36,14 @@ Options:
   -B    The subdirectory within the -b directory where the build tree is.
   -D	wipe database content during initialization phase (database content is kept by default)
   -O	wipe objectstore content during initialization phase (objectstore content is kept by default)
+  -a    additional kubernetes resources added to the kubernetes namespace
 EOF
 exit 1
 }
 
 die() { echo "$@" 1>&2 ; exit 1; }
 
-while getopts "n:o:d:e:p:b:B:SDOm:" o; do
+while getopts "n:o:d:e:a:p:b:B:SDOm:" o; do
     case "${o}" in
         o)
             config_objectstore=${OPTARG}
@@ -56,6 +57,10 @@ while getopts "n:o:d:e:p:b:B:SDOm:" o; do
             config_eos=${OPTARG}
             test -f ${config_eos} || error="${error}EOS configmap file ${config_eos} does not exist\n"
             ;;
+        a)
+            additional_resources=${OPTARG}
+            test -f ${additional_resources} || error="${error}File ${additional_resources} does not exist\n"
+            ;;
         m)
             model=${OPTARG}
             if [ "-${model}-" != "-ibm-" ] && [ "-${model}-" != "-mhvtl-" ] ; then error="${error}Library model ${model} does not exist\n"; fi 
@@ -181,13 +186,17 @@ kubectl --namespace ${instance} create configmap init --from-literal=keepdatabas
 
 kubectl --namespace ${instance} create configmap buildtree --from-literal=base=${buildtree} --from-literal=subdir=${buildtreesubdir}
 
+if [ ! -z "${additional_resources}" ]; then
+  kubectl --namespace ${instance} create -f ${additional_resources} || die "Could not create additional resources described in ${additional_resources}"
+  kubectl --namespace ${instance} get pods -a
+fi
+
 echo "creating configmaps in instance"
 
 kubectl create -f ${config_objectstore} --namespace=${instance}
 kubectl create -f ${config_database} --namespace=${instance}
 kubectl create -f ${config_eos} --namespace=${instance}
 
-
 echo -n "Requesting an unused ${model} library"
 kubectl create -f ./pvc_library_${model}.yaml --namespace=${instance}
 for ((i=0; i<120; i++)); do
diff --git a/continuousintegration/orchestration/database-postgres-sample.yaml b/continuousintegration/orchestration/database-postgres-sample.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..e74b1e88b6b2bcc95260e49d46ceb9d5d208ca25
--- /dev/null
+++ b/continuousintegration/orchestration/database-postgres-sample.yaml
@@ -0,0 +1,14 @@
+apiVersion: v1
+kind: ConfigMap
+metadata:
+  name: database-config
+  labels:
+    config: database
+    type: postgres
+data:
+  database.type: postgres
+  database.postgres.username: cta
+  database.postgres.password: cta
+  database.postgres.database: cta
+  # postgres server points to the postgres external server
+  database.postgres.server: postgres1234.cern.ch
diff --git a/continuousintegration/orchestration/internal_postgres.yaml b/continuousintegration/orchestration/internal_postgres.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..2b16819bf3548582a160e9d111b3501e4b529f0a
--- /dev/null
+++ b/continuousintegration/orchestration/internal_postgres.yaml
@@ -0,0 +1,71 @@
+###
+# Internal postgres server
+# implements:
+# - a postgres server relying on official docker images
+# - a postgres service
+# - a configmap for pod configuration and CTA configuration
+###
+apiVersion: v1
+kind: Service
+metadata:
+  name: postgres
+  labels:
+    k8s-app: postgres
+spec:
+  selector:
+    k8s-app: postgres
+  clusterIP: None
+  ports:
+  - name: postgres
+    port: 5432
+    protocol: TCP
+---
+apiVersion: v1
+kind: ConfigMap
+metadata:
+  name: database-config
+  labels:
+    config: database
+    type: postgres
+data:
+  database.type: postgres
+  database.postgres.username: cta
+  database.postgres.password: cta
+  database.postgres.database: cta
+  database.postgres.path: /var/lib/postgresql/data/pgdata
+  # postgres service points to the postgresql container in namespace
+  database.postgres.server: postgres
+---
+apiVersion: v1
+kind: Pod
+metadata:
+  name: postgres
+  labels:
+    k8s-app: postgres
+spec:
+  restartPolicy: Never
+  containers:
+  - name: postgres
+    image: postgres:9.6
+    stdin: true
+    env:
+    - name: POSTGRES_USER
+      valueFrom:
+        configMapKeyRef:
+          name: database-config
+          key: database.postgres.username
+    - name: POSTGRES_PASSWORD
+      valueFrom:
+        configMapKeyRef:
+          name: database-config
+          key: database.postgres.password
+    - name: PGDATA
+      valueFrom:
+        configMapKeyRef:
+          name: database-config
+          key: database.postgres.path
+    - name: POSTGRES_DB
+      valueFrom:
+        configMapKeyRef:
+          name: database-config
+          key: database.postgres.database
diff --git a/continuousintegration/orchestration/run_systemtest.sh b/continuousintegration/orchestration/run_systemtest.sh
index cefadc2c75449505806dec1c8fc9244011ae1766..66a9af44fbae393a2ac6dceee6b45fe6a6452f8c 100755
--- a/continuousintegration/orchestration/run_systemtest.sh
+++ b/continuousintegration/orchestration/run_systemtest.sh
@@ -27,7 +27,7 @@ SYSTEMTEST_TIMEOUT=3600
 die() { echo "$@" 1>&2 ; exit 1; }
 
 usage() { cat <<EOF 1>&2
-Usage: $0 -n <namespace> -s <systemtest_script> [-p <gitlab pipeline ID> | -b <build tree base> -B <build tree subdir> ] [-t <systemtest timeout in seconds>] [-e <eos_configmap>] [-k] [-O] [-D] [-S]
+Usage: $0 -n <namespace> -s <systemtest_script> [-p <gitlab pipeline ID> | -b <build tree base> -B <build tree subdir> ] [-t <systemtest timeout in seconds>] [-e <eos_configmap>] [-a <additional_k8_resources>] [-k] [-O] [-D | -d <database_configmap>] [-S]
 
 Options:
   -b    The directory containing both the source and the build tree for CTA. It will be mounted RO in the
@@ -36,7 +36,8 @@ Options:
   -k    keep namespace after systemtest_script run if successful
   -O    use Ceph account associated to this node (wipe content before tests), by default use local VFS
   -D    use Oracle account associated to this node (wipe content before tests), by default use local sqlite DB
-  -S    Use systemd to manage services inside containers 
+  -S    Use systemd to manage services inside containers
+  -a    additional kubernetes resources added to the kubernetes namespace
 
 
 Create a kubernetes instance and launch the system test script specified.
@@ -50,7 +51,7 @@ exit 1
 # always delete DB and OBJECTSTORE for tests
 CREATE_OPTS="-D -O"
 
-while getopts "n:s:p:b:e:B:t:kDOS" o; do
+while getopts "n:d:s:p:b:e:a:B:t:kDOS" o; do
     case "${o}" in
         s)
             systemtest_script=${OPTARG}
@@ -59,6 +60,9 @@ while getopts "n:s:p:b:e:B:t:kDOS" o; do
         n)
             namespace=${OPTARG}
             ;;
+        d)
+            CREATE_OPTS="${CREATE_OPTS} -d ${OPTARG}"
+            ;;
         p)
             CREATE_OPTS="${CREATE_OPTS} -p ${OPTARG}"
             ;;
@@ -69,6 +73,9 @@ while getopts "n:s:p:b:e:B:t:kDOS" o; do
             config_eos=${OPTARG}
             test -f ${config_eos} || error="${error}EOS configmap file ${config_eos} does not exist\n"
             ;;
+        a)
+            CREATE_OPTS="${CREATE_OPTS} -a ${OPTARG}"
+            ;;
         B)
             CREATE_OPTS="${CREATE_OPTS} -B ${OPTARG}"
             ;;
diff --git a/cta.spec.in b/cta.spec.in
index 7d20632a5da2af70598cb400a52d9b55a1648196..4a7933ec1ef15948ed17d91a4692aafc8b49830c 100644
--- a/cta.spec.in
+++ b/cta.spec.in
@@ -55,6 +55,7 @@ BuildRequires: json-c-devel >= 0.11
 BuildRequires: libattr-devel >= 2.4.44
 BuildRequires: oracle-instantclient12.2-devel
 BuildRequires: mariadb-devel
+BuildRequires: postgresql-devel
 BuildRequires: valgrind
 BuildRequires: valgrind-devel
 %{?systemd_requires}
@@ -228,6 +229,7 @@ Group: Application/CTA
 Requires: oracle-instantclient12.2-basic
 Requires: librados2 = %{radosVersion}
 Requires: mariadb-libs
+Requires: postgresql-libs
 Requires: zeromq
 %description -n cta-lib
 CERN Tape Archive:
@@ -287,7 +289,6 @@ Unit tests and system tests with virtual tape drives
 %{_libdir}/libctatapeserverscsiunittests.so*
 %{_libdir}/libctadaemonunittests.so*
 %{_libdir}/libctamediachangerunittests.so*
-%{_libdir}/libctamediachangeracsdaemonunittests.so*
 %{_bindir}/cta-systemTests
 %{_libdir}/libctadaemonunittests-multiprocess.so*
 %attr(0644,root,root) %{_datadir}/%{name}-%{ctaVersion}/unittest/*.suppr
@@ -342,34 +343,6 @@ Utilities to faciliate working with the mediachangers
 %attr(0644,root,root) %doc /usr/share/man/man1/cta-mediachanger-dismount.1cta.gz
 %attr(0644,root,root) %doc /usr/share/man/man1/cta-mediachanger-mount.1cta.gz
 
-%package -n cta-acsd
-Summary: Tools to faciliate working with acsd in cta
-Group: Application/CTA
-Requires: logrotate
-Requires: cta-common = %{version}-%{release}
-Requires: cta-lib = %{version}-%{release}
-%description -n cta-acsd
-CERN Tape Archive:
-Tools to faciliate working with acsd in cta
-%files -n cta-acsd
-%defattr(-,root,root)
-%attr(0644,root,root) %config(noreplace) /etc/logrotate.d/cta-acsd
-#%attr(0644,root,root) %doc /usr/share/man/man1/cta-acsd.1cta.gz
-%attr(0755,root,root) %{_bindir}/cta-acsd
-%attr(0644,root,root) %config(noreplace) %{_sysconfdir}/cta/cta-acsd.conf
-%attr(0644,root,root) /etc/systemd/system/cta-acsd.service
-
-%post -n cta-acsd
-%systemd_post cta-acsd.service
-%systemdDaemonReload
-
-%preun -n cta-acsd
-%systemd_preun cta-acsd.service
-
-%postun -n cta-acsd
-%systemd_postun cta-acsd.service
-%systemdDaemonReload
-
 %package -n cta-rmcd
 Summary: Tools to faciliate working with rmcd and smc in cta
 Group: Application/CTA
@@ -401,25 +374,6 @@ Tools to faciliate working with rmcd and smc in cta
 %systemd_postun cta-rmcd.service
 %systemdDaemonReload
 
-%package -n cta-tape-developer-acs-tools
-Summary: Cern Advanced mass STORage
-Group: Application/Castor
-Requires: stk-ssi-lib
-BuildRequires: stk-ssi-devel
-%description -n cta-tape-developer-acs-tools
-castor (Cern Advanced STORage system)
- ASC tools for CASTOR tape developers
-%files -n cta-tape-developer-acs-tools
-%defattr(-,root,root)
-%attr(0755,root,root) /usr/bin/cta-acs-queryvolume
-%attr(0755,root,root) /usr/bin/cta-acs-dismount
-%attr(0755,root,root) /usr/bin/cta-acs-mount
-%attr(0755,root,root) /usr/bin/cta-acs-querydrive
-%attr(0644,root,root) %doc /usr/share/man/man1/cta-acs-queryvolume.1cta.gz
-%attr(0644,root,root) %doc /usr/share/man/man1/cta-acs-mount.1cta.gz
-%attr(0644,root,root) %doc /usr/share/man/man1/cta-acs-dismount.1cta.gz
-%attr(0644,root,root) %doc /usr/share/man/man1/cta-acs-querydrive.1cta.gz
-
 %package -n cta-common
 Summary: CERN Tape Archive common items
 Group: Application/CTA
diff --git a/mediachanger/CMakeLists.txt b/mediachanger/CMakeLists.txt
index 4f464de54e0fb17ea150e153dba1b48a215ccc30..2f8e3afe0ea7d89c811d7458d7bf9d32298e072d 100644
--- a/mediachanger/CMakeLists.txt
+++ b/mediachanger/CMakeLists.txt
@@ -15,10 +15,6 @@
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 cmake_minimum_required (VERSION 2.6)
 
-if (NOT DEFINED NoACS)
-  add_subdirectory(acs)
-endif (NOT DEFINED NoACS)
-
 add_subdirectory(reactor)
 add_subdirectory(castorrmc)
 find_package(openssl REQUIRED)
diff --git a/mediachanger/acs/Acs.cpp b/mediachanger/acs/Acs.cpp
deleted file mode 100644
index 9e039e9245aa67534b2e2058cc3bbd5aba41f804..0000000000000000000000000000000000000000
--- a/mediachanger/acs/Acs.cpp
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * 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 "Acs.hpp"
-
-#include <iomanip>
-#include <sstream>
-#include <stdint.h>
-#include <string.h>
-#include <vector>
-
-//------------------------------------------------------------------------------
-// destructor
-//------------------------------------------------------------------------------
-cta::mediachanger::acs::Acs::~Acs() {
-}
-
-//------------------------------------------------------------------------------
-// alpd2DriveId
-//------------------------------------------------------------------------------
-DRIVEID cta::mediachanger::acs::Acs::alpd2DriveId(const uint32_t acs,
-  const uint32_t lsm, const uint32_t panel, const uint32_t drive) {
-  
-  DRIVEID driveId;
-  driveId.panel_id.lsm_id.acs = (ACS)acs;
-  driveId.panel_id.lsm_id.lsm = (LSM)lsm;
-  driveId.panel_id.panel = (PANEL)panel;
-  driveId.drive = (DRIVE)drive;
-
-  return driveId;
-}
-
-//------------------------------------------------------------------------------
-// str2Volid
-//------------------------------------------------------------------------------
-VOLID cta::mediachanger::acs::Acs::str2Volid(const std::string &str) {
-  if(EXTERNAL_LABEL_SIZE < str.length()) {
-    InvalidVolid ex;
-    ex.getMessage() << "Failed to convert string to volume identifier"
-      ": String is longer than the " << EXTERNAL_LABEL_SIZE <<
-      " character maximum";
-    throw ex;
-  }
-
-  VOLID v;
-  strncpy(v.external_label, str.c_str(), sizeof(v.external_label));
-  v.external_label[sizeof(v.external_label) - 1] = '\0';
-  return v;
-}
-
-//------------------------------------------------------------------------------
-// driveId2Str
-//------------------------------------------------------------------------------
-std::string cta::mediachanger::acs::Acs::driveId2Str(const DRIVEID &driveId) {
-  std::ostringstream oss;
-  oss << std::setfill('0') <<
-    std::setw(3) << (int32_t)driveId.panel_id.lsm_id.acs << ":" <<
-    std::setw(3) << (int32_t)driveId.panel_id.lsm_id.lsm << ":" <<
-    std::setw(3) << (int32_t)driveId.panel_id.panel << ":" <<
-    std::setw(3) << (int32_t)driveId.drive;
-  return oss.str();
-}
diff --git a/mediachanger/acs/Acs.hpp b/mediachanger/acs/Acs.hpp
deleted file mode 100644
index a334210813ea924139383b564af23359594257f8..0000000000000000000000000000000000000000
--- a/mediachanger/acs/Acs.hpp
+++ /dev/null
@@ -1,168 +0,0 @@
-/*
- * 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/>.
- */
-
-#pragma once
-
-#include "common/exception/Exception.hpp"
-
-extern "C" {
-#include "acssys.h"
-#include "acsapi.h"
-}
-
-#include <string>
-#include <stdint.h>
-
-namespace cta {
-namespace mediachanger {
-namespace acs {
-
-/**
- * Abstract class that defines the interface to an object that wraps the ACLS
- * C-API.
- */
-class Acs {
-public:
-  /**
-   * Pure-virtual destructor to ensure this class is abstract.
-   */
-  virtual ~Acs() = 0;
-
-  /**
-   * Converts acs, lsm, panel, drive numbers to the corresponding 
-   * drive ID object.
-   * 
-   * @param acs The integer for acs.
-   * @param lsm The integer for lsm.
-   * @param panel The integer for panel.
-   * @param drive The integer for drive.
-   * @return The drive ID object.
-   */
-  static DRIVEID alpd2DriveId(const uint32_t acs, const uint32_t lsm, 
-    const uint32_t panel, const uint32_t drive);
-
-  /**
-   * Invalid volume identifier.
-   */
-  struct InvalidVolid: public exception::Exception {
-    InvalidVolid(const std::string &context = "", const bool embedBacktrace = true):
-      cta::exception::Exception(context, embedBacktrace) {}
-  };
-
-  /**
-   * Returns the VOLID equibvalent of the specified string.
-   *
-   * @param str The string representation of the volume identifier.
-   * @return The VOLID representation of the volume identifier.
-   * @throw InvalidVolid if the string is longer than EXTERNAL_LABEL_SIZE.
-   */
-  static VOLID str2Volid(const std::string &str);
-  
-  /**
-   * Returns the string reprsentation of the specified drive identifier.
-   *
-   * The string format is ACS:LSM:panel:drive
-   *
-   * @param driveId The drive identifier.
-   * @return The string representation.
-   */
-  static std::string driveId2Str(const DRIVEID &driveId);
-  
-  /**
-   * C++ wrapper around the acs_mount() function of the ACSLS C-API.
-   *
-   * @param seqNumber Client supplied sequence number.
-   * @param lockId Lock identifier or 0 meaning no lock.
-   * @param volId The indentifier of volume to be mounted.
-   * @param driveId The ID of the drive into which the volume is to be mounted.
-   * @param readOnly Set to true to request the volume be mounted for read-only
-   * access.
-   * @param bypass Set to true to override the ACSLS verification of
-   * compatibility between the drive and the media type of the volume.
-   * @return status value returned by acs_mount().
-   */
-  virtual STATUS mount(
-    const SEQ_NO seqNumber,
-    const LOCKID lockId,
-    const VOLID &volId,
-    const DRIVEID &driveId,
-    const BOOLEAN readOnly,
-    const BOOLEAN bypass)
-    = 0;
-
-  /**
-   * C++ wrapper around the acs_dismount() function of the ACSLS C-API.
-   *
-   * @param seqNumber Client supplied sequence number.
-   * @param lockId Lock identifier or 0 meaning no lock.
-   * @param volId The identifier of the volume to be mounted.
-   * @param driveId The ID of the drive into which the volume is to be mounted.
-   * @param force Set to true if the dismount should be forced.  Forcing a
-   * dismount means dismounting the volume from the specified drive without
-   * checking the identifier of the volume.
-   * @return status value returned by acs_dismount().
-   */
-  virtual STATUS dismount(
-    const SEQ_NO seqNumber,
-    const LOCKID lockId,
-    const VOLID &volId,
-    const DRIVEID &driveId,
-    const BOOLEAN force)
-    = 0;
-
-  /**
-   * C++ wrapper around the acs_response() function of the ACSLS C-API.
-   *
-   * @param timeout Time in seconds to wait for a response.  A value of -1
-   * means block indefinitely and an a value of 0 means poll for the existence
-   * of a response.
-   * @param seqNumber Output parameter.  If a response exists then seqNumber
-   * is set.
-   * @param reqId Output parameter.  For an acknowledge response reqId is set
-   * to the request identifier of the original request. For an intermediate or
-   * final response reqId will be set to 0.
-   * @param rType Output parameter.  Set to the type of the response.
-   * @param rBuf Output parameter.  Set to the response information.
-   * @return status value returned by acs_response().
-   */
-  virtual STATUS response(
-    const int timeout,
-    SEQ_NO &seqNumber,
-    REQ_ID &reqId,
-    ACS_RESPONSE_TYPE &rType,
-    ALIGNED_BYTES rBuf) = 0;
-
-  /**
-   * C++ wrapper around the acs_query_volume() function of the ACSLS C-API.
-   *
-   * @param seqNumber Client supplied sequence number.
-   * @param volIds Array of the volume identifiers to be queried.
-   * @param count The number of volume identifiers contained iwthin the volId
-   * parameter.
-   * @return status value returned by acs_response().
-   */
-  virtual STATUS queryVolume(
-    const SEQ_NO seqNumber,
-    VOLID (&volIds)[MAX_ID],
-    const unsigned short count) = 0;
-
-}; // class  Acs
-
-} // namespace acs
-} // namespace mediachanger
-} // namespace cta
diff --git a/mediachanger/acs/AcsCmd.cpp b/mediachanger/acs/AcsCmd.cpp
deleted file mode 100644
index 13c726692a0de45ea0073f4c6e0eae0c02936154..0000000000000000000000000000000000000000
--- a/mediachanger/acs/AcsCmd.cpp
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * 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 "AcsCmd.hpp"
-#include "common/exception/Exception.hpp"
-#include <stdlib.h>
-
-//------------------------------------------------------------------------------
-// constructor
-//------------------------------------------------------------------------------
-cta::mediachanger::acs::AcsCmd::AcsCmd(std::istream &inStream,
-  std::ostream &outStream, std::ostream &errStream, Acs &acs):
-  CmdLineTool(inStream, outStream, errStream), m_acs(acs) {
-}
-
-//------------------------------------------------------------------------------
-// destructor
-//------------------------------------------------------------------------------
-cta::mediachanger::acs::AcsCmd::~AcsCmd() {
-}
-
-//------------------------------------------------------------------------------
-// bool2Str
-//------------------------------------------------------------------------------
-std::string cta::mediachanger::acs::AcsCmd::bool2Str(const BOOLEAN value) const
-  {
-  return value ? "TRUE" : "FALSE";
-}
-
-//------------------------------------------------------------------------------
-// requestResponsesUntilFinal
-//------------------------------------------------------------------------------
-void cta::mediachanger::acs::AcsCmd::requestResponsesUntilFinal(
-  const SEQ_NO requestSeqNumber,
-  ALIGNED_BYTES (&buf)[MAX_MESSAGE_SIZE / sizeof(ALIGNED_BYTES)],
-  const int queryInterval, const int timeout) {
-  ACS_RESPONSE_TYPE responseType = RT_NONE;
-  int elapsedTime = 0;
-  do {
-    const int remainingTime = timeout - elapsedTime;
-    const int responseTimeout = remainingTime > queryInterval ?
-      queryInterval : remainingTime;
-
-    const time_t startTime = time(NULL);
-    responseType = requestResponse(responseTimeout, requestSeqNumber, buf);
-    elapsedTime += time(NULL) - startTime;
-
-    if(RT_ACKNOWLEDGE == responseType) {
-      m_dbg << "Received RT_ACKNOWLEDGE" << std::endl;
-    }
-
-    if(elapsedTime >= timeout) {
-      cta::exception::RequestFailed ex;
-      ex.getMessage() << "Timed out after " << timeout << " seconds";
-      throw ex;
-    }
-  } while(RT_FINAL != responseType);
-
-  m_dbg << "Received RT_FINAL" << std::endl;
-}
-
-//------------------------------------------------------------------------------
-// requestResponse
-//------------------------------------------------------------------------------
-ACS_RESPONSE_TYPE cta::mediachanger::acs::AcsCmd::requestResponse(
-  const int timeout, const SEQ_NO requestSeqNumber,
-  ALIGNED_BYTES (&buf)[MAX_MESSAGE_SIZE / sizeof(ALIGNED_BYTES)]) {
-  SEQ_NO responseSeqNumber = 0;
-  REQ_ID reqId = (REQ_ID)0;
-  ACS_RESPONSE_TYPE responseType = RT_NONE;
-
-  m_dbg << "Calling Acs::response()" << std::endl;
-  const STATUS s = m_acs.response(timeout, responseSeqNumber, reqId,
-    responseType, buf);
-  m_dbg << "Acs::response() returned " << acs_status(s) << std::endl;
-
-  switch(s) {
-  case STATUS_SUCCESS:
-    checkResponseSeqNumber(requestSeqNumber, responseSeqNumber);
-    return responseType;
-  case STATUS_PENDING:
-    return RT_NONE;
-  default:
-    cta::exception::RequestFailed ex;
-    ex.getMessage() << "Failed to request response: " << acs_status(s);
-    throw ex;
-  }
-}
-
-//------------------------------------------------------------------------------
-// checkSeqNumber
-//------------------------------------------------------------------------------
-void cta::mediachanger::acs::AcsCmd::checkResponseSeqNumber( const SEQ_NO requestSeqNumber, const SEQ_NO responseSeqNumber) {
-  if(requestSeqNumber != responseSeqNumber) {
-    cta::exception::Mismatch ex;
-    ex.getMessage() <<  ": Sequence number mismatch: requestSeqNumber="
-      << requestSeqNumber << " responseSeqNumber=" << responseSeqNumber;
-    throw ex;
-  }
-}
diff --git a/mediachanger/acs/AcsCmd.hpp b/mediachanger/acs/AcsCmd.hpp
deleted file mode 100644
index 54650e61ac05ff581bd0fdea6db80779e7dc3130..0000000000000000000000000000000000000000
--- a/mediachanger/acs/AcsCmd.hpp
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * 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/>.
- */
-
-#pragma once
-
-#include "common/exception/Mismatch.hpp"
-//#include "common/exception/RequestFailed.hpp"
-#include "common/exception/RequestFailed.hpp"
-#include "Acs.hpp"
-#include "AcsCmd.hpp"
-#include "CmdLineTool.hpp"
-
-#include <istream>
-#include <ostream>
-#include <string>
-
-extern "C" {
-#include "acssys.h"
-#include "acsapi.h"
-}
-
-namespace cta {
-namespace mediachanger {
-namespace acs {
-
-/**
- * Abstract class implementing common code and data structures for command-line
- * tools that interact with ACLS compatible tape libraries.
- */
-class AcsCmd: public CmdLineTool {
-public:
-  /**
-   * Constructor.
-   *
-   * @param inStream Standard input stream.
-   * @param outStream Standard output stream.
-   * @param errStream Standard error stream.
-   * @param acs Wrapper around the ACSLS C-API.
-   */
-  AcsCmd(std::istream &inStream, std::ostream &outStream,
-    std::ostream &errStream, Acs &acs);
-
-  /**
-   * Pure-virtual destructor to guarantee this class is abstract.
-   */
-  virtual ~AcsCmd() = 0;
-
-protected:
-
-  /**
-   * Wrapper around the ACSLS C-API.
-   */
-  Acs &m_acs;
-
-  /**
-   * Returns the string representation of the specfied boolean value.
-   *
-   * @param value The boolean value.
-   */
-  std::string bool2Str(const BOOLEAN value) const;
-
-  /**
-   * Requests responses from ACSLS in a loop until the RT_FINAL response is
-   * received.
-   *
-   * @param requestSeqNumber The sequemce number that was sent in the initial
-   * request to the ACSLS.
-   * @param buf Output parameter.  Message buffer into which the RT_FINAL
-   * response shall be written.
-   * @param queryInterval Time in seconds to wait between queries to ACS for
-   * responses.
-   * @param timeout The time in seconds to spend trying to get the RT_FINAL
-   * response.
-   */
-  void requestResponsesUntilFinal(const SEQ_NO requestSeqNumber,
-    ALIGNED_BYTES (&buf)[MAX_MESSAGE_SIZE / sizeof(ALIGNED_BYTES)],
-    const int queryInterval, const int timeout);
-
-  /**
-   * Sends a request for a response to the ACSLS.
-   *
-   * @param timeout The timeout.
-   * @param requestSeqNumber The sequemce number that was sent in the initial
-   * request to the ACSLS.
-   * @param buf Output parameter.  The response message if there is one.
-   * @return The type of the response message if there is one or RT_NONE if
-   * there isn't one.
-   */
-  ACS_RESPONSE_TYPE requestResponse(const int timeout,
-    const SEQ_NO requestSeqNumber,
-    ALIGNED_BYTES (&buf)[MAX_MESSAGE_SIZE / sizeof(ALIGNED_BYTES)]);
-
-  /**
-   * Throws cta::exception::Mismatch if the specified request and
-   * response sequence-numbers do not match.
-   *
-   * @param requestSeqNumber Request sequence-number.
-   * @param responseSeqNumber Response sequence-number.
-   */
-  void checkResponseSeqNumber(const SEQ_NO requestSeqNumber,
-    const SEQ_NO responseSeqNumber);
-
-}; // class AcsCmd
-
-} // namespace acs
-} // namespace mediachanger
-} // namespace cta
diff --git a/mediachanger/acs/AcsCmdLine.cpp b/mediachanger/acs/AcsCmdLine.cpp
deleted file mode 100644
index 9ffa7d9e2dea67b1c4cb7d3841ac223c424b810f..0000000000000000000000000000000000000000
--- a/mediachanger/acs/AcsCmdLine.cpp
+++ /dev/null
@@ -1,178 +0,0 @@
-/*
- * 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 "AcsCmdLine.hpp"
-
-#include <stdlib.h>
-#include <unistd.h>
-#include <vector>
-
-//------------------------------------------------------------------------------
-// str2DriveId
-//------------------------------------------------------------------------------
-DRIVEID cta::mediachanger::acs::AcsCmdLine::str2DriveId(const std::string &str) {
-  std::vector<std::string> components;
-
-  if(!str.empty()) {
-    const char separator = ':';
-    std::string::size_type beginIndex = 0;
-    std::string::size_type endIndex   = str.find(separator);
-
-    while(endIndex != std::string::npos) {
-      components.push_back(str.substr(beginIndex, endIndex - beginIndex));
-      beginIndex = ++endIndex;
-      endIndex = str.find(separator, endIndex);
-    }
-
-    components.push_back(str.substr(beginIndex));
-  }
-
-  // The drive ID should consist of 4 components: ACS, LSM, Panel and Transport
-  if(4 != components.size()) {
-    InvalidDriveId ex;
-    ex.getMessage() << "Invalid number of components in drive ID"
-      ": expected=4, actual=" << components.size();
-    throw ex;
-  }
-
-  const std::string &acsStr = components[0];
-  const std::string &lsmStr = components[1];
-  const std::string &panStr = components[2];
-  const std::string &drvStr = components[3];
-
-  // Each of the 4 components must be between 1 and than 3 characters long
-  if(1 > acsStr.length() ||  3 < acsStr.length()) {
-    InvalidDriveId ex;
-    ex.getMessage() << "Invalid ACS string length"
-      ": expected=1..3, actual=" << acsStr.length();
-    throw ex;
-  }
-  if(1 > lsmStr.length() || 3 < lsmStr.length()) {
-    InvalidDriveId ex;
-    ex.getMessage() << "Invalid LSM string length"
-      ": expected=1..3, actual=" << lsmStr.length();
-    throw ex;
-  }
-  if(1 > panStr.length() || 3 < panStr.length()) {
-    InvalidDriveId ex;
-    ex.getMessage() << "Invalid panel string length"
-      ": expected=1..3, actual=" << panStr.length();
-    throw ex;
-  }
-  if(1 > drvStr.length() || 3 < drvStr.length()) {
-    InvalidDriveId ex;
-    ex.getMessage() << "Invalid drive string length"
-      ": expected=1..3, actual=" << drvStr.length();
-    throw ex;
-  }
-
-  // Each of the 4 components must only contain numerals
-  if(!onlyContainsNumerals(acsStr)) {
-    InvalidDriveId ex;
-    ex.getMessage() << "ACS must only contain numerals: value=" << acsStr;
-    throw ex;
-  }
-  if(!onlyContainsNumerals(lsmStr)) {
-    InvalidDriveId ex;
-    ex.getMessage() << "LSM must only contain numerals: value=" << acsStr;
-    throw ex;
-  }
-  if(!onlyContainsNumerals(panStr)) {
-    InvalidDriveId ex;
-    ex.getMessage() << "Panel must only contain numerals: value=" << acsStr;
-    throw ex;
-  }
-  if(!onlyContainsNumerals(drvStr)) {
-    InvalidDriveId ex;
-    ex.getMessage() << "Drive/Transport must only contain numerals: value=" <<
-      acsStr;
-    throw ex;
-  }
-
-  DRIVEID driveId;
-  driveId.panel_id.lsm_id.acs = (ACS)atoi(acsStr.c_str());
-  driveId.panel_id.lsm_id.lsm = (LSM)atoi(lsmStr.c_str());
-  driveId.panel_id.panel = (PANEL)atoi(panStr.c_str());
-  driveId.drive = (DRIVE)atoi(drvStr.c_str());
-
-  return driveId;
-}
-
-//------------------------------------------------------------------------------
-// onlyContainsNumerals
-//------------------------------------------------------------------------------
-bool cta::mediachanger::acs::AcsCmdLine::onlyContainsNumerals(const std::string &str) {
-  for(std::string::const_iterator itor = str.begin(); itor != str.end();
-    itor++) {
-    if(*itor < '0' || *itor  > '9') {
-      return false;
-    }
-  }
-  return true;
-}
-
-//------------------------------------------------------------------------------
-// parseQueryInterval
-//------------------------------------------------------------------------------
-int cta::mediachanger::acs::AcsCmdLine::parseQueryInterval(const std::string &s) {
-  const int queryInterval = atoi(s.c_str());
-  if(0 >= queryInterval) {
-    InvalidQueryInterval ex;
-    ex.getMessage() << "Query value must be an integer greater than 0"
-      ": value=" << queryInterval;
-    throw ex;
-  }
-
-  return queryInterval;
-}
-
-//------------------------------------------------------------------------------
-// parseTimeout
-//------------------------------------------------------------------------------
-int cta::mediachanger::acs::AcsCmdLine::parseTimeout(const std::string &s) {
-  const int timeout = atoi(s.c_str());
-  if(0 >= timeout) {
-    InvalidTimeout ex;
-    ex.getMessage() << "Timeout value must be an integer greater than 0"
-      ": value=" << timeout;
-    throw ex;
-  }
-  return timeout;
-}
-
-//------------------------------------------------------------------------------
-// handleMissingParameter
-//------------------------------------------------------------------------------
-void cta::mediachanger::acs::AcsCmdLine::handleMissingParameter(const int opt) {
-  MissingParam ex;
-  ex.getMessage() << "The -" << (char)opt << " option requires a parameter";
-  throw ex;
-}
-
-//------------------------------------------------------------------------------
-// handleUnknownOption
-//------------------------------------------------------------------------------
-void cta::mediachanger::acs::AcsCmdLine::handleUnknownOption(const int opt) {
-  UnknownOption ex;
-  if(0 == optopt) {
-    ex.getMessage() << "Unknown command-line option";
-  } else {
-    ex.getMessage() << "Unknown command-line option: -" << (char)opt;
-  }
-  throw ex;
-}
diff --git a/mediachanger/acs/AcsCmdLine.hpp b/mediachanger/acs/AcsCmdLine.hpp
deleted file mode 100644
index 38495afee87d7347853087573f54fc8c3ec160cb..0000000000000000000000000000000000000000
--- a/mediachanger/acs/AcsCmdLine.hpp
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * 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/>.
- */
-
-#pragma once
-
-#include "common/exception/Exception.hpp"
-
-extern "C" {
-#include "acssys.h"
-#include "acsapi.h"
-}
-
-#include <string>
-
-namespace cta {
-namespace mediachanger {
-namespace acs {
-
-/**
- * Class containing the code common to the parsed command-line of the ACS
- * command-line tools provided by CASTOR.
- */
-class AcsCmdLine {
-public:
-
-  /**
-   * Invalid drive identifier.
-   */
-  struct InvalidDriveId: public exception::Exception {
-    InvalidDriveId(const std::string &context = "", const bool embedBacktrace = true):
-      cta::exception::Exception(context, embedBacktrace) {}
-  };
-
-  /**
-   * Parses the specified string and returns the corresponding drive ID object.
-   *
-   * @param str The string to be parsed.
-   * @return The drive ID object.
-   * @throw InvalidDriveId if the syntax of the string is invalid.
-   */
-  static DRIVEID str2DriveId(const std::string &str);
-
-protected:
-
-  /**
-   * Invalid query interval.
-   */
-  struct InvalidQueryInterval: public exception::Exception {
-    InvalidQueryInterval(const std::string &context = "", const bool embedBacktrace = true):
-      cta::exception::Exception(context, embedBacktrace) {}
-  };
-
-  /**
-   * Parses the specified query interval.
-   *
-   * @return The parse query interval.
-   * @throw InvalidQueryInterval if the query interval is invalid.
-   */
-  int parseQueryInterval(const std::string &s);
-
-  /**
-   * Invalid timeout.
-   */
-  struct InvalidTimeout: public exception::Exception {
-    InvalidTimeout(const std::string &context = "", const bool embedBacktrace = true):
-      cta::exception::Exception(context, embedBacktrace) {}
-  };
-
-  /**
-   * Parses the specified timeout.
-   *
-   * @return The parse query interval.
-   * @throw InvalidTimout if the timeout is invalid.
-   */
-  int parseTimeout(const std::string &s);
-
-  /**
-   * Missing parameter.
-   */
-  struct MissingParam: public exception::Exception {
-    MissingParam(const std::string &context = "", const bool embedBacktrace = true):
-      cta::exception::Exception(context, embedBacktrace) {}
-  };
-
-  /**
-   * Handles the specified parameter that is missing a parameter.
-   *
-   * @param opt The option.
-   * @throw MissingParam in all cases.
-   */
-  void handleMissingParameter(const int opt);
-
-  /**
-   * Unkown option.
-   */
-  struct UnknownOption: public exception::Exception {
-    UnknownOption(const std::string &context = "", const bool embedBacktrace = true):
-      cta::exception::Exception(context, embedBacktrace) {}
-  };
-
-  /**
-   * Handles the specified unknown option.
-   *
-   * @param opt The option.
-   * @throw UnknownOption indepedent of the value of opt.
-   */
-  void handleUnknownOption(const int opt);
-
-private:
-
-  /**
-   * Returns true if the specified string only contains numerals else false.
-   *
-   * @return True if the specified string only contains numerals else false.
-   */
-  static bool onlyContainsNumerals(const std::string &str);
-
-}; // class AcsCmdLine
-
-} // namespace acs
-} // namespace mediachanger
-} // namespace cta
diff --git a/mediachanger/acs/AcsCmdLineTest.cpp b/mediachanger/acs/AcsCmdLineTest.cpp
deleted file mode 100644
index 8a1e50061df469edf15a088aacbd38165126aed8..0000000000000000000000000000000000000000
--- a/mediachanger/acs/AcsCmdLineTest.cpp
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * 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 "mediachanger/acs/AcsCmdLine.hpp"
-
-#include <gtest/gtest.h>
-
-namespace unitTests {
-
-class cta_mediachanger_acs_AcsCmdLineTest: public ::testing::Test {
-protected:
-
-  virtual void SetUp() {
-  }
-
-  virtual void TearDown() {
-  }
-};
-
-/**
- * Tests good day senario with Acs::strToDrveId.
- */
-TEST_F(cta_mediachanger_acs_AcsCmdLineTest, goodDayStr2DriveId) {
-  using namespace cta::mediachanger::acs;
-  const std::string str("1:2:3:4");
-  const auto driveId = AcsCmdLine::str2DriveId(str);
-
-  ASSERT_EQ(1, driveId.panel_id.lsm_id.acs);
-  ASSERT_EQ(2, driveId.panel_id.lsm_id.lsm);
-  ASSERT_EQ(3, driveId.panel_id.panel);
-  ASSERT_EQ(4, driveId.drive);
-}
-
-/**
- * Tests too many components with Acs::strToDrveId.
- */
-TEST_F(cta_mediachanger_acs_AcsCmdLineTest, tooManyComponentsStr2DriveId) {
-  using namespace cta::mediachanger::acs;
-  const std::string str("1:2:3:4:5");
-  ASSERT_THROW(AcsCmdLine::str2DriveId(str), AcsCmdLine::InvalidDriveId);
-}
-
-/**
- * Tests too few components with Acs::strToDrveId.
- */
-TEST_F(cta_mediachanger_acs_AcsCmdLineTest, tooFewComponentsStr2DriveIdgoodDayStr2DriveId) {
-  using namespace cta::mediachanger::acs;
-  const std::string str("1:2:3");
-  ASSERT_THROW(AcsCmdLine::str2DriveId(str), AcsCmdLine::InvalidDriveId);
-}
-
-/**
- * Tests tool long component with Acs::strToDrveId.
- */
-TEST_F(cta_mediachanger_acs_AcsCmdLineTest, tooLongAcsComponentStr2DriveId) {
-  using namespace cta::mediachanger::acs;
-  const std::string str("1111:2:3:4");
-  ASSERT_THROW(AcsCmdLine::str2DriveId(str), AcsCmdLine::InvalidDriveId);
-}
-
-/**
- * Tests tool long component with Acs::strToDrveId.
- */
-TEST_F(cta_mediachanger_acs_AcsCmdLineTest, tooLongLsmComponentStr2DriveId) {
-  using namespace cta::mediachanger::acs;
-  const std::string str("1:2222:3:4");
-  ASSERT_THROW(AcsCmdLine::str2DriveId(str), AcsCmdLine::InvalidDriveId);
-}
-
-/**
- * Tests tool long component with Acs::strToDrveId.
- */
-TEST_F(cta_mediachanger_acs_AcsCmdLineTest, tooLongPanComponentStr2DriveId) {
-  using namespace cta::mediachanger::acs;
-  const std::string str("1:2:3333:4");
-  ASSERT_THROW(AcsCmdLine::str2DriveId(str), AcsCmdLine::InvalidDriveId);
-}
-
-/**
- * Tests tool long component with Acs::strToDrveId.
- */
-TEST_F(cta_mediachanger_acs_AcsCmdLineTest, tooLongDrvComponentStr2DriveId) {
-  using namespace cta::mediachanger::acs;
-  const std::string str("1:2:3:4444");
-  ASSERT_THROW(AcsCmdLine::str2DriveId(str), AcsCmdLine::InvalidDriveId);
-}
-
-/**
- * Tests empty component with Acs::strToDrveId.
- */
-TEST_F(cta_mediachanger_acs_AcsCmdLineTest, emptyAcsComponentStr2DriveId) {
-  using namespace cta::mediachanger::acs;
-  const std::string str(":2:3:4");
-  ASSERT_THROW(AcsCmdLine::str2DriveId(str), AcsCmdLine::InvalidDriveId);
-}
-
-/**
- * Tests empty component with Acs::strToDrveId.
- */
-TEST_F(cta_mediachanger_acs_AcsCmdLineTest, emptyLsmComponentStr2DriveId) {
-  using namespace cta::mediachanger::acs;
-  const std::string str("1::3:4");
-  ASSERT_THROW(AcsCmdLine::str2DriveId(str), AcsCmdLine::InvalidDriveId);
-}
-
-/**
- * Tests empty component with Acs::strToDrveId.
- */
-TEST_F(cta_mediachanger_acs_AcsCmdLineTest, emptyPanComponentStr2DriveId) {
-  using namespace cta::mediachanger::acs;
-  const std::string str("1:2::4");
-  ASSERT_THROW(AcsCmdLine::str2DriveId(str), AcsCmdLine::InvalidDriveId);
-}
-
-/**
- * Tests empty component with Acs::strToDrveId.
- */
-TEST_F(cta_mediachanger_acs_AcsCmdLineTest, emptyDrvComponentStr2DriveId) {
-  using namespace cta::mediachanger::acs;
-  const std::string str("1:2:3:");
-  ASSERT_THROW(AcsCmdLine::str2DriveId(str), AcsCmdLine::InvalidDriveId);
-}
-
-} // namespace unitTests
diff --git a/mediachanger/acs/AcsDaemonConfig.cpp b/mediachanger/acs/AcsDaemonConfig.cpp
deleted file mode 100644
index 90520257afa9080c7068dcd655ed58e8acbc7b0f..0000000000000000000000000000000000000000
--- a/mediachanger/acs/AcsDaemonConfig.cpp
+++ /dev/null
@@ -1,57 +0,0 @@
-/******************************************************************************
- *
- * This file is part of the Castor project.
- * See http://castor.web.cern.ch/castor
- *
- * Copyright (C) 2003  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 2
- * 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * 
- *
- * @author Castor Dev team, castor-dev@cern.ch
- *****************************************************************************/
-
-#include "AcsDaemonConfig.hpp"
-//#include "castor/acs/Constants.hpp"
-#include "common/log/Constants.hpp"
-#include "castor/server/LoggedCastorConfiguration.hpp"
-
-//------------------------------------------------------------------------------
-// constructor
-//------------------------------------------------------------------------------
-castor::acs::AcsDaemonConfig::AcsDaemonConfig():
-  port(0),
-  queryInterval(0),
-  cmdTimeout(0) {
-}
-
-//------------------------------------------------------------------------------
-// createFromCastorConfig
-//------------------------------------------------------------------------------
-castor::acs::AcsDaemonConfig castor::acs::AcsDaemonConfig::
-  createFromCastorConf(log::Logger *const log) {
-  server::LoggedCastorConfiguration castorConf(
-    common::CastorConfiguration::getConfig());
-  AcsDaemonConfig config;
-
-  config.port = castorConf.getConfEntInt("AcsDaemon", "Port",
-    (unsigned short)ACS_PORT);
-
-  config.queryInterval = castorConf.getConfEntInt("AcsDaemon", "QueryInterval",
-    (time_t)ACS_QUERY_INTERVAL);
-
-  config.cmdTimeout = castorConf.getConfEntInt("AcsDaemon", "CmdTimeout",
-    (time_t)ACS_CMD_TIMEOUT);
-
-  return config;
-}
diff --git a/mediachanger/acs/AcsDaemonConfig.hpp b/mediachanger/acs/AcsDaemonConfig.hpp
deleted file mode 100644
index 1f5ea3fcfe885c9ae8672c16d940248cb564bf4d..0000000000000000000000000000000000000000
--- a/mediachanger/acs/AcsDaemonConfig.hpp
+++ /dev/null
@@ -1,75 +0,0 @@
-/******************************************************************************
- *
- * This file is part of the Castor project.
- * See http://castor.web.cern.ch/castor
- *
- * Copyright (C) 2003  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 2
- * 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * @author Castor Dev team, castor-dev@cern.ch
- *****************************************************************************/
-
-#pragma once
-
-//#include "castor/log/Logger.hpp"
-#include "common/log/Logger.hpp"
-
-#include <time.h>
-
-namespace castor {
-namespace acs    {
-
-/**
- * Structure used to store the CASTOR configuration parameters used by the
- * CASTOR ACS daemon.
- */
-struct AcsDaemonConfig {
-
-  /**
-   * The TCP/IP port on which the CASTOR ACS daemon listens for incoming Zmq
-   * connections from the tape server.
-   */
-  unsigned short port;
-
-  /**
-   * Time to wait in seconds between queries to the tape Library.
-   */
-  time_t queryInterval; 
-
-  /**
-   * The maximum time to wait in seconds for a tape-library command to
-   * conclude.
-   */
-  time_t cmdTimeout;
-
-  /**
-   * Constructor that sets all integer member-variables to 0 and all string
-   * member-variables to the empty string.
-   */
-  AcsDaemonConfig();
-
-  /**
-   * Returns a configuration structure based on the contents of
-   * /etc/castor/castor.conf and compile-time constants.
-   *
-   * @param log pointer to NULL or an optional logger object.
-   * @return The configuration structure.
-   */
-  static AcsDaemonConfig createFromCastorConf(
-    log::Logger *const log = NULL);
-
-}; // struct AcsDaemonConfig
-
-} // namespace acs
-} // namespace castor
-
diff --git a/mediachanger/acs/AcsDebugBuf.cpp b/mediachanger/acs/AcsDebugBuf.cpp
deleted file mode 100644
index eb900d5a7b779d5c4d43e6182af14f0cd80d704c..0000000000000000000000000000000000000000
--- a/mediachanger/acs/AcsDebugBuf.cpp
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * 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 "mediachanger/acs/AcsDebugBuf.hpp"
-
-//------------------------------------------------------------------------------
-// constructor
-//------------------------------------------------------------------------------
-cta::mediachanger::acs::DebugBuf::DebugBuf(std::ostream &os):
-  m_debug(false), m_os(os), m_writePreamble(true) {
-}
-
-//------------------------------------------------------------------------------
-// destructor
-//------------------------------------------------------------------------------
-cta::mediachanger::acs::DebugBuf::~DebugBuf() {
-}
-
-//------------------------------------------------------------------------------
-// setDebug
-//------------------------------------------------------------------------------
-void cta::mediachanger::acs::DebugBuf::setDebug(const bool value) {
-  m_debug = value;
-}
-
-//------------------------------------------------------------------------------
-// overflow
-//------------------------------------------------------------------------------
-std::streambuf::int_type cta::mediachanger::acs::DebugBuf::overflow(
-  const int_type c) {
-  // Only write something if debug mode is on
-  if(m_debug) {
-    if(m_writePreamble) {
-      writePreamble();
-      m_writePreamble = false;
-    }
-    m_os << (char)c;
-  }
-
-  // If an end of line was encountered then the next write should be preceeded
-  // with a preamble
-  if('\n' == (char)c) {
-    m_writePreamble = true;
-  }
-
-  return c;
-}
-
-//------------------------------------------------------------------------------
-// writePreamble
-//------------------------------------------------------------------------------
-void cta::mediachanger::acs::DebugBuf::writePreamble() {
-  m_os << "DEBUG: ";
-}
diff --git a/mediachanger/acs/AcsDebugBuf.hpp b/mediachanger/acs/AcsDebugBuf.hpp
deleted file mode 100644
index afc4168d958de6d4099a47f7d082f4386652706c..0000000000000000000000000000000000000000
--- a/mediachanger/acs/AcsDebugBuf.hpp
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * 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/>.
- */
-
-#pragma once
-
-#include <ostream>
-#include <streambuf>
-
-namespace cta {
-namespace mediachanger {
-namespace acs {
-
-/**
- * Stream buffer class used to prepend a standard preamble to debug
- * message-lines.
- *
- * This stream buffer does not write any output if debug mode has not been
- * turned on by calling setDebugMode(true).  Any debug message written to this
- * stream buffer will be discarded if debug mode is off.
- */
-class DebugBuf : public std::streambuf {
-public:
-
-  /**
-   * Constructor.
-   *
-   * Initialises the the debug mode to be off.
-   *
-   * @param os The output stream to which each debug message-line togther with
-   * its standard preamble shall be written.
-   */
-  DebugBuf(std::ostream &os);
-
-  /**
-   * Destructor.
-   */
-  ~DebugBuf();
-
-  /**
-   * Set the debug mode to be on (true) or off (false).
-   *
-   * The default set in the constructor is off (false).
-   */
-  void setDebug(const bool value);
-
-protected:
-
-  /**
-   * Sends the specified character to the output channnel.
-   */
-  int_type overflow (const int_type c);
-
-  /**
-   * Writes the standard preamble to the output stream.
-   */
-  void writePreamble();
-
-private:
-
-  /**
-   * True if debug mode is on.
-   */
-  bool m_debug;
-
-  /**
-   * The output stream to which each debug message-line togther with its
-   * standard preamble shall be written.
-   */
-  std::ostream &m_os;
-
-  /**
-   * True is a preamble should be written.
-   */
-  bool m_writePreamble;
-
-}; // class DebugBuf
-
-} // namespace acs
-} // namespace mediachanger
-} // namespace cta
diff --git a/mediachanger/acs/AcsDismountCmd.cpp b/mediachanger/acs/AcsDismountCmd.cpp
deleted file mode 100644
index 8c8c8d1f2b010fbbeeb706eb0c6d9c3a6d3fb18b..0000000000000000000000000000000000000000
--- a/mediachanger/acs/AcsDismountCmd.cpp
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * 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 "AcsDismountCmd.hpp"
-
-#include <getopt.h>
- 
-//------------------------------------------------------------------------------
-// constructor
-//------------------------------------------------------------------------------
-cta::mediachanger::acs::AcsDismountCmd::AcsDismountCmd(
-  std::istream &inStream, std::ostream &outStream, std::ostream &errStream,
-  Acs &acs):
-  AcsCmd(inStream, outStream, errStream, acs) {
-}
-
-//------------------------------------------------------------------------------
-// destructor
-//------------------------------------------------------------------------------
-cta::mediachanger::acs::AcsDismountCmd::~AcsDismountCmd() {
-  // Do nothing
-}
-
-//------------------------------------------------------------------------------
-// exceptionThrowingMain
-//------------------------------------------------------------------------------
-int cta::mediachanger::acs::AcsDismountCmd::exceptionThrowingMain(const int argc,
-  char *const *const argv) {
-  try {
-    m_cmdLine = AcsDismountCmdLine(argc, argv);
-  } catch(cta::exception::Exception &ex) {
-    m_err << ex.getMessage().str() << std::endl;
-    m_err << std::endl;
-    m_err << m_cmdLine.getUsage() << std::endl;
-    return 1;
-  }
-
-  // Display the usage message to standard out and exit with success if the
-  // user requested help
-  if(m_cmdLine.help) {
-    m_out << AcsDismountCmdLine::getUsage();
-    return 0;
-  }
-
-  // Setup debug mode to be on or off depending on the command-line arguments
-  m_debugBuf.setDebug(m_cmdLine.debug);
-
-  m_dbg << "force = " << (m_cmdLine.force ? "TRUE" : "FALSE") << std::endl;
-  m_dbg << "query = " << m_cmdLine.queryInterval << std::endl;
-  m_dbg << "timeout = " << m_cmdLine.timeout << std::endl;
-  m_dbg << "VID = " << m_cmdLine.volId.external_label << std::endl;
-  m_dbg << "DRIVE_SLOT = " << m_acs.driveId2Str(m_cmdLine.libraryDriveSlot)
-    << std::endl;
-
-  syncDismount();
-  return 0;
-}
-
-//------------------------------------------------------------------------------
-// syncDismount
-//------------------------------------------------------------------------------
-void cta::mediachanger::acs::AcsDismountCmd::syncDismount() {
-  const SEQ_NO requestSeqNumber = 1;
-  ALIGNED_BYTES buf[MAX_MESSAGE_SIZE / sizeof(ALIGNED_BYTES)];
-
-  try {
-    sendDismountRequest(requestSeqNumber);
-    requestResponsesUntilFinal(requestSeqNumber, buf, m_cmdLine.queryInterval,
-      m_cmdLine.timeout);
-    processDismountResponse(buf);
-  } catch(cta::exception::Exception &ne) {
-    cta::exception::Exception ex;
-    ex.getMessage() << "Failed to dismount volume " <<
-      m_cmdLine.volId.external_label << ": " << ne.getMessage().str();
-    throw ex;
-  }
-}
-
-//------------------------------------------------------------------------------
-// sendDismountRequest
-//------------------------------------------------------------------------------
-void cta::mediachanger::acs::AcsDismountCmd::sendDismountRequest(
-  const SEQ_NO seqNumber) {
-  const LOCKID lockId = 0; // No lock
-
-  m_dbg << "Calling Acs::dismount()" << std::endl;
-  const STATUS s = m_acs.dismount(seqNumber, lockId, m_cmdLine.volId,
-    m_cmdLine.libraryDriveSlot, m_cmdLine.force);
-  m_dbg << "Acs::dismount() returned " << acs_status(s) << std::endl;
-  if(STATUS_SUCCESS != s) {
-    cta::exception::Exception ex;
-    ex.getMessage() << "Failed to send request to dismount volume " <<
-      m_cmdLine.volId.external_label << " from drive " <<
-      m_acs.driveId2Str(m_cmdLine.libraryDriveSlot) << ": force=" <<
-      (m_cmdLine.force ? "TRUE" : "FALSE") << ": " << acs_status(s);
-    throw ex;
-  }
-}
-
-//------------------------------------------------------------------------------
-// processDismountResponse
-//------------------------------------------------------------------------------
-void cta::mediachanger::acs::AcsDismountCmd::processDismountResponse(
-  ALIGNED_BYTES (&buf)[MAX_MESSAGE_SIZE / sizeof(ALIGNED_BYTES)]) {
-  const ACS_DISMOUNT_RESPONSE *const msg = (ACS_DISMOUNT_RESPONSE *)buf;
-
-  if(STATUS_SUCCESS != msg->dismount_status) {
-    cta::exception::Exception ex;
-    ex.getMessage() << "Status of dismount response is not success: " <<
-      acs_status(msg->dismount_status);
-    throw ex;
-  }
-}
diff --git a/mediachanger/acs/AcsDismountCmd.hpp b/mediachanger/acs/AcsDismountCmd.hpp
deleted file mode 100644
index 43a4c5e6065f511cb890c3974b1c57c6eaa37db8..0000000000000000000000000000000000000000
--- a/mediachanger/acs/AcsDismountCmd.hpp
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * 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/>.
- */
-
-#pragma once
-
-#include "AcsCmd.hpp"
-#include "AcsDismountCmdLine.hpp"
-
-namespace cta {
-namespace mediachanger {
-namespace acs {
-
-/**
- * The class implementing the mount command.
- */
-class AcsDismountCmd: public AcsCmd {
-public:
-
-  /**
-   * Constructor.
-   *
-   * @param inStream Standard input stream.
-   * @param outStream Standard output stream.
-   * @param errStream Standard error stream.
-   * @param acs Wrapper around the ACSLS C-API.
-   */
-  AcsDismountCmd(std::istream &inStream, std::ostream &outStream,
-    std::ostream &errStream, Acs &acs);
-
-  /**
-   * Destructor.
-   */
-  virtual ~AcsDismountCmd();
-
-  /**
-   * The entry function of the command.
-   *
-   * This method sets the m_cmdLine member-variable.
-   *
-   * @param argc The number of command-line arguments.
-   * @param argv The command-line arguments.
-   * @return The exit value of the program.
-   */
-  int exceptionThrowingMain(const int argc, char *const *const argv);
-
-protected:
-
-  /**
-   * Dismounts the tape with the specified VID into the drive with the specified
-   * drive ID.
-   *
-   * This method does not return until the mount has either suceeded, failed or
-   * the specified timeout has been reached.
-   *
-   * @param dismountTimeout The maximum amount of time in seconds to wait for
-   * the dismount operation to conclude.
-   * @param queryInterval The amount of time in seconds to wait between
-   * querying ACS for responses.
-   */
-  void syncDismount();
-
-  /**
-   * Sends the dismount request to ACSLS.
-   *
-   * @param seqNumber The sequence number to be used in the request.
-   */
-  void sendDismountRequest(const SEQ_NO seqNumber);
-
-  /**
-   * Process dismount response.
-   *
-   * @param buf The mount-response message.
-   */
-  void processDismountResponse(
-    ALIGNED_BYTES (&buf)[MAX_MESSAGE_SIZE / sizeof(ALIGNED_BYTES)]);
-
-private:
-
-  /**
-   * The parsed command-line.
-   *
-   * This member-variable is set by the main() method of this class.
-   */
-  AcsDismountCmdLine m_cmdLine;
-
-}; // class AcsDismountCmd
-
-} // namespace acs
-} // namepace mediachanger
-} // namespace cta
diff --git a/mediachanger/acs/AcsDismountCmdLine.cpp b/mediachanger/acs/AcsDismountCmdLine.cpp
deleted file mode 100644
index 42c0058a371a3b23636adb55cd04a8fee3824fd5..0000000000000000000000000000000000000000
--- a/mediachanger/acs/AcsDismountCmdLine.cpp
+++ /dev/null
@@ -1,180 +0,0 @@
-/*
- * 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 "Acs.hpp"
-#include "AcsCmdLine.hpp"
-#include "AcsDismountCmdLine.hpp"
-#include "Constants.hpp"
-
-#include <getopt.h>
-#include <stdlib.h>
-#include <string.h>
-
-//-----------------------------------------------------------------------------
-// constructor
-//-----------------------------------------------------------------------------
-cta::mediachanger::acs::AcsDismountCmdLine::AcsDismountCmdLine():
-  debug(false),
-  force(FALSE),
-  help(false),
-  queryInterval(0),
-  timeout(0) {
-  libraryDriveSlot.panel_id.lsm_id.acs = (ACS)0;
-  libraryDriveSlot.panel_id.lsm_id.lsm = (LSM)0;
-  libraryDriveSlot.panel_id.panel = (PANEL)0;
-  libraryDriveSlot.drive = (DRIVE)0;
-  memset(volId.external_label, '\0', sizeof(volId.external_label));
-}
-
-//------------------------------------------------------------------------------
-// constructor
-//------------------------------------------------------------------------------
-cta::mediachanger::acs::AcsDismountCmdLine::AcsDismountCmdLine(const int argc,
-  char *const *const argv):
-  debug(false),
-  force(FALSE),
-  help(false),
-  queryInterval(ACS_QUERY_INTERVAL),
-  timeout(ACS_CMD_TIMEOUT) {
-  libraryDriveSlot.panel_id.lsm_id.acs = (ACS)0;
-  libraryDriveSlot.panel_id.lsm_id.lsm = (LSM)0;
-  libraryDriveSlot.panel_id.panel = (PANEL)0;
-  libraryDriveSlot.drive = (DRIVE)0;
-  memset(volId.external_label, '\0', sizeof(volId.external_label));
-
-  static struct option longopts[] = {
-    {"debug", 0, NULL, 'd'},
-    {"force", 0, NULL, 'f'},
-    {"help" , 0, NULL, 'h'},
-    {"query" , required_argument, NULL, 'q'},
-    {"timeout" , required_argument, NULL, 't'},
-    {NULL   , 0, NULL,  0 }
-  };
-
-  // Prevent getopt() from printing an error message if it does not recognize
-  // an option character
-  opterr = 0;
-
-  int opt = 0;
-  while((opt = getopt_long(argc, argv, ":dfhq:t:", longopts, NULL)) != -1) {
-    processOption(opt);
-  }
-
-  // There is no need to continue parsing when the help option is set
-  if(help) {
-    return;
-  }
-
-  // Calculate the number of non-option ARGV-elements
-  const int nbArgs = argc-optind;
-
-  // Check that both VID and DRIVE_SLOT have been specified
-  if(nbArgs < 2) {
-    cta::exception::Exception ex;
-
-    ex.getMessage() <<
-      "Both VID and DRIVE_SLOT must be specified";
-
-    throw ex;
-  }
-
-  // Parse VID
-  volId = Acs::str2Volid(argv[optind]);
-
-  // Move on to the next command-line argument
-  optind++;
-
-  // Parse DRIVE_SLOT
-  libraryDriveSlot = str2DriveId(argv[optind]);
-}
-
-//------------------------------------------------------------------------------
-// processOption
-//------------------------------------------------------------------------------
-void cta::mediachanger::acs::AcsDismountCmdLine::processOption(const int opt) {
-  switch (opt) {
-  case 'd':
-    debug = true;
-    break;
-  case 'f':
-    force = TRUE;
-    break;
-  case 'h':
-    help = true;
-    break;
-  case 'q':
-    queryInterval = parseQueryInterval(optarg);
-    break;
-  case 't':
-    timeout = parseTimeout(optarg);
-    break;
-  case ':':
-    return handleMissingParameter(optopt);
-  case '?': 
-    return handleUnknownOption(optopt);
-  default:
-    {
-      cta::exception::Exception ex;
-      ex.getMessage() <<
-        "getopt_long returned the following unknown value: 0x" <<
-        std::hex << (int)opt;
-      throw ex;
-    }
-  } // switch(opt)
-}
-
-//------------------------------------------------------------------------------
-// getUsage
-//------------------------------------------------------------------------------
-std::string cta::mediachanger::acs::AcsDismountCmdLine::getUsage() {
-  std::ostringstream usage;
-  usage <<
-  "Usage:\n"
-  "\n"
-  "  cta-acs-dismount [options] VID DRIVE_SLOT\n"
-  "\n"
-  "Where:\n"
-  "\n"
-  "  VID        The VID of the volume to be dismounted.\n"
-  "\n"
-  "  DRIVE_SLOT The slot in the tape library where the drive is located.\n"
-  "             The format of DRIVE_SLOT is as follows:\n"
-  "\n"
-  "               ACS:LSM:panel:transport\n"
-  "\n"
-  "Options:\n"
-  "\n"
-  "  -d|--debug            Turn on the printing of debug information.\n"
-  "\n"
-  "  -f|--force            Force the dismount.\n"
-  "\n"
-  "  -h|--help             Print this help message and exit.\n"
-  "\n"
-  "  -q|--query SECONDS    Time to wait between queries to ACS for responses.\n"
-  "                        SECONDS must be an integer value greater than 0.\n"
-  "                        The default value of SECONDS is "
-    << ACS_QUERY_INTERVAL << ".\n"
-  "\n"
-  "  -t|--timeout SECONDS  Time to wait for the dismount to conclude. SECONDS\n"
-  "                        must be an integer value greater than 0.  The\n"
-  "                        default value of SECONDS is "
-    << ACS_CMD_TIMEOUT << ".\n"
-  "\n"
-  "Comments to: CTA team\n";
-  return usage.str();
-}
diff --git a/mediachanger/acs/AcsDismountCmdLine.hpp b/mediachanger/acs/AcsDismountCmdLine.hpp
deleted file mode 100644
index c2e9f72e97faa3135c551bcb8a26c16dc2d4bf66..0000000000000000000000000000000000000000
--- a/mediachanger/acs/AcsDismountCmdLine.hpp
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * 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/>.
- */
-
-#pragma once
-
-#include "AcsCmdLine.hpp"
-
-extern "C" {
-#include "acssys.h"
-#include "acsapi.h"
-}
-
-#include <string>
-
-namespace cta {
-namespace mediachanger {
-namespace acs {
-
-/**
- * Data type used to store the results of parsing the command-line.
- */
-struct AcsDismountCmdLine: public AcsCmdLine {
-  /**
-   * True if the debug option has been set.
-   */
-  bool debug;
-
-  /**
-   * True if the dismount should be forced.
-   *
-   * Forcing a dismount means dismounting the tape in the specified drive
-   * without checking the volume identifier of the tape.
-   */
-  BOOLEAN force;
-
-  /**
-   * True if the help option has been set.
-   */
-  bool help;
-
-  /**
-   * Time in seconds to wait between queries to ACS for responses.
-   */
-  int queryInterval;
-
-  /**
-   * Time in seconds to wait for the dismount to conclude.
-   */
-  int timeout;
-
-  /**
-   * The volume identifier of the tape to be mounted.
-   */
-  VOLID volId;
-
-  /**
-   * The slot in the tape library where the drive is located.
-   */
-  DRIVEID libraryDriveSlot;
-
-  /**
-   * Constructor.
-   *
-   * Initialises all boolean member-variables to false, all integer
-   * member-variables to 0 and the volume identifier to an empty string.
-   */
-  AcsDismountCmdLine();
-
-  /**
-   * Constructor.
-   *
-   * Parses the specified command-line arguments.
-   *
-   * @param argc Argument count from the executable's entry function: main().
-   * @param argv Argument vector from the executable's entry function: main().
-   */
-  AcsDismountCmdLine(const int argc, char *const *const argv);
-
-  /**
-   * Gets the usage message that describes the comamnd line.
-   *
-   * @return The usage message.
-   */
-  static std::string getUsage();
-
-private:
-
-  /**
-   * Processes the specified option that was returned by getopt_long().
-   *
-   * @param opt The option that was returned by getopt_long().
-   */
-  void processOption(const int opt);
-
-}; // class AcsDismountCmdLine
-
-} // namespace acs
-} // namespace mediachanger
-} // namespace cta
diff --git a/mediachanger/acs/AcsDismountCmdMain.cpp b/mediachanger/acs/AcsDismountCmdMain.cpp
deleted file mode 100644
index b01f3cf3886a472f4d58dfd09cd715ff78171d3c..0000000000000000000000000000000000000000
--- a/mediachanger/acs/AcsDismountCmdMain.cpp
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * 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 "AcsDismountCmd.hpp"
-#include "AcsDismountCmdLine.hpp"
-#include "AcsImpl.hpp"
-
-#include <iostream>
-
-/**
- * An exception throwing version of main().
- *
- * @param argc The number of command-line arguments including the program name.
- * @param argv The command-line arguments.
- * @return The exit value of the program.
- */
-static int exceptionThrowingMain(const int argc, char *const *const argv);
-
-//------------------------------------------------------------------------------
-// main
-//------------------------------------------------------------------------------
-int main(const int argc, char *const *const argv) {
-  using namespace cta;
-
-  std::string errorMessage;
-
-  try {
-    return exceptionThrowingMain(argc, argv);
-  } catch(cta::exception::Exception &ex) {
-    errorMessage = ex.getMessage().str();
-  } catch(std::exception &se) {
-    errorMessage = se.what();
-  } catch(...) {
-    errorMessage = "An unknown exception was thrown";
-  }
-
-  // Reaching this point means the command has failed, ane exception was throw
-  // and errorMessage has been set accordingly
-
-  std::cerr << "Aborting: " << errorMessage << std::endl;
-  return 1;
-}
-
-//------------------------------------------------------------------------------
-// exceptionThrowingMain
-//------------------------------------------------------------------------------
-static int exceptionThrowingMain(const int argc, char *const *const argv) {
-  using namespace cta;
-
-  mediachanger::acs::AcsImpl acs;
-  mediachanger::acs::AcsDismountCmd cmd(std::cin, std::cout, std::cerr, acs);
-
-  return cmd.exceptionThrowingMain(argc, argv);
-}
diff --git a/mediachanger/acs/AcsImpl.cpp b/mediachanger/acs/AcsImpl.cpp
deleted file mode 100644
index fa228703310319a88e70f3f22740a43d4008eddc..0000000000000000000000000000000000000000
--- a/mediachanger/acs/AcsImpl.cpp
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * 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 "AcsImpl.hpp"
-
-#include <errno.h>
-#include <sstream>
-#include <string.h>
-
-//------------------------------------------------------------------------------
-// destructor
-//------------------------------------------------------------------------------
-cta::mediachanger::acs::AcsImpl::~AcsImpl() {
-}
-
-//------------------------------------------------------------------------------
-// mount
-//------------------------------------------------------------------------------
-STATUS cta::mediachanger::acs::AcsImpl::mount(
-  const SEQ_NO seqNumber,
-  const LOCKID lockId,
-  const VOLID &volId,
-  const DRIVEID &driveId,
-  const BOOLEAN readOnly,
-  const BOOLEAN bypass)
-  {
-  return acs_mount(seqNumber, lockId, volId, driveId, readOnly, bypass);
-}
-
-//------------------------------------------------------------------------------
-// dismount
-//------------------------------------------------------------------------------
-STATUS cta::mediachanger::acs::AcsImpl::dismount(
-  const SEQ_NO seqNumber,
-  const LOCKID lockId,
-  const VOLID &volId,
-  const DRIVEID &driveId,
-  const BOOLEAN force)
-  {
-  return acs_dismount(seqNumber, lockId, volId, driveId, force);
-}
-
-//------------------------------------------------------------------------------
-// response
-//------------------------------------------------------------------------------
-STATUS cta::mediachanger::acs::AcsImpl::response(
-  const int timeout,
-  SEQ_NO &seqNumber,
-  REQ_ID &reqId,
-  ACS_RESPONSE_TYPE &rType,
-  ALIGNED_BYTES rBuf) {
-  return acs_response(timeout, &seqNumber, &reqId, &rType, rBuf);
-}
-
-//------------------------------------------------------------------------------
-// queryVolume
-//------------------------------------------------------------------------------
-STATUS cta::mediachanger::acs::AcsImpl::queryVolume(
-  const SEQ_NO seqNumber,
-  VOLID (&volIds)[MAX_ID],
-  const unsigned short count) {
-  return acs_query_volume(seqNumber, volIds, count);
-}
diff --git a/mediachanger/acs/AcsImpl.hpp b/mediachanger/acs/AcsImpl.hpp
deleted file mode 100644
index 5353b7b464db0c502fb3c257a327736a37a951b3..0000000000000000000000000000000000000000
--- a/mediachanger/acs/AcsImpl.hpp
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * 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/>.
- */
-
-#pragma once
-
-#include "Acs.hpp"
-
-namespace cta {
-namespace mediachanger {
-namespace acs {
-
-/**
- * Concrete class that wraps the ACLS C-API.
- */
-class AcsImpl: public Acs {
-public:
-  /**
-   * Destructor.
-   */
-  ~AcsImpl();
-
-  /**
-   * C++ wrapper around the acs_mount() function of the ACSLS C-API.
-   *
-   * @param seqNumber Client supplied sequence number.
-   * @param lockId Lock identifier or 0 meaning no lock.
-   * @param volId The identifier of the volume to be mounted.
-   * @param driveId The ID of the drive into which the volume is to be mounted.
-   * @param readOnly Set to true to request the volume be mounted for read-only
-   * access.
-   * @param bypass Set to true to override the ACSLS verification of
-   * compatibility between the drive and the media type of the volume.
-   * @return status value returned by acs_mount().
-   */
-  STATUS mount(
-    const SEQ_NO seqNumber,
-    const LOCKID lockId,
-    const VOLID &volId,
-    const DRIVEID &driveId,
-    const BOOLEAN readOnly,
-    const BOOLEAN bypass)
-   ;
-
-  /**
-   * C++ wrapper around the acs_dismount() function of the ACSLS C-API.
-   *
-   * @param seqNumber Client supplied sequence number.
-   * @param lockId Lock identifier or 0 meaning no lock.
-   * @param volId The identifier of the volume to be mounted.
-   * @param driveId The ID of the drive into which the volume is to be mounted.
-   * @param force Set to true if the dismount should be forced.  Forcing a
-   * dismount means dismounting the volume from the specified drive without
-   * checking the identifier of the volume.
-   * @return status value returned by acs_dismount().
-   */
-  STATUS dismount(
-    const SEQ_NO seqNumber,
-    const LOCKID lockId,
-    const VOLID &volId,
-    const DRIVEID &driveId,
-    const BOOLEAN force)
-   ;
-
-  /**
-   * C++ wrapper around the acs_response() function of the ACSLS C-API.
-   *
-   * @param timeout Time in seconds to wait for a response.  A value of -1
-   * means block indefinitely and an a value of 0 means poll for the existence
-   * of a response.
-   * @param seqNumber Output parameter.  If a response exists then seqNumber
-   * is set.
-   * @param reqId Output parameter.  For an acknowledge response reqId is set
-   * to the request identifier of the original request. For an intermediate or
-   * final response reqId will be set to 0.
-   * @param rType Output parameter.  Set to the type of the response.
-   * @param rBuf Output parameter.  Set to the response information.
-   * @return status value returned by acs_response().
-   */
-  STATUS response(
-    const int timeout,
-    SEQ_NO &seqNumber,
-    REQ_ID &reqId,
-    ACS_RESPONSE_TYPE &rType,
-    ALIGNED_BYTES rBuf);
-
-  /**
-   * C++ wrapper around the acs_query_volume() function of the ACSLS C-API.
-   *
-   * @param seqNumber Client supplied sequence number.
-   * @param volIds Array of the volume identifiers to be queried.
-   * @param count The number of volume identifiers contained iwthin the volId
-   * parameter.
-   * @return status value returned by acs_response().
-   */
-  STATUS queryVolume(
-    const SEQ_NO seqNumber,
-    VOLID (&volIds)[MAX_ID],
-    const unsigned short count);
-
-}; // class AcsImpl
-
-} // namespace acs
-} // namespace mediachanger
-} // namespace cta
diff --git a/mediachanger/acs/AcsLibraryInteraction.cpp b/mediachanger/acs/AcsLibraryInteraction.cpp
deleted file mode 100644
index 645711a3570279ade84a56b468a226054334910d..0000000000000000000000000000000000000000
--- a/mediachanger/acs/AcsLibraryInteraction.cpp
+++ /dev/null
@@ -1,160 +0,0 @@
-
-/*
- * 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 "AcsLibraryInteraction.hpp"
-#include "common/log/log.hpp"
-
-#include <stdlib.h>
-
-//------------------------------------------------------------------------------
-// constructor
-//------------------------------------------------------------------------------
-cta::mediachanger::acs::AcsLibraryInteraction::AcsLibraryInteraction(
-  Acs &acs, cta::log::Logger& log): m_acs(acs), m_log(log) {
-}
-
-//------------------------------------------------------------------------------
-// destructor
-//------------------------------------------------------------------------------
-cta::mediachanger::acs::AcsLibraryInteraction::~AcsLibraryInteraction() {
-}
-
-
-//------------------------------------------------------------------------------
-// requestResponsesUntilFinal
-//------------------------------------------------------------------------------
-void cta::mediachanger::acs::AcsLibraryInteraction::requestResponsesUntilFinal(
-  const SEQ_NO requestSeqNumber,
-  ALIGNED_BYTES (&buf)[MAX_MESSAGE_SIZE / sizeof(ALIGNED_BYTES)],
-  const int queryInterval, const int timeout) const
-  {
-  ACS_RESPONSE_TYPE responseType = RT_NONE;
-  int elapsedTime = 0;
-  do {
-    const int remainingTime = timeout - elapsedTime;
-    const int responseTimeout = remainingTime > queryInterval ?
-      queryInterval : remainingTime;
-
-    const time_t startTime = time(NULL);
-    responseType = requestResponse(responseTimeout, requestSeqNumber, buf);
-    elapsedTime += time(NULL) - startTime;
-
-    if(RT_ACKNOWLEDGE == responseType) {
-      m_log(LOG_DEBUG,"Received RT_ACKNOWLEDGE");
-    }
-
-    if(elapsedTime >= timeout) {
-      cta::exception::RequestFailed ex;
-      ex.getMessage() << "Timed out after " << timeout << " seconds";
-      throw ex;
-    }
-  } while(RT_FINAL != responseType);
-
-  m_log(LOG_DEBUG,"Received RT_FINAL");
-}
-
-//------------------------------------------------------------------------------
-// requestResponse
-//------------------------------------------------------------------------------
-ACS_RESPONSE_TYPE cta::mediachanger::acs::AcsLibraryInteraction::requestResponse(
-  const int timeout, const SEQ_NO requestSeqNumber,
-  ALIGNED_BYTES (&buf)[MAX_MESSAGE_SIZE / sizeof(ALIGNED_BYTES)]) const
-   {
-  SEQ_NO responseSeqNumber = 0;
-  REQ_ID reqId = (REQ_ID)0;
-  ACS_RESPONSE_TYPE responseType = RT_NONE;
-
-  std::stringstream dbgMsg;
-  dbgMsg << "Calling Acs::response() for requestSeqNumber=" << requestSeqNumber;
-  m_log(LOG_DEBUG, dbgMsg.str());
-  
-  const STATUS s = m_acs.response(timeout, responseSeqNumber, reqId,
-    responseType, buf);
-  
-  dbgMsg.str("");
-  dbgMsg << "Acs::response() for requestSeqNumber=" << requestSeqNumber <<
-    " returned responseSeqNumber=" << responseSeqNumber << " and status " << 
-    acs_status(s);          
-  m_log(LOG_DEBUG,dbgMsg.str());
-  
-  switch(s) {
-  case STATUS_SUCCESS:
-    checkResponseSeqNumber(requestSeqNumber, responseSeqNumber);
-    return responseType;
-  case STATUS_PENDING:
-    return RT_NONE;
-  default:
-    cta::exception::RequestFailed ex;
-    ex.getMessage() << "Failed to request response: " << acs_status(s);
-    throw ex;
-  }
-}
-
-//------------------------------------------------------------------------------
-// checkSeqNumber
-//------------------------------------------------------------------------------
-void cta::mediachanger::acs::AcsLibraryInteraction::checkResponseSeqNumber(
-  const SEQ_NO requestSeqNumber, const SEQ_NO responseSeqNumber) const
-   {
-  if(requestSeqNumber != responseSeqNumber) {
-    cta::exception::Mismatch ex;
-    ex.getMessage() <<  ": Sequence number mismatch: requestSeqNumber="
-      << requestSeqNumber << " responseSeqNumber=" << responseSeqNumber;
-    throw ex;
-  }
-}
-
-//------------------------------------------------------------------------------
-// volumeStatusAsString
-//------------------------------------------------------------------------------
-std::string cta::mediachanger::acs::AcsLibraryInteraction::volumeStatusAsString(
-  const QU_VOL_STATUS &s) const {
-  
-  std::ostringstream os;
-  os << "vid=" << s.vol_id.external_label << " ";
-  os << "media_types.dat=" << (int)s.media_type << " ";
-
-  switch(s.location_type) {
-  case LOCATION_CELL: {
-    os << "location=cell" << " ";
-    const CELLID &cellId = s.location.cell_id;
-    os << "acs=" << (int)cellId.panel_id.lsm_id.acs << " ";
-    os << "lsm=" << (int)cellId.panel_id.lsm_id.lsm << " ";
-    os << "panel=" << (int)cellId.panel_id.panel << " ";
-    os << "raw=" << (int)cellId.row << " ";
-    os << "column=" << (int)cellId.col << " ";
-    break;
-  }
-  case LOCATION_DRIVE: {
-    os << "location=drive" << " ";
-    const DRIVEID &driveId = s.location.drive_id;
-    os << "acs=" << (int)driveId.panel_id.lsm_id.acs << " ";
-    os << "lsm=" << (int)driveId.panel_id.lsm_id.lsm << " ";
-    os << "panel=" << (int)driveId.panel_id.panel << " ";
-    os << "column=" << (int)driveId.drive << " ";
-    break;
-  }
-  default:
-    os << "location=UNKNOWN" << " ";
-    break;
-  }
-
-  os << "status=" << acs_status(s.status);
-  return os.str();
-}
diff --git a/mediachanger/acs/AcsLibraryInteraction.hpp b/mediachanger/acs/AcsLibraryInteraction.hpp
deleted file mode 100644
index 9e0c32d0644fe869acab1165466fe77c84955dc6..0000000000000000000000000000000000000000
--- a/mediachanger/acs/AcsLibraryInteraction.hpp
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * 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/>.
- */
-
-#pragma once
-
-#include "common/exception/Mismatch.hpp"
-#include "common/exception/RequestFailed.hpp"
-#include "common/log/log.hpp"
-#include "Acs.hpp"
-
-#include <string>
-
-extern "C" {
-#include "acssys.h"
-#include "acsapi.h"
-}
-
-namespace cta {
-namespace mediachanger {
-namespace acs {
-
-/**
- * Abstract class implementing common code and data structures for mount 
- * for read-only access, mount for read/write access and dismount requests 
- * that interact with ACS compatible tape libraries.
- */
-class AcsLibraryInteraction  {
-public:
-  /**
-   * Constructor.
-   *
-   * @param acs Wrapper around the ACSLS C-API.
-   */
-  AcsLibraryInteraction(Acs &acs, cta::log::Logger &log);
-
-  /**
-   * Pure-virtual destructor to guarantee this class is abstract.
-   */
-  virtual ~AcsLibraryInteraction() = 0;
-
-protected:
-
-  /**
-   * Requests responses from ACSLS in a loop until the RT_FINAL response is
-   * received.
-   *
-   * @param requestSeqNumber The sequemce number that was sent in the initial
-   * request to the ACSLS.
-   * @param buf Output parameter.  Message buffer into which the RT_FINAL
-   * response shall be written.
-   * @param queryInterval Time in seconds to wait between queries to ACS for
-   * responses.
-   * @param timeout The time in seconds to spend trying to get the RT_FINAL
-   * response.
-   */
-  void requestResponsesUntilFinal(const SEQ_NO requestSeqNumber,
-    ALIGNED_BYTES (&buf)[MAX_MESSAGE_SIZE / sizeof(ALIGNED_BYTES)],
-    const int queryInterval, const int timeout) const
-    ;
-
-  /**
-   * Sends a request for a response to the ACSLS.
-   *
-   * @param timeout The timeout.
-   * @param requestSeqNumber The sequemce number that was sent in the initial
-   * request to the ACSLS.
-   * @param buf Output parameter.  The response message if there is one.
-   * @return The type of the response message if there is one or RT_NONE if
-   * there isn't one.
-   */
-  ACS_RESPONSE_TYPE requestResponse(const int timeout,
-    const SEQ_NO requestSeqNumber,
-    ALIGNED_BYTES (&buf)[MAX_MESSAGE_SIZE / sizeof(ALIGNED_BYTES)]) const
-    ;
-
-  /**
-   * Throws cta::exception::Mismatch if the specified request and
-   * response sequence-numbers do not match.
-   *
-   * @param requestSeqNumber Request sequence-number.
-   * @param responseSeqNumber Response sequence-number.
-   */
-  void checkResponseSeqNumber(const SEQ_NO requestSeqNumber,
-    const SEQ_NO responseSeqNumber) const ;
-  
-  /**
-   * Converts the specified volume status to a human readable representation.
-   *
-   * @param s The volume status.
-   * @return  The string presentation of the volume status.
-   */
-  std::string volumeStatusAsString(const QU_VOL_STATUS &s) const;
-
-  /**
-   * Wrapper around the ACSLS C-API.
-   */
-  Acs &m_acs;
-  log::Logger &m_log;
-}; // class AcsLibraryInteraction
-
-} // namespace acs
-} // namespace mediachanger
-} // namespace cta
-
-
diff --git a/mediachanger/acs/AcsMountCmd.cpp b/mediachanger/acs/AcsMountCmd.cpp
deleted file mode 100644
index 4707be4325e52f244b1b9e315e10e9eb03fe2cde..0000000000000000000000000000000000000000
--- a/mediachanger/acs/AcsMountCmd.cpp
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- * 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 "AcsMountCmd.hpp"
-#include "AcsMountCmdLine.hpp"
-#include <getopt.h>
-#include <iostream>
-//------------------------------------------------------------------------------
-// constructor
-//------------------------------------------------------------------------------
-cta::mediachanger::acs::AcsMountCmd::AcsMountCmd(
-  std::istream &inStream, std::ostream &outStream, std::ostream &errStream,
-  Acs &acs):
-  AcsCmd(inStream, outStream, errStream, acs) {
-}
-
-//------------------------------------------------------------------------------
-// destructor
-//------------------------------------------------------------------------------
-cta::mediachanger::acs::AcsMountCmd::~AcsMountCmd() {
-  // Do nothing
-}
-
-//------------------------------------------------------------------------------
-// exceptionThrowingMain
-//------------------------------------------------------------------------------
-int cta::mediachanger::acs::AcsMountCmd::exceptionThrowingMain(const int argc,
-  char *const *const argv) {
-  try {
-    m_cmdLine = AcsMountCmdLine(argc, argv);
-  } catch(cta::exception::Exception &ex) {
-    m_err << ex.getMessage().str() << std::endl;
-    m_err << std::endl;
-    m_err << m_cmdLine.getUsage() << std::endl;
-    return 1;
-  }
-
-  // Display the usage message to standard out and exit with success if the
-  // user requested help
-  if(m_cmdLine.help) {
-    m_out << AcsMountCmdLine::getUsage();
-    return 0;
-  }
-
-  // Setup debug mode to be on or off depending on the command-line arguments
-  m_debugBuf.setDebug(m_cmdLine.debug);
-
-  m_dbg << "query = " << m_cmdLine.queryInterval << std::endl;
-  m_dbg << "readonly = " << bool2Str(m_cmdLine.readOnly) << std::endl;
-  m_dbg << "timeout = " << m_cmdLine.timeout << std::endl;
-  m_dbg << "VID = " << m_cmdLine.volId.external_label << std::endl;
-  m_dbg << "DRIVE_SLOT = " << m_acs.driveId2Str(m_cmdLine.libraryDriveSlot)
-    << std::endl;
-
-  syncMount();
-
-  return 0;
-}
-
-//------------------------------------------------------------------------------
-// syncMount
-//------------------------------------------------------------------------------
-void cta::mediachanger::acs::AcsMountCmd::syncMount() {
-  const SEQ_NO requestSeqNumber = 1;
-  ALIGNED_BYTES buf[MAX_MESSAGE_SIZE / sizeof(ALIGNED_BYTES)];
-
-  try {
-    sendMountRequest(requestSeqNumber);
-    requestResponsesUntilFinal(requestSeqNumber, buf, m_cmdLine.queryInterval,
-      m_cmdLine.timeout);
-    processMountResponse(buf);
-  } catch(cta::exception::Exception &ne) {
-    cta::exception::Exception ex;
-    ex.getMessage() << "Failed to mount volume " <<
-      m_cmdLine.volId.external_label << ": " << ne.getMessage().str();
-    throw ex;
-  }
-}
-
-//------------------------------------------------------------------------------
-// sendMountRequest
-//------------------------------------------------------------------------------
-void cta::mediachanger::acs::AcsMountCmd::sendMountRequest(const SEQ_NO seqNumber) {
-  const LOCKID lockId = 0; // No lock
-  const BOOLEAN bypass = FALSE;
-
-  m_dbg << "Calling Acs::mount()" << std::endl;
-  const STATUS s = m_acs.mount(seqNumber, lockId, m_cmdLine.volId,
-    m_cmdLine.libraryDriveSlot, m_cmdLine.readOnly, bypass);
-  m_dbg << "Acs::mount() returned " << acs_status(s) << std::endl;
-
-  if(STATUS_SUCCESS != s) {
-    cta::exception::Exception ex;
-    ex.getMessage() << "Failed to send request to mount volume " <<
-      m_cmdLine.volId.external_label << " into drive " <<
-      m_acs.driveId2Str(m_cmdLine.libraryDriveSlot) << ": readOnly=" <<
-      (m_cmdLine.readOnly ? "TRUE" : "FALSE") << ": " << acs_status(s);
-    throw ex;
-  }
-}
-
-//------------------------------------------------------------------------------
-// processMountResponse
-//------------------------------------------------------------------------------
-void cta::mediachanger::acs::AcsMountCmd::processMountResponse(
-  ALIGNED_BYTES (&buf)[MAX_MESSAGE_SIZE / sizeof(ALIGNED_BYTES)])
-   {
-  const ACS_MOUNT_RESPONSE *const msg = (ACS_MOUNT_RESPONSE *)buf;
-
-  if(STATUS_SUCCESS != msg->mount_status) {
-    cta::exception::Exception ex;
-    ex.getMessage() << "Status of mount response is not success: " <<
-      acs_status(msg->mount_status);
-    throw ex;
-  }
-}
diff --git a/mediachanger/acs/AcsMountCmd.hpp b/mediachanger/acs/AcsMountCmd.hpp
deleted file mode 100644
index 2c142888e20f6216f6a2bc6354e3abdb94ec3df0..0000000000000000000000000000000000000000
--- a/mediachanger/acs/AcsMountCmd.hpp
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * 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/>.
- */
-
-#pragma once
-
-#include "AcsCmd.hpp"
-#include "AcsMountCmdLine.hpp"
-
-#include <stdint.h>
-
-namespace cta {
-namespace mediachanger    {
-namespace acs    {
-
-/**
- * The class implementing the mount command.
- */
-class AcsMountCmd: public AcsCmd {
-public:
-
-  /**
-   * Constructor.
-   *
-   * @param inStream Standard input stream.
-   * @param outStream Standard output stream.
-   * @param errStream Standard error stream.
-   * @param acs Wrapper around the ACSLS C-API.
-   */
-  AcsMountCmd(std::istream &inStream, std::ostream &outStream,
-    std::ostream &errStream, Acs &acs);
-
-  /**
-   * Destructor.
-   */
-  virtual ~AcsMountCmd();
-
-  /**
-   * The entry function of the command.
-   *
-   * @param argc The number of command-line arguments.
-   * @param argv The command-line arguments.
-   * @return The exit value of the program.
-   */
-  int exceptionThrowingMain(const int argc, char *const *const argv);
-
-protected:
-
-  /**
-   * Mounts the tape with the specified VID into the drive with the specified
-   * drive ID.
-   *
-   * This method does not return until the mount has either suceeded, failed or
-   * the specified timeout has been reached.
-   */
-  void syncMount();
-
-  /**
-   * Sends the mount request to ACSLS.
-   *
-   * @param seqNumber The sequence number to be used in the request.
-   */
-  void sendMountRequest(const SEQ_NO seqNumber);
-
-  /**
-   * Process mount rsponse.
-   *
-   * @param buf The mount-response message.
-   */
-  void processMountResponse(
-    ALIGNED_BYTES (&buf)[MAX_MESSAGE_SIZE / sizeof(ALIGNED_BYTES)]);
-
-private:
-
-  /**
-   * The parsed command-line.
-   *
-   * The value of this member variable is set within the main() method of this
-   * class.
-   */
-  AcsMountCmdLine m_cmdLine;
-
-}; // class AcsMountCmd
-
-} // namespace acs
-} // namespace mediachanger
-} // namespace cta
diff --git a/mediachanger/acs/AcsMountCmdLine.cpp b/mediachanger/acs/AcsMountCmdLine.cpp
deleted file mode 100644
index b73f34ddb164317ae582f1c8bee050299f5a1b1d..0000000000000000000000000000000000000000
--- a/mediachanger/acs/AcsMountCmdLine.cpp
+++ /dev/null
@@ -1,175 +0,0 @@
-/*
- * 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 "Acs.hpp"
-#include "AcsMountCmdLine.hpp"
-#include "Constants.hpp"
-
-#include <getopt.h>
-#include <stdlib.h>
-#include <string.h>
-
-//-----------------------------------------------------------------------------
-// constructor
-//-----------------------------------------------------------------------------
-cta::mediachanger::acs::AcsMountCmdLine::AcsMountCmdLine():
-  debug(false),
-  help(false),
-  queryInterval(0),
-  readOnly(FALSE),
-  timeout(0) {
-  libraryDriveSlot.panel_id.lsm_id.acs = (ACS)0;
-  libraryDriveSlot.panel_id.lsm_id.lsm = (LSM)0;
-  libraryDriveSlot.panel_id.panel = (PANEL)0;
-  libraryDriveSlot.drive = (DRIVE)0;
-  memset(volId.external_label, '\0', sizeof(volId.external_label));
-}
-
-//------------------------------------------------------------------------------
-// constructor
-//------------------------------------------------------------------------------
-cta::mediachanger::acs::AcsMountCmdLine::AcsMountCmdLine(const int argc,
-  char *const *const argv):
-  debug(false),
-  help(false),
-  queryInterval(ACS_QUERY_INTERVAL),
-  readOnly(FALSE),
-  timeout(ACS_CMD_TIMEOUT) {
-  libraryDriveSlot.panel_id.lsm_id.acs = (ACS)0;
-  libraryDriveSlot.panel_id.lsm_id.lsm = (LSM)0;
-  libraryDriveSlot.panel_id.panel = (PANEL)0;
-  libraryDriveSlot.drive = (DRIVE)0;
-  memset(volId.external_label, '\0', sizeof(volId.external_label));
-
-  static struct option longopts[] = {
-    {"debug", 0, NULL, 'd'},
-    {"help" , 0, NULL, 'h'},
-    {"query" , required_argument, NULL, 'q'},
-    {"readonly" , 0, NULL, 'r'},
-    {"timeout" , required_argument, NULL, 't'},
-    {NULL, 0, NULL, 0}
-  };
-
-  // Prevent getopt() from printing an error message if it does not recognize
-  // an option character
-  opterr = 0;
-
-  int opt = 0;
-  while((opt = getopt_long(argc, argv, ":dhq:rt:", longopts, NULL)) != -1) {
-    processOption(opt);
-  }
-
-  // There is no need to continue parsing when the help option is set
-  if(help) {
-    return;
-  }
-
-  // Calculate the number of non-option ARGV-elements
-  const int nbArgs = argc - optind;
-
-  // Check that both VID and DRIVE_SLOT have been specified
-  if(nbArgs < 2) {
-    cta::exception::Exception ex;
-    ex.getMessage() << "Both VID and DRIVE_SLOT must be specified";
-    throw ex;
-  }
-
-  // Parse VID
-  volId = Acs::str2Volid(argv[optind]);
-
-  // Move on to the next command-line argument
-  optind++;
-
-  // Parse DRIVE_SLOT
-  libraryDriveSlot = str2DriveId(argv[optind]);
-}
-
-//------------------------------------------------------------------------------
-// processOption
-//------------------------------------------------------------------------------
-void cta::mediachanger::acs::AcsMountCmdLine::processOption(const int opt) {
-  switch(opt) {
-  case 'd':
-    debug = true;
-    break;
-  case 'h':
-    help = true;
-    break;
-  case 'q':
-    queryInterval = parseQueryInterval(optarg);
-    break;
-  case 'r':
-    readOnly = TRUE;
-    break;
-  case 't':
-    timeout = parseTimeout(optarg);
-    break;
-  case ':':
-    return handleMissingParameter(optopt);
-  case '?':
-    return handleUnknownOption(optopt);
-  default:
-    {
-      cta::exception::Exception ex;
-      ex.getMessage() <<
-        "getopt_long returned the following unknown value: 0x" <<
-        std::hex << (int)opt;
-      throw ex;
-    }
-  } // switch(opt)
-}
-
-//------------------------------------------------------------------------------
-// getUsage
-//------------------------------------------------------------------------------
-std::string cta::mediachanger::acs::AcsMountCmdLine::getUsage() {
-  std::ostringstream usage;
-  usage <<
-  "Usage:\n"
-  "\n"
-  "  cta-acs-mount [options] VID DRIVE_SLOT\n"
-  "\n"
-  "Where:\n"
-  "\n"
-  "  VID        The VID of the volume to be mounted.\n"
-  "  DRIVE_SLOT The slot in the tape library where the drive is located.\n"
-  "             The format of DRIVE_SLOT is as follows:\n"
-  "\n"
-  "               ACS:LSM:panel:transport\n"
-  "\n"
-  "Options:\n"
-  "\n"
-  "  -d|--debug            Turn on the printing of debug information.\n"
-  "\n"
-  "  -h|--help             Print this help message and exit.\n"
-  "\n"
-  "  -q|--query SECONDS    Time to wait between queries to ACS for responses.\n"
-  "                        SECONDS must be an integer value greater than 0.\n"
-  "                        The default value of SECONDS is "
-    << ACS_QUERY_INTERVAL << ".\n"
-  "\n"
-  "  -r|--readOnly         Request the volume is mounted for read-only access\n"
-  "\n"
-  "  -t|--timeout SECONDS  Time to wait for the mount to conclude. SECONDS\n"
-  "                        must be an integer value greater than 0.  The\n"
-  "                        default value of SECONDS is "
-    << ACS_CMD_TIMEOUT << ".\n"
-  "\n"
-  "Comments to: CTA team\n";
-  return usage.str();
-}
diff --git a/mediachanger/acs/AcsMountCmdLine.hpp b/mediachanger/acs/AcsMountCmdLine.hpp
deleted file mode 100644
index c15637b5e1ec7e3338154901c32ce210a29080a2..0000000000000000000000000000000000000000
--- a/mediachanger/acs/AcsMountCmdLine.hpp
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * 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/>.
- */
-
-#pragma once
-
-#include "AcsCmdLine.hpp"
-
-extern "C" {
-#include "acssys.h"
-#include "acsapi.h"
-}
-
-#include <string>
-
-namespace cta {
-namespace mediachanger {
-namespace acs {
-
-/**
- * Data type used to store the results of parsing the command-line.
- */
-struct AcsMountCmdLine: public AcsCmdLine {
-  /**
-   * True if the debug option has been set.
-   */
-  bool debug;
-
-  /**
-   * True if the help option has been set.
-   */
-  bool help;
-
-  /**
-   * Time in seconds to wait between queries to ACS for responses.
-   */
-  int queryInterval;
-
-  /**
-   * True if the tape is to be mount for read-only access.
-   */
-  BOOLEAN readOnly;
-
-  /**
-   * Time in seconds to wait for the mount to conclude.
-   */
-  int timeout;
-
-  /**
-   * The volume identifier of the tape to be mounted.
-   */
-  VOLID volId;
-
-  /**
-   * The slot in the tape library where the drive is located.
-   */
-  DRIVEID libraryDriveSlot;
-
-  /**
-   * Constructor.
-   *
-   * Initialises all BOOLEAN member-variables to FALSE, all integer
-   * member-variables to 0 and the volume identifier to an empty string.
-   */
-  AcsMountCmdLine();
-
-  /**
-   * Constructor.
-   *
-   * Parses the specified command-line arguments.
-   *
-   * @param argc Argument count from the executable's entry function: main().
-   * @param argv Argument vector from the executable's entry function: main().
-   */
-  AcsMountCmdLine(const int argc, char *const *const argv);
-
-  /**
-   * Gets the usage message that describes the comamnd line.
-   *
-   * @return The usage message.
-   */
-  static std::string getUsage();
-
-private:
-
-  /** 
-   * Processes the specified option that was returned by getopt_long().
-   *
-   * @param opt The option that was returned by getopt_long().
-   */
-  void processOption(const int opt);
-
-}; // class AcsMountCmdLine
-
-} // namespace acs
-} // namespace mediachanger
-} // namespace cta
diff --git a/mediachanger/acs/AcsMountCmdMain.cpp b/mediachanger/acs/AcsMountCmdMain.cpp
deleted file mode 100644
index b1c4e965c72b2ef124d8a2a9774db947661f9a76..0000000000000000000000000000000000000000
--- a/mediachanger/acs/AcsMountCmdMain.cpp
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * 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 "AcsImpl.hpp"
-#include "AcsMountCmd.hpp"
-#include "AcsMountCmdLine.hpp"
-
-#include <iostream>
-
-/**
- * An exception throwing version of main().
- *
- * @param argc The number of command-line arguments including the program name.
- * @param argv The command-line arguments.
- * @return The exit value of the program.
- */
-static int exceptionThrowingMain(const int argc, char *const *const argv);
-
-//------------------------------------------------------------------------------
-// main
-//------------------------------------------------------------------------------
-int main(const int argc, char *const *const argv) {
-  using namespace cta;
-
-  std::string errorMessage;
-
-  try {
-    return exceptionThrowingMain(argc, argv);
-  } catch(cta::exception::Exception &ex) {
-    errorMessage = ex.getMessage().str();
-  } catch(std::exception &se) {
-    errorMessage = se.what();
-  } catch(...) {
-    errorMessage = "An unknown exception was thrown";
-  }
-
-  // Reaching this point means the command has failed, ane exception was throw
-  // and errorMessage has been set accordingly
-
-  std::cerr << "Aborting: " << errorMessage << std::endl;
-  return 1;
-}
-
-//------------------------------------------------------------------------------
-// exceptionThrowingMain
-//------------------------------------------------------------------------------
-static int exceptionThrowingMain(const int argc, char *const *const argv) {
-  using namespace cta;
-
-  mediachanger::acs::AcsImpl acs;
-  mediachanger::acs::AcsMountCmd cmd(std::cin, std::cout, std::cerr, acs);
-
-  return cmd.exceptionThrowingMain(argc, argv);
-}
diff --git a/mediachanger/acs/AcsQueryDriveCmd.cpp b/mediachanger/acs/AcsQueryDriveCmd.cpp
deleted file mode 100644
index a3150c9fe5e3305518c919f66369199377eb7aa0..0000000000000000000000000000000000000000
--- a/mediachanger/acs/AcsQueryDriveCmd.cpp
+++ /dev/null
@@ -1,161 +0,0 @@
-/*
- * 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 "AcsQueryDriveCmd.hpp"
-#include "AcsQueryDriveCmdLine.hpp"
-#include <getopt.h>
-#include <iostream>
-#include <string.h>
- 
-//------------------------------------------------------------------------------
-// constructor
-//------------------------------------------------------------------------------
-cta::mediachanger::acs::AcsQueryDriveCmd::AcsQueryDriveCmd(
-  std::istream &inStream, std::ostream &outStream, std::ostream &errStream,
-  Acs &acs):
-  AcsCmd(inStream, outStream, errStream, acs) {
-}
-
-//------------------------------------------------------------------------------
-// destructor
-//------------------------------------------------------------------------------
-cta::mediachanger::acs::AcsQueryDriveCmd::~AcsQueryDriveCmd() {
-  // Do nothing
-}
-
-//------------------------------------------------------------------------------
-// exceptionThrowingMain
-//------------------------------------------------------------------------------
-int cta::mediachanger::acs::AcsQueryDriveCmd::exceptionThrowingMain(const int argc,
-  char *const *const argv) {
-  try {
-    m_cmdLine = AcsQueryDriveCmdLine(argc, argv);
-  } catch(cta::exception::Exception &ex) {
-    m_err << ex.getMessage().str() << std::endl;
-    m_err << std::endl;
-    m_err << m_cmdLine.getUsage() << std::endl;
-    return 1;
-  }
-
-  // Display the usage message to standard out and exit with success if the
-  // user requested help
-  if(m_cmdLine.help) {
-    m_out << AcsQueryDriveCmdLine::getUsage();
-    return 0;
-  }
-
-  // Setup debug mode to be on or off depending on the command-line arguments
-  m_debugBuf.setDebug(m_cmdLine.debug);
-
-  m_dbg << "query = " << m_cmdLine.queryInterval << std::endl;
-  m_dbg << "timeout = " << m_cmdLine.timeout << std::endl;
-  m_dbg << "DRIVE_SLOT = " << m_acs.driveId2Str(m_cmdLine.libraryDriveSlot) << std::endl;
-
-  syncQueryDrive();
-  return 0;
-}
-
-//------------------------------------------------------------------------------
-// syncQueryDrive
-//------------------------------------------------------------------------------
-void cta::mediachanger::acs::AcsQueryDriveCmd::syncQueryDrive() {
-  const SEQ_NO requestSeqNumber = 1;
-  ALIGNED_BYTES buf[MAX_MESSAGE_SIZE / sizeof(ALIGNED_BYTES)];
-
-  try {
-    sendQueryDriveRequest(requestSeqNumber);
-    requestResponsesUntilFinal(requestSeqNumber, buf, m_cmdLine.queryInterval,
-      m_cmdLine.timeout);
-    processQueryResponse(m_out, buf);
-  } catch(cta::exception::Exception &ne) {
-    cta::exception::Exception ex;
-    ex.getMessage() << "Failed to query drive " <<
-      m_acs.driveId2Str(m_cmdLine.libraryDriveSlot) << ": " << ne.getMessage().str();
-    throw ex;
-  }
-}
-
-//------------------------------------------------------------------------------
-// sendQueryDriveRequest
-//------------------------------------------------------------------------------
-void cta::mediachanger::acs::AcsQueryDriveCmd::sendQueryDriveRequest(
-  const SEQ_NO sequence)  {
-
-  m_dbg << "Calling Acs::queryDrive()" << std::endl;
-  const STATUS s = acs_query_drive(sequence, &(m_cmdLine.libraryDriveSlot), 1);
-  m_dbg << "Acs::queryDrive() returned " << acs_status(s) << std::endl;
-
-  if(STATUS_SUCCESS != s) {
-    cta::exception::Exception ex;
-    ex.getMessage() << "Failed to send query request for drive " <<
-     m_acs.driveId2Str(m_cmdLine.libraryDriveSlot)<< ": " << acs_status(s);
-    throw ex;
-  }
-}
-
-//------------------------------------------------------------------------------
-// processQueryResponse
-//------------------------------------------------------------------------------
-void cta::mediachanger::acs::AcsQueryDriveCmd::processQueryResponse(
-  std::ostream &os,
-  ALIGNED_BYTES (&buf)[MAX_MESSAGE_SIZE / sizeof(ALIGNED_BYTES)]) {
-
-  const ACS_QUERY_DRV_RESPONSE *const msg = (ACS_QUERY_DRV_RESPONSE *)buf;
-
-  if(STATUS_SUCCESS != msg->query_drv_status) {
-    cta::exception::Exception ex;
-    ex.getMessage() << "Status of query response is not success: " <<
-      acs_status(msg->query_drv_status);
-    throw ex;
-  }
-
-  if((unsigned short)1 != msg->count) {
-    cta::exception::Exception ex;
-    ex.getMessage() << "Query response does not contain a single drive: count="
-      << msg->count;
-    throw ex;
-  }
-
-  // count is 1 so it is safe to make a reference to the single drive status
-  const QU_DRV_STATUS &drvStatus = msg->drv_status[0];
-
-  if(m_acs.driveId2Str(m_cmdLine.libraryDriveSlot)!= m_acs.driveId2Str(drvStatus.drive_id)) {
-    cta::exception::Exception ex;
-    ex.getMessage() <<
-      "Drive identifier of query response does not match that of request"
-      " requestDriveID=" <<m_acs.driveId2Str(m_cmdLine.libraryDriveSlot) <<
-      " responseDriveID=" << m_acs.driveId2Str(drvStatus.drive_id);
-    throw ex;
-  }
-
-  writeDriveStatus(os, drvStatus);
-}
-
-//------------------------------------------------------------------------------
-// writeDriveStatus
-//------------------------------------------------------------------------------
-void cta::mediachanger::acs::AcsQueryDriveCmd::writeDriveStatus(
-  std::ostream &os, const QU_DRV_STATUS &s) {
-
-  os << "Drive identifier: " << m_acs.driveId2Str(s.drive_id) << std::endl;
-  os << "Drive type: " << acs_type((TYPE)s.drive_type) << std::endl;
-  os << "Drive state: " << acs_state(s.state) << std::endl;
-  os << "Drive status: " << acs_status(s.status) << std::endl;
-  os << "Volume identifier: " << s.vol_id.external_label << std::endl;
-}
diff --git a/mediachanger/acs/AcsQueryDriveCmd.hpp b/mediachanger/acs/AcsQueryDriveCmd.hpp
deleted file mode 100644
index 2463a16323c390e1408dd89aa0b8236a7d73ab0a..0000000000000000000000000000000000000000
--- a/mediachanger/acs/AcsQueryDriveCmd.hpp
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * 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/>.
- */
-
-#pragma once
-
-#include "AcsCmd.hpp"
-#include "AcsQueryDriveCmdLine.hpp"
-#include "mediachanger/CmdLineTool.hpp"
-#include <stdint.h>
-
-namespace cta {
-namespace mediachanger {
-namespace acs {
-
-/**
- * The class implementing the mount command.
- */
-class AcsQueryDriveCmd: public AcsCmd {
-public:
-
-  /**
-   * Constructor.
-   *
-   * @param inStream Standard input stream.
-   * @param outStream Standard output stream.
-   * @param errStream Standard error stream.
-   * @param acs Wrapper around the ACSLS C-API.
-   */
-  AcsQueryDriveCmd(std::istream &inStream, std::ostream &outStream,
-    std::ostream &errStream, Acs &acs);
-
-  /**
-   * Destructor.
-   */
-  virtual ~AcsQueryDriveCmd();
-
-  /**
-   * The entry function of the command.
-   *
-   * @param argc The number of command-line arguments.
-   * @param argv The command-line arguments.
-   * @return The exit value of the program.
-   */
-  int exceptionThrowingMain(const int argc, char *const *const argv);
-protected:
-
-  /**
-   * Queries ACS for information about the drive identifier specified on the
-   * command-line.
-   *
-   * This method does not return until the information has been successfully
-   * retrieved, an error has occurred or the specified timeout has been
-   * reached.
-   *
-   * @return The drive status of the drive identifier specified on the
-   * command-line.
-   */
-  void syncQueryDrive();
-
-  /**
-   * Sends the query drive  request to ACSLS.
-   *
-   * @param seqNumber The sequence number to be used in the request.
-   */
-  void sendQueryDriveRequest(const SEQ_NO seqNumber);
-
-  /**
-   * Extracts the drive status from the specified query-response message and
-   * writes it in human-readable form to the specified output stream.
-   *
-   * @param os The output stream.
-   * @param buf The query-response message.
-   */
-  void processQueryResponse(std::ostream &os,
-    ALIGNED_BYTES (&buf)[MAX_MESSAGE_SIZE / sizeof(ALIGNED_BYTES)]);
-
-  /**
-   * Writes a human readable representation of the specified drive status to
-   * the specified output stream.
-   *
-   * @param os The output stream.
-   * @param s The drive status.
-   */
-  void writeDriveStatus(std::ostream &os, const QU_DRV_STATUS &s);
-
-private:
-
-  /**
-   * The parsed command-line.
-   *
-   * The value of this member variable is set within the main() method of this
-   * class.
-   */
-  AcsQueryDriveCmdLine m_cmdLine;
-
-}; // class AcsQueryDriveCmd
-
-} // namespace acs
-} // namepsace mediachanger
-} // namespace cta
diff --git a/mediachanger/acs/AcsQueryDriveCmdLine.cpp b/mediachanger/acs/AcsQueryDriveCmdLine.cpp
deleted file mode 100644
index e48c347b9fa95c98339f921177767f31a5de5ee2..0000000000000000000000000000000000000000
--- a/mediachanger/acs/AcsQueryDriveCmdLine.cpp
+++ /dev/null
@@ -1,174 +0,0 @@
-
-/*
- * 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 "Acs.hpp"
-#include "AcsQueryDriveCmdLine.hpp"
-#include "Constants.hpp"
-#include <getopt.h>
-#include <stdlib.h>
-#include <string.h>
-
-
-//-----------------------------------------------------------------------------
-// constructor
-//-----------------------------------------------------------------------------
-cta::mediachanger::acs::AcsQueryDriveCmdLine::AcsQueryDriveCmdLine():
-  debug(false),
-  help(false),
-  queryInterval(0),
-  timeout(0) {
-  libraryDriveSlot.panel_id.lsm_id.acs = (ACS)0;
-  libraryDriveSlot.panel_id.lsm_id.lsm = (LSM)0;
-  libraryDriveSlot.panel_id.panel = (PANEL)0;
-  libraryDriveSlot.drive = (DRIVE)0;
-  memset(volId.external_label, '\0', sizeof(volId.external_label));
-}
-
-
-//------------------------------------------------------------------------------
-// constructor
-//------------------------------------------------------------------------------
-cta::mediachanger::acs::AcsQueryDriveCmdLine::AcsQueryDriveCmdLine(const int argc,
-  char *const *const argv):
-  debug(false),
-  help(false),
-  queryInterval(ACS_QUERY_INTERVAL),
-  timeout(ACS_CMD_TIMEOUT) {
-  libraryDriveSlot.panel_id.lsm_id.acs = (ACS)0;
-  libraryDriveSlot.panel_id.lsm_id.lsm = (LSM)0;
-  libraryDriveSlot.panel_id.panel = (PANEL)0;
-  libraryDriveSlot.drive = (DRIVE)0;
-  memset(volId.external_label, '\0', sizeof(volId.external_label));
-
-  static struct option longopts[] = {
-  {"debug", 0, NULL, 'd'},
-  {"help" , 0, NULL, 'h'},
-  {"query" , required_argument, NULL, 'q'},
-  {"timeout" , required_argument, NULL, 't'},
-  {NULL, 0, NULL, 0}
-  };
-
-  // Prevent getopt() from printing an error message if it does not recognize
-  // an option character
-  opterr = 0;
-
-  int opt = 0;
-  while((opt = getopt_long(argc, argv, ":dhq:t:", longopts, NULL)) != -1) {
-    processOption(opt);
-  }
-  // There is no need to continue parsing when the help option is set
-  if(help) {
-    return;
-  }
-
-  // Calculate the number of non-option ARGV-elements
-  const int nbArgs = argc - optind;
-
-  // Check that DRIVE_SLOT has been specified
-  if(1 > nbArgs) {
-    cta::exception::Exception ex;
-    ex.getMessage() << "DRIVE_SLOT must be specified";
-    throw ex;
-  }
-
-  // Check that aren't too many non-optional arguments
-  if(1 < nbArgs) {
-    cta::exception::Exception ex;
-    ex.getMessage() << "To many non-optional arguments: expected=1,actual=" << nbArgs;
-    throw ex;
-  }
-
-  // Parse DRIVE_SLOT
-  libraryDriveSlot = str2DriveId(argv[optind]);
-}
-
-//------------------------------------------------------------------------------
-// processOption
-//------------------------------------------------------------------------------
-void cta::mediachanger::acs::AcsQueryDriveCmdLine::processOption(const int opt) {
-  switch(opt) {
-  case 'd':
-    debug = true;
-    break;
-  case 'h':
-    help = true;
-    break;
-  case 'q':
-    queryInterval = parseQueryInterval(optarg);
-    break;
-  case 't':
-    timeout = parseTimeout(optarg);
-    break;
-  case ':':
-    return handleMissingParameter(optopt);
-  case '?':
-    return handleUnknownOption(optopt);
-  default:
-    {
-      cta::exception::Exception ex;
-      ex.getMessage() <<
-        "getopt_long returned the following unknown value: 0x" <<
-        std::hex << (int)opt;
-      throw ex;
-    }
-  } // switch(opt)
-}
-
-
-//------------------------------------------------------------------------------
-// getUsage
-//------------------------------------------------------------------------------
-  std::string cta::mediachanger::acs::AcsQueryDriveCmdLine::getUsage() {
-  std::ostringstream usage;
-  usage <<
-  "Usage:\n"
-  "\n"
-  << getProgramName() << " [options] DRIVE_SLOT\n"
-  "\n"
-  "Where:\n"
-  "\n"
-  "  DRIVE_SLOT The slot in the tape library where the drive is located.\n"
-  "             The format of DRIVE_SLOT is as follows:\n"
-  "\n"
-  "               ACS:LSM:panel:transport\n"
-  "\n"
-  "Options:\n"
-  "\n"
-  "  -d|--debug            Turn on the printing of debug information.\n"
-  "\n"
-  "  -h|--help             Print this help message and exit.\n"
-  "  -q|--query SECONDS    Time to wait between queries to ACS for responses.\n"
-  "                        SECONDS must be an integer value greater than 0.\n"
-  "                        The default value of SECONDS is "
-    << ACS_QUERY_INTERVAL << ".\n"
-  "  -t|--timeout SECONDS  Time to wait for the query to conclude. SECONDS\n"
-  "                        must be an integer value greater than 0.  The\n"
-  "                        default value of SECONDS is "
-    << ACS_CMD_TIMEOUT << ".\n"
-  "\n";
-  return usage.str();
-}
-
-//------------------------------------------------------------------------------
-// getProgramName
-//------------------------------------------------------------------------------
-std::string cta::mediachanger::acs::AcsQueryDriveCmdLine::getProgramName() {
-  return "cta-acs-querydrive";
-}
-
diff --git a/mediachanger/acs/AcsQueryDriveCmdLine.hpp b/mediachanger/acs/AcsQueryDriveCmdLine.hpp
deleted file mode 100644
index b62df0e7d6850505a607b8d2a61b352cda15c339..0000000000000000000000000000000000000000
--- a/mediachanger/acs/AcsQueryDriveCmdLine.hpp
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * 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/>.
- */
-
-#pragma once
-
-#include "AcsCmdLine.hpp"
-#include "mediachanger/AcsLibrarySlot.hpp"
-#include "mediachanger/LibrarySlotParser.hpp"
-
-extern "C" {
-#include "acssys.h"
-#include "acsapi.h"
-}
-
-#include <string>
-
-namespace cta {
-namespace mediachanger {
-namespace acs {
-
-/**
- * Data type used to store the results of parsing the command-line.
- */
-struct AcsQueryDriveCmdLine: public AcsCmdLine {
-  /**
-   * True if the debug option has been set.
-   */
-  BOOLEAN debug;
-
-  /**
-   * True if the help option has been set.
-   */
-  BOOLEAN help;
-
-  /**
-   * Time in seconds to wait between queries to ACS for responses.
-   */
-  int queryInterval;
-
-  /**
-   * Time in seconds to wait for the dismount to conclude.
-   */
-  int timeout;
-
-  /**
-   * The volume identifier of the tape to be mounted.
-   */
-  VOLID volId;
-
-  /**
-   * Constructor.
-   *
-   * Initialises all BOOLEAN member-variables to FALSE, all integer
-   * member-variables to 0 and the volume identifier to an empty string.
-   */
-  AcsQueryDriveCmdLine();
-
-  /**
-   * Constructor.
-   *
-   * Parses the specified command-line arguments.
-   *
-   * @param argc Argument count from the executable's entry function: main().
-   * @param argv Argument vector from the executable's entry function: main().
-   */
-  AcsQueryDriveCmdLine(const int argc, char *const *const argv);
-
-
- /**
-  * Gets the usage message that describes the command line.
-  *
-  * @return The usage message.
-  */
-  static std::string getUsage();
-
-  /**
-   * Return sthe program name.
-   *
-   * @return sthe program name.
-   */
-  static std::string getProgramName();
-
-  /**
-   * The slot in the tape library where the drive is located.
-   */
-
-  DRIVEID libraryDriveSlot;
-
-
-private:
-
-  /**
-   * Processes the specified option that was returned by getopt_long().
-   *
-   * @param opt The option that was returned by getopt_long().
-   */
-  void processOption(const int opt);
-
-}; // class AcsQueryDriveCmdLine
-
-} // namespace acs
-} // namespace mediachanger
-} // namespace cta
diff --git a/mediachanger/acs/AcsQueryDriveCmdMain.cpp b/mediachanger/acs/AcsQueryDriveCmdMain.cpp
deleted file mode 100644
index cfc8d406ae0a9ffbe052a1c4e08456365be69000..0000000000000000000000000000000000000000
--- a/mediachanger/acs/AcsQueryDriveCmdMain.cpp
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * 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 "AcsImpl.hpp"
-#include "AcsQueryDriveCmd.hpp"
-#include "AcsQueryDriveCmdLine.hpp"
-
-#include <iostream>
-
-/**
- * An exception throwing version of main().
- *
- * @param argc The number of command-line arguments including the program name.
- * @param argv The command-line arguments.
- * @param The exit value of the program.
- */ 
-static int exceptionThrowingMain(const int argc, char *const *const argv);
-  
-//------------------------------------------------------------------------------
-// main
-//------------------------------------------------------------------------------
-int main(const int argc, char *const *const argv) {
-  using namespace cta;
-  std::string errorMessage;
-  try {
-    return exceptionThrowingMain(argc, argv);
-  } catch(cta::exception::Exception &ex) {
-    errorMessage = ex.getMessage().str();
-  } catch(std::exception &se) {
-    errorMessage = se.what();
-  } catch(...) {
-    errorMessage = "An unknown exception was thrown";
-  }
-  return 1;
-}
-
-//------------------------------------------------------------------------------
-// exceptionThrowingMain
-//------------------------------------------------------------------------------
-static int exceptionThrowingMain(const int argc, char *const *const argv) {
-  using namespace cta;
-  mediachanger::acs::AcsImpl acs;
-  mediachanger::acs::AcsQueryDriveCmd cmd(std::cin, std::cout, std::cerr, acs);
-  return cmd.exceptionThrowingMain(argc, argv);
-}
diff --git a/mediachanger/acs/AcsQueryVolumeCmd.cpp b/mediachanger/acs/AcsQueryVolumeCmd.cpp
deleted file mode 100644
index 9384ed51942d0c1da4f4a3f0211fe764b12c6759..0000000000000000000000000000000000000000
--- a/mediachanger/acs/AcsQueryVolumeCmd.cpp
+++ /dev/null
@@ -1,190 +0,0 @@
-/*
- * 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 "AcsQueryVolumeCmd.hpp"
-#include "AcsQueryVolumeCmdLine.hpp"
-#include <getopt.h>
-#include <iostream>
-#include <string.h>
- 
-//------------------------------------------------------------------------------
-// constructor
-//------------------------------------------------------------------------------
-cta::mediachanger::acs::AcsQueryVolumeCmd::AcsQueryVolumeCmd(
-  std::istream &inStream, std::ostream &outStream, std::ostream &errStream,
-  Acs &acs):
-  AcsCmd(inStream, outStream, errStream, acs) {
-}
-
-//------------------------------------------------------------------------------
-// destructor
-//------------------------------------------------------------------------------
-cta::mediachanger::acs::AcsQueryVolumeCmd::~AcsQueryVolumeCmd() {
-  // Do nothing
-}
-
-//------------------------------------------------------------------------------
-// exceptionThrowingMain
-//------------------------------------------------------------------------------
-int cta::mediachanger::acs::AcsQueryVolumeCmd::exceptionThrowingMain(const int argc,
-  char *const *const argv) {
-  try {
-    m_cmdLine = AcsQueryVolumeCmdLine(argc, argv);
-  } catch(cta::exception::Exception &ex) {
-    m_err << ex.getMessage().str() << std::endl;
-    m_err << std::endl;
-    m_err << m_cmdLine.getUsage() << std::endl;
-    return 1;
-  }
-
-  // Display the usage message to standard out and exit with success if the
-  // user requested help
-  if(m_cmdLine.help) {
-    m_out << AcsQueryVolumeCmdLine::getUsage();
-    return 0;
-  }
-
-  // Setup debug mode to be on or off depending on the command-line arguments
-  m_debugBuf.setDebug(m_cmdLine.debug);
-
-  m_dbg << "query = " << m_cmdLine.queryInterval << std::endl;
-  m_dbg << "timeout = " << m_cmdLine.timeout << std::endl;
-  m_dbg << "VID = " << m_cmdLine.volId.external_label << std::endl;
-
-  syncQueryVolume();
-  return 0;
-}
-
-//------------------------------------------------------------------------------
-// syncQueryVolume
-//------------------------------------------------------------------------------
-void cta::mediachanger::acs::AcsQueryVolumeCmd::syncQueryVolume() {
-  const SEQ_NO requestSeqNumber = 1;
-  ALIGNED_BYTES buf[MAX_MESSAGE_SIZE / sizeof(ALIGNED_BYTES)];
-
-  try {
-    sendQueryVolumeRequest(requestSeqNumber);
-    requestResponsesUntilFinal(requestSeqNumber, buf, m_cmdLine.queryInterval,
-      m_cmdLine.timeout);
-    processQueryResponse(m_out, buf);
-  } catch(cta::exception::Exception &ne) {
-    cta::exception::Exception ex;
-    ex.getMessage() << "Failed to query volume " <<
-      m_cmdLine.volId.external_label << ": " << ne.getMessage().str();
-    throw ex;
-  }
-}
-
-//------------------------------------------------------------------------------
-// sendQueryVolumeRequest
-//------------------------------------------------------------------------------
-void cta::mediachanger::acs::AcsQueryVolumeCmd::sendQueryVolumeRequest(
-  const SEQ_NO seqNumber)  {
-  VOLID volIds[MAX_ID];
-
-  memset(volIds, '\0', sizeof(volIds));
-  strncpy(volIds[0].external_label, m_cmdLine.volId.external_label,
-    sizeof(volIds[0].external_label));
-  volIds[0].external_label[sizeof(volIds[0].external_label) - 1]  = '\0';
-
-  m_dbg << "Calling Acs::queryVolume()" << std::endl;
-  const STATUS s = m_acs.queryVolume(seqNumber, volIds, 1);
-  m_dbg << "Acs::queryVolume() returned " << acs_status(s) << std::endl;
-
-  if(STATUS_SUCCESS != s) {
-    cta::exception::Exception ex;
-    ex.getMessage() << "Failed to send query request for volume " <<
-      m_cmdLine.volId.external_label << ": " << acs_status(s);
-    throw ex;
-  }
-}
-
-//------------------------------------------------------------------------------
-// processQueryResponse
-//------------------------------------------------------------------------------
-void cta::mediachanger::acs::AcsQueryVolumeCmd::processQueryResponse(
-  std::ostream &os,
-  ALIGNED_BYTES (&buf)[MAX_MESSAGE_SIZE / sizeof(ALIGNED_BYTES)]) {
-
-  const ACS_QUERY_VOL_RESPONSE *const msg = (ACS_QUERY_VOL_RESPONSE *)buf;
-
-  if(STATUS_SUCCESS != msg->query_vol_status) {
-    cta::exception::Exception ex;
-    ex.getMessage() << "Status of query response is not success: " <<
-      acs_status(msg->query_vol_status);
-    throw ex;
-  }
-
-  if((unsigned short)1 != msg->count) {
-    cta::exception::Exception ex;
-    ex.getMessage() << "Query response does not contain a single volume: count="
-      << msg->count;
-    throw ex;
-  }
-
-  // count is 1 so it is safe to make a reference to the single volume status
-  const QU_VOL_STATUS &volStatus = msg->vol_status[0];
-
-  if(strcmp(m_cmdLine.volId.external_label, volStatus.vol_id.external_label)) {
-    cta::exception::Exception ex;
-    ex.getMessage() <<
-      "Volume identifier of query response does not match that of request"
-      ": requestVID=" << m_cmdLine.volId.external_label <<
-      " responseVID=" << volStatus.vol_id.external_label;
-    throw ex;
-  }
-
-  writeVolumeStatus(os, volStatus);
-}
-
-//------------------------------------------------------------------------------
-// writeVolumeStatus
-//------------------------------------------------------------------------------
-void cta::mediachanger::acs::AcsQueryVolumeCmd::writeVolumeStatus(
-  std::ostream &os, const QU_VOL_STATUS &s) {
-  os << "Volume identifier: " << s.vol_id.external_label << std::endl;
-  os << "Media type (media_types.dat): " << (int)s.media_type << std::endl;
-
-  switch(s.location_type) {
-  case LOCATION_CELL: {
-    os << "Location type: cell" << std::endl;
-    const CELLID &cellId = s.location.cell_id;
-    os << "ACS: " << (int)cellId.panel_id.lsm_id.acs << std::endl;
-    os << "LSM: " << (int)cellId.panel_id.lsm_id.lsm << std::endl;
-    os << "Panel: " << (int)cellId.panel_id.panel << std::endl;
-    os << "Row: " << (int)cellId.row << std::endl;
-    os << "Column: " << (int)cellId.col << std::endl;
-    break;
-  }
-  case LOCATION_DRIVE: {
-    os << "Location type: drive" << std::endl;
-    const DRIVEID &driveId = s.location.drive_id;
-    os << "ACS: " << (int)driveId.panel_id.lsm_id.acs << std::endl;
-    os << "LSM: " << (int)driveId.panel_id.lsm_id.lsm << std::endl;
-    os << "Panel: " << (int)driveId.panel_id.panel << std::endl;
-    os << "Drive: " << (int)driveId.drive << std::endl;
-    break;
-  }
-  default:
-    os << "Location type: UNKNOWN" << std::endl;
-    break;
-  }
-
-  os << "Status: " << acs_status(s.status) << std::endl;
-}
diff --git a/mediachanger/acs/AcsQueryVolumeCmd.hpp b/mediachanger/acs/AcsQueryVolumeCmd.hpp
deleted file mode 100644
index 9221d96cbbbe0c1b6af9821d257bf65cbe551f31..0000000000000000000000000000000000000000
--- a/mediachanger/acs/AcsQueryVolumeCmd.hpp
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * 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/>.
- */
-
-#pragma once
-
-#include "AcsCmd.hpp"
-#include "AcsQueryVolumeCmdLine.hpp"
-
-#include <stdint.h>
-
-namespace cta {
-namespace mediachanger {
-namespace acs {
-
-/**
- * The class implementing the mount command.
- */
-class AcsQueryVolumeCmd: public AcsCmd {
-public:
-
-  /**
-   * Constructor.
-   *
-   * @param inStream Standard input stream.
-   * @param outStream Standard output stream.
-   * @param errStream Standard error stream.
-   * @param acs Wrapper around the ACSLS C-API.
-   */
-  AcsQueryVolumeCmd(std::istream &inStream, std::ostream &outStream,
-    std::ostream &errStream, Acs &acs);
-
-  /**
-   * Destructor.
-   */
-  virtual ~AcsQueryVolumeCmd();
-
-  /**
-   * The entry function of the command.
-   *
-   * @param argc The number of command-line arguments.
-   * @param argv The command-line arguments.
-   * @return The exit value of the program.
-   */
-  int exceptionThrowingMain(const int argc, char *const *const argv);
-
-protected:
-
-  /**
-   * Queries ACS for information about the volume identifier specified on the
-   * command-line.
-   *
-   * This method does not return until the information has been successfully
-   * retrieved, an error has occurred or the specified timeout has been
-   * reached.
-   *
-   * @return The volume status of the volume identifier specified on the
-   * command-line.
-   */
-  void syncQueryVolume();
-
-  /**
-   * Sends the query volume  request to ACSLS.
-   *
-   * @param seqNumber The sequence number to be used in the request.
-   */
-  void sendQueryVolumeRequest(const SEQ_NO seqNumber);
-
-  /**
-   * Extracts the volume status from the specified query-response message and
-   * writes it in human-readable form to the specified output stream.
-   *
-   * @param os The output stream.
-   * @param buf The query-response message.
-   */
-  void processQueryResponse(std::ostream &os,
-    ALIGNED_BYTES (&buf)[MAX_MESSAGE_SIZE / sizeof(ALIGNED_BYTES)]);
-
-  /**
-   * Writes a human readable representation of the specified volume status to
-   * the specified output stream.
-   *
-   * @param os The output stream.
-   * @param s The volume status.
-   */
-  void writeVolumeStatus(std::ostream &os, const QU_VOL_STATUS &s);
-
-private:
-
-  /**
-   * The parsed command-line.
-   *
-   * The value of this member variable is set within the main() method of this
-   * class.
-   */
-  AcsQueryVolumeCmdLine m_cmdLine;
-
-}; // class AcsQueryVolumeCmd
-
-} // namespace acs
-} // namepsace mediachanger
-} // namespace cta
diff --git a/mediachanger/acs/AcsQueryVolumeCmdLine.cpp b/mediachanger/acs/AcsQueryVolumeCmdLine.cpp
deleted file mode 100644
index 375112ad50d531d9a51febb739419a9a336c90b7..0000000000000000000000000000000000000000
--- a/mediachanger/acs/AcsQueryVolumeCmdLine.cpp
+++ /dev/null
@@ -1,147 +0,0 @@
-
-/*
- * 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 "Acs.hpp"
-#include "AcsQueryVolumeCmdLine.hpp"
-#include "Constants.hpp"
-
-#include <getopt.h>
-#include <stdlib.h>
-#include <string.h>
-
-//-----------------------------------------------------------------------------
-// constructor
-//-----------------------------------------------------------------------------
-cta::mediachanger::acs::AcsQueryVolumeCmdLine::AcsQueryVolumeCmdLine()
- :
-  debug(FALSE),
-  help(FALSE),
-  queryInterval(0),
-  timeout(0) {
-  memset(volId.external_label, '\0', sizeof(volId.external_label));
-}
-
-//------------------------------------------------------------------------------
-// constructor
-//------------------------------------------------------------------------------
-cta::mediachanger::acs::AcsQueryVolumeCmdLine::AcsQueryVolumeCmdLine(const int argc,
-  char *const *const argv):
-  debug(FALSE),
-  help(FALSE),
-  queryInterval(ACS_QUERY_INTERVAL),
-  timeout(ACS_CMD_TIMEOUT) {
-  memset(volId.external_label, '\0', sizeof(volId.external_label));
-
-  static struct option longopts[] = {
-    {"debug", 0, NULL, 'd'},
-    {"help" , 0, NULL, 'h'},
-    {"query" , required_argument, NULL, 'q'},
-    {"timeout" , required_argument, NULL, 't'},
-    {NULL, 0, NULL, 0}
-  };
-
-  // Prevent getopt() from printing an error message if it does not recognize
-  // an option character
-  opterr = 0;
-
-  int opt = 0;
-  while((opt = getopt_long(argc, argv, ":dhq:t:", longopts, NULL)) != -1) {
-    processOption(opt);
-  }
-
-  // There is no need to continue parsing when the help option is set
-  if(help) {
-    return;
-  }
-
-  // Calculate the number of non-option ARGV-elements
-  const int nbArgs = argc - optind;
-
-  // Check that VID has been specified
-  if(nbArgs < 1) {
-    cta::exception::Exception ex;
-    ex.getMessage() << "VID must be specified";
-    throw ex;
-  }
-
-  // Parse the VID command-line argument
-  volId = Acs::str2Volid(argv[optind]);
-}
-
-//------------------------------------------------------------------------------
-// processOption
-//------------------------------------------------------------------------------
-void cta::mediachanger::acs::AcsQueryVolumeCmdLine::processOption(const int opt) {
-  switch(opt) {
-  case 'd':
-    debug = true;
-    break;
-  case 'h':
-    help = true;
-    break;
-  case 'q':
-    queryInterval = parseQueryInterval(optarg);
-    break;
-  case 't':
-    timeout = parseTimeout(optarg);
-    break;
-  case ':':
-    return handleMissingParameter(optopt);
-  case '?':
-    return handleUnknownOption(optopt);
-  default:
-    {
-      cta::exception::Exception ex;
-      ex.getMessage() <<
-        "getopt_long returned the following unknown value: 0x" <<
-        std::hex << (int)opt;
-      throw ex;
-    }
-  } // switch(opt)
-}
-
-//------------------------------------------------------------------------------
-// getUsage
-//------------------------------------------------------------------------------
-std::string cta::mediachanger::acs::AcsQueryVolumeCmdLine::getUsage() {
-  std::ostringstream usage;
-  usage <<
-  "Usage:\n"
-  "  cta-acs-queryvolume [options] VID\n"
-  "\n"
-  "Where:\n"
-  "\n"
-  "  VID    The VID of the volume to be queried.\n"
-  "\n"
-  "Options:\n"
-  "\n"
-  "  -d|--debug            Turn on the printing of debug information.\n"
-  "  -h|--help             Print this help message and exit.\n"
-  "  -q|--query SECONDS    Time to wait between queries to ACS for responses.\n"
-  "                        SECONDS must be an integer value greater than 0.\n"
-  "                        The default value of SECONDS is "
-    << ACS_QUERY_INTERVAL << ".\n"
-  "  -t|--timeout SECONDS  Time to wait for the query to conclude. SECONDS\n"
-  "                        must be an integer value greater than 0.  The\n"
-  "                        default value of SECONDS in "
-    << ACS_CMD_TIMEOUT << ".\n"
-  "\n"
-  "Comments to: CTA team\n";
-  return usage.str();
-}
diff --git a/mediachanger/acs/AcsQueryVolumeCmdLine.hpp b/mediachanger/acs/AcsQueryVolumeCmdLine.hpp
deleted file mode 100644
index d99feb237f067e14bf966f75d943119cb6faa6e2..0000000000000000000000000000000000000000
--- a/mediachanger/acs/AcsQueryVolumeCmdLine.hpp
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * 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/>.
- */
-
-#pragma once
-
-#include "AcsCmdLine.hpp"
-
-extern "C" {
-#include "acssys.h"
-#include "acsapi.h"
-}
-
-#include <string>
-
-namespace cta {
-namespace mediachanger {
-namespace acs {
-
-/**
- * Data type used to store the results of parsing the command-line.
- */
-struct AcsQueryVolumeCmdLine: public AcsCmdLine {
-  /**
-   * True if the debug option has been set.
-   */
-  BOOLEAN debug;
-
-  /**
-   * True if the help option has been set.
-   */
-  BOOLEAN help;
-
-  /**
-   * Time in seconds to wait between queries to ACS for responses.
-   */
-  int queryInterval;
-
-  /**
-   * Time in seconds to wait for the dismount to conclude.
-   */
-  int timeout;
-
-  /**
-   * The volume identifier of the tape to be mounted.
-   */
-  VOLID volId;
-
-  /**
-   * Constructor.
-   *
-   * Initialises all BOOLEAN member-variables to FALSE, all integer
-   * member-variables to 0 and the volume identifier to an empty string.
-   */
-  AcsQueryVolumeCmdLine();
-
-  /**
-   * Constructor.
-   *
-   * Parses the specified command-line arguments.
-   *
-   * @param argc Argument count from the executable's entry function: main().
-   * @param argv Argument vector from the executable's entry function: main().
-   */
-  AcsQueryVolumeCmdLine(const int argc, char *const *const argv);
-
-  /**
-   * Gets the usage message that describes the comamnd line.
-   *
-   * @return The usage message.
-   */
-  static std::string getUsage();
-
-private:
-
-  /**
-   * Processes the specified option that was returned by getopt_long().
-   *
-   * @param opt The option that was returned by getopt_long().
-   */
-  void processOption(const int opt);
-
-}; // class AcsQueryVolumeCmdLine
-
-} // namespace acs
-} // namespace mediachanger
-} // namespace cta
diff --git a/mediachanger/acs/AcsQueryVolumeCmdMain.cpp b/mediachanger/acs/AcsQueryVolumeCmdMain.cpp
deleted file mode 100644
index a9472eaf9479f311dacbe2ae1067553304cb31ef..0000000000000000000000000000000000000000
--- a/mediachanger/acs/AcsQueryVolumeCmdMain.cpp
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * 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 "AcsImpl.hpp"
-#include "AcsQueryVolumeCmd.hpp"
-#include "AcsQueryVolumeCmdLine.hpp"
-
-#include <iostream>
-
-/**
- * An exception throwing version of main().
- *
- * @param argc The number of command-line arguments including the program name.
- * @param argv The command-line arguments.
- * @param The exit value of the program.
- */ 
-static int exceptionThrowingMain(const int argc, char *const *const argv);
-  
-//------------------------------------------------------------------------------
-// main
-//------------------------------------------------------------------------------
-int main(const int argc, char *const *const argv) {
-  using namespace cta;
-  std::string errorMessage;
-
-  try {
-    return exceptionThrowingMain(argc, argv);
-  } catch(cta::exception::Exception &ex) {
-    errorMessage = ex.getMessage().str();
-  } catch(std::exception &se) {
-    errorMessage = se.what();
-  } catch(...) {
-    errorMessage = "An unknown exception was thrown";
-  }
-
-  // Reaching this point means the command has failed, ane exception was throw
-  // and errorMessage has been set accordingly
-
-  std::cerr << "Aborting: " << errorMessage << std::endl;
-  return 1;
-}
-
-//------------------------------------------------------------------------------
-// exceptionThrowingMain
-//------------------------------------------------------------------------------
-static int exceptionThrowingMain(const int argc, char *const *const argv) {
-  using namespace cta;
-
-  mediachanger::acs::AcsImpl acs;
-  mediachanger::acs::AcsQueryVolumeCmd cmd(std::cin, std::cout, std::cerr, acs);
-
-  return cmd.exceptionThrowingMain(argc, argv);
-}
diff --git a/mediachanger/acs/CMakeLists.txt b/mediachanger/acs/CMakeLists.txt
deleted file mode 100644
index cd3b19b64e594b96d9422aa7a3baeab78ebcba78..0000000000000000000000000000000000000000
--- a/mediachanger/acs/CMakeLists.txt
+++ /dev/null
@@ -1,155 +0,0 @@
-# This file is part of the Castor project.
-# See http://castor.web.cern.ch/castor
-#
-# Copyright (C) 2003  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 2
-# 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, write to the Free Software
-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-#
-#
-# @author Castor Dev team, castor-dev@cern.ch
-#
-
-################################################################################
-# Rules to build and install acsd
-################################################################################
-
-find_package(stk REQUIRED)
-
-add_subdirectory(daemon)
-
-add_library(cta-acs 
-  Acs.cpp
-  AcsImpl.cpp
-  AcsDebugBuf.cpp
-  AcsLibraryInteraction.cpp)
-
-target_link_libraries(cta-acs
-  ctamediachanger 
-  ctacommon
-  ctareactor 
-  zmq
-  ${STK_LIBRARIES})
-
-set_target_properties (cta-acs PROPERTIES
- COMPILE_FLAGS -I/usr/include/CDK
- COMPILE_DEFINITIONS LINUX)
-
-################################################################################
-# Rules to build and install castor-tape-acs-dismount
-################################################################################
-message(STATUS "Adding cta-acs-dismount target")
-set (ACS_DISMOUNT_SRC_FILES
-  ../../common/exception/Backtrace.cpp
-  ../../common/exception/Exception.cpp
-  ../../common/exception/Mismatch.cpp
-  ../../common/exception/RequestFailed.cpp
-  Acs.cpp
-  AcsCmd.cpp
-  AcsCmdLine.cpp
-  AcsImpl.cpp
-  AcsDismountCmd.cpp
-  AcsDismountCmdLine.cpp
-  AcsDismountCmdMain.cpp
-  CmdLineTool.cpp
-  AcsDebugBuf.cpp)
-add_executable (cta-acs-dismount ${ACS_DISMOUNT_SRC_FILES})
-set_target_properties (cta-acs-dismount PROPERTIES
-  COMPILE_FLAGS -I/usr/include/CDK
-  COMPILE_DEFINITIONS LINUX)
-target_link_libraries (cta-acs-dismount
-  ${STK_LIBRARIES})
-install (TARGETS cta-acs-dismount DESTINATION /usr/bin)
-install (FILES cta-acs-dismount.1cta DESTINATION /usr/share/man/man1)
-
-################################################################################
-# Rules to build and install cta-acs-mount
-################################################################################
-set (ACS_MOUNT_SRC_FILES
-  ../../common/exception/Backtrace.cpp
-  ../../common/exception/Exception.cpp
-  ../../common/exception/Mismatch.cpp
-  ../../common/exception/RequestFailed.cpp
-  Acs.cpp
-  AcsCmd.cpp
-  AcsCmdLine.cpp
-  AcsImpl.cpp
-  AcsMountCmd.cpp
-  AcsMountCmdLine.cpp
-  AcsMountCmdMain.cpp
-  CmdLineTool.cpp
-  AcsDebugBuf.cpp)
-add_executable (cta-acs-mount ${ACS_MOUNT_SRC_FILES})
-set_target_properties (cta-acs-mount PROPERTIES
-  COMPILE_FLAGS -I/usr/include/CDK
-  COMPILE_DEFINITIONS LINUX)
-target_link_libraries (cta-acs-mount
-  ${STK_LIBRARIES})
-install (TARGETS cta-acs-mount DESTINATION /usr/bin)
-install (FILES cta-acs-mount.1cta DESTINATION /usr/share/man/man1)
-
-################################################################################
-# Rules to build and install cta-acs-queryvolume
-################################################################################
-message(STATUS "Adding cta-acs-queryvolume target")
-set (ACS_QUERYVOLUME_SRC_FILES
-  ../../common/exception/Backtrace.cpp
-  ../../common/exception/Exception.cpp
-  ../../common/exception/Mismatch.cpp
-  ../../common/exception/RequestFailed.cpp
-  Acs.cpp
-  AcsCmd.cpp
-  AcsCmdLine.cpp
-  AcsImpl.cpp
-  AcsQueryVolumeCmd.cpp
-  AcsQueryVolumeCmdLine.cpp
-  AcsQueryVolumeCmdMain.cpp
-  CmdLineTool.cpp
-  AcsDebugBuf.cpp)
-
-add_executable (cta-acs-queryvolume ${ACS_QUERYVOLUME_SRC_FILES})
-target_link_libraries (cta-acs-queryvolume
-  ${STK_LIBRARIES})
-set_target_properties (cta-acs-queryvolume PROPERTIES
-  COMPILE_FLAGS -I/usr/include/CDK
-  COMPILE_DEFINITIONS LINUX)
-install (TARGETS cta-acs-queryvolume
-  DESTINATION /usr/bin)
-install (FILES cta-acs-queryvolume.1cta DESTINATION /usr/share/man/man1)
-
-################################################################################
-# Rules to build and install cta-acs-querydrive
-################################################################################
-message(STATUS "Adding cta-acs-querydrive target")
-set (ACS_QUERYDRIVE_SRC_FILES
-  ../../common/exception/Backtrace.cpp
-  ../../common/exception/Exception.cpp
-  ../../common/exception/Mismatch.cpp
-  ../../common/exception/RequestFailed.cpp
-  Acs.cpp
-  AcsCmd.cpp
-  AcsCmdLine.cpp
-  AcsImpl.cpp
-  AcsQueryDriveCmd.cpp
-  AcsQueryDriveCmdLine.cpp
-  AcsQueryDriveCmdMain.cpp
-  CmdLineTool.cpp
-  AcsDebugBuf.cpp)
-
-add_executable (cta-acs-querydrive ${ACS_QUERYDRIVE_SRC_FILES})
-target_link_libraries (cta-acs-querydrive
-  ${STK_LIBRARIES})
-set_target_properties (cta-acs-querydrive PROPERTIES
-  COMPILE_FLAGS -I/usr/include/CDK
-  COMPILE_DEFINITIONS LINUX)
-install (TARGETS cta-acs-querydrive
-  DESTINATION /usr/bin)
-install (FILES cta-acs-querydrive.1cta DESTINATION /usr/share/man/man1)
diff --git a/mediachanger/acs/CmdLineTool.hpp b/mediachanger/acs/CmdLineTool.hpp
deleted file mode 100644
index cd622725a9f3ea79b3ecf8a32c3c06a280e37380..0000000000000000000000000000000000000000
--- a/mediachanger/acs/CmdLineTool.hpp
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * 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/>.
- */
-
-#pragma once
-
-#include "mediachanger/acs/AcsDebugBuf.hpp"
-
-#include <istream>
-#include <ostream>
-#include <string>
-
-namespace cta {
-namespace mediachanger {
-namespace acs {
-
-/**
- * Abstract class implementing common code and data structures for a
- * command-line tool.
- */
-class CmdLineTool {
-public:
-  /**
-   * Constructor.
-   *
-   * @param inStream Standard input stream.
-   * @param outStream Standard output stream.
-   * @param errStream Standard error stream.
-   */
-  CmdLineTool(std::istream &inStream, std::ostream &outStream, std::ostream &errStream)
-   ;
-
-  /**
-   * Pure-virtual destructor to guarantee this class is abstract.
-   */
-  virtual ~CmdLineTool() = 0;
-
-protected:
-
-  /**
-   * Standard input stream.
-   */
-  std::istream &m_in;
-
-  /**
-   * Standard output stream.
-   */
-  std::ostream &m_out;
-
-  /**
-   * Standard error stream.
-   */
-  std::ostream &m_err;
-
-  /**
-   * Debug stream buffer that inserts a standard debug preamble before each
-   * message-line written to it.
-   */
-  cta::mediachanger::acs::DebugBuf m_debugBuf;
-
-  /**
-   * Stream used to write debug messages.
-   *
-   * This stream will insert a standard debug preamble before each message-line
-   * written to it.
-   */
-  std::ostream m_dbg;
-
-  /**
-   * Returns the string representation of the specfied boolean value.
-   *
-   * @param value The boolean value.
-   */
-  std::string bool2Str(const bool value) const;
-
-}; // class CmdLineTool
-
-} // namespace acs
-} // namespace mediachanger
-} // namespace cta
diff --git a/mediachanger/acs/Constants.hpp b/mediachanger/acs/Constants.hpp
deleted file mode 100644
index b6c9cfb970840ca2d955a7afc8d9c677858cdfa2..0000000000000000000000000000000000000000
--- a/mediachanger/acs/Constants.hpp
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * 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/>.
- */
-
-#pragma once
-
-namespace cta     {
-//namespace acs        {
-
-/**
- * The default TCP/IP port on which the CASTOR ACS daemon listens for incoming Zmq
- * connections from the tape server.
- */
-const unsigned short ACS_PORT = 54521; 
-      
-/**
- * Default time to wait in seconds between queries to ACS Library for responses.
- */
-const int ACS_QUERY_INTERVAL = 10;
-
-/**
- * Default time to wait in seconds for the tape-library command to conclude.
- */
-const int ACS_CMD_TIMEOUT = 610;
-
-/**
- * The maximum ACS sequence number value to be used.
- */
-const unsigned short ACS_MAX_SEQ = 65535;
-
-/**
- * Default timeout for the response command to the ACS library.
- */
-const int ACS_RESPONSE_TIMEOUT = 5;
-
-/**
- * Enumeration of the states of an ACS request.
- */
-enum RequestState {
-  ACS_REQUEST_TO_EXECUTE,
-  ACS_REQUEST_IS_RUNNING,
-  ACS_REQUEST_COMPLETED,
-  ACS_REQUEST_FAILED,
-  ACS_REQUEST_TO_DELETE};
-
-//} // namespace acs
-} // namespace cta
-
diff --git a/mediachanger/acs/acsd.init b/mediachanger/acs/acsd.init
deleted file mode 100755
index c4f78f7857a35ccd47100c5efc345ceecc91ea91..0000000000000000000000000000000000000000
--- a/mediachanger/acs/acsd.init
+++ /dev/null
@@ -1,111 +0,0 @@
-#! /bin/sh
-#
-#/******************************************************************************
-#                      acsd.init
-#
-# This file is part of the Castor project.
-# See http://castor.web.cern.ch/castor
-#
-# Copyright (C) 2003  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 2
-# 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, write to the Free Software
-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-#
-#
-# chkconfig: 345 74 31
-# description: Tape server daemon initialisation script
-#
-# @author castor dev team
-#*****************************************************************************/
-
-# Source function library.
-. /etc/rc.d/init.d/functions
-
-# Variables
-prog="acsd"
-export DAEMON_COREFILE_LIMIT="unlimited"
-RETVAL=0
-
-# Source sysconfig files
-if [ -f /etc/sysconfig/castor ]; then
-        . /etc/sysconfig/castor
-fi
-if [ -f /etc/sysconfig/$prog ]; then
-        . /etc/sysconfig/$prog
-fi
-
-start() {
-        # Run daemon
-        echo -n $"Starting $prog: "
-
-        cd /var/log/castor
-        daemon /usr/bin/$prog $ACSD_OPTIONS
-
-        # Write the pid to a file.
-        RETVAL=$?
-        if [ $RETVAL -eq 0 ]; then
-                pid=`ps -eo pid,ppid,comm | egrep " 1 $prog\$" | awk '{print $1}'`
-                rm -f /var/run/$prog.pid
-                if [ -n "$pid" ]; then
-                        echo $pid > /var/run/$prog.pid
-                        RETVAL=0
-                else
-                        RETVAL=1
-                fi
-        fi
-
-        [ $RETVAL -eq 0 ] && success $"$base startup" || failure $"$base startup"
-        echo
-        [ $RETVAL -eq 0 ] && touch /var/lock/subsys/$prog
-        return $RETVAL
-}
-
-stop() {
-        echo -n $"Stopping $prog: "
-        killproc $prog
-
-        RETVAL=$?
-        echo
-        [ -f /var/lock/subsys/$prog ] && rm -f /var/lock/subsys/$prog
-        return $RETVAL
-}
-
-
-restart() {
-        stop
-        start
-}
-
-# See how we were called
-case "$1" in
-
-        start)
-                start
-                ;;
-        stop)
-                stop
-                ;;
-        status)
-                status $prog
-                RETVAL=$?
-                ;;
-        restart)
-                restart
-                ;;
-        condrestart)
-                [ -f /var/lock/subsys/$prog ] && restart || :
-                ;;
-        *)
-                echo $"Usage: $0 {start|stop|status|restart|condrestart}"
-                exit 1
-esac
-
-exit $RETVAL
diff --git a/mediachanger/acs/acsd.man b/mediachanger/acs/acsd.man
deleted file mode 100644
index 675fa7e74653ebabb594a70a2ea81f26bd5ebba8..0000000000000000000000000000000000000000
--- a/mediachanger/acs/acsd.man
+++ /dev/null
@@ -1,66 +0,0 @@
-.\" Copyright (C) 2003  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 2
-.\" 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, write to the Free Software
-.\" Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-.TH ACSD "8castor" "$Date: 2014/03/24 14:44:00 $" CASTOR "CASTOR"
-.SH NAME
-acsd \- Automated Cartdridge System daemon
-.SH SYNOPSIS
-.BI "acsd [OPTIONS]"
-
-.SH DESCRIPTION
-\fBacsd\fP is the daemon responsible for controlling ACS mount and ACS dismount 
-requests.
-.P
-When \fBacsd\fP is executed it immediately forks with the parent
-terminating and the child running in the background.  If required the
-\fB\-f, \-\-foreground\fP option can be used to stop \fBacsd\fP from
-forking and keep the parent process in the foreground.
-
-.SH OPTIONS
-.TP
-\fB\-f, \-\-foreground
-Remain in the foreground.
-.TP
-\fB\-h, \-\-help
-Prints the usage message.
-.TP
-\fB\-c, \-\-config <config-file>
-Set the location of the CASTOR configuration file (castor.conf).  The default location is /etc/castor/castor.conf.
-
-.SH CASTOR CONFIGURATION PARAMETERS
-The acsd daemon reads and uses the following CASTOR configuration
-parameters which are specified within the CASTOR configuration file (the
-default location is /etc/castor/castor.conf).
-
-.TP
-\fBAcsDaemon CmdTimeout
-The maximum time to wait in seconds for a tape-library command to conclude.
-
-.TP
-\fBAcsDaemon Port
-The TCP/IP port on which the CASTOR ACS daemon listens for incoming Zmq
-connections from the tape server.
-
-.TP
-\fBAcsDaemon QueryInterval
-Time to wait in seconds between queries to the tape Library.
-
-.SH FILES
-.TP
-.B /etc/castor/castor.conf
-Default location of the CASTOR configuration file.
-.TP
-.B /var/log/castor/acsd.log
-Default location of the acsd log file.
-
-.SH AUTHOR
-\fBCASTOR\fP Team <castor.support@cern.ch>
diff --git a/mediachanger/acs/cta-acs-dismount.1cta b/mediachanger/acs/cta-acs-dismount.1cta
deleted file mode 100644
index 39cc0c6fd242e3beded80f8f676b37110fabbbaf..0000000000000000000000000000000000000000
--- a/mediachanger/acs/cta-acs-dismount.1cta
+++ /dev/null
@@ -1,68 +0,0 @@
-.\" 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/>.
-
-.TH CASTOR-TAPE-ACS-DISMOUNT "1cta" "$Date: 2013/10/09 14:00:00 $" CASTOR "CASTOR"
-.SH NAME
-cta-acs-dismount \- dismount a volume
-.SH SYNOPSIS
-.BI "cta-acs-dismount [options] VID DRIVE_SLOT"
-
-.SH DESCRIPTION
-\fBWarning\fP, \fBcta-acs-dismount\fP is a developer tool and is
-therefore subject to change in and even removal from a future release of CASTOR.
-End users should not rely on this tool to operate their CASTOR installation.
-
-\fBcta-acs-dismount\fP dismounts the volume with the specfied \fBVID\fP
-from the drive located in the specified \fBDRIVE_SLOT\fP of the tape library.
-The format of \fBDRIVE_SLOT\fP is as follows:
-
-.B ACS:LSM:panel:transport
-
-Please note that this command-line tool communicates directly with the CSI of 
-the ACS system. This command-line tool does not communicate with any CASTOR
-daemons.
-
-.SH OPTIONS
-.TP
-\fB\-d, \-\-debug
-Turns on the printing of debug information.
-.TP
-\fB\-f, \-\-force
-Force the dismount.
-.TP
-\fB\-h, \-\-help
-Prints the usage message.
-.TP
-\fB\-q, \-\-query SECONDS
-Time wait between queries to ACLS for responses.
-\fBSECONDS\fP must be an integer value greater than 0.
-The default value of \fBSECONDS\fP is 10.
-.TP
-\fB\-t, \-\-timeout SECONDS
-Time to wait for the dismount operation to conclude.
-\fBSECONDS\fP must be an integer value greater than 0.
-The default value of \fBSECONDS\fP is 610.
-
-.SH "RETURN CODES"
-.TP
-\fB 0
-Ok.
-.TP
-\fB 1
-Command failed.
-
-.SH AUTHOR
-\fBCTA\fP Team
diff --git a/mediachanger/acs/cta-acs-mount.1cta b/mediachanger/acs/cta-acs-mount.1cta
deleted file mode 100644
index 1adc058396985a8db481bc7bfa0ad7ed3bbe394f..0000000000000000000000000000000000000000
--- a/mediachanger/acs/cta-acs-mount.1cta
+++ /dev/null
@@ -1,69 +0,0 @@
-
-.\" 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/>.
-
-.TH CTA-TAPE-ACS-MOUNT "1cta" "$Date: 2013/10/09 14:00:00 $" CTA "CTA"
-.SH NAME
-cta-acs-mount \- mount a volume
-.SH SYNOPSIS
-.BI "cta-acs-mount [options] VID DRIVE_SLOT"
-
-.SH DESCRIPTION
-\fBWarning\fP, \fBcta-acs-mount\fP is a developer tool and is therefore
-subject to change in and even removal from a future release of CTA.
-End users should not rely on this tool to operate their CTA installation.
-
-\fBcta-acs-mount\fP mounts the volume with the specfied \fBVID\fP into
-the drive located in the specified \fBDRIVE_SLOT\fP of the tape library.
-The format of \fBDRIVE_SLOT\fP is as follows:
-
-.B ACS:LSM:panel:transport
-
-Please note that this command-line tool communicates directly with the CSI of
-the ACS system. This command-line tool does not communicate with any CTA
-daemons.
-
-.SH OPTIONS
-.TP
-\fB\-d, \-\-debug
-Turns on the printing of debug information.
-.TP
-\fB\-h, \-\-help
-Prints the usage message.
-.TP
-\fB\-q, \-\-query SECONDS
-Time wait between queries to ACLS for responses.
-\fBSECONDS\fP must be an integer value greater than 0.
-The default value of \fBSECONDS\fP is 10.
-.TP
-\fB\-r, \-\-readonly
-Request the volume is mounted for read-only access.
-.TP
-\fB\-t, \-\-timeout SECONDS
-Time to wait for the mount operation to conclude.  
-\fBSECONDS\fP must be an integer value greater than 0.
-The default value of \fBSECONDS\fP is 610.
-
-.SH "RETURN CODES"
-.TP
-\fB 0
-Ok.
-.TP
-\fB 1
-Command failed.
-
-.SH AUTHOR
-\fBCTA\fP Team
diff --git a/mediachanger/acs/cta-acs-querydrive.1cta b/mediachanger/acs/cta-acs-querydrive.1cta
deleted file mode 100644
index f6359650d22d1e425d3a24cca4386db616ccb06b..0000000000000000000000000000000000000000
--- a/mediachanger/acs/cta-acs-querydrive.1cta
+++ /dev/null
@@ -1,65 +0,0 @@
-.\" 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/>.
-
-.TH CTA-TAPE-ACS-QUERYDRIVE "1cta" "$Date: 2013/10/09 14:00:00 $" CTA "CTA"
-.SH NAME
-cta-acs-querydrive \- queries a drive
-.SH SYNOPSIS
-.BI "cta-acs-querydrive [options] DRIVE_SLOT"
-
-.SH DESCRIPTION
-\fBWarning\fP, \fBcta-acs-querydrive\fP is a developer tool and is
-therefore subject to change and even removal from a future release of CTA.
-End users should not rely on this tool to operate their CTA installation.
-
-\fBcta-acs-querydrive\fP quieries ACS for information about the drive
-located in the specified \fBDRIVE_SLOT\fP.  The format of \fBDRIVE_SLOT\fP
-is as follows:
-
-.B ACS:LSM:panel:transport
-
-Please note that this command-line tool communicates directly with the CSI of 
-the ACS system. This command-line tool does not communicate with any CTA
-daemons.
-
-.SH OPTIONS
-.TP
-\fB\-d, \-\-debug
-Turns on the printing of debug information.
-.TP
-\fB\-h, \-\-help
-Prints the usage message.
-.TP
-\fB\-q, \-\-query SECONDS
-Time wait between queries to ACLS for responses.
-\fBSECONDS\fP must be an integer value greater than 0.
-The default values of \fBSECONDS\fP is 610.
-.TP
-\fB\-t, \-\-timeout SECONDS
-Time to wait for the mount operation to conclude.  
-\fBSECONDS\fP must be an integer value greater than 0.
-The default value of \fBSECONDS\fP is 10.
-
-.SH "RETURN CODES"
-.TP
-\fB 0
-Ok.
-.TP
-\fB 1
-Command failed.
-
-.SH AUTHOR
-\fBCTA\fP Team
diff --git a/mediachanger/acs/cta-acs-queryvolume.1cta b/mediachanger/acs/cta-acs-queryvolume.1cta
deleted file mode 100644
index e4c2a0c35f94a7b6dd1e8d0fd2ce3cab2f1fc304..0000000000000000000000000000000000000000
--- a/mediachanger/acs/cta-acs-queryvolume.1cta
+++ /dev/null
@@ -1,62 +0,0 @@
-.\" 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/>.
-
-.TH CTA-TAPE-ACS-QUERYVOLUME "1cta" "$Date: 2013/10/09 14:00:00 $" CTA "CTA"
-.SH NAME
-cta-acs-queryvolume \- queries a volume
-.SH SYNOPSIS
-.BI "cta-acs-queryvolume [options] VID"
-
-.SH DESCRIPTION
-\fBWarning\fP, \fBcastor-tape-acs-queryvolume\fP is a developer tool and is
-therefore subject to change in and even removal from a future release of CTA.
-End users should not rely on this tool to operate their CTA installation.
-
-\fBcastor-tape-acs-queryvolume\fP quieries ACS for information about the volume
-with the specfied \fBVID\fP.
-
-Please note that this command-line tool communicates directly with the CSI of 
-the ACS system. This command-line tool does not communicate with any CTA
-daemons.
-
-.SH OPTIONS
-.TP
-\fB\-d, \-\-debug
-Turns on the printing of debug information.
-.TP
-\fB\-h, \-\-help
-Prints the usage message.
-.TP
-\fB\-q, \-\-query SECONDS
-Time wait between queries to ACLS for responses.
-\fBSECONDS\fP must be an integer value greater than 0.
-The default values of \fBSECONDS\fP is 610.
-.TP
-\fB\-t, \-\-timeout SECONDS
-Time to wait for the mount operation to conclude.  
-\fBSECONDS\fP must be an integer value greater than 0.
-The default value of \fBSECONDS\fP is 10.
-
-.SH "RETURN CODES"
-.TP
-\fB 0
-Ok.
-.TP
-\fB 1
-Command failed.
-
-.SH AUTHOR
-\fBCTA\fP Team
diff --git a/mediachanger/acs/cta-acsd.1cta b/mediachanger/acs/cta-acsd.1cta
deleted file mode 100644
index b7ab08406df8939d7eb3f9bad69c785c444a9d04..0000000000000000000000000000000000000000
--- a/mediachanger/acs/cta-acsd.1cta
+++ /dev/null
@@ -1,117 +0,0 @@
-.\" 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/>.
-.TH CTA-ACSD "cta" "$Date: 2018/01/10 14:44:00 $" CTA "CTA"
-.SH NAME
-cta-taped \- Tape server daemon
-.SH SYNOPSIS
-.BI "cta-taped [OPTIONS]"
-
-.SH DESCRIPTION
-\fBcta-taped\fP is the daemon responsible for controlling one or more tape
-drives.
-.P
-When \fBcta-taped\fP is executed it immediately forks with the parent
-terminating and the child running in the background.  If required the
-\fB\-f, \-\-foreground\fP option can be used to stop \fBcta-taped\fP from
-forking and keep the parent process in the foreground.
-
-.SH TAPE LIBRARY SUPPORT
-
-CTA supports two types of tape libraries, SCSI compatible ones and Oracle
-Automatic Cartridge System (ACS) ones.  The cta-taped daemon requires a tape
-library daemon to be installed and run on the same tape server as itself.
-There are two types of CTA tape library daemons, one for SCSI compatible tape
-libraries and one for ACS tape libraries.
-
-A SCSI compatible tape library requires the following daemon:
-
-\fBrmcd\fP
-
-The installation RPM for the \fBrmcd\fP daemon and its manual page is:
-
-\fBcta-rmc-server-0.0-XX.slc6.x86_64\fP
-
-The \fBcta-rmcd\fP daemon can be started, stopped and its status queried using
-the usual service commands:
-
-\fBservice cta-rmcd start\fP
-.br
-\fBservice cta-acsd status\fP
-.br
-\fBservice cta-acsd stop\fP
-
-Even though there is a separate daemon for each of the supported tape library
-types, there is a single generic set of command-line tools for mounting and
-un-mounting tapes:
-
-\fBcta-tape-mediachanger-mount\fP
-.br
-\fBcta-tape-mediachanger-dismount\fP
-
-The installation RPM for these command-line tools and their manual pages is:
-
-\fBcta-tape-developer-tools-2.1.15-XX.slc6.x86_64\fP
-
-.SH OPTIONS
-.TP
-\fB\-f, \-\-foreground
-Remain in the foreground.
-.TP
-\fB\-h, \-\-help
-Prints the usage message.
-.TP
-\fB\-c, \-\-config <config-file>
-Set the location of the CTA configuration file (cta.conf).  The default location is /etc/cta/cta.conf.
-
-.SH CTA CONFIGURATION PARAMETERS
-The cta-taped daemon reads and uses the following CTA configuration
-parameters which are specified within the CTA configuration file (the
-default location is /etc/cta/cta.conf).
-
-.TP
-\fBRMC HOST
-The host on which the rmcd daemon is running.
-
-.TP
-\fBRMC MAXRQSTATTEMPTS
-Maximum number of attempts a retriable RMC request should be issued.
-
-.TP
-\fBTapeServer BlkMoveTimeout
-The maximum time in seconds the data-transfer session of tapeserverd can
-cease to move data blocks
-
-.TP
-\fBTapeServer BufSize
-Size of a memory buffer in the data-transfer cache in bytes (default is 5
-Mebibytes).
-## acsd ########################################################################
-# The TCP/IP port on which the CASTOR ACS daemon listens for incoming Zmq
-#AcsDaemon Port 54521
-#AcsDaemon QueryInterval 10
-#AcsDaemon CmdTimeout 610
-# The TCP/IP port on which the CTA ACS daemon listens for incoming Zmq
-# connections from the tape server.
-#AcsDaemon Port 54521
-
-# Time to wait in seconds between queries to the tape Library.
-#AcsDaemon QueryInterval 10
-
-# The maximum time to wait in seconds for a tape-library command to
-# conclude.
-#AcsDaemon CmdTimeout 610
-
-# End-of-File
diff --git a/mediachanger/acs/daemon/AcsDaemon.cpp b/mediachanger/acs/daemon/AcsDaemon.cpp
deleted file mode 100644
index 5acb5540d75c8ff301190adce65591337bd659c8..0000000000000000000000000000000000000000
--- a/mediachanger/acs/daemon/AcsDaemon.cpp
+++ /dev/null
@@ -1,384 +0,0 @@
-/*
- * 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 "common/Constants.hpp"
-#include "AcsDaemon.hpp"
-#include "AcsdConfiguration.hpp"
-#include "mediachanger/acs/daemon/AcsMessageHandler.hpp"
-#include "AcsPendingRequests.hpp"
-#include "common/exception/Errnum.hpp"
-#include "common/exception/BadAlloc.hpp"
-#include "common/exception/Exception.hpp"
-#include "common/log/log.hpp"
-#include "common/log/SyslogLogger.hpp"
-#include "common/threading/Daemon.hpp"
-#include <memory>
-#include <signal.h>
-#include <unistd.h>
-
-#include <getopt.h>
-#include <iostream>
-
-namespace cta { namespace mediachanger { namespace acs { namespace daemon {
-
-//------------------------------------------------------------------------------
-// constructor
-//------------------------------------------------------------------------------
-AcsDaemon::AcsDaemon(
-  const int argc,
-  char **const argv,
-  cta::log::Logger& log,
-  std::ostream &outStream, 
-  std::ostream &errStream, 
-  cta::mediachanger::reactor::ZMQReactor &reactor,
-  const AcsdConfiguration &config):
-  cta::server::Daemon(log),
-  m_argc(argc),
-  m_argv(argv),
-  m_log(log),
-  m_out(outStream),
-  m_err(errStream),  
-  m_reactor(reactor),
-  m_programName("acsd"),
-  m_hostName(getHostName()),  
-  m_zmqContext(NULL),
-  m_config(config),
-  m_acsPendingRequests(config,log) {
-}
-
-//------------------------------------------------------------------------------
-// getHostName
-//------------------------------------------------------------------------------
-
-std::string cta::mediachanger::acs::daemon::AcsDaemon::getHostName() const  {
-  char nameBuf[81];
-  if(gethostname(nameBuf, sizeof(nameBuf))) {
-    cta::exception::Exception ex;
-    ex.getMessage() << "Failed to get host name: "<<ex.getMessage().str();
-    m_log(LOG_ERR, ex.getMessage().str());  
-    throw ex;
-  }
-
-  return nameBuf;
-}
-
-
-//------------------------------------------------------------------------------
-// destructor
-//------------------------------------------------------------------------------
-  AcsDaemon::~AcsDaemon() {  
-  m_reactor.clear();  
-  destroyZmqContext();
-  google::protobuf::ShutdownProtobufLibrary();
-}
-
-//------------------------------------------------------------------------------
-// destroyZmqContext
-//------------------------------------------------------------------------------
-
-  void AcsDaemon::destroyZmqContext() {
-  if(NULL != m_zmqContext) {
-    if(zmq_term(m_zmqContext)) {
-      cta::exception::Exception ex;
-      std::list<log::Param> params = {log::Param("message", ex.getMessage().str())};
-      m_log(LOG_ERR, "Failed to destroy ZMQ context", params);
-    } else {
-      m_zmqContext = NULL;
-      m_log(LOG_INFO, "Successfully destroyed ZMQ context");
-    }
-  }
-}
-
-//------------------------------------------------------------------------------
-// main
-//------------------------------------------------------------------------------
-int AcsDaemon::main() {
-    
-  try {
-    exceptionThrowingMain(m_argc, m_argv);
-  } catch (cta::exception::Exception &ex) {
-    // Write the error to standard error
-    std::cerr << std::endl << "Aborting: " << ex.getMessage().str() << std::endl
-      << std::endl;
-    // Log the error
-    std::list<log::Param> params = {
-    log::Param("Message", ex.getMessage().str())};
-    m_log(LOG_ERR, "Aborting", params);
-
-    return 1;
-  }
-
-  return 0;
-}
-//------------------------------------------------------------------------------
-// exceptionThrowingMain
-//------------------------------------------------------------------------------
-
-void AcsDaemon::exceptionThrowingMain(const int argc, char **const argv)  {
-  logStartOfDaemon(argc, argv);
-  m_cmdline = AcsdCmdLine::parse(argc,argv);
-
-  //Display the usage message to standard out and exit with success if the
-  //user requested help
-  if(m_cmdline.help) {
-    m_out << AcsdCmdLine::getUsage();
-    return;
-  }
-  setCommandLineHasBeenParsed(m_cmdline.foreground);
-  const std::string runAsStagerSuperuser = m_config.daemonUserName.value();
-  const std::string runAsStagerSupergroup = m_config.daemonGroupName.value();
-  daemonizeIfNotRunInForegroundAndSetUserAndGroup(runAsStagerSuperuser, runAsStagerSupergroup);
-  setDumpable();
-
-  blockSignals();
-  initZmqContext();
-  setUpReactor();  
-  mainEventLoop();
-
-}
-
-//------------------------------------------------------------------------------
-// logStartOfDaemon
-//------------------------------------------------------------------------------
-
-  void AcsDaemon::logStartOfDaemon(
-  const int argc, const char *const *const argv) {
-  const std::string concatenatedArgs = argvToString(argc, argv);
-  std::ostringstream msg;
-  msg << m_programName << " started";
-
-  std::list<log::Param> params = {
-    log::Param("argc", argc),
-    log::Param("argv", concatenatedArgs)};
-  m_log(LOG_INFO, msg.str(), params);
-}
-
-//------------------------------------------------------------------------------
-// argvToString
-//------------------------------------------------------------------------------
-
-  std::string AcsDaemon::argvToString(
-  const int argc, const char *const *const argv) {
-  std::string str;
-
-  for(int i=0; i < argc; i++) {
-    if(i != 0) {
-      str += " ";
-    }
-
-    str += argv[i];
-  }
-  return str;
-}
-
-//------------------------------------------------------------------------------
-// setDumpable
-//------------------------------------------------------------------------------
-void AcsDaemon::setDumpable() {
-  cta::utils::setDumpableProcessAttribute(true);
-  const bool dumpable = cta::utils::getDumpableProcessAttribute();
-  std::list<log::Param> params = {
-    log::Param("dumpable", dumpable ? "true" : "false")};
-  m_log(LOG_INFO, "Got dumpable attribute of process", params);
-  if(!dumpable) {
-    cta::exception::Exception ex;
-    ex.getMessage() << "Failed to set dumpable attribute of process to true";
-    throw ex;
-  }
-}
-
-//------------------------------------------------------------------------------
-// blockSignals
-//------------------------------------------------------------------------------
-void AcsDaemon::blockSignals() const {
-  sigset_t sigs;
-  sigemptyset(&sigs);
-  // The signals that should not asynchronously disturb the daemon
-  sigaddset(&sigs, SIGHUP);
-  sigaddset(&sigs, SIGINT);
-  sigaddset(&sigs, SIGQUIT);
-  sigaddset(&sigs, SIGPIPE);
-  sigaddset(&sigs, SIGTERM);
-  sigaddset(&sigs, SIGUSR1);
-  sigaddset(&sigs, SIGUSR2);
-  sigaddset(&sigs, SIGCHLD);
-  sigaddset(&sigs, SIGTSTP);
-  sigaddset(&sigs, SIGTTIN);
-  sigaddset(&sigs, SIGTTOU);
-  sigaddset(&sigs, SIGPOLL);
-  sigaddset(&sigs, SIGURG);
-  sigaddset(&sigs, SIGVTALRM);
-  cta::exception::Errnum::throwOnNonZero(
-    sigprocmask(SIG_BLOCK, &sigs, NULL),
-    "Failed to block signals: sigprocmask() failed");
-}
-
-//------------------------------------------------------------------------------
-// initZmqContext
-//------------------------------------------------------------------------------
-
-  void AcsDaemon::initZmqContext() {
-  const int sizeOfIOThreadPoolForZMQ = 1;
-  m_zmqContext = zmq_init(sizeOfIOThreadPoolForZMQ);
-  if(NULL == m_zmqContext) {
-    cta::exception::Exception ex;
-    ex.getMessage() << "Failed to instantiate ZMQ context: " << ex.getMessage().str();
-    throw ex;
-  }
-}
-
-//------------------------------------------------------------------------------
-// setUpReactor
-//------------------------------------------------------------------------------
-void AcsDaemon::setUpReactor() {
-  createAndRegisterAcsMessageHandler();
-}
-
-//------------------------------------------------------------------------------
-// createAndRegisterAcsMessageHandler
-//------------------------------------------------------------------------------
-void AcsDaemon::createAndRegisterAcsMessageHandler()  {
-  try {
-    std::unique_ptr<AcsMessageHandler> handler;
-    try {
-      handler.reset(new AcsMessageHandler(m_log, m_reactor, m_zmqContext, m_hostName,
-        m_config,  m_acsPendingRequests));   //create event handler for communicating with the acs daemon
-    } catch(std::bad_alloc &ba) {
-      cta::exception::BadAlloc ex;
-      ex.getMessage() <<
-        "Failed to create event handler for communicating with "
-        "the CTA ACS daemon: " << ba.what();
-      throw ex;
-    }
-    m_reactor.registerHandler(handler.get());
-    handler.release();
-  } catch(cta::exception::Exception &ne) {
-    cta::exception::Exception ex;
-    ex.getMessage() <<
-      "Failed to create and register AcsMessageHandler: " <<
-      ne.getMessage().str();
-    throw ex;
-  }
-}
-
-//------------------------------------------------------------------------------
-// mainEventLoop
-//------------------------------------------------------------------------------
-void AcsDaemon::mainEventLoop() {
-  while(handleEvents()) {
-  }
-}
-
-//------------------------------------------------------------------------------
-// handleEvents
-//------------------------------------------------------------------------------
-bool AcsDaemon::handleEvents() { 
-  try {
-    const int timeout = 100; // 100 milliseconds
-    m_reactor.handleEvents(timeout);
-  } catch(cta::exception::Exception &ex) {
-    // Log exception and continue
-    std::list<log::Param> params = {
-      log::Param("message", ex.getMessage().str()),
-      log::Param("backtrace", ex.backtrace())
-    };
-    m_log(LOG_ERR,
-      "Unexpected cta exception thrown when handling an I/O event", params);
-  } catch(std::exception &se) {
-    // Log exception and continue
-    std::list<log::Param> params = {log::Param("message", se.what())};
-    m_log(LOG_ERR, "Unexpected exception thrown when handling an I/O event",
-      params);
-  } catch(...) {
-    // Log exception and continue
-    m_log(LOG_ERR,
-      "Unexpected and unknown exception thrown when handling an I/O event");
-  }
-  
-  try {
-    handlePendingRequests();
-  } catch(cta::exception::Exception &ex) {
-    // Log exception and continue
-    std::list<log::Param> params = {
-      log::Param("message", ex.getMessage().str()),
-      log::Param("backtrace", ex.backtrace())
-    };
-    m_log(LOG_ERR,
-      "Unexpected cta exception thrown when handling pending requests", 
-      params);
-  } catch(std::exception &se) {
-    // Log exception and continue
-    std::list<log::Param> params = {log::Param("message", se.what())};
-    m_log(LOG_ERR,
-      "Unexpected exception thrown when handling pending requests", params);
-  } catch(...) {
-    // Log exception and continue
-    m_log(LOG_ERR,
-      "Unexpected and unknown exception thrown when handling pending requests");
-  }
-  
-  return handlePendingSignals();
-}
-
-//------------------------------------------------------------------------------
-// handlePendingRequests
-//------------------------------------------------------------------------------
-void AcsDaemon::handlePendingRequests() {
-  m_acsPendingRequests.tick(); 
-  m_acsPendingRequests.handleCompletedRequests();
-  m_acsPendingRequests.handleFailedRequests();
-  m_acsPendingRequests.handleToDeleteRequests();
-}
-
-//------------------------------------------------------------------------------
-// handlePendingSignals
-//------------------------------------------------------------------------------
-
-bool AcsDaemon::handlePendingSignals() {
-  bool continueMainEventLoop = true;
-  int sig = 0;
-  sigset_t allSignals;
-  siginfo_t sigInfo;
-  sigfillset(&allSignals);
-  struct timespec immediateTimeout = {0, 0};
-
-  // While there is a pending signal to be handled
-  while (0 < (sig = sigtimedwait(&allSignals, &sigInfo, &immediateTimeout))) {
-    switch(sig) {
-    case SIGINT: // Signal number 2
-      m_log(LOG_INFO, "Stopping gracefully because SIGINT was received");
-      continueMainEventLoop = false;
-      break;
-    case SIGTERM: // Signal number 15
-      m_log(LOG_INFO, "Stopping gracefully because SIGTERM was received");
-      continueMainEventLoop = false;
-      break;
-    default:
-      {
-        std::list<log::Param> params = {log::Param("signal", sig)};
-        m_log(LOG_INFO, "Ignoring signal", params);
-      }
-      break;
-    }
-  }
-       
-  return continueMainEventLoop;
-}
-
-
-}}}}
diff --git a/mediachanger/acs/daemon/AcsDaemon.hpp b/mediachanger/acs/daemon/AcsDaemon.hpp
deleted file mode 100644
index 44d5112ce240687deafefc1dbaf7b2588a08b85d..0000000000000000000000000000000000000000
--- a/mediachanger/acs/daemon/AcsDaemon.hpp
+++ /dev/null
@@ -1,228 +0,0 @@
-/*
- * 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/>.
- */
-
-#pragma once
-#include "common/processCap/ProcessCap.hpp"
-#include "common/threading/Daemon.hpp"
-#include "mediachanger/reactor/ZMQReactor.hpp"
-#include "mediachanger/acs/daemon/AcsdCmdLine.hpp"
-#include "AcsdConfiguration.hpp"
-#include "AcsPendingRequests.hpp"
-#include "common/Constants.hpp"
-#include "common/log/SyslogLogger.hpp"
-#include "AcsdCmdLine.hpp"
-#include <signal.h>
-
-#include <getopt.h>
-
-namespace cta {   
-namespace mediachanger {   
-namespace acs {  
-namespace daemon {
-
-/**
- * CTA ACS daemon responsible for mounting and dismounting tapes for ACS.
- */
-class AcsDaemon : public server::Daemon {
-
-public:
-  /**
-   * Constructor.
-   *
-   * @param argc The argc of main().
-   * @param argv The argv of main().
-   * @param stdOut Stream representing standard out.
-   * @param stdErr Stream representing standard error.
-   * @param reactor The reactor responsible for dispatching the I/O requests to
-   * the CTA ACS daemon.
-   * @param config The CTA configuration parameters used by the CTA ACS
-   * daemon.
-   */
-  AcsDaemon(
-    const int argc,
-    char **const argv,
-    log::Logger& log,
-    std::ostream &outStream,
-    std::ostream &errStream,
-    cta::mediachanger::reactor::ZMQReactor &reactor,
-    const AcsdConfiguration &config);
-
-  /**
-   * Destructor.
-   */
-  ~AcsDaemon();
-
-  /**
-   * The main entry function of the daemon.
-   *
-   * @return The return code of the process.
-   */
-  int main();
-  
-protected:
-
-  /**
-   * Returns the name of the host on which the daemon is running.
-   */
-  std::string getHostName() const;
-
-  /**
-   * Exception throwing main() function.
-   *
-   * @param argc The number of command-line arguments.
-   * @param argv The array of command-line arguments.
-   */
-  void exceptionThrowingMain(const int argc, char **const argv);
-
-  /**
-   * Logs the start of the daemon.
-   */
-  void logStartOfDaemon(const int argc, const char *const *const argv);
-
-  /**
-   * Creates a string that contains the specified command-line arguments
-   * separated by single spaces.
-   *
-   * @param argc The number of command-line arguments.
-   * @param argv The array of command-line arguments.
-   */
-  std::string argvToString(const int argc, const char *const *const argv)
-   ;
-
-  /**
-   * Idempotent method that destroys the ZMQ context.
-   */
-  void destroyZmqContext();
-
-  /**
-   * Sets the dumpable attribute of the current process to true.
-   */
-  void setDumpable();
-
-  /**
-   * Blocks the signals that should not asynchronously disturb the daemon.
-   */
-  void blockSignals() const;
-  
-  /**
-   * Initialises the ZMQ context.
-   */
-  void initZmqContext();
-  /**
-   * Sets up the reactor.
-   */
-  void setUpReactor();
- 
-  /**
-   * Creates the handler to handle messages for the acs Zmq requests.
-   */
-  void createAndRegisterAcsMessageHandler();
-  
-  /**
-   * The main event loop of the daemon.
-   */
-  void mainEventLoop();
-
-  /**
-   * Handles any pending events.
-   *
-   * @return True if the main event loop should continue, else false.
-   */
-  bool handleEvents();
-
-  /**
-   * Handles any pending signals.
-   *
-   * @return True if the main event loop should continue, else false.
-   */
-  bool handlePendingSignals();
-  
-  /**
-   * Handles any pending Acs requests.
-   *
-   */
-  void handlePendingRequests();
-
-  /**
-   * The argc of main().
-   */
-  const int m_argc;
-
-  /**
-   * The argv of main().
-   */
-  char **const m_argv;
-
-  log::Logger &m_log;
-
-  /**
-   * Standard output stream.
-   */
-  std::ostream &m_out;
-
-  /**
-   * Standard error stream.
-   */
-  std::ostream &m_err;
-
-  /**
-   * The reactor responsible for dispatching the file-descriptor event-handlers
-   * of the CTA ACS daemon.
-   */
-  cta::mediachanger::reactor::ZMQReactor &m_reactor;
-  /**
-   * The program name of the daemon.
-   */
-  const std::string m_programName;
-
-  /**
-   * The name of the host on which the daemon is running. 
-   */
-  const std::string m_hostName;
-
-  /**
-   * The ZMQ context.
-   */
-  void *m_zmqContext;
-  
-  /**
-   * The CTA configuration parameters used by the CTA ACS daemon.
-   */
-  const AcsdConfiguration m_config;
-  
-  /**
-   * The object to handle requests to the CTA ACS daemon.
-   */
-  AcsPendingRequests m_acsPendingRequests;
-
-private:
- 
-  /**
-   * The parsed command-line.
-   *
-   * The value of this member variable is set within the main() method of this
-   * class.
-   */
-  AcsdCmdLine m_cmdline;
-
-}; // class AcsDaemon
-
-} // namespace daemon
-} // namespace acs
-} // namespace mediachanger
-} // namespace cta
diff --git a/mediachanger/acs/daemon/AcsDaemonMain.cpp b/mediachanger/acs/daemon/AcsDaemonMain.cpp
deleted file mode 100644
index 5163f7cf7f99a00a7859f8b2da1df82d7effaf33..0000000000000000000000000000000000000000
--- a/mediachanger/acs/daemon/AcsDaemonMain.cpp
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * 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 "common/log/log.hpp"
-#include "common/log/SyslogLogger.hpp"
-#include "mediachanger/acs/Constants.hpp"
-#include "AcsDaemon.hpp"
-#include "AcsdCmdLine.hpp"
-#include "mediachanger/reactor/ZMQReactor.hpp"
-#include "AcsdConfiguration.hpp"
-#include "common/utils/utils.hpp"
-#include "common/exception/Exception.hpp"
-#include <iostream>
-
-
-//------------------------------------------------------------------------------
-// exceptionThrowingMain
-//
-// The main() function delegates the bulk of its implementation to this
-// exception throwing version.
-//
-// @param argc The number of command-line arguments.
-// @param argv The command-line arguments.
-//------------------------------------------------------------------------------
-static int exceptionThrowingMain(cta::log::Logger &log,const int argc,char **const argv);
-
-//------------------------------------------------------------------------------
-// main
-//------------------------------------------------------------------------------
-int main(const int argc, char **const argv) {
-  using namespace cta;
-
-    const std::string shortHostName = utils::getShortHostname();
-    cta::log::SyslogLogger logger(shortHostName, "cta-acsd", log::DEBUG);
-  try {
-    logger(LOG_INFO, "started ACSD in CTA");
-  } catch(cta::exception::Exception &ex) {
-    std::cerr <<
-      "Failed to instantiate object representing CTA logging system: " <<
-      ex.getMessage().str() << std::endl;
-    return 1;
-  } 
-  int programRc = 1; 
-  try {
-    programRc = exceptionThrowingMain(logger, argc, argv) ;
-  } catch(cta::exception::Exception &ex) {
-    std::list<log::Param> params = {
-      log::Param("message", ex.getMessage().str())};
-    logger(LOG_ERR, "Caught an unexpected CTA exception", params);
-  } catch(std::exception &se) {
-    std::list<log::Param> params = {log::Param("what", se.what())};
-    logger(LOG_ERR, "Caught an unexpected standard exception", params);
-  } catch(...) {
-    logger(LOG_ERR, "Caught an unexpected and unknown exception");
-  }
-
-  return programRc;
-}
-
-//------------------------------------------------------------------------------
-// exceptionThrowingMain
-//------------------------------------------------------------------------------
-static int exceptionThrowingMain(cta::log::Logger &log, const int argc, char **const argv) {
-  
-
- cta::mediachanger::reactor::ZMQReactor reactor(log);
-
- const cta::mediachanger::acs::daemon::AcsdConfiguration config = cta::mediachanger::acs::daemon::AcsdConfiguration::createFromCtaConf("/etc/cta/cta-acsd.conf",log);
-
- 
-  // Create the main acsd object
-  cta::mediachanger::acs::daemon::AcsDaemon daemon(
-    argc,
-    argv,
-    log,
-    std::cout,
-    std::cerr,
-    reactor,
-    config);
-
-  // Run the acsd daemon
-  return daemon.main();
-
-return 0;
-}
diff --git a/mediachanger/acs/daemon/AcsDismountTape.cpp b/mediachanger/acs/daemon/AcsDismountTape.cpp
deleted file mode 100644
index bbf7da9813d3d8a2e8cbcb431918db5bb824225a..0000000000000000000000000000000000000000
--- a/mediachanger/acs/daemon/AcsDismountTape.cpp
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * 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 "AcsDismountTape.hpp"
-#include "common/exception/DismountFailed.hpp"
-#include "common/log/log.hpp"
-
-//------------------------------------------------------------------------------
-// constructor
-//------------------------------------------------------------------------------
-cta::mediachanger::acs::daemon::AcsDismountTape::AcsDismountTape(
-  const std::string &vid,
-  const uint32_t acs,
-  const uint32_t lsm,
-  const uint32_t panel,
-  const uint32_t drive,
-  Acs &acsWrapper,
-  log::Logger& log,
-  const AcsdConfiguration &ctaConf):
-  cta::mediachanger::acs::AcsLibraryInteraction(acsWrapper, log),
-  m_volId(acsWrapper.str2Volid(vid)),
-  m_driveId(acsWrapper.alpd2DriveId(acs,lsm,panel,drive)), 
-  m_acsWrapper(acsWrapper),
-  m_log(log),
-  m_ctaConf(ctaConf) {
-}
-
-//------------------------------------------------------------------------------
-// execute
-//------------------------------------------------------------------------------
-void cta::mediachanger::acs::daemon::AcsDismountTape::execute() const {
-  syncDismount();
-}
-
-//------------------------------------------------------------------------------
-// asyncExecute
-//------------------------------------------------------------------------------
-void cta::mediachanger::acs::daemon::AcsDismountTape::asyncExecute(const SEQ_NO seqNo) const {
-  asyncDismount(seqNo);
-}
-
-
-//------------------------------------------------------------------------------
-// syncDismount
-//------------------------------------------------------------------------------
-void cta::mediachanger::acs::daemon::AcsDismountTape::syncDismount() const {
-  const SEQ_NO requestSeqNumber = 1;
-  ALIGNED_BYTES buf[MAX_MESSAGE_SIZE / sizeof(ALIGNED_BYTES)];
-
-  try {
-    sendDismountRequest(requestSeqNumber);
-    requestResponsesUntilFinal(requestSeqNumber, buf,
-     m_ctaConf.QueryInterval.value(),
-     m_ctaConf.CmdTimeout.value());
-    processDismountResponse(buf);
-  } catch(cta::exception::Exception &ex) {
-    cta::exception::DismountFailed df;
-    df.getMessage() << "Failed to dismount volume " <<
-      m_volId.external_label << ": " << ex.getMessage().str();     
-    throw df;
-  }
-}
-
-//------------------------------------------------------------------------------
-// asyncDismount
-//------------------------------------------------------------------------------
-void cta::mediachanger::acs::daemon::AcsDismountTape::asyncDismount(const SEQ_NO seqNo) const
-  {
-  try {
-    sendDismountRequest(seqNo);    
-  } catch(cta::exception::Exception &ex) {
-    cta::exception::DismountFailed df;
-    df.getMessage() << "Failed to send dismount request to ACS " <<
-      m_volId.external_label << ": " << ex.getMessage().str();     
-    throw df;
-  }
-}
-
-//------------------------------------------------------------------------------
-// sendDismountRequest
-//------------------------------------------------------------------------------
-void cta::mediachanger::acs::daemon::AcsDismountTape::sendDismountRequest(
-  const SEQ_NO seqNumber) const {
-  const LOCKID lockId = 0; // No lock
-  const BOOLEAN force = FALSE; 
-  
-  std::stringstream dbgMsg;
-  dbgMsg << "Calling Acs::dismount() with seqNumber=" << seqNumber;
-  m_log(LOG_DEBUG, dbgMsg.str());
-  const STATUS s = m_acsWrapper.dismount(seqNumber, lockId, m_volId,
-    m_driveId, force);
-  
-  dbgMsg.str("");
-  dbgMsg << "Acs::dismount() for seqNumber=" << seqNumber << " returned " <<
-    acs_status(s);           
-  m_log(LOG_DEBUG,dbgMsg.str());
-  if(STATUS_SUCCESS != s) {
-    cta::exception::DismountFailed ex;
-    ex.getMessage() << "Failed to send request to dismount volume " <<
-      m_volId.external_label << " from drive " <<
-      m_acsWrapper.driveId2Str(m_driveId) << ": force=" <<
-      (force ? "TRUE" : "FALSE") << ": " << acs_status(s);
-    throw ex;
-  }
-}
-
-//------------------------------------------------------------------------------
-// processDismountResponse
-//------------------------------------------------------------------------------
-void cta::mediachanger::acs::daemon::AcsDismountTape::processDismountResponse(
-  ALIGNED_BYTES (&buf)[MAX_MESSAGE_SIZE / sizeof(ALIGNED_BYTES)]) const
-  {
-  const ACS_DISMOUNT_RESPONSE *const msg = (ACS_DISMOUNT_RESPONSE *)buf;
-
-  if(STATUS_SUCCESS != msg->dismount_status) {
-    cta::exception::DismountFailed ex;
-    ex.getMessage() << "Status of dismount response is not success: " <<
-      acs_status(msg->dismount_status);
-    throw ex;
-  }
-}
-
-//------------------------------------------------------------------------------
-// destructor
-//------------------------------------------------------------------------------
-cta::mediachanger::acs::daemon::AcsDismountTape::~AcsDismountTape() {  
-}
diff --git a/mediachanger/acs/daemon/AcsDismountTape.hpp b/mediachanger/acs/daemon/AcsDismountTape.hpp
deleted file mode 100644
index 9393c575860c9b16bc1f6823e289c3d456793d8d..0000000000000000000000000000000000000000
--- a/mediachanger/acs/daemon/AcsDismountTape.hpp
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
- * 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/>.
- */
-
-#pragma once
-
-#include "mediachanger/acs/Acs.hpp"
-#include "AcsdConfiguration.hpp"
-#include "mediachanger/acs/AcsLibraryInteraction.hpp"
-
-namespace cta     {
-namespace mediachanger        {
-namespace acs	{
-namespace daemon	{
-
-/**
- * Class responsible for dismounting tapes through ACS API.
- */
-class AcsDismountTape: public cta::mediachanger::acs::AcsLibraryInteraction {
-
-public:
-
-  /**
-   * Constructor.
-   */
-  AcsDismountTape(
-    const std::string &vid,
-    const uint32_t acs,
-    const uint32_t lsm,
-    const uint32_t panel,
-    const uint32_t drive,
-    cta::mediachanger::acs::Acs &acsWrapper,
-    cta::log::Logger& log,
-    const mediachanger::acs::daemon::AcsdConfiguration &ctaConf);
-
-  /**
-   * Destructor.
-   */
-  ~AcsDismountTape();
-
-  /**
-   * Execute dismount request through ACS API.
-   */
-  void execute() const;
-  
-  /**
-   * Execute asynchronous dismount request through ACS API.
-   * 
-   * @param The value of sequence number for ACS API.
-   */
-  void asyncExecute(const SEQ_NO seqNo) const;
-  
-protected:
-
-  /**
-   * Dismounts the tape with the specified m_volId from the drive with the
-   * specified m_driveId.
-   *
-   * This method does not return until the dismount has either succeeded, failed
-   * or the specified timeout has been reached.
-   */
-  void syncDismount() const;
-  
-  
-  /**
-   * Dismounts the tape with the specified m_volId from the drive with the
-   * specified m_driveId.
-   * This method sends a dismount request to ACSLS and returns.
-   * 
-   * @param The value of sequence number for ACS API.
-   */
-  void asyncDismount(const SEQ_NO seqNo) const;
-  
-  /**
-   * Sends the dismount request to ACSLS.
-   *
-   * @param seqNumber The sequence number to be used in the request.
-   */
-  void sendDismountRequest(const SEQ_NO seqNumber) const;
- 
-  /**
-   * Throws cta::exception::DismountFailed if the mount was not
-   * successful.
-   *
-   * @param buf The mount-response message.
-   */
-  void processDismountResponse(
-    ALIGNED_BYTES (&buf)[MAX_MESSAGE_SIZE / sizeof(ALIGNED_BYTES)]) const;
-  
-  /**
-   * VOLID
-   */  
-  VOLID m_volId;
-  
-  /**
-   * DRIVEID
-   */  
-  DRIVEID m_driveId;  
-  
-  /**
-   * Object providing c wrapper for ACS commands.
-   */
-  Acs &m_acsWrapper;
-
-  log::Logger &m_log;
-  /**
-   * The configuration parameters for the CTA ACS daemon.
-   */
-  const mediachanger::acs::daemon::AcsdConfiguration m_ctaConf;
-
-}; // class AcsDismountTape
-
-} // namespace daemon
-} // namespace acs
-} // namespace mediachanger
-} // namespace cta
diff --git a/mediachanger/acs/daemon/AcsForceDismountTape.cpp b/mediachanger/acs/daemon/AcsForceDismountTape.cpp
deleted file mode 100644
index 00a25ad83bd038b195180ec082d963405d43a6d6..0000000000000000000000000000000000000000
--- a/mediachanger/acs/daemon/AcsForceDismountTape.cpp
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * 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 "AcsForceDismountTape.hpp"
-#include "common/exception/ForceDismountFailed.hpp"
-#include "common/log/log.hpp"
-#include "common/log/SyslogLogger.hpp"
-
-//------------------------------------------------------------------------------
-// constructor
-//------------------------------------------------------------------------------
-cta::mediachanger::acs::daemon::AcsForceDismountTape::AcsForceDismountTape(
-  const std::string &vid,
-  const uint32_t acs,
-  const uint32_t lsm,
-  const uint32_t panel,
-  const uint32_t drive,
-  cta::mediachanger::acs::Acs &acsWrapper,
-  cta::log::Logger& log,
-  const AcsdConfiguration &ctaConf):
-  AcsLibraryInteraction(acsWrapper, log),
-  m_volId(acsWrapper.str2Volid(vid)),
-  m_driveId(acsWrapper.alpd2DriveId(acs,lsm,panel,drive)), 
-  m_acsWrapper(acsWrapper),
-  m_log(log),
-  m_ctaConf(ctaConf) {
-}
-
-//------------------------------------------------------------------------------
-// execute
-//------------------------------------------------------------------------------
-void cta::mediachanger::acs::daemon::AcsForceDismountTape::execute() const {
-  syncForceDismount();
-}
-
-//------------------------------------------------------------------------------
-// asyncExecute
-//------------------------------------------------------------------------------
-void cta::mediachanger::acs::daemon::AcsForceDismountTape::asyncExecute(const SEQ_NO seqNo) const {
-  asyncForceDismount(seqNo);
-}
-
-
-//------------------------------------------------------------------------------
-// syncForceDismount
-//------------------------------------------------------------------------------
-void cta::mediachanger::acs::daemon::AcsForceDismountTape::syncForceDismount() const {
-  const SEQ_NO requestSeqNumber = 1;
-  ALIGNED_BYTES buf[MAX_MESSAGE_SIZE / sizeof(ALIGNED_BYTES)];
-
-  try {
-    sendForceDismountRequest(requestSeqNumber);
-    requestResponsesUntilFinal(requestSeqNumber, buf,
-      m_ctaConf.QueryInterval.value(),
-      m_ctaConf.CmdTimeout.value());
-    processForceDismountResponse(buf);
-  } catch(cta::exception::Exception &ex) {
-    cta::exception::ForceDismountFailed df;
-    df.getMessage() << "Failed to force dismount volume " <<
-      m_volId.external_label << ": " << ex.getMessage().str();     
-    throw df;
-  }
-}
-
-//------------------------------------------------------------------------------
-// asyncDismount
-//------------------------------------------------------------------------------
-void cta::mediachanger::acs::daemon::AcsForceDismountTape::asyncForceDismount(const SEQ_NO seqNo)
-  const {
-  try {
-    sendForceDismountRequest(seqNo);    
-  } catch(cta::exception::Exception &ex) {
-    cta::exception::ForceDismountFailed df;
-    df.getMessage() << "Failed to send dismount request to ACS " <<
-      m_volId.external_label << ": " << ex.getMessage().str();     
-    throw df;
-  }
-}
-
-//------------------------------------------------------------------------------
-// sendDismountRequest
-//------------------------------------------------------------------------------
-void cta::mediachanger::acs::daemon::AcsForceDismountTape::sendForceDismountRequest(
-  const SEQ_NO seqNumber) const {
-  const LOCKID lockId = 0; // No lock
-  const BOOLEAN force = TRUE; 
-  
-  std::stringstream dbgMsg;
-  dbgMsg << "Calling Acs::dismount() with seqNumber=" << seqNumber;
-  m_log(LOG_DEBUG, dbgMsg.str());
-  const STATUS s = m_acsWrapper.dismount(seqNumber, lockId, m_volId,
-    m_driveId, force);
-  
-  dbgMsg.str("");
-  dbgMsg << "Acs::dismount() for seqNumber=" << seqNumber << " returned " <<
-    acs_status(s);           
-  m_log(LOG_DEBUG,dbgMsg.str());
-  if(STATUS_SUCCESS != s) {
-    cta::exception::ForceDismountFailed ex;
-    ex.getMessage() << "Failed to send request to force dismount volume " <<
-      m_volId.external_label << " from drive " <<
-      m_acsWrapper.driveId2Str(m_driveId) << ": force=" <<
-      (force ? "TRUE" : "FALSE") << ": " << acs_status(s);
-    throw ex;
-  }
-}
-
-//------------------------------------------------------------------------------
-// processForceDismountResponse
-//------------------------------------------------------------------------------
-void cta::mediachanger::acs::daemon::AcsForceDismountTape::processForceDismountResponse(
-  ALIGNED_BYTES (&buf)[MAX_MESSAGE_SIZE / sizeof(ALIGNED_BYTES)]) const {
-  const ACS_DISMOUNT_RESPONSE *const msg = (ACS_DISMOUNT_RESPONSE *)buf;
-
-  if(STATUS_SUCCESS != msg->dismount_status) {
-    cta::exception::ForceDismountFailed ex;
-    ex.getMessage() << "Status of force dismount response is not success: " <<
-      acs_status(msg->dismount_status);
-    throw ex;
-  }
-}
-
-//------------------------------------------------------------------------------
-// destructor
-//------------------------------------------------------------------------------
-cta::mediachanger::acs::daemon::AcsForceDismountTape::~AcsForceDismountTape() {  
-}
diff --git a/mediachanger/acs/daemon/AcsForceDismountTape.hpp b/mediachanger/acs/daemon/AcsForceDismountTape.hpp
deleted file mode 100644
index 5f4cbf69fed27836bf31a3e8fe8af1dc29da2c4f..0000000000000000000000000000000000000000
--- a/mediachanger/acs/daemon/AcsForceDismountTape.hpp
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * 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/>.
- */
-
-#pragma once
-
-#include "mediachanger/acs/Acs.hpp"
-#include "mediachanger/acs/daemon/AcsdConfiguration.hpp"
-#include "mediachanger/acs/AcsLibraryInteraction.hpp"
-#include "common/log/log.hpp"
-#include "common/log/SyslogLogger.hpp"
-
-namespace cta        {
-namespace mediachanger     {
-namespace acs        {
-namespace daemon       {
-
-/**
- * Class responsible for dismounting tapes through ACS API.
- */
-class AcsForceDismountTape: public cta::mediachanger::acs::AcsLibraryInteraction {
-
-public:
-
-  /**
-   * Constructor.
-   */
-  AcsForceDismountTape(
-    const std::string &vid,
-    const uint32_t acs,
-    const uint32_t lsm,
-    const uint32_t panel,
-    const uint32_t drive,
-    cta::mediachanger::acs::Acs &acsWrapper,
-    log::Logger& log,
-    const AcsdConfiguration &ctaConf);
-
-  /**
-   * Destructor.
-   */
-  ~AcsForceDismountTape();
-
-  /**
-   * Execute force dismount request through ACS API.
-   */
-  void execute() const;
-  
-  /**
-   * Execute asynchronous force dismount request through ACS API.
-   * 
-   * @param The value of sequence number for ACS API.
-   */
-  void asyncExecute(const SEQ_NO seqNo) const;
-  
-protected:
-
-  /**
-   * Force dismounts the tape with the specified m_volId from the drive with the
-   * specified m_driveId.
-   *
-   * This method does not return until the dismount has either succeeded, failed
-   * or the specified timeout has been reached.
-   */
-  void syncForceDismount() const;
-  
-  
-  /**
-   * Force dismounts the tape with the specified m_volId from the drive with the
-   * specified m_driveId.
-   * This method sends a dismount request to ACSLS and returns.
-   * 
-   * @param The value of sequence number for ACS API.
-   */
-  void asyncForceDismount(const SEQ_NO seqNo) const;
-  
-  /**
-   * Sends the force dismount request to ACSLS.
-   *
-   * @param seqNumber The sequence number to be used in the request.
-   */
-  void sendForceDismountRequest(const SEQ_NO seqNumber) const;
- 
-  /**
-   * Throws cta::exception::DismountFailed if the mount was not
-   * successful.
-   *
-   * @param buf The mount-response message.
-   */
-  void processForceDismountResponse(
-    ALIGNED_BYTES (&buf)[MAX_MESSAGE_SIZE / sizeof(ALIGNED_BYTES)]) const;
-  
-  /**
-   * VOLID
-   */  
-  VOLID m_volId;
-  
-  /**
-   * DRIVEID
-   */  
-  DRIVEID m_driveId;  
-  
-  /**
-   * Object providing c wrapper for ACS commands.
-   */
-  Acs &m_acsWrapper;
-  
-  log::Logger &m_log;
-
-  /**
-   * The configuration parameters for the CTA ACS daemon.
-   */
-  const AcsdConfiguration m_ctaConf;
-
-}; // class AcsForceDismountTape
-
-} // namespace daemon
-} // namespace acs
-} // namespace mediachanger
-} // namespace cta
diff --git a/mediachanger/acs/daemon/AcsMessageHandler.cpp b/mediachanger/acs/daemon/AcsMessageHandler.cpp
deleted file mode 100644
index 2d9af754b90b7340c4547a2aca4f74795be2b11b..0000000000000000000000000000000000000000
--- a/mediachanger/acs/daemon/AcsMessageHandler.cpp
+++ /dev/null
@@ -1,444 +0,0 @@
-/*
- * 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 "common/Constants.hpp"
-#include "mediachanger/acs/daemon/Constants.hpp"
-#include "AcsMessageHandler.hpp"
-#include "AcsDismountTape.hpp"
-#include "AcsForceDismountTape.hpp"
-#include "AcsMountTapeReadOnly.hpp"
-#include "AcsMountTapeReadWrite.hpp"
-#include "mediachanger/acs/Acs.hpp"
-#include "mediachanger/acs/AcsImpl.hpp"
-#include "common/log/log.hpp"
-#include "common/log/SyslogLogger.hpp"
-#include "mediachanger/messages.hpp"
-#include "mediachanger/ReturnValue.pb.h"
-#include "mediachanger/AcsMountTapeReadOnly.pb.h"
-#include "mediachanger/AcsMountTapeReadWrite.pb.h"
-#include "mediachanger/AcsDismountTape.pb.h"
-#include "mediachanger/AcsForceDismountTape.pb.h"
-#include "mediachanger/Exception.pb.h"
-#include "mediachanger/reactor/ZMQPollEventHandler.hpp"
-#include "mediachanger/reactor/ZMQReactor.hpp"
-#include "mediachanger/ZmqSocket.hpp"
-#include "errno.h"
-
-#include <iostream>
-#include <unistd.h>
-
-//------------------------------------------------------------------------------
-// constructor
-//------------------------------------------------------------------------------
-cta::mediachanger::acs::daemon::AcsMessageHandler::AcsMessageHandler(
-  cta::log::Logger &log,
-  cta::mediachanger::reactor::ZMQReactor &reactor,
-  void *const zmqContext,
-  const std::string &hostName,
-  const AcsdConfiguration &ctaConf,
-  AcsPendingRequests &acsPendingRequests):
-  m_log(log),
-  m_reactor(reactor),
-  m_socket(zmqContext, ZMQ_ROUTER),
-  m_hostName(hostName),
-  m_ctaConf(ctaConf),
-  m_acsPendingRequests(acsPendingRequests) { 
-
-  std::ostringstream endpoint;
-  endpoint << "tcp://127.0.0.1:" << m_ctaConf.port.value();
-  
-  try {
-    m_socket.bind(endpoint.str().c_str());
-    std::list<log::Param> params = {log::Param("endpoint", endpoint.str())};
-    m_log(LOG_INFO, "Bound the ZMQ socket of the AcsMessageHandler",
-      params);
-  } catch(cta::exception::Exception &ne){
-    cta::exception::Exception ex;
-    ex.getMessage() <<
-      "Failed to bind the ZMQ socket of the AcsMessageHandler"
-      ": endpoint=" << endpoint.str() << ": " << ne.getMessage().str();
-    throw ex;
-  }
-}
-
-//------------------------------------------------------------------------------
-// destructor
-//------------------------------------------------------------------------------
-cta::mediachanger::acs::daemon::AcsMessageHandler::~AcsMessageHandler()
-  {
-}
-
-//------------------------------------------------------------------------------
-// getName
-//------------------------------------------------------------------------------
-std::string cta::mediachanger::acs::daemon::AcsMessageHandler::getName()
-  const {
-  return "AcsMessageHandler";
-}
-
-//------------------------------------------------------------------------------
-// fillPollFd
-//------------------------------------------------------------------------------
-void cta::mediachanger::acs::daemon::AcsMessageHandler::fillPollFd(
-  zmq_pollitem_t &fd) {
-  fd.events = ZMQ_POLLIN;
-  fd.revents = 0;
-  fd.socket = m_socket.getZmqSocket();
-  fd.fd = -1;
-}
-
-//------------------------------------------------------------------------------
-// handleEvent
-//------------------------------------------------------------------------------
-bool cta::mediachanger::acs::daemon::AcsMessageHandler::handleEvent(
-  const zmq_pollitem_t &fd) {
-  // Try to receive a request, simply giving up if an exception is raised
-  cta::mediachanger::Frame rqst;
-
-  //for handling zeroMQ's router socket type specific elements 
-  //ie first frame = identity of the sender
-  //   second one  =  empty
-  //   third and following = actual data frames
- 
-  //The ZmqMsg address data can be dump as string and used as key for storing 
-  //the identity (for clients who need a late answer)
-  cta::mediachanger::ZmqMsg address;
-  cta::mediachanger::ZmqMsg empty;
-  try {
-    checkSocket(fd);
-    m_socket.recv(address);
-    m_socket.recv(empty);
-    rqst = recvFrame(m_socket);
-  } catch(cta::exception::Exception &ex) {
-    std::list<log::Param> params = {log::Param("message", ex.getMessage().str())};
-    m_log(LOG_ERR, "AcsMessageHandler failed to handle event", params);
-    return false; // Give up and stay registered with the reactor
-  }
-  std::list<log::Param> params = {
-      log::Param("sender identity", 
-              utils::hexDump(address.getData(),address.size()))
-     };
-  m_log(LOG_DEBUG, "handling event in AcsMessageHandler", params);
- 
-  // From this point on any exception thrown should be converted into an
-  // Exception message and sent back to the client 
-  cta::mediachanger::Frame reply;
-  
-  try {
-    // if there are any problems we need to send the replay to the client.
-    reply = dispatchMsgHandler(rqst);
-  } catch(cta::exception::Exception &ex) {
-    reply = createExceptionFrame(ECANCELED, ex.getMessage().str()); 
-    m_log(LOG_ERR, ex.getMessage().str());
-  } catch(std::exception &se) {
-    reply = createExceptionFrame(ECANCELED, se.what());
-    m_log(LOG_ERR, se.what());
-  } catch(...) {
-    reply = createExceptionFrame(ECANCELED, "Caught an unknown exception"); 
-    m_log(LOG_ERR, "Caught an unknown exception");
-  }
-
-  // Send the reply to the client
-  try {
-    //we need to prepend our frames the same way we received them
-    // ie identity + empty frames 
-    m_socket.send(address,ZMQ_SNDMORE);
-    m_socket.send(empty,ZMQ_SNDMORE);
-
-    cta::mediachanger::sendFrame(m_socket, reply);
-  } catch(cta::exception::Exception &ex) {
-    std::list<log::Param> params = {log::Param("message", ex.getMessage().str())};
-    m_log(LOG_ERR, "AcsMessageHandler failed to send reply to client", params);
-  }
-
-  return false; // Stay registered with the reactor
-}
-
-//------------------------------------------------------------------------------
-// checkSocket
-//------------------------------------------------------------------------------
-void cta::mediachanger::acs::daemon::AcsMessageHandler::checkSocket(
-  const zmq_pollitem_t &fd) const{
-  void* underlyingSocket = m_socket.getZmqSocket();
-  if(fd.socket != underlyingSocket){
-    cta::exception::Exception ex;
-    ex.getMessage() << "AcsMessageHandler passed wrong poll item";
-    throw ex;
-  }
-}
-
-//------------------------------------------------------------------------------
-// dispatchMsgHandler
-//------------------------------------------------------------------------------
-cta::mediachanger::Frame cta::mediachanger::acs::daemon::AcsMessageHandler::
-  dispatchMsgHandler(const cta::mediachanger::Frame &rqst) {
-  m_log(LOG_DEBUG, "AcsMessageHandler dispatching message handler");
-  
-  const cta::mediachanger::acs::daemon::MsgType msgType = (cta::mediachanger::acs::daemon::MsgType)rqst.header.msgtype();
-  switch(msgType) {
-  case cta::mediachanger::MSG_TYPE_ACSMOUNTTAPEREADONLY:
-    return handleAcsMountTapeReadOnly(rqst);
-      
-  case cta::mediachanger::MSG_TYPE_ACSMOUNTTAPEREADWRITE:
-    return handleAcsMountTapeReadWrite(rqst);  
-
-  case cta::mediachanger::MSG_TYPE_ACSDISMOUNTTAPE:
-    return handleAcsDismountTape(rqst);
-
-  case cta::mediachanger::MSG_TYPE_ACSFORCEDISMOUNTTAPE:
-    return handleAcsForceDismountTape(rqst);
-
-  default:
-    {
-      const std::string msgTypeStr = cta::mediachanger::acs::daemon::msgTypeToString(msgType);
-      cta::exception::Exception ex;
-      ex.getMessage() << "Failed to dispatch message handler"
-        ": Unexpected request type: msgType=" << msgType << " msgTypeStr=" <<
-        msgTypeStr;
-      throw ex;
-    }
-  }
-}
-
-//------------------------------------------------------------------------------
-// handleAcsMountTapeReadOnly
-//------------------------------------------------------------------------------
-cta::mediachanger::Frame cta::mediachanger::acs::daemon::AcsMessageHandler::
-  handleAcsMountTapeReadOnly(const cta::mediachanger::Frame &rqst) {
-  m_log(LOG_DEBUG, "Handling AcsMountTapeReadOnly message");
-
-  try {
-    cta::mediachanger::AcsMountTapeReadOnly rqstBody;
-    rqst.parseBodyIntoProtocolBuffer(rqstBody);
-    
-    const std::string vid = rqstBody.vid();
-    const uint32_t acs    = rqstBody.acs();
-    const uint32_t lsm    = rqstBody.lsm();
-    const uint32_t panel  = rqstBody.panel();
-    const uint32_t drive  = rqstBody.drive();
-    
-    std::list<log::Param> params = {log::Param("tapeVid", vid),
-      log::Param("acs", acs),
-      log::Param("lsm", lsm),
-      log::Param("panel", panel),
-      log::Param("drive", drive)};
-    m_log(LOG_INFO, "Mount tape for read-only access", params);
-
-    cta::mediachanger::acs::AcsImpl acsWrapper;
-    cta::mediachanger::acs::daemon::AcsMountTapeReadOnly acsMountTapeReadOnly(vid, acs, lsm, 
-      panel, drive, acsWrapper, m_log, m_ctaConf);
-    try {
-      acsMountTapeReadOnly.execute();
-      m_log(LOG_INFO,"Tape successfully mounted for read-only access", params);
-    } catch (cta::exception::Exception &ne) {
-      m_log(LOG_ERR,"Tape mount for read-only access failed: "
-        + ne.getMessage().str(), params);  
-      throw;  
-    }     
-    const cta::mediachanger::Frame reply = createReturnValueFrame(0);
-    return reply;
-  } catch(cta::exception::Exception &ne) {
-    cta::exception::Exception ex;
-    ex.getMessage() << "Failed to handle AcsMountTapeReadOnly message: " <<
-      ne.getMessage().str();
-    throw ex;
-  }
-}
-
-//------------------------------------------------------------------------------
-// handleAcsMountTapeReadWrite
-//------------------------------------------------------------------------------
-cta::mediachanger::Frame cta::mediachanger::acs::daemon::AcsMessageHandler::
-  handleAcsMountTapeReadWrite(const cta::mediachanger::Frame &rqst) {
-  m_log(LOG_DEBUG, "Handling AcsMountTapeReadWrite message");
-
-  try {
-    cta::mediachanger::AcsMountTapeReadWrite rqstBody;
-    rqst.parseBodyIntoProtocolBuffer(rqstBody);
-     
-    const std::string vid = rqstBody.vid();
-    const uint32_t acs    = rqstBody.acs();
-    const uint32_t lsm    = rqstBody.lsm();
-    const uint32_t panel  = rqstBody.panel();
-    const uint32_t drive  = rqstBody.drive();
-    
-    std::list<log::Param> params = {log::Param("tapeVid", vid),
-      log::Param("acs", acs),
-      log::Param("lsm", lsm),
-      log::Param("panel", panel),
-      log::Param("drive", drive)};
-    m_log(LOG_INFO, "Mount tape for read/write access",params);
-
-    cta::mediachanger::acs::AcsImpl acsWrapper;
-    cta::mediachanger::acs::daemon::AcsMountTapeReadWrite acsMountTapeReadWrite(vid, acs,
-      lsm, panel, drive, acsWrapper, m_log, m_ctaConf);
-    try {
-      acsMountTapeReadWrite.execute();   
-      m_log(LOG_INFO,"Tape successfully mounted for read/write access", params);
-    } catch (cta::exception::Exception &ne) {
-      m_log(LOG_ERR,"Tape mount for read/write access failed: "
-        + ne.getMessage().str(), params);  
-      throw;  
-    }     
-    const cta::mediachanger::Frame reply = createReturnValueFrame(0);
-    return reply;
-  } catch(cta::exception::Exception &ne) {
-    cta::exception::Exception ex;
-    ex.getMessage() << "Failed to handle AcsMountTapeReadWrite message: " <<
-      ne.getMessage().str();
-    throw ex;
-  }
-}
-
-//------------------------------------------------------------------------------
-// handleAcsDismountTape
-//------------------------------------------------------------------------------
-cta::mediachanger::Frame cta::mediachanger::acs::daemon::AcsMessageHandler::
-  handleAcsDismountTape(const cta::mediachanger::Frame& rqst) {
-  m_log(LOG_DEBUG, "Handling AcsDismountTape message");
-
-  try {
-    cta::mediachanger::AcsDismountTape rqstBody;
-    rqst.parseBodyIntoProtocolBuffer(rqstBody);
-
-    const std::string vid = rqstBody.vid();
-    const uint32_t acs    = rqstBody.acs();
-    const uint32_t lsm    = rqstBody.lsm();
-    const uint32_t panel  = rqstBody.panel();
-    const uint32_t drive  = rqstBody.drive();
-    
-    std::list<log::Param> params = {log::Param("tapeVid", vid),
-      log::Param("acs", acs),
-      log::Param("lsm", lsm),
-      log::Param("panel", panel),
-      log::Param("drive", drive)};
-    m_log(LOG_INFO, "Dismount tape",params);
-
-    cta::mediachanger::acs::AcsImpl acsWrapper;
-    cta::mediachanger::acs::daemon::AcsDismountTape acsDismountTape(vid, acs, lsm, panel, drive,
-      acsWrapper, m_log, m_ctaConf);
-    try {
-      acsDismountTape.execute();
-      m_log(LOG_INFO,"Tape successfully dismounted", params);
-    } catch (cta::exception::Exception &ne) {
-      m_log(LOG_ERR,"Tape dismount failed: "+ne.getMessage().str(), params);  
-      throw;  
-    }    
-    const cta::mediachanger::Frame reply = createReturnValueFrame(0);
-    return reply;
-  } catch(cta::exception::Exception &ne) {
-    cta::exception::Exception ex;
-    ex.getMessage() << "Failed to handle AcsDismountTape message: " <<
-      ne.getMessage().str();
-    throw ex;
-  } catch(...) {
-    cta::exception::Exception ex;
-    ex.getMessage() << "Failed to handle AcsDismountTape message: " 
-                    << "Caught an unknown exception";
-    throw ex;
-  }
-}
-
-//------------------------------------------------------------------------------
-// handleAcsForceDismountTape
-//------------------------------------------------------------------------------
-cta::mediachanger::Frame cta::mediachanger::acs::daemon::AcsMessageHandler::
-  handleAcsForceDismountTape(const cta::mediachanger::Frame& rqst) {
-  m_log(LOG_DEBUG, "Handling AcsDismountTape message");
-
-  try {
-    cta::mediachanger::AcsForceDismountTape rqstBody;
-    rqst.parseBodyIntoProtocolBuffer(rqstBody);
-
-    const std::string vid = rqstBody.vid();
-    const uint32_t acs    = rqstBody.acs();
-    const uint32_t lsm    = rqstBody.lsm();
-    const uint32_t panel  = rqstBody.panel();
-    const uint32_t drive  = rqstBody.drive();
-
-    std::list<log::Param> params = {log::Param("tapeVid", vid),
-      log::Param("acs", acs),
-      log::Param("lsm", lsm),
-      log::Param("panel", panel),
-      log::Param("drive", drive)};
-    m_log(LOG_INFO, "Force dismount tape", params);
-
-    cta::mediachanger::acs::AcsImpl acsWrapper;
-    cta::mediachanger::acs::daemon::AcsForceDismountTape acsForceDismountTape(vid, acs, lsm,
-      panel, drive, acsWrapper, m_log, m_ctaConf);
-    try {
-      acsForceDismountTape.execute();
-      m_log(LOG_INFO,"Tape successfully force dismounted", params);
-    } catch (cta::exception::Exception &ne) {
-      m_log(LOG_ERR,"Tape force dismount failed: "+ne.getMessage().str(),
-        params);
-      throw;
-    }
-    const cta::mediachanger::Frame reply = createReturnValueFrame(0);
-    return reply;
-  } catch(cta::exception::Exception &ne) {
-    cta::exception::Exception ex;
-    ex.getMessage() << "Failed to handle AcsForceDismountTape message: " <<
-      ne.getMessage().str();
-    throw ex;
-  } catch(...) {
-    cta::exception::Exception ex;
-    ex.getMessage() << "Failed to handle AcsForceDismountTape message: "
-                    << "Caught an unknown exception";
-    throw ex;
-  }
-}
-
-//------------------------------------------------------------------------------
-// createReturnValueFrame
-//------------------------------------------------------------------------------
-cta::mediachanger::Frame cta::mediachanger::acs::daemon::AcsMessageHandler::
-  createReturnValueFrame(const int value) {
-  cta::mediachanger::Frame frame;
-
-  frame.header = cta::mediachanger::protoTapePreFillHeader();
-  frame.header.set_msgtype(cta::mediachanger::MSG_TYPE_RETURNVALUE);
-  frame.header.set_bodyhashvalue(cta::mediachanger::computeSHA1Base64(frame.body));
-  frame.header.set_bodysignature("PIPO");
-
-  cta::mediachanger::ReturnValue body;
-  body.set_value(value);
-  frame.serializeProtocolBufferIntoBody(body);
-
-  return frame;
-}
-
-//------------------------------------------------------------------------------
-// createExceptionFrame
-//------------------------------------------------------------------------------
-cta::mediachanger::Frame cta::mediachanger::acs::daemon::AcsMessageHandler::
-  createExceptionFrame(const int code, const std::string& msg) {
-  cta::mediachanger::Frame frame;
-
-  frame.header = cta::mediachanger::protoTapePreFillHeader();
-  frame.header.set_msgtype(cta::mediachanger::MSG_TYPE_EXCEPTION);
-  frame.header.set_bodyhashvalue(cta::mediachanger::computeSHA1Base64(frame.body));
-  frame.header.set_bodysignature("PIPO");
-
-  cta::mediachanger::Exception body;
-  body.set_code(code);
-  body.set_message(msg);
-  frame.serializeProtocolBufferIntoBody(body);
-
-  return frame;
-}
diff --git a/mediachanger/acs/daemon/AcsMessageHandler.hpp b/mediachanger/acs/daemon/AcsMessageHandler.hpp
deleted file mode 100644
index 418bf4a84d663ac4a1299eb3840c2dd0976339da..0000000000000000000000000000000000000000
--- a/mediachanger/acs/daemon/AcsMessageHandler.hpp
+++ /dev/null
@@ -1,187 +0,0 @@
-/*
- * 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/>.
- */
-
-#pragma once
-
-#include "mediachanger/acs/Constants.hpp"
-#include "mediachanger/Frame.hpp"
-#include "mediachanger/ZmqSocket.hpp"
-#include "mediachanger/reactor/ZMQReactor.hpp"
-#include "AcsDaemon.hpp"
-#include "AcsdConfiguration.hpp"
-#include "AcsPendingRequests.hpp"
-#include "common/log/SyslogLogger.hpp"
-#include "mediachanger/reactor/ZMQPollEventHandler.hpp"
-
-namespace cta     {
-namespace mediachanger      {
-namespace acs     {
-namespace daemon     {
-
-/**
- * Handles the events of the socket listening for connection from the tape 
- * server daemon.
- */
-class AcsMessageHandler: public cta::mediachanger::reactor::ZMQPollEventHandler {
-public:
-
-  /**
-   * Constructor.
-   *
-   * @param reactor The reactor to which new CTA ACS daemon connection 
-   * handlers are to be registered.
-   * @param hostName   The name of the host.
-   * @param zmqContext The ZMQ context.
-   * @param ctaConf The configuration for the CTA ACS daemon.
-   * @param acsPendingRequests The object to handle requests to the CTA ACS
-   * daemon.
-   */
-  AcsMessageHandler(
-    log::Logger &log,
-    cta::mediachanger::reactor::ZMQReactor &reactor,
-    void *const zmqContext,
-    const std::string &hostName,
-    const AcsdConfiguration &ctaConf,
-    AcsPendingRequests &acsPendingRequests);
-
-  /**
-   * Destructor.
-   */
-  ~AcsMessageHandler();
-
-  /**
-   * Returns the human-readable name this event handler.
-   */
-  std::string getName() const;
-
-  /**
-   * Fills the specified poll file-descriptor ready to be used in a call to
-   * poll().
-   */
-  void fillPollFd(zmq_pollitem_t &fd);
-
-  /**
-   * Handles the specified event.
-   *
-   * @param fd The poll file-descriptor describing the event.
-   * @return true if the event handler should be removed from and deleted by
-   * the reactor.
-   */
-  bool handleEvent(const zmq_pollitem_t &fd);
-  
-private:
-
-  /**
-   * Creates a message frame containing a ReturnValue message.
-   *
-   * @param value The return value of the ReturnValue message.
-   * @return The message frame.
-   */
-  cta::mediachanger::Frame createReturnValueFrame(const int value);
-
-  /**
-   * Creates a message frame containing an Exception message.
-   *
-   * @param code The error code of the exception.
-   * @param msg The message string of the exception.
-   */
-  cta::mediachanger::Frame createExceptionFrame(const int code,
-    const std::string& msg);
-     
-  /**
-   * Make sure the  zmq_pollitem_t's socket is the same as m_socket
-   * Throw an exception if it is not the case
-   * @param fd the poll item 
-   */
-  void checkSocket(const zmq_pollitem_t &fd) const;
-  
-  /**
-   * Dispatches the appropriate handler method for the specified request
-   * message.
-   *
-   * @param  rqst The request.
-   * @return The reply.
-   */
-  cta::mediachanger::Frame dispatchMsgHandler(const cta::mediachanger::Frame &rqst) ;
-
-  /**
-   * Handles the mount tape for read-only.
-   *
-   * @param  rqst The request.
-   * @return The reply.
-   */
-  cta::mediachanger::Frame handleAcsMountTapeReadOnly(const cta::mediachanger::Frame &rqst);
-  
-  /**
-   * Handles the mount tape for read/write.
-   *
-   * @param  rqst The request.
-   * @return The reply.
-   */
-  cta::mediachanger::Frame handleAcsMountTapeReadWrite(const cta::mediachanger::Frame &rqst);
-
-  /**
-   * Handles the dismount tape request.
-   *
-   * @param rqst The request.
-   * @return The reply.
-   */
-  cta::mediachanger::Frame handleAcsDismountTape(const cta::mediachanger::Frame &rqst);
-
-  /**
-   * Handles the force dismount tape request.
-   *
-   * @param rqst The request.
-   * @return The reply.
-   */
-  cta::mediachanger::Frame handleAcsForceDismountTape(const cta::mediachanger::Frame &rqst);
-  
-  log::Logger &m_log;
-  /**
-   * The reactor to which new CTA ACS daemon connection handlers are to
-   * be registered.
-   */
-  cta::mediachanger::reactor::ZMQReactor &m_reactor;
-
-  /**
-   * The ZMQ socket listening for messages.
-   */
-  cta::mediachanger::ZmqSocketST m_socket;
- 
-  /**
-   * The name of the host on which CTA ACS daemon is running.
-   */
-  const std::string m_hostName;
-  
-
-  /**
-   * The configuration parameters for the CTA ACS daemon.
-   */
-  const acs::daemon::AcsdConfiguration m_ctaConf;
-  
-  /**
-   * The object to handle requests to the CTA ACS daemon.
-   */
-  AcsPendingRequests &m_acsPendingRequests;
-  
-}; // class AcsMessageHandler
-
-} // namespace deamon
-} // namespace acs
-} // namespace mediachanger
-} // namespace cta
diff --git a/mediachanger/acs/daemon/AcsMountTapeReadOnly.cpp b/mediachanger/acs/daemon/AcsMountTapeReadOnly.cpp
deleted file mode 100644
index a8a0c398810bb182706fe1aa83d79c990805261c..0000000000000000000000000000000000000000
--- a/mediachanger/acs/daemon/AcsMountTapeReadOnly.cpp
+++ /dev/null
@@ -1,213 +0,0 @@
-/*
- * 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 "AcsMountTapeReadOnly.hpp"
-#include "common/exception/MountFailed.hpp"
-#include "common/exception/QueryVolumeFailed.hpp"
-#include "common/log/log.hpp"
-
-//------------------------------------------------------------------------------
-// constructor
-//------------------------------------------------------------------------------
-cta::mediachanger::acs::daemon::AcsMountTapeReadOnly::AcsMountTapeReadOnly(
-  const std::string &vid,
-  const uint32_t acs,
-  const uint32_t lsm,
-  const uint32_t panel,
-  const uint32_t drive,
-  cta::mediachanger::acs::Acs &acsWrapper,
-  log::Logger& log,
-  const AcsdConfiguration &ctaConf):
-  AcsLibraryInteraction(acsWrapper, log),
-  m_volId(acsWrapper.str2Volid(vid)),
-  m_driveId(acsWrapper.alpd2DriveId(acs,lsm,panel,drive)),      
-  m_acsWrapper(acsWrapper),
-  m_log(log),
-  m_ctaConf(ctaConf) {    
-}
-
-//------------------------------------------------------------------------------
-// execute
-//------------------------------------------------------------------------------
-void cta::mediachanger::acs::daemon::AcsMountTapeReadOnly::execute() const {      
-  try {
-    syncMountTapeReadOnly();
-  } catch (cta::exception::MountFailed &mountFailed) {
-    try {
-      const std::string queryVolumeResponse = syncQueryVolume();      
-      mountFailed.getMessage() << " : The query volume response: " << 
-        queryVolumeResponse;
-    } catch (cta::exception::QueryVolumeFailed &queryFailed) {
-      mountFailed.getMessage() << " : " << queryFailed.getMessage().str();
-    } 
-    throw mountFailed;
-  }    
-}
-
-//------------------------------------------------------------------------------
-// syncMountTapeReadOnly
-//------------------------------------------------------------------------------
-void cta::mediachanger::acs::daemon::AcsMountTapeReadOnly::syncMountTapeReadOnly() const
-  {
-  const SEQ_NO requestSeqNumber = 1;
-  ALIGNED_BYTES buf[MAX_MESSAGE_SIZE / sizeof(ALIGNED_BYTES)];
-
-  try {
-    sendMountTapeReadOnlyRequest(requestSeqNumber);
-    requestResponsesUntilFinal(requestSeqNumber, buf, 
-      m_ctaConf.QueryInterval.value(), m_ctaConf.CmdTimeout.value());
-    processMountTapeReadOnlyResponse(buf);
-  }  catch(cta::exception::Exception &ex) {
-    cta::exception::MountFailed mf;
-    mf.getMessage() << "Failed to mount for read-only access volume " <<
-      m_volId.external_label << ": " << ex.getMessage().str();
-    throw mf;
-  }
-}
-
-//------------------------------------------------------------------------------
-// sendMountTapeReadOnlyRequest
-//------------------------------------------------------------------------------
-void cta::mediachanger::acs::daemon::AcsMountTapeReadOnly::sendMountTapeReadOnlyRequest(
-  const SEQ_NO seqNumber) const {
-  const LOCKID lockId    = 0; // No lock
-  const BOOLEAN bypass   = FALSE;
-  const BOOLEAN readOnly = TRUE;
-
-  m_log(LOG_DEBUG,"Calling Acs::mount()");
-  const STATUS s = m_acsWrapper.mount(seqNumber, lockId, m_volId,
-    m_driveId, readOnly, bypass);
-  std::stringstream dbgMsg;
-  dbgMsg << "Acs::mount() returned " << acs_status(s);            
-  m_log(LOG_DEBUG,dbgMsg.str());
-
-  if(STATUS_SUCCESS != s) {
-    cta::exception::MountFailed ex;
-    ex.getMessage() << "Failed to send request to mount for read-only access"
-      " volume " << m_volId.external_label << " into drive " <<
-      m_acsWrapper.driveId2Str(m_driveId) << ": readOnly=" <<
-      (readOnly ? "TRUE" : "FALSE") << ": " << acs_status(s);
-    throw ex;
-  } 
-}
-
-//------------------------------------------------------------------------------
-// processMountTapeReadOnlyResponse
-//------------------------------------------------------------------------------
-void cta::mediachanger::acs::daemon::AcsMountTapeReadOnly::processMountTapeReadOnlyResponse(
-  ALIGNED_BYTES (&buf)[MAX_MESSAGE_SIZE / sizeof(ALIGNED_BYTES)]) const
-  {
-  const ACS_MOUNT_RESPONSE *const msg = (ACS_MOUNT_RESPONSE *)buf;
-
-  if(STATUS_SUCCESS != msg->mount_status) {
-    cta::exception::MountFailed ex;
-    ex.getMessage() << "Status of mount response is not success: " << 
-      acs_status(msg->mount_status);
-    throw ex;
-  }
-}
-
-//------------------------------------------------------------------------------
-// syncQueryVolume
-//------------------------------------------------------------------------------
-std::string cta::mediachanger::acs::daemon::AcsMountTapeReadOnly::syncQueryVolume() const {
-  const SEQ_NO requestSeqNumber = 1;
-  ALIGNED_BYTES buf[MAX_MESSAGE_SIZE / sizeof(ALIGNED_BYTES)];
-  try {
-    sendQueryVolumeRequest(requestSeqNumber);
-    requestResponsesUntilFinal(requestSeqNumber, buf, 
-      m_ctaConf.QueryInterval.value(), m_ctaConf.CmdTimeout.value());
-    return processQueryResponse(buf);
-  } catch(cta::exception::Exception &ex) {
-    cta::exception::QueryVolumeFailed qf;
-    qf.getMessage() << "Failed to query volume " <<
-      m_volId.external_label << ": " << ex.getMessage().str();
-    throw qf;
-  }
-}
-
-//------------------------------------------------------------------------------
-// sendQueryVolumeRequest
-//------------------------------------------------------------------------------
-void cta::mediachanger::acs::daemon::AcsMountTapeReadOnly::sendQueryVolumeRequest (
-  const SEQ_NO seqNumber) const {
-  VOLID volIds[MAX_ID];
-
-  memset(volIds, '\0', sizeof(volIds));
-  strncpy(volIds[0].external_label, m_volId.external_label,
-    sizeof(volIds[0].external_label));
-  volIds[0].external_label[sizeof(volIds[0].external_label) - 1]  = '\0';
-           
-  m_log(LOG_DEBUG,"Calling Acs::queryVolume()");
-    
-  const STATUS s = m_acs.queryVolume(seqNumber, volIds, 1);
-
-  std::stringstream dbgMsg;
-  dbgMsg << "Acs::queryVolume() returned " << acs_status(s);            
-  m_log(LOG_DEBUG,"Calling Acs::queryVolume()");
-
-  if(STATUS_SUCCESS != s) {
-    cta::exception::QueryVolumeFailed ex;
-    ex.getMessage() << "Failed to send query request for volume " <<
-      m_volId.external_label << ": " << acs_status(s);
-    throw ex;
-  }
-}
-
-//------------------------------------------------------------------------------
-// processQueryResponse
-//------------------------------------------------------------------------------
-std::string cta::mediachanger::acs::daemon::AcsMountTapeReadOnly::processQueryResponse(
-  ALIGNED_BYTES (&buf)[MAX_MESSAGE_SIZE / sizeof(ALIGNED_BYTES)]) const {
-
-  const ACS_QUERY_VOL_RESPONSE *const msg = (ACS_QUERY_VOL_RESPONSE *)buf;
-
-  if(STATUS_SUCCESS != msg->query_vol_status) {
-    cta::exception::QueryVolumeFailed ex;
-    ex.getMessage() << "Status of query response is not success: " <<
-      acs_status(msg->query_vol_status);
-    throw ex;
-  }
-
-  if((unsigned short)1 != msg->count) {
-    cta::exception::QueryVolumeFailed ex;
-    ex.getMessage() << "Query response does not contain a single volume: count="
-      << msg->count;
-    throw ex;
-  }
-
-  // count is 1 so it is safe to make a reference to the single volume status
-  const QU_VOL_STATUS &volStatus = msg->vol_status[0];
-
-  if(strcmp(m_volId.external_label, volStatus.vol_id.external_label)) {
-    cta::exception::QueryVolumeFailed ex;
-    ex.getMessage() <<
-      "Volume identifier of query response does not match that of request"
-      ": requestVID=" << m_volId.external_label <<
-      " responseVID=" << volStatus.vol_id.external_label;
-    throw ex;
-  }
-
-  return volumeStatusAsString(volStatus);
-}
-
-//------------------------------------------------------------------------------
-// destructor
-//------------------------------------------------------------------------------
-cta::mediachanger::acs::daemon::AcsMountTapeReadOnly::~AcsMountTapeReadOnly() {  
-}
diff --git a/mediachanger/acs/daemon/AcsMountTapeReadOnly.hpp b/mediachanger/acs/daemon/AcsMountTapeReadOnly.hpp
deleted file mode 100644
index 86d070eaadba4a0a043e6d1f5b2144146d221d5b..0000000000000000000000000000000000000000
--- a/mediachanger/acs/daemon/AcsMountTapeReadOnly.hpp
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * 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/>.
- */
-
-#pragma once
-
-#include "mediachanger/acs/Acs.hpp"
-#include "AcsdConfiguration.hpp"
-#include "mediachanger/acs/AcsLibraryInteraction.hpp"
-
-namespace cta        {
-namespace mediachanger     {
-namespace acs        {
-namespace daemon	{
-
-/**
- * Class responsible for mounting tapes for read-only access through ACS API.
- */
-class AcsMountTapeReadOnly: public cta::mediachanger::acs::AcsLibraryInteraction {
-
-public:
-
-  /**
-   * Constructor.
-   */
-  AcsMountTapeReadOnly(
-    const std::string &vid,
-    const uint32_t acs,
-    const uint32_t lsm,
-    const uint32_t panel,
-    const uint32_t drive,
-    cta::mediachanger::acs::Acs &acsWrapper,
-    cta::log::Logger& log,
-    const AcsdConfiguration &ctaConf);
-
-  /**
-   * Destructor.
-   */
-  ~AcsMountTapeReadOnly();
-
-  /**
-   * Execute mount request through ACS API.
-   * Throws cta::exception::Exception if the mount is not successful. Adds to
-   * the exception the result of the query volume request for the given volume.
-   */
-  void execute() const ;
-  
-protected:
-
-  /**
-   * mounts the tape with the specified VID into the drive with the specified
-   * drive ID.
-   *
-   * This method does not return until the mount has either succeeded, failed or
-   * the specified timeout has been reached.
-   */
-  void syncMountTapeReadOnly() const;
-  
-  /**
-   * Sends the mount request to ACSLS.
-   *
-   * @param seqNumber The sequence number to be used in the request.
-   */
-  void sendMountTapeReadOnlyRequest(const SEQ_NO seqNumber) const;
- 
-  /**
-   * Throws cta::exception::MountFailed if the mount was not
-   * successful.
-   *
-   * @param buf The mount-response message.
-   */
-  void processMountTapeReadOnlyResponse(
-    ALIGNED_BYTES (&buf)[MAX_MESSAGE_SIZE / sizeof(ALIGNED_BYTES)]) const;
-  
-  /**
-   * Queries ACS for information about the volume identifier.
-   *
-   * This method does not return until the information has been successfully
-   * retrieved, an error has occurred or the specified timeout has been
-   * reached.
-   *
-   * @return The string presentation of the query volume response.
-   */
-  std::string syncQueryVolume() const;
-  
-  /**
-   * Sends the query volume  request to ACSLS.
-   *
-   * @param seqNumber The sequence number to be used in the request.
-   */
-  void sendQueryVolumeRequest(const SEQ_NO seqNumber) const;
-
-  /**
-   * Extracts the volume status from the specified query-response message and
-   * returns it in human-readable form.
-   *
-   * @param buf The query-response message.
-   * @return    The string presentation of the query volume response.
-   */
-  std::string processQueryResponse(
-    ALIGNED_BYTES (&buf)[MAX_MESSAGE_SIZE / sizeof(ALIGNED_BYTES)]) const;
-  
-  /**
-   * ACS VOLID
-   */  
-  VOLID m_volId;
-  
-  /**
-   * ACS DRIVEID
-   */  
-  DRIVEID m_driveId;  
-  
-  /**
-   * Object providing c wrapper for ACS commands.
-   */
-  Acs &m_acsWrapper;
-  log::Logger& m_log;
-  /**
-   * The configuration parameters for the CTA ACS daemon.
-   */
-  const AcsdConfiguration m_ctaConf;
-
-}; // class AcsMountTapeReadOnly
-
-} // namespace daemon
-} // namepsace acs
-} // namespace mediachanger
-} // namespace cta
diff --git a/mediachanger/acs/daemon/AcsMountTapeReadWrite.cpp b/mediachanger/acs/daemon/AcsMountTapeReadWrite.cpp
deleted file mode 100644
index 67594140813ace37e0068b7510d68e0a3a25522a..0000000000000000000000000000000000000000
--- a/mediachanger/acs/daemon/AcsMountTapeReadWrite.cpp
+++ /dev/null
@@ -1,216 +0,0 @@
-/*
- * 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 "AcsMountTapeReadWrite.hpp"
-#include "common/exception/MountFailed.hpp"
-#include "mediachanger/acs/AcsLibraryInteraction.hpp"
-#include "common/exception/QueryVolumeFailed.hpp"
-#include "common/log/log.hpp"
-
-//------------------------------------------------------------------------------
-// constructor
-//------------------------------------------------------------------------------
-cta::mediachanger::acs::daemon::AcsMountTapeReadWrite::AcsMountTapeReadWrite(
-  const std::string &vid,
-  const uint32_t acs,
-  const uint32_t lsm,
-  const uint32_t panel,
-  const uint32_t drive,
-  cta::mediachanger::acs::Acs &acsWrapper,
-  cta::log::Logger &log,
-  const AcsdConfiguration &ctaConf):
-  AcsLibraryInteraction(acsWrapper, log),
-  m_volId(acsWrapper.str2Volid(vid)),
-  m_driveId(acsWrapper.alpd2DriveId(acs,lsm,panel,drive)), 
-  m_acsWrapper(acsWrapper),
-  m_log(log),
-  m_ctaConf(ctaConf) {
-}
-
-//------------------------------------------------------------------------------
-// execute
-//------------------------------------------------------------------------------
-void cta::mediachanger::acs::daemon::AcsMountTapeReadWrite::execute() const {
-  try {
-    syncMountTapeReadWrite();
-  } catch (cta::exception::MountFailed &mountFailed) {
-    try {
-      const std::string queryVolumeResponse = syncQueryVolume();
-      mountFailed.getMessage() << " : The query volume response: " << 
-        queryVolumeResponse;
-    } catch (cta::exception::QueryVolumeFailed &queryFailed) {
-      mountFailed.getMessage() << " : " << queryFailed.getMessage().str();
-    }
-    throw mountFailed;
-  }  
-}
-
-//------------------------------------------------------------------------------
-// syncMountTapeReadWrite
-//------------------------------------------------------------------------------
-void cta::mediachanger::acs::daemon::AcsMountTapeReadWrite::syncMountTapeReadWrite() const
-  {
-  const SEQ_NO requestSeqNumber = 1;
-  ALIGNED_BYTES buf[MAX_MESSAGE_SIZE / sizeof(ALIGNED_BYTES)];
-
-  try {
-    sendMountTapeReadWriteRequest(requestSeqNumber);
-    requestResponsesUntilFinal(requestSeqNumber, buf, 
-      m_ctaConf.QueryInterval.value(), m_ctaConf.CmdTimeout.value());
-    processMountTapeReadWriteResponse(buf);
-  }  catch(cta::exception::Exception &ex) {
-    cta::exception::MountFailed mf;
-    mf.getMessage() << "Failed to mount for read/write access volume " <<
-      m_volId.external_label << ": " << ex.getMessage().str();
-    throw mf;
-  }
-}
-
-//------------------------------------------------------------------------------
-// sendMountTapeReadWriteRequest
-//------------------------------------------------------------------------------
-void cta::mediachanger::acs::daemon::AcsMountTapeReadWrite::sendMountTapeReadWriteRequest(
-  const SEQ_NO seqNumber) const {
-  const LOCKID lockId    = 0; // No lock
-  const BOOLEAN bypass   = FALSE;
-  const BOOLEAN readOnly = FALSE;
-
-  m_log(LOG_DEBUG,"Calling Acs::mount()");
-  const STATUS s = m_acsWrapper.mount(seqNumber, lockId, m_volId,
-    m_driveId, readOnly, bypass);
-  std::stringstream dbgMsg;
-  dbgMsg << "Acs::mount() returned " << acs_status(s);          
-  m_log(LOG_DEBUG,dbgMsg.str());
-
-  if(STATUS_SUCCESS != s) {
-    cta::exception::MountFailed ex;
-    ex.getMessage() << "Failed to send request to mount for read/write access"
-      " volume " << m_volId.external_label << " into drive " 
-      << m_acsWrapper.driveId2Str(m_driveId) 
-      << ": readOnly=" 
-      << (readOnly ? "TRUE" : "FALSE") << ": " << acs_status(s);
-    throw ex;
-  } 
-}
-
-//------------------------------------------------------------------------------
-// processMountTapeReadWriteResponse
-//------------------------------------------------------------------------------
-void cta::mediachanger::acs::daemon::AcsMountTapeReadWrite::processMountTapeReadWriteResponse(
-  ALIGNED_BYTES (&buf)[MAX_MESSAGE_SIZE / sizeof(ALIGNED_BYTES)]) const
-  {
-  const ACS_MOUNT_RESPONSE *const msg = (ACS_MOUNT_RESPONSE *)buf;
-
-  if(STATUS_SUCCESS != msg->mount_status) {
-    cta::exception::MountFailed ex;
-    ex.getMessage() << "Status of mount response is not success: " << 
-      acs_status(msg->mount_status);
-    throw ex;
-  }
-}
-
-//------------------------------------------------------------------------------
-// syncQueryVolume
-//------------------------------------------------------------------------------
-std::string cta::mediachanger::acs::daemon::AcsMountTapeReadWrite::syncQueryVolume() const {
-  const SEQ_NO requestSeqNumber = 1;
-  ALIGNED_BYTES buf[MAX_MESSAGE_SIZE / sizeof(ALIGNED_BYTES)];
-  try {
-    sendQueryVolumeRequest(requestSeqNumber);
-    requestResponsesUntilFinal(requestSeqNumber, buf, 
-      m_ctaConf.QueryInterval.value(), m_ctaConf.CmdTimeout.value());
-    return processQueryResponse(buf);
-  } catch(cta::exception::Exception &ex) {
-    cta::exception::QueryVolumeFailed qf;
-    qf.getMessage() << "Failed to query volume " <<
-      m_volId.external_label << ": " << ex.getMessage().str();
-    throw qf;
-  }
-}
-
-//------------------------------------------------------------------------------
-// sendQueryVolumeRequest
-//------------------------------------------------------------------------------
-void cta::mediachanger::acs::daemon::AcsMountTapeReadWrite::sendQueryVolumeRequest (
-  const SEQ_NO seqNumber) const {
-  VOLID volIds[MAX_ID];
-
-  memset(volIds, '\0', sizeof(volIds));
-  strncpy(volIds[0].external_label, m_volId.external_label,
-    sizeof(volIds[0].external_label));
-  volIds[0].external_label[sizeof(volIds[0].external_label) - 1]  = '\0';
-           
-  m_log(LOG_DEBUG,"Calling Acs::queryVolume()");
-  
-  
-  const STATUS s = m_acs.queryVolume(seqNumber, volIds, 1);
-
-  std::stringstream dbgMsg;
-  dbgMsg << "Acs::queryVolume() returned " << acs_status(s);            
-  m_log(LOG_DEBUG,"Calling Acs::queryVolume()");
-
-  if(STATUS_SUCCESS != s) {
-    cta::exception::QueryVolumeFailed ex;
-    ex.getMessage() << "Failed to send query request for volume " <<
-      m_volId.external_label << ": " << acs_status(s);
-    throw ex;
-  }
-}
-
-//------------------------------------------------------------------------------
-// processQueryResponse
-//------------------------------------------------------------------------------
-std::string cta::mediachanger::acs::daemon::AcsMountTapeReadWrite::processQueryResponse(
-  ALIGNED_BYTES (&buf)[MAX_MESSAGE_SIZE / sizeof(ALIGNED_BYTES)]) const {
-
-  const ACS_QUERY_VOL_RESPONSE *const msg = (ACS_QUERY_VOL_RESPONSE *)buf;
-
-  if(STATUS_SUCCESS != msg->query_vol_status) {
-    cta::exception::QueryVolumeFailed ex;
-    ex.getMessage() << "Status of query response is not success: " <<
-      acs_status(msg->query_vol_status);
-    throw ex;
-  }
-
-  if((unsigned short)1 != msg->count) {
-    cta::exception::QueryVolumeFailed ex;
-    ex.getMessage() << "Query response does not contain a single volume: count="
-      << msg->count;
-    throw ex;
-  }
-
-  // count is 1 so it is safe to make a reference to the single volume status
-  const QU_VOL_STATUS &volStatus = msg->vol_status[0];
-
-  if(strcmp(m_volId.external_label, volStatus.vol_id.external_label)) {
-    cta::exception::QueryVolumeFailed ex;
-    ex.getMessage() <<
-      "Volume identifier of query response does not match that of request"
-      ": requestVID=" << m_volId.external_label <<
-      " responseVID=" << volStatus.vol_id.external_label;
-    throw ex;
-  }
-
-  return volumeStatusAsString(volStatus);
-}
-
-//------------------------------------------------------------------------------
-// destructor
-//------------------------------------------------------------------------------
-cta::mediachanger::acs::daemon::AcsMountTapeReadWrite::~AcsMountTapeReadWrite() {  
-}
diff --git a/mediachanger/acs/daemon/AcsMountTapeReadWrite.hpp b/mediachanger/acs/daemon/AcsMountTapeReadWrite.hpp
deleted file mode 100644
index 17cecfb9eff509c88ff653ed6a6cfc286f79b7a7..0000000000000000000000000000000000000000
--- a/mediachanger/acs/daemon/AcsMountTapeReadWrite.hpp
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * 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/>.
- */
-
-#pragma once
-
-#include "mediachanger/acs/Acs.hpp"
-#include "AcsdConfiguration.hpp"
-#include "mediachanger/acs/AcsLibraryInteraction.hpp"
-
-namespace cta        {
-namespace mediachanger        {
-namespace acs     {
-namespace daemon        {
-
-/**
- * Class responsible for mounting tapes for read/write access through ACS API.
- */
-class AcsMountTapeReadWrite: public cta::mediachanger::acs::AcsLibraryInteraction {
-
-public:
-
-  /**
-   * Constructor.
-   */
-  AcsMountTapeReadWrite(
-    const std::string &vid,
-    const uint32_t acs,
-    const uint32_t lsm,
-    const uint32_t panel,
-    const uint32_t drive,
-    cta::mediachanger::acs::Acs &acsWrapper,
-    log::Logger& log,
-    const AcsdConfiguration &ctaConf);
-
-  /**
-   * Destructor.
-   */
-  ~AcsMountTapeReadWrite();
-
-  /**
-   * Execute mount request through ACS API.
-   */
-  void execute() const;
-  
-protected:
-
-  /**
-   * mounts the tape with the specified VID into the drive with the specified
-   * drive ID.
-   *
-   * This method does not return until the mount has either succeeded, failed or
-   * the specified timeout has been reached.
-   */
-  void syncMountTapeReadWrite() const;
-  
-  /**
-   * Sends the mount request to ACSLS.
-   *
-   * @param seqNumber The sequence number to be used in the request.
-   */
-  void sendMountTapeReadWriteRequest(const SEQ_NO seqNumber) const;
- 
-  /**
-   * Throws cta::exception::MountFailed if the mount was not
-   * successful.
-   *
-   * @param buf The mount-response message.
-   */
-  void processMountTapeReadWriteResponse(
-    ALIGNED_BYTES (&buf)[MAX_MESSAGE_SIZE / sizeof(ALIGNED_BYTES)]) const;
-  
-  /**
-   * Queries ACS for information about the volume identifier.
-   *
-   * This method does not return until the information has been successfully
-   * retrieved, an error has occurred or the specified timeout has been
-   * reached.
-   *
-   * @return The string presentation of the query volume response.
-   */
-  std::string syncQueryVolume() const;
-  
-  /**
-   * Sends the query volume  request to ACSLS.
-   *
-   * @param seqNumber The sequence number to be used in the request.
-   */
-  void sendQueryVolumeRequest(const SEQ_NO seqNumber) const;
-
-  /**
-   * Extracts the volume status from the specified query-response message and
-   * returns it in human-readable form.
-   *
-   * @param buf The query-response message.
-   * @return    The string presentation of the query volume response.
-   */
-  std::string processQueryResponse(
-    ALIGNED_BYTES (&buf)[MAX_MESSAGE_SIZE / sizeof(ALIGNED_BYTES)]) const;
-  
-  /**
-   * ACS VOLID
-   */  
-  VOLID m_volId;
-  
-  /**
-   * ACS DRIVEID
-   */  
-  DRIVEID m_driveId;  
-  
-  /**
-   * Object providing C wrapper for ACS commands.
-   */
-  Acs &m_acsWrapper;
-  
-  log::Logger& m_log;
-
-  /**
-   * The configuration parameters for the CTA ACS daemon.
-   */
-  const AcsdConfiguration m_ctaConf;
-  
-}; // class AcsMountTapeReadWrite
-
-} // namespace daemon
-} // namepsace acs 
-} // namespace mediachanger
-} // namespace cta
diff --git a/mediachanger/acs/daemon/AcsPendingRequests.cpp b/mediachanger/acs/daemon/AcsPendingRequests.cpp
deleted file mode 100644
index 16025a007882a4d83698d7cb41895192ff76cba4..0000000000000000000000000000000000000000
--- a/mediachanger/acs/daemon/AcsPendingRequests.cpp
+++ /dev/null
@@ -1,331 +0,0 @@
-/*
- * 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 "AcsPendingRequests.hpp"
-#include "mediachanger/acs/AcsImpl.hpp"
-#include "mediachanger/acs/daemon/AcsRequest.hpp"
-#include "mediachanger/acs/daemon/AcsDismountTape.hpp"
-#include "AcsRequestDismountTape.hpp"
-#include "common/Constants.hpp"
-#include "mediachanger/Constants.hpp"
-#include "mediachanger/acs/daemon/Constants.hpp"
-#include "common/log/log.hpp"
-#include "mediachanger/messages.hpp"
-#include "mediachanger/Frame.hpp"
-#include "mediachanger/AcsDismountTape.pb.h"
-//-----------------------------------------------------------------------------
-// constructor
-//-----------------------------------------------------------------------------
-cta::mediachanger::acs::daemon::AcsPendingRequests::AcsPendingRequests(
-  const AcsdConfiguration &ctaConf, cta::log::Logger &l):
-  m_ctaConf(ctaConf),
-  m_log(l),
-  m_lastTimeResponseUsed(0) {
-}
-
-//-----------------------------------------------------------------------------
-// destructor
-//-----------------------------------------------------------------------------
-cta::mediachanger::acs::daemon::AcsPendingRequests::~AcsPendingRequests() {
-  for(RequestList::const_iterator itor = m_acsRequestList.begin(); 
-    itor != m_acsRequestList.end();  itor++) {
-    cta::mediachanger::acs::daemon::AcsRequest *const acsRequest = *itor;
-    delete acsRequest;
-  }
-}
-
-//-----------------------------------------------------------------------------
-// tick
-//-----------------------------------------------------------------------------
-
-  void cta::mediachanger::acs::daemon::AcsPendingRequests::tick() {
-  bool haveRunningRequests = false;
-  for(RequestList::const_iterator itor = m_acsRequestList.begin(); 
-    itor != m_acsRequestList.end();itor++) {
-    cta::mediachanger::acs::daemon::AcsRequest *const acsRequest = *itor;
-    acsRequest->tick();
-    if(acsRequest->isRunning()) {
-      haveRunningRequests = true;
-    }
-  }
-  
-  if (haveRunningRequests) {
-    const time_t now = time(0);
-    
-    const time_t secsSinceLastResponse = now -  m_lastTimeResponseUsed;
-    const bool responseTimeExceeded = secsSinceLastResponse >
-      ACS_RESPONSE_TIMEOUT;
-    
-    if (responseTimeExceeded) {
-      const int responseTimeout = 0 ; // 0 - means pool for 
-                                      // the existence of a response.
-
-      SEQ_NO responseSeqNumber = 0;
-      REQ_ID reqId = (REQ_ID)0;
-      ACS_RESPONSE_TYPE responseType = RT_NONE;
-      ALIGNED_BYTES buf[MAX_MESSAGE_SIZE / sizeof(ALIGNED_BYTES)];
-
-      m_log(LOG_DEBUG,
-        "AcsPendingRequests::tick() Calling Acs::response()");
-
-      const STATUS responseStatus = m_acs.response(responseTimeout,
-        responseSeqNumber, reqId, responseType, buf);
-
-      if (STATUS_SUCCESS == responseStatus) {
-        setRequestResponse(responseSeqNumber,responseType, buf);
-      }
-      m_lastTimeResponseUsed = time(0);
-    }
-  }    
-}
-
-//-----------------------------------------------------------------------------
-// setRequestResponse
-//-----------------------------------------------------------------------------
-void cta::mediachanger::acs::daemon::AcsPendingRequests::setRequestResponse(
-  const SEQ_NO responseSeqNumber, const ACS_RESPONSE_TYPE responseType,
-  const ALIGNED_BYTES *const responseMsg) {
-  for(RequestList::const_iterator itor = m_acsRequestList.begin(); 
-    itor != m_acsRequestList.end();itor++) {
-    cta::mediachanger::acs::daemon::AcsRequest *const acsRequest = *itor;
-    if ( responseSeqNumber == acsRequest->getSeqNo()) {
-      std::stringstream dbgMsg;
-      dbgMsg << "AcsPendingRequests::setRequestResponse responseType=" <<
-        responseType << " " << acsRequest->str();
-      m_log(LOG_DEBUG, dbgMsg.str());      
-      acsRequest->setResponse(responseType, responseMsg);      
-    }
-  }
-}
-
-//-----------------------------------------------------------------------------
-// handleCompletedRequests
-//-----------------------------------------------------------------------------
-void cta::mediachanger::acs::daemon::AcsPendingRequests::handleCompletedRequests() {
-  for(RequestList::const_iterator itor = m_acsRequestList.begin(); 
-    itor != m_acsRequestList.end();itor++) {
-    cta::mediachanger::acs::daemon::AcsRequest *const acsRequest = *itor;
-    if (acsRequest->isCompleted()) {
-      std::list<log::Param> params = {log::Param("tapeVid", acsRequest->getVid()),
-        log::Param("acs", acsRequest->getAcs()),
-        log::Param("lsm", acsRequest->getLsm()),
-        log::Param("panel", acsRequest->getPanel()),
-        log::Param("drive", acsRequest->getDrive()),
-        log::Param("sender identity", acsRequest->getIdentity())
-      };
-      m_log(LOG_INFO,"Tape successfully dismounted",params);
-      acsRequest->sendReplayToClientOnce();
-      acsRequest->setStateToDelete();
-    }
-  }
-}
-
-//-----------------------------------------------------------------------------
-// handleFailedRequests
-//-----------------------------------------------------------------------------
-void cta::mediachanger::acs::daemon::AcsPendingRequests::handleFailedRequests() {
-  for(RequestList::const_iterator itor = m_acsRequestList.begin(); 
-    itor != m_acsRequestList.end();itor++) {
-    cta::mediachanger::acs::daemon::AcsRequest *const acsRequest = *itor;
-    if (acsRequest->isFailed()) {
-      std::list<log::Param> params = {log::Param("tapeVid", acsRequest->getVid()),
-        log::Param("acs", acsRequest->getAcs()),
-        log::Param("lsm", acsRequest->getLsm()),
-        log::Param("panel", acsRequest->getPanel()),
-        log::Param("drive", acsRequest->getDrive()),
-        log::Param("sender identity", acsRequest->getIdentity())
-      };    
-      m_log(LOG_INFO,"Dismount tape failed", params);
-      acsRequest->sendReplayToClientOnce();
-      acsRequest->setStateToDelete();
-    }
-  }
-}
-
-//-----------------------------------------------------------------------------
-// handleToDeleteRequests
-//-----------------------------------------------------------------------------
-void cta::mediachanger::acs::daemon::AcsPendingRequests::handleToDeleteRequests() {
-  for(RequestList::iterator itor = m_acsRequestList.begin(); 
-    itor != m_acsRequestList.end();itor++) {
-    cta::mediachanger::acs::daemon::AcsRequest *const acsRequest = *itor;
-    if (acsRequest->isToDelete()) {
-      m_log(LOG_DEBUG,"AcsPendingRequests::handleToDeleteRequests " +
-        acsRequest->str());     
-      delete acsRequest;
-      itor=m_acsRequestList.erase(itor);      
-    }    
-  }
-}
-
-//-----------------------------------------------------------------------------
-// checkAndAddRequest
-//-----------------------------------------------------------------------------
-void cta::mediachanger::acs::daemon::AcsPendingRequests::checkAndAddRequest(
- mediachanger::ZmqMsg &address, mediachanger::ZmqMsg &empty,
- const cta::mediachanger::Frame &rqst, cta::mediachanger::ZmqSocketST &socket) {
-  std::list<log::Param> params = {
-    log::Param("sender identity", 
-      utils::hexDump(address.getData(), address.size()))
-  };
-  m_log(LOG_DEBUG, "AcsPendingRequests::checkAndAddRequest", params);
-
-  const cta::mediachanger::acs::daemon::MsgType msgType = (cta::mediachanger::acs::daemon::MsgType)rqst.header.msgtype();
-  switch(msgType) {
-  case mediachanger::MSG_TYPE_ACSMOUNTTAPEREADONLY:
-  case mediachanger::MSG_TYPE_ACSMOUNTTAPEREADWRITE:
-    {  
-      cta::exception::Exception ex;
-      ex.getMessage() << "Failed to check request"
-        ": Handling of this message type is not implemented: msgtype=" <<
-        rqst.header.msgtype();
-      throw ex;      
-    }
-  case mediachanger::MSG_TYPE_ACSDISMOUNTTAPE:
-    checkAndAddRequestDismountTape(address, empty, rqst, socket);
-    break;
-  default:
-    {
-      const std::string msgTypeStr = cta::mediachanger::acs::daemon::msgTypeToString(msgType);
-      cta::exception::Exception ex;
-      ex.getMessage() << "Failed to check request"
-        ": Unexpected request type: msgType=" << msgType << " msgTypeStr=" <<
-        msgTypeStr;
-      throw ex;
-    }
-  }
-}
-
-//-----------------------------------------------------------------------------
-// checkAndAddRequestDismountTape
-//-----------------------------------------------------------------------------
-void cta::mediachanger::acs::daemon::AcsPendingRequests::checkAndAddRequestDismountTape(
-  mediachanger::ZmqMsg &address,  mediachanger::ZmqMsg &empty,
-  const mediachanger::Frame &rqst, mediachanger::ZmqSocketST &socket) {
-  m_log(LOG_DEBUG, 
-    "AcsPendingRequests::checkAndAddRequestDismountTape");
-    
-  mediachanger::AcsDismountTape rqstBody;
-  rqst.parseBodyIntoProtocolBuffer(rqstBody);
-
-  const std::string vid = rqstBody.vid();
-  const uint32_t acs    = rqstBody.acs();
-  const uint32_t lsm    = rqstBody.lsm();
-  const uint32_t panel  = rqstBody.panel();
-  const uint32_t drive  = rqstBody.drive();
-
-  checkRequest(vid, acs, lsm, panel, drive);
-  
-  std::list<log::Param> params = {log::Param("tapeVid", vid),
-    log::Param("acs", acs),
-    log::Param("lsm", lsm),
-    log::Param("panel", panel),
-    log::Param("drive", drive),
-    log::Param("sender identity", 
-      utils::hexDump(address.getData(), address.size()))
-  };
-  m_log(LOG_INFO, "Dismount tape", params);
-   
-  const SEQ_NO seqNo = getSequenceNumber();
-  std::list<log::Param> seqParam = {log::Param("seqNumber", seqNo)};
-  m_log(LOG_DEBUG, "ACS sequence number", seqParam);  
-
-  try {
-    cta::mediachanger::acs::daemon::AcsRequest * acsRequestDismountTape = 
-      new AcsRequestDismountTape(vid, acs, lsm, panel, drive, 
-      //new AcsRequestDismountTape AcsRequestDismountTape(vid, acs, lsm, panel, drive, 
-        m_ctaConf, socket, address, empty, m_log, seqNo);
-    
-    acsRequestDismountTape->setStateToExecute(); 
-    m_acsRequestList.push_back(acsRequestDismountTape); 
-  } catch (cta::exception::Exception &ne) {
-    cta::exception::Exception ex;
-    ex.getMessage() << "Failed to add dismount request: "
-      << ne.getMessage().str();
-    m_log(LOG_ERR, ex.getMessage().str());  
-    throw ex;  
-  }
-}
-
-//-----------------------------------------------------------------------------
-// checkRequest
-//-----------------------------------------------------------------------------
-void cta::mediachanger::acs::daemon::AcsPendingRequests::checkRequest(const std::string &vid, 
-  const uint32_t acs, const uint32_t lsm, const uint32_t panel,
-  const uint32_t drive) const {
-  for(RequestList::const_iterator itor = m_acsRequestList.begin(); 
-    itor != m_acsRequestList.end();itor++) {
-    cta::mediachanger::acs::daemon::AcsRequest *const acsRequest = *itor;
-    if (acs == acsRequest->getAcs() && lsm == acsRequest->getLsm() &&
-      panel == acsRequest->getPanel() && drive == acsRequest->getDrive()) {   
-      cta::exception::Exception ex;
-      ex.getMessage() << "Check request failed: "
-        "acs, lsm, panel, drive already are used by another request: "<<
-         acsRequest->str();
-      throw ex; 
-    }
-    if (std::string::npos !=  vid.find(acsRequest->getVid())) {
-      cta::exception::Exception ex;
-      ex.getMessage() << "Check request failed: "
-        "vid already is used by another request: "<<
-         acsRequest->str();
-      throw ex; 
-    }
-  }
-}
-
-//-----------------------------------------------------------------------------
-// getSequenceNumber
-//-----------------------------------------------------------------------------
-SEQ_NO cta::mediachanger::acs::daemon::AcsPendingRequests::getSequenceNumber() const {
-  unsigned short maxSeqNo = 0;
-  unsigned short minSeqNo = ACS_MAX_SEQ;
-  
-  for(RequestList::const_iterator itor = m_acsRequestList.begin(); 
-    itor != m_acsRequestList.end();itor++) {
-    cta::mediachanger::acs::daemon::AcsRequest *const acsRequest = *itor;
-    if (maxSeqNo < acsRequest->getSeqNo()) {
-      maxSeqNo = acsRequest->getSeqNo();
-    }
-    if (minSeqNo > acsRequest->getSeqNo()) {
-      minSeqNo = acsRequest->getSeqNo();
-    }
-  }
-  
-  // first request
-  if(ACS_MAX_SEQ == minSeqNo && 0 == maxSeqNo) {
-    return 1;
-  }
-    
-  // try to get number from 1 to minSeqNo
-  if(1 != minSeqNo ) {
-      return minSeqNo-1;
-    }
-  
-  // try to get number from maxSeqNo to maximum allowed
-  if (ACS_MAX_SEQ != maxSeqNo) {
-    return maxSeqNo+1;
-  }
-  
-  cta::exception::Exception ex;
-  ex.getMessage() << "Failed to get sequence number for ACS"
-    ": allocated minimum seqNo=\""<<minSeqNo<<"\""<<
-    " allocated maximum seqNo=\""<<maxSeqNo<<"\"";
-  m_log(LOG_ERR, ex.getMessage().str());  
-  throw ex;   
-}
diff --git a/mediachanger/acs/daemon/AcsPendingRequests.hpp b/mediachanger/acs/daemon/AcsPendingRequests.hpp
deleted file mode 100644
index b7fff05a269d6fd26710211fbdf11066532d2a92..0000000000000000000000000000000000000000
--- a/mediachanger/acs/daemon/AcsPendingRequests.hpp
+++ /dev/null
@@ -1,196 +0,0 @@
-/*
- * 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/>.
- */
-
-#pragma once
-
-#include "mediachanger/acs/daemon/AcsdConfiguration.hpp"
-#include "common/log/log.hpp"
-#include "common/log/SyslogLogger.hpp"
-#include "mediachanger/acs/daemon/AcsRequest.hpp"
-#include "mediachanger/acs/AcsImpl.hpp"
-#include "mediachanger/messages.hpp"
-#include "mediachanger/Frame.hpp"
-#include "mediachanger/ZmqMsg.hpp"
-#include "mediachanger/ZmqSocket.hpp"
-#include "mediachanger/ZmqSocketST.hpp"
-#include <list>
-#include <time.h>
-
-namespace cta     {
-namespace mediachanger        {
-namespace acs        {
-namespace daemon        {
-   
-/**
- * Class responsible for keeping track of the Acs requests  controlled by
- * the CTA ACS daemon.
- */
-class AcsPendingRequests {
-public:
-
-  /**
-   * Constructor.
-   *
-   * @param ctaConf The configuration for the CTA ACS daemon.
-   */
-  AcsPendingRequests(const AcsdConfiguration &ctaConf, cta::log::Logger &);
-  
-  /**
-   * Destructor.
-   */
-  ~AcsPendingRequests();
-
-  /**
-   * Notifies the AcsPendingRequests that it should perform any time related 
-   * actions.
-   *
-   * This method does not have to be called at any time precise interval.
-   */
-  void tick();
-
-  /**
-   * Requests to the CTA ACS daemon might have several states.
-   * 
-   *  ACS_REQUEST_TO_EXECUTE - is initial state. When request arrives from a 
-   *    client it is set to be asynchronous executed to ACS Library.
-   *  ACS_REQUEST_IS_RUNNING - the state in which we periodically query ACS 
-   *    Library to check the status of the ongoing request.
-   *  ACS_REQUEST_COMPLETED  - indicates that the request is completed 
-   *    successfully.
-   *  ACS_REQUEST_FAILED     - indicates that the request is completed 
-   *    unsuccessfully.
-   *  ACS_REQUEST_TO_DELETE  - indicates that the request is handled and might 
-   *    be deleted.
-   * 
-   *                             /- COMPLETED -\ 
-   * TO_EXECUTE -> IS_RUNNING ->|               |-> TO_DELETE
-   *                             \- FAILED    -/
-   */
-  
-  /**
-   * Handles successfully completed requests.
-   */
-  void handleCompletedRequests();
-  
-  /**
-   * Handles failed requests.
-   */
-  void handleFailedRequests();
-  
-  /**
-   * Performs cleanup for deleted requests.
-   */
-  void handleToDeleteRequests();
-  
-  /**
-   * Performs general checks for the incoming requests and calls next checker 
-   * for the message. Throws exceptions if checks are not passed.
-   * 
-   * @param address ZMQ message with client address.
-   * @param empty   ZMQ empty message.
-   * @param rqst    ZMQ message with CTA frame.
-   * @param socket  ZMQ socket to use.
-   */
-
-   void checkAndAddRequest(mediachanger::ZmqMsg &address,
-    mediachanger::ZmqMsg &empty,
-    const mediachanger:: Frame &rqst,
-    mediachanger::ZmqSocketST &socket);
-  
-/**
-   * Performs dismount specific checks for the incoming request and add it to 
-   * the list of the request to be handled.
-   * 
-   * @param address ZMQ message with client address.
-   * @param empty   ZMQ empty message.
-   * @param rqst    ZMQ message with CTA frame.
-   * @param socket  ZMQ socket to use.
-   */
-  void checkAndAddRequestDismountTape(mediachanger::ZmqMsg &address,
-    mediachanger::ZmqMsg &empty,
-    const mediachanger::Frame &rqst,
-    mediachanger::ZmqSocketST &socket);
-  
-  /**
-   * Find and return free sequence number for the ACS request.
-   * 
-   * @return The value of free sequence number for the ACS request. Throws
-   * exception if the is no free sequence number.
-   */
-  SEQ_NO getSequenceNumber() const;
-
-  /**
-   * Sets the type of the response and the response message in the ACS request
-   * with the sequence number equal response sequence number.
-   * 
-   * @param responseSeqNumber The sequence number to find ongoing ACS request.
-   * @param responseType The type of the response message.
-   * @param responseMsg  The response message
-   */ 
-   void setRequestResponse(const SEQ_NO responseSeqNumber,
-   const ACS_RESPONSE_TYPE responseType, 
-   const  ALIGNED_BYTES *const responseMsg);
-    
-  /**
-   * Performs checks for the request before adding it to the ACS requests list.
-   * Throws exceptions if there are any problems.
-   * 
-   * @param vid     The vid of the ACS request.
-   * @param acs     The acs value of the ACS request.
-   * @param lsm     The lsm value of the ACS request.
-   * @param panel   The panel value of the ACS request.
-   * @param drive   The drive value of the ACS request.
-   */ 
-  void checkRequest(const std::string &vid, const uint32_t acs, 
-    const uint32_t lsm, const uint32_t panel, const uint32_t drive) const ;
-  
-private:
-
-  /**
-   * The object representing cta configuration parameters for 
-   * the CTA ACS daemon.
-   */
-  const AcsdConfiguration m_ctaConf;
-  
-  log::Logger &m_log;
-  /**
-   * Type for the list of the ACS requests.
-   */
-  typedef std::list<AcsRequest *> RequestList;
-  
-  /**
-   * The list for the ACS requests.
-   */
-  RequestList m_acsRequestList;
-  
-  /**
-   * The ACLS C-API wrapper.
-   */  
-  AcsImpl m_acs;
-  
-  /**
-   * The time when the last ACS response command was used.
-   */ 
-  time_t m_lastTimeResponseUsed;
-  
-}; // class AcsPendingRequests
-
-} // namespace deamon
-} // namepsace acs
-} // namespace mediachanger
-} // namespace cta
diff --git a/mediachanger/acs/daemon/AcsRequest.cpp b/mediachanger/acs/daemon/AcsRequest.cpp
deleted file mode 100644
index cde1dae83e40e8dd2130c2512bbfab52ffca5e98..0000000000000000000000000000000000000000
--- a/mediachanger/acs/daemon/AcsRequest.cpp
+++ /dev/null
@@ -1,283 +0,0 @@
-/*
- * 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 "AcsRequest.hpp"
-#include "mediachanger/messages.hpp"
-#include "mediachanger/ReturnValue.pb.h"
-#include "mediachanger/Exception.pb.h"
-#include "common/utils/utils.hpp"
-
-//-----------------------------------------------------------------------------
-// constructor
-//-----------------------------------------------------------------------------
-cta::mediachanger::acs::daemon::AcsRequest::AcsRequest(cta::mediachanger::ZmqSocketST &socket,
-  cta::mediachanger::ZmqMsg &address,  cta::mediachanger::ZmqMsg &empty,
-  const SEQ_NO seqNo, const std::string vid, const uint32_t acs,
-  const uint32_t lsm, const uint32_t panel, const uint32_t drive):
-  m_seqNo(seqNo), 
-  m_vid(vid), 
-  m_acs(acs), 
-  m_lsm(lsm),
-  m_panel(panel),
-  m_drive(drive), 
-  m_socket(socket),
-  m_identity(utils::hexDump(address.getData(),address.size())),
-  m_isReplaySent(false) {
-    zmq_msg_init_size (&m_addressMsg, address.size());
-    memcpy (zmq_msg_data (&m_addressMsg), (const void*)&address.getZmqMsg(), 
-      address.size());
-
-    zmq_msg_init_size (&m_emptyMsg, empty.size());
-    memcpy (zmq_msg_data (&m_emptyMsg), (const void*)&empty.getZmqMsg(),
-      empty.size());
-}
-
-//-----------------------------------------------------------------------------
-// destructor
-//-----------------------------------------------------------------------------
-cta::mediachanger::acs::daemon::AcsRequest::~AcsRequest() {
-    zmq_msg_close(&m_addressMsg);
-    zmq_msg_close(&m_emptyMsg);  
-}
-
-//-----------------------------------------------------------------------------
-// isToExecute
-//-----------------------------------------------------------------------------
-bool cta::mediachanger::acs::daemon::AcsRequest::isToExecute() const {
-  if (ACS_REQUEST_TO_EXECUTE == m_state) {
-    return true;
-  } else {
-    return false;
-  };
-}
-
-//-----------------------------------------------------------------------------
-// isRunning
-//-----------------------------------------------------------------------------
-bool cta::mediachanger::acs::daemon::AcsRequest::isRunning() const  {
-  if (ACS_REQUEST_IS_RUNNING == m_state) {
-    return true;
-  } else {
-    return false;
-  };
-}
-
-//-----------------------------------------------------------------------------
-// isCompleted
-//-----------------------------------------------------------------------------
-bool cta::mediachanger::acs::daemon::AcsRequest::isCompleted() const {
-  if (ACS_REQUEST_COMPLETED == m_state) {
-    return true;
-  } else {
-    return false;
-  };
-}
-
-//-----------------------------------------------------------------------------
-// isFailed
-//-----------------------------------------------------------------------------
-bool cta::mediachanger::acs::daemon::AcsRequest::isFailed() const  {
-  if (ACS_REQUEST_FAILED == m_state) {
-    return true;
-  } else {
-    return false;
-  };
-}
-
-//-----------------------------------------------------------------------------
-// isToDelete
-//-----------------------------------------------------------------------------
-bool cta::mediachanger::acs::daemon::AcsRequest::isToDelete() const  {
-  if (ACS_REQUEST_TO_DELETE == m_state) {
-    return true;
-  } else {
-    return false;
-  };
-}
-
-//------------------------------------------------------------------------------
-// createReturnValueFrame
-//------------------------------------------------------------------------------
-cta::mediachanger::Frame cta::mediachanger::acs::daemon::AcsRequest::createReturnValueFrame(
-  const int value) {
-  cta::mediachanger::Frame frame;
-
-  frame.header = cta::mediachanger::protoTapePreFillHeader();
-  frame.header.set_msgtype(cta::mediachanger::MSG_TYPE_RETURNVALUE);
-  frame.header.set_bodyhashvalue(
-    cta::mediachanger::computeSHA1Base64(frame.body));
-  frame.header.set_bodysignature("PIPO");
-
-  cta::mediachanger::ReturnValue body;
-  body.set_value(value);
-  frame.serializeProtocolBufferIntoBody(body);
-
-  return frame;
-}
-
-//------------------------------------------------------------------------------
-// createExceptionFrame
-//------------------------------------------------------------------------------
-cta::mediachanger::Frame cta::mediachanger::acs::daemon::AcsRequest::
-  createExceptionFrame(const int code, const std::string& msg) {
-  cta::mediachanger::Frame frame;
-
-  frame.header = cta::mediachanger::protoTapePreFillHeader();
-  frame.header.set_msgtype(mediachanger::MSG_TYPE_EXCEPTION);
-  frame.header.set_bodyhashvalue(mediachanger::computeSHA1Base64(frame.body));
-  frame.header.set_bodysignature("PIPO");
-
-  cta::mediachanger::Exception body;
-  body.set_code(code);
-  body.set_message(msg);
-  frame.serializeProtocolBufferIntoBody(body);
-
-  return frame;
-}
-
-
-//-----------------------------------------------------------------------------
-// sendReplayToClientOnce
-//-----------------------------------------------------------------------------
-void cta::mediachanger::acs::daemon::AcsRequest::sendReplayToClientOnce() {
-  if(m_isReplaySent) {
-    cta::exception::Exception ex;
-    ex.getMessage() << "Failed to send second replay to the client";
-    throw ex;
-  }
-  m_socket.send(&m_addressMsg,ZMQ_SNDMORE);
-  m_socket.send(&m_emptyMsg,ZMQ_SNDMORE);
-
-  //messages::sendFrame(m_socket, m_reply);
-  sendFrame(m_socket, m_reply);
-}
-
-//-----------------------------------------------------------------------------
-// getIdentity
-//-----------------------------------------------------------------------------
-std::string cta::mediachanger::acs::daemon::AcsRequest::getIdentity() const {
-  return m_identity;
-}
-
-//-----------------------------------------------------------------------------
-// str
-//-----------------------------------------------------------------------------
-std::string cta::mediachanger::acs::daemon::AcsRequest::str() const {
-  std::ostringstream oss;
-  oss << "vid=" << m_vid << " acs=" << m_acs << " lsm=" << m_lsm << " panel=" <<
-    m_panel << " drive=" << m_drive << " identity=" << getIdentity();
-  return oss.str();
-}
-
-//------------------------------------------------------------------------------
-// getVid
-//------------------------------------------------------------------------------
-const std::string &cta::mediachanger::acs::daemon::AcsRequest::getVid() const {
-  return m_vid;
-}
-
-//------------------------------------------------------------------------------
-// getAcs
-//------------------------------------------------------------------------------
-uint32_t cta::mediachanger::acs::daemon::AcsRequest::getAcs() const {
-  return m_acs;
-}
-
-//------------------------------------------------------------------------------
-// getLsm
-//------------------------------------------------------------------------------
-uint32_t cta::mediachanger::acs::daemon::AcsRequest::getLsm() const {
-  return m_lsm;
-}
-
-//------------------------------------------------------------------------------
-// getPanel
-//------------------------------------------------------------------------------
-uint32_t cta::mediachanger::acs::daemon::AcsRequest::getPanel() const {
-  return m_panel;
-}
-
-//------------------------------------------------------------------------------
-// getDrive
-//------------------------------------------------------------------------------
-uint32_t cta::mediachanger::acs::daemon::AcsRequest::getDrive() const {
-  return m_drive;
-}
-
-
-//------------------------------------------------------------------------------
-// getSeqNo
-//------------------------------------------------------------------------------
-SEQ_NO cta::mediachanger::acs::daemon::AcsRequest::getSeqNo() const {
-  return m_seqNo; 
-}
-
-//------------------------------------------------------------------------------
-// setResponse
-//------------------------------------------------------------------------------
-void cta::mediachanger::acs::daemon::AcsRequest::setResponse(
-  const ACS_RESPONSE_TYPE responseType, 
-  const ALIGNED_BYTES *const responseMsg) {
-  m_responseType = responseType;
-  memcpy(m_responseMsg,responseMsg,MAX_MESSAGE_SIZE / sizeof(ALIGNED_BYTES));
-}
-
-//------------------------------------------------------------------------------
-// setStateFailed
-//------------------------------------------------------------------------------
-void cta::mediachanger::acs::daemon::AcsRequest::setStateFailed(const int code,
-  const std::string& msg) {
-  m_reply = createExceptionFrame(code, msg);
-  m_state = ACS_REQUEST_FAILED;
-}
-
-//------------------------------------------------------------------------------
-// setStateCompleted
-//------------------------------------------------------------------------------
-void cta::mediachanger::acs::daemon::AcsRequest::setStateCompleted() {
-  m_reply = createReturnValueFrame(0);
-  m_state = ACS_REQUEST_COMPLETED;       
-}
-
-//------------------------------------------------------------------------------
-// setStateIsRunning
-//------------------------------------------------------------------------------
-void cta::mediachanger::acs::daemon::AcsRequest::setStateIsRunning() {
-  if (isToExecute()) {
-    m_state = ACS_REQUEST_IS_RUNNING;
-  } else {
-    cta::exception::Exception ex;
-    ex.getMessage() << "Failed to set request state to running from state="<<
-      m_state;
-    throw ex;
-  }
-}
-
-//------------------------------------------------------------------------------
-// setStateToExecute
-//------------------------------------------------------------------------------
-void cta::mediachanger::acs::daemon::AcsRequest::setStateToExecute() {
-  m_state = ACS_REQUEST_TO_EXECUTE;       
-}
-
-//------------------------------------------------------------------------------
-// setStateToDelete
-//------------------------------------------------------------------------------
-void cta::mediachanger::acs::daemon::AcsRequest::setStateToDelete() {
-  m_state = ACS_REQUEST_TO_DELETE;       
-}
diff --git a/mediachanger/acs/daemon/AcsRequest.hpp b/mediachanger/acs/daemon/AcsRequest.hpp
deleted file mode 100644
index 03bfc88d2fa67876a56b90aeb99cd9c1600b9b9c..0000000000000000000000000000000000000000
--- a/mediachanger/acs/daemon/AcsRequest.hpp
+++ /dev/null
@@ -1,317 +0,0 @@
-/*
- * 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/>.
- */
-
-#pragma once
-
-#include "common/Constants.hpp"
-#include "mediachanger/acs/Constants.hpp"
-#include "mediachanger/messages.hpp"
-#include "mediachanger/ZmqSocket.hpp"
-#include "mediachanger/ZmqSocketST.hpp"
-#include "mediachanger/acs/AcsImpl.hpp"
-#include "common/exception/Exception.hpp"
-#include <time.h>
-
-namespace cta     {
-namespace mediachanger        {
-namespace acs     {
-namespace daemon	{
-  
-  
-/**
- * Abstract class defining the ACS request presentation to be used in the list
- * of pending ACS requests.
- */
-class AcsRequest {
-public:
-  
-  /**
-   * Constructor.
-   * 
-   * @param socket  ZMQ socket to use.
-   * @param address ZMQ message with client address.
-   * @param empty   ZMQ empty message.
-   * @param seqNo   Sequence number for the ACS request.
-   * @param vid     The vid of the ACS request.
-   * @param acs     The acs value of the ACS request.
-   * @param lsm     The lsm value of the ACS request.
-   * @param panel   The panel value of the ACS request.
-   * @param drive   The drive value of the ACS request.
-   */
-  AcsRequest(ZmqSocketST &socket, ZmqMsg &address,
-    ZmqMsg &empty, const SEQ_NO seqNo,
-    const std::string vid, const uint32_t acs,
-    const uint32_t lsm, const uint32_t panel, const uint32_t drive);
-  
-  /**
-   * Destructor.
-   */
-  virtual ~AcsRequest() = 0;
-
-  /**
-   * Perform any time related actions with the request to CTA ACS daemon.
-   *
-   * This method does not have to be called at any time precise interval.
-   */
-  virtual void tick() = 0;
-  
-  /**
-   * Checks if the ACS request is in to be executed state.
-   * 
-   * @return true if the ACS request in state to Execute.
-   */  
-  bool isToExecute() const;  
-  
-  /**
-   * Sets state of the ACS request to be executed.
-   */
-  void setStateToExecute();
-  
-  /**
-   * Checks if the ACS request is in running state.
-   * 
-   * @return true if the ACS request is in running state.
-   */  
-  bool isRunning() const;
-  
-  /**
-   * Sets state of the ACS request to running.
-   */
-  void setStateIsRunning();
-  
-  /**
-   * Checks if the ACS request is in completed state.
-   * 
-   * @return true if the ACS request is in completed state.
-   */  
-  bool isCompleted() const;
-  
-  /**
-   * Sets state of the ACS request to completed and fills ZMQ replay frame with 
-   * good status 0.
-   */
-  void setStateCompleted();
-  
-  /**
-   * Checks if the ACS request is in failed state.
-   * 
-   * @return true if the ACS request is in failed state.
-   */  
-  bool isFailed() const;
-  
-  /**
-   * Sets state of the ACS request to failed and fills ZMQ replay frame with
-   * exception data.
-   */
-  void setStateFailed(const int code,const std::string& msg);
-  
-  /**
-   * Checks if the ACS request is in to delete state.
-   * 
-   * @return true if the ACS request is in to delete state.
-   */  
-  bool isToDelete() const;
-  
-  /**
-   * Sets state of the ACS request to be deleted.
-   */
-  void setStateToDelete();
-
-  /**
-   * Gets the vid component of the ACS request.
-   *
-   * @return the vid component of the ACS request.
-   */
-  const std::string &getVid() const;
-  
-  /**
-   * Gets the acs component of the ACS request.
-   *
-   * @return the acs component of the ACS request.
-   */
-  uint32_t getAcs() const;
-
-  /**
-   * Gets the lsm component of the ACS request.
-   *
-   * @return the lsm component of the ACS request.
-   */
-  uint32_t getLsm() const;
-
-  /**
-   * Gets the panel component of the ACS request.
-   *
-   * @return the panel component of the ACS request.
-   */
-  uint32_t getPanel() const;
-
-  /**
-   * Gets the drive component of the ACS request.
-   *
-   * @return the drive component of the ACS request.
-   */
-  uint32_t getDrive() const;
-  
-  /**
-   * Gets the SeqNumber component of the ACS request.
-   *
-   * @return the SeqNo component of the ACS request.
-   */
-  SEQ_NO getSeqNo() const;
-  
-  /**
-   * Sets the fields of the response message of the ACS response request.
-   * 
-   * @param responseType The type of the response message.
-   * @param responseMsg  The response message.
-   */
-  void setResponse(const ACS_RESPONSE_TYPE responseType,
-    const ALIGNED_BYTES *const responseMsg);
-  
-  /**
-   * Send a replay to the client who issued the ACS request.
-   */
-  void sendReplayToClientOnce();
-  
-  /**
-   * Returns string presentation for the connection identity with the client.
-   * 
-   * @return The connection Identity.
-   */
-  std::string getIdentity() const;
-  
-  /**
-   * Returns a string representing ACS request.
-   * 
-   * @return The value of string presentation for the request 
-   */
-  std::string str() const;
-  
-  /**
-   * Abstract method to be implemented in concrete implementation. Checks 
-   * the status of the response from the response message buffer and the type of
-   * the response. Throws exception if the type of the response is RT_FINAL but
-   * the status is not success.
-   * 
-   * @return true if the type of response RT_FINAL and the response status 
-   *         is STATUS_SUCCESS.
-   */
-  virtual bool isResponseFinalAndSuccess() const = 0; 
-   
-private:
-
-  /**
-   * Creates a message frame containing a ReturnValue message.
-   *
-   * @param value The return value of the ReturnValue message.
-   * @return The message frame.
-   */
-  //cta::messages::Frame createReturnValueFrame(const int value);
-  Frame createReturnValueFrame(const int value);
-  
-  /**
-   * Creates a message frame containing an Exception message.
-   *
-   * @param code The error code of the exception.
-   * @param msg The message string of the exception.
-   */
-  Frame createExceptionFrame(const int code, 
-    const std::string& msg);
-  
-  /**
-   * Request sequence number of the ACS request.
-   */
-  const SEQ_NO m_seqNo;
-  
-  /**
-   * The vid component of the ACS request.
-   */
-  const std::string m_vid;
-
-  /**
-   * The acs component of the ACS request.
-   */
-  const uint32_t m_acs;
-  
-  /**
-   * The lsm component of the ACS request.
-   */
-  const uint32_t m_lsm;
-  
-  /**
-   * The panel component of the ACS request.
-   */
-  const uint32_t m_panel;
-  
-  /**
-   * The drive component of the ACS request.
-   */
-  const uint32_t m_drive;
-  
-  /**
-   * Internal state of the ACS request.
-   */  
-  RequestState m_state ; 
-  
-  /**
-   * Replay ZMQ frame for the client.
-   */
-  Frame m_reply;
-    
-  /**
-   * The ZMQ socket listening for messages.
-   */
-  ZmqSocketST &m_socket;
-  
-  /**
-   * Client identity for logging.
-   */  
-  const std::string m_identity;
-  
-  /**
-   * ZMQ address message for the client.
-   */
-  zmq_msg_t m_addressMsg;
-  
-  /**
-   * ZMQ empty message for the client.
-   */
-  zmq_msg_t m_emptyMsg;
-  
-  /**
-   * Store is the replay to the client has been sent or not.
-   */
-  bool m_isReplaySent;
-  
-protected:  
-  /**
-   * The type of the response message associated with the ACS request.
-   */
-  ACS_RESPONSE_TYPE m_responseType;
-  
-  /**
-   * The response message associated with the ACS request.
-   */
-  ALIGNED_BYTES m_responseMsg[MAX_MESSAGE_SIZE / sizeof(ALIGNED_BYTES)];
-  
-}; // class AcsRequest
-
-} // namepsace daemon
-} // namespace acs
-} // namespace mediachanger
-} // namespace cta
diff --git a/mediachanger/acs/daemon/AcsRequestDismountTape.cpp b/mediachanger/acs/daemon/AcsRequestDismountTape.cpp
deleted file mode 100644
index 74ed0fa0a952acb49bc121fc81033c3d43c69576..0000000000000000000000000000000000000000
--- a/mediachanger/acs/daemon/AcsRequestDismountTape.cpp
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * 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 "AcsRequestDismountTape.hpp"
-#include "common/exception/DismountFailed.hpp"
-#include "common/log/log.hpp"
-
-//-----------------------------------------------------------------------------
-// constructor 
-//-----------------------------------------------------------------------------
-cta::mediachanger::acs::daemon::AcsRequestDismountTape::AcsRequestDismountTape(
-  const std::string &vid, const uint32_t acs,
-  const uint32_t lsm, const uint32_t panel, const uint32_t drive, 
-  const AcsdConfiguration &ctaConf,
-  mediachanger::ZmqSocketST &socket,
-  mediachanger::ZmqMsg &address,
-  mediachanger::ZmqMsg &empty,
-  log::Logger &log,
-  const SEQ_NO seqNo): 
-  AcsRequest(socket, address, empty, seqNo, vid, acs, lsm, panel, drive),
-  m_ctaConf(ctaConf),
-  m_acsDismountTape(vid, acs, lsm, panel, drive, m_acs, log, ctaConf),
-  m_lastTimeLibraryQueried(0),
-  m_log(log),
-  m_timeAcsCommandStarted(0) {  
-}
-
-//-----------------------------------------------------------------------------
-// tick 
-//-----------------------------------------------------------------------------
-void cta::mediachanger::acs::daemon::AcsRequestDismountTape::tick() {
-  try {
-    if (isToExecute()) {
-      m_log(LOG_DEBUG,"AcsRequestDismountTape::tick isToExecute");
-      m_acsDismountTape.asyncExecute(getSeqNo());
-      setStateIsRunning();  
-      m_timeAcsCommandStarted = time(0);
-    }  
-
-    const time_t now = time(0);
-    
-    const time_t secsSinceLastQuery = now -  m_lastTimeLibraryQueried;
-    const bool firstQueryOrTimeExceeded = (unsigned int)secsSinceLastQuery > 
-      m_ctaConf.QueryInterval.value();
-    
-    if(isRunning() && firstQueryOrTimeExceeded) {      
-      if(isResponseFinalAndSuccess()) {
-        setStateCompleted();
-        m_log(LOG_DEBUG,
-         "AcsRequestDismountTape::tick ACS_REQUEST_COMPLETED");
-      } else {
-        m_log(LOG_DEBUG,"AcsRequestDismountTape::tick "
-          "firstQueryOrTimeExceeded()");
-        m_lastTimeLibraryQueried = time(0);
-      }        
-    }
-    
-    const time_t secsSinceCommandStarted = now -  m_timeAcsCommandStarted;
-    const bool acsCommandTimeExceeded = (unsigned int)secsSinceCommandStarted >
-      m_ctaConf.CmdTimeout.value();
-    
-    if(isRunning() && acsCommandTimeExceeded) {
-      cta::exception::RequestFailed ex;
-      ex.getMessage() << "ACS command timed out after " << 
-        secsSinceCommandStarted << " seconds";
-      throw ex;
-    }
-  } catch (cta::exception::Exception &ex) {
-   setStateFailed(ECANCELED, ex.getMessage().str());
-    m_log(LOG_ERR,"Failed to handle the ACS dismount tape request: "
-      + ex.getMessage().str());
-  } catch(std::exception &se) {
-    setStateFailed(ECANCELED, se.what());
-    m_log(LOG_ERR, se.what());
-  } catch(...) {
-    setStateFailed(ECANCELED, "Caught an unknown exception");
-    m_log(LOG_ERR, "Caught an unknown exception");
-  }    
-}
-
-//------------------------------------------------------------------------------
-// isResponseFinalAndSuccess
-//------------------------------------------------------------------------------
-bool cta::mediachanger::acs::daemon::AcsRequestDismountTape::isResponseFinalAndSuccess() const  {
-  if (RT_FINAL == m_responseType ) {
-    const ACS_DISMOUNT_RESPONSE *const msg = 
-      (ACS_DISMOUNT_RESPONSE *)m_responseMsg;
-    if(STATUS_SUCCESS != msg->dismount_status) {
-      cta::exception::DismountFailed ex;
-      ex.getMessage() << "Status of dismount response is not success: " <<
-        acs_status(msg->dismount_status);
-      throw ex;
-    }    
-    return true;
-  }
-  return false;  
-}
diff --git a/mediachanger/acs/daemon/AcsRequestDismountTape.hpp b/mediachanger/acs/daemon/AcsRequestDismountTape.hpp
deleted file mode 100644
index 7ec284f6e473901e32fc4d555efdb94ca7c9cbf0..0000000000000000000000000000000000000000
--- a/mediachanger/acs/daemon/AcsRequestDismountTape.hpp
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * 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/>.
- */
-
-#pragma once
-
-#include "mediachanger/acs/daemon/AcsdConfiguration.hpp"
-#include "mediachanger/acs/daemon/AcsDismountTape.hpp"
-#include "mediachanger/acs/AcsImpl.hpp"
-#include "mediachanger/acs/daemon/AcsRequest.hpp"
-
-namespace cta     {
-namespace mediachanger     {
-namespace acs        {
-namespace daemon       {
-/**
- * Concrete class providing a dismount tape implementation of an AcsRequest 
- * abstract class.
- */
-class AcsRequestDismountTape: public AcsRequest {
-public:
-
-  /**
-   * Constructor.
-   * 
-   * @param vid     The vid of the ACS request.
-   * @param acs     The acs value of the ACS request.
-   * @param lsm     The lsm value of the ACS request.
-   * @param panel   The panel value of the ACS request.
-   * @param drive   The drive value of the ACS request.
-   * @param ctaConf The configuration for the CTA ACS daemon.
-   * @param socket  ZMQ socket to use.
-   * @param address ZMQ message with client address.
-   * @param empty   ZMQ empty message.
-   * @param seqNo   Sequence number for the ACS request.
-   */
-  AcsRequestDismountTape(
-    const std::string &vid, 
-    const uint32_t acs,
-    const uint32_t lsm,
-    const uint32_t panel, 
-    const uint32_t drive,
-    const AcsdConfiguration &ctaConf,
-    mediachanger::ZmqSocketST &socket,
-    mediachanger::ZmqMsg &address,
-    mediachanger::ZmqMsg &empty,
-    cta::log::Logger& log,
-    const SEQ_NO seqNo);
-  
-  /**
-   * Perform any time related actions with the request to CTA ACS daemon.
-   *
-   * This method does not have to be called at any time precise interval.
-   */
-  void tick();
- 
-  /**
-   * Checks the status of the response from the dismount response message buffer
-   * and the type of the response. Throws exception if the type of the response 
-   * is RT_FINAL but the status is not success.
-   * 
-   * @return true if the type of response RT_FINAL and the response status 
-   *         is STATUS_SUCCESS.
-   */
-  bool isResponseFinalAndSuccess() const;
- 
-private:
-  
-  /**
-   * The CTA configuration parameters for the CTA ACS daemon.
-   */
-  const AcsdConfiguration m_ctaConf;
-  
-  /**
-   * The object representing the class for tape dismount through ACS API.
-   */
-  AcsDismountTape m_acsDismountTape;
-  
-  /**
-   * The ACLS C-API wrapper.
-   */  
-  AcsImpl m_acs;
-  
-  /**
-   * The time when the ACS library queried last time.
-   */  
-  time_t m_lastTimeLibraryQueried;
-  
-  cta::log::Logger &m_log;
-  /**
-   * The time at which ACS command was started.
-   */
-  time_t m_timeAcsCommandStarted;
-  
-}; // class AcsRequestDismountTape
-} // namespace daemon
-} // namespace acs
-} // namespace mediachanger
-} // namespace cta
diff --git a/mediachanger/acs/daemon/AcsdCmdLine.cpp b/mediachanger/acs/daemon/AcsdCmdLine.cpp
deleted file mode 100644
index c55e5484f9f2e31619b800474bad572b456bb605..0000000000000000000000000000000000000000
--- a/mediachanger/acs/daemon/AcsdCmdLine.cpp
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
- * 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 "AcsdCmdLine.hpp"
-#include "common/exception/Exception.hpp"
-#include "common/log/log.hpp"
-#include <iostream>
-#include <getopt.h>
-
-namespace cta {
-namespace mediachanger {
-namespace acs {
-namespace daemon {
-
-//-----------------------------------------------------------------------------
-// constructor
-//-----------------------------------------------------------------------------
-AcsdCmdLine::AcsdCmdLine():
-  foreground(false),                                     
-  help(false),
-  readOnly(false) {
-}
-
-//so instead 
-//use the factory pattern that makes an instance of that class together with the arguments wanted passed but not a constryuctor by itself
-
-AcsdCmdLine AcsdCmdLine::parse(const int argc, char *const *const argv) {
-  AcsdCmdLine cmdline;
-
-  struct option longopts[] = {
-    // { .name, .has_args, .flag, .val } (see getopt.h))
-    { "foreground", no_argument, NULL, 'f' },
-    { "help", no_argument, NULL, 'h' },
-    { "config", required_argument, NULL, 'c' },
-    { "readOnly" , no_argument, NULL, 'r'},
-    { NULL, 0, NULL, '\0' }
-  };
-
-  char c;
-  // Reset getopt's global variables to make sure we start fresh
-  optind=0;
-  // Prevent getopt from printing out errors on stdout
-  opterr=0;
-  // We ask getopt to not reshuffle argv ('+')
-  while ((c = getopt_long(argc, argv, ":fhc:r", longopts, NULL)) != -1) {
-     //log:write(LOG_INFO, "Usage: [options]\n");
-   switch (c) {
-   case 'r':
-     cmdline.readOnly = true;
-     break;
-   case 'f':
-     cmdline.foreground = true;
-     break;
-   case 'c':
-     cmdline.configLocation = optarg;
-     break;
-   case 'h':
-     cmdline.help = true;
-     break;
-   case ':':
-     throw exception::Exception(std::string("Incorrect command-line arguments: The -") + (char)optopt +
-       " option is missing an argument\n\n" + getUsage());
-   case '?':
-     throw exception::Exception(std::string("Incorrect command-line arguments: Unknown option\n\n") + getUsage());
-   default:
-     throw exception::Exception(std::string("Incorrect command-line arguments\n\n") + getUsage());
-   }
-  }
-
-
-  const int expectedNbNonOptionalArgs = 0;
-  const int nbNonOptionalArgs = argc - optind;
-
-  // Check for empty string arguments
-  // These might have been passed in by systemd
-  for(int i = optind; i < argc; i++) {
-    if(std::string(argv[i]).empty()) {
-      exception::Exception ex;
-        ex.getMessage() << "Incorrect command-line arguments: Encountered an empty string argument at argv[" << i
-          << "]\n\n" << getUsage();
-      throw ex;
-    }
-  }
-
-  if (expectedNbNonOptionalArgs != nbNonOptionalArgs) {
-     exception::Exception ex;
-     ex.getMessage() << "Incorrect command-line arguments: Incorrect number of non-optional arguments: expected=" <<
-       expectedNbNonOptionalArgs << ",actual=" << nbNonOptionalArgs << "\n\n" << getUsage();
-     throw ex;
-  }
-
-  return cmdline;
-}
-
-//------------------------------------------------------------------------------
-// getUsage
-//------------------------------------------------------------------------------
-std::string AcsdCmdLine::getUsage() {
-  std::ostringstream usage;
-  usage <<
-    "Usage:\n"
-    "  cta-acsd [options]\n"
-    "\n"
-    "Where:\n"
-    "\n"
-    "Options:\n"
-    "\n"
-    "--foreground            or -f         Remain in the Foreground\n"
-    "--readOnly              or -r         Request the volume is mounted for read-only access\n"
-    "--config <config-file>  or -c         Configuration file\n"
-    "--help                  or -h         Print this help and exit\n"
-    "\n"
-    "Comments to CTA team\n";
-  return usage.str();
-}
-
-} // namespace daemon
-} // namespace acs
-} // namespace mediachanger
-} // namespace cta
diff --git a/mediachanger/acs/daemon/AcsdCmdLine.hpp b/mediachanger/acs/daemon/AcsdCmdLine.hpp
deleted file mode 100644
index e43801a21c2d68c2733a00a524c7389b26195ba5..0000000000000000000000000000000000000000
--- a/mediachanger/acs/daemon/AcsdCmdLine.hpp
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * 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/>.
- */
-
-#pragma once
-
-#include "mediachanger/CmdLine.hpp"
-#include <string.h>
-
-namespace cta{
-namespace mediachanger{
-namespace acs{
-namespace daemon{
-
-struct AcsdCmdLine {
-
-  bool foreground;
-
-  bool help;
- 
-  std::string configLocation;
- 
-  /**
-   * True if the tape is to be mount for read-only access.
-   */
-  bool readOnly;
-
-  /**
-   * Constructor.
-   *
-   * Initialises all BOOLEAN member-variables to FALSE, all integer
-   * member-variables to 0 and the volume identifier to an empty string.
-   */
-  AcsdCmdLine();
-
-  /**
-   * Constructor.
-   *
-   * Parses the specified command-line arguments.
-   *
-   * @param argc Argument count from the executable's entry function: main().
-   * @param argv Argument vector from the executable's entry function: main().
-   */
-  static AcsdCmdLine parse(const int argc, char *const *const argv);
-
-  /**
-   * Gets the usage message that describes the comamnd line.
-   *
-   * @return The usage message.
-   */
-  static std::string getUsage();
-
-};
-
-}
-}
-}
-}
-
diff --git a/mediachanger/acs/daemon/AcsdCmdLineTest.cpp b/mediachanger/acs/daemon/AcsdCmdLineTest.cpp
deleted file mode 100644
index 2f116f138efa426cb246d29ff1459c420e12bf02..0000000000000000000000000000000000000000
--- a/mediachanger/acs/daemon/AcsdCmdLineTest.cpp
+++ /dev/null
@@ -1,156 +0,0 @@
-/*
- * 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 "common/exception/Exception.hpp"
-#include "mediachanger/acs/daemon/AcsdCmdLine.hpp"
-#include <gtest/gtest.h>
-#include <list>
-#include <memory>
-
-namespace unitTests {
-
-class cta_mediachanger_acs_daemon_AcsdCmdLineTest : public ::testing::Test {
-protected:
-
-  struct Argcv {
-    int argc;
-    char **argv;
-    Argcv(): argc(0), argv(NULL) {
-    }
-  };
-  typedef std::list<Argcv*> ArgcvList;
-  ArgcvList m_argsList;
-
-  /**
-   * Creates a duplicate string using the new operator.
-   */
-  char *dupString(const char *str) {
-    const size_t len = strlen(str);
-    char *duplicate = new char[len+1];
-    strncpy(duplicate, str, len);
-    duplicate[len] = '\0';
-    return duplicate;
-  }
-
-  virtual void SetUp() {
-  }
-
-  virtual void TearDown() {
-    // Allow getopt_long to be called again
-    optind = 0;
-
-    for(ArgcvList::const_iterator itor = m_argsList.begin();
-      itor != m_argsList.end(); itor++) {
-      for(int i=0; i < (*itor)->argc; i++) {
-        delete[] (*itor)->argv[i];
-      }
-      delete[] (*itor)->argv;
-      delete *itor;
-    }
-  }
-};
-
-
-TEST_F(cta_mediachanger_acs_daemon_AcsdCmdLineTest, constructor_no_command_line_args) {
-  using namespace cta::mediachanger::acs::daemon;
-
-  Argcv *args = new Argcv();
-  m_argsList.push_back(args);
-  args->argc = 1;
-  args->argv = new char *[2];
-  args->argv[0] = dupString("cta-acsd");
-  args->argv[1] = NULL;
-  const auto acsdcmdLine = AcsdCmdLine::parse(args->argc, args->argv);
- 
-  ASSERT_FALSE(acsdcmdLine.foreground);
-  ASSERT_TRUE(acsdcmdLine.configLocation.empty());
-  ASSERT_FALSE(acsdcmdLine.help);
-}
-
-TEST_F(cta_mediachanger_acs_daemon_AcsdCmdLineTest, default_constructor) {
-  using namespace cta::mediachanger::acs::daemon;
-
-  Argcv *args = new Argcv();
-  m_argsList.push_back(args);
-  args->argc = 0;
-  const auto acsdcmdLine = AcsdCmdLine::parse(args->argc, args->argv);
- 
-  ASSERT_FALSE(acsdcmdLine.foreground);
-  ASSERT_TRUE(acsdcmdLine.configLocation.empty());
-  ASSERT_FALSE(acsdcmdLine.help);
-}
-
-TEST_F(cta_mediachanger_acs_daemon_AcsdCmdLineTest, constructor_foreground) {
-  using namespace cta::mediachanger::acs::daemon;
-
-  Argcv *args = new Argcv();
-  m_argsList.push_back(args);
-  args->argc = 2;
-  args->argv = new char *[3];
-  args->argv[0] = dupString("cta-acsd");
-  args->argv[1] = dupString("-f");
-  args->argv[2] = NULL;
-  const auto acsdcmdLine = AcsdCmdLine::parse(args->argc, args->argv);
- 
-  ASSERT_TRUE(acsdcmdLine.foreground);
-}
-
-TEST_F(cta_mediachanger_acs_daemon_AcsdCmdLineTest, constructor_help) {
-  using namespace cta::mediachanger::acs::daemon;
-
-  Argcv *args = new Argcv();
-  m_argsList.push_back(args);
-  args->argc = 2;
-  args->argv = new char *[3];
-  args->argv[0] = dupString("cta-acsd");
-  args->argv[1] = dupString("-h");
-  args->argv[2] = NULL;
-  const auto acsdcmdLine = AcsdCmdLine::parse(args->argc, args->argv);
-  ASSERT_TRUE(acsdcmdLine.help);
-}
-
-TEST_F(cta_mediachanger_acs_daemon_AcsdCmdLineTest, constructor_configLocation) {
-  using namespace cta::mediachanger::acs::daemon;
-
-  Argcv *args = new Argcv();
-  m_argsList.push_back(args);
-  args->argc = 3;
-  args->argv = new char *[4];
-  args->argv[0] = dupString("cta-acsd");
-  args->argv[1] = dupString("-c");
-  args->argv[2] = dupString("");
-  args->argv[3] = NULL;
-  const auto acsdcmdLine = AcsdCmdLine::parse(args->argc, args->argv);
-  ASSERT_EQ(acsdcmdLine.configLocation,"");
-}
-
-TEST_F(cta_mediachanger_acs_daemon_AcsdCmdLineTest, constructor_readOnly) {
-  using namespace cta::mediachanger::acs::daemon;
-
-  Argcv *args = new Argcv();
-  m_argsList.push_back(args);
-  args->argc = 2;
-  args->argv = new char *[3];
-  args->argv[0] = dupString("cta-acsd");
-  args->argv[1] = dupString("-r");
-  args->argv[2] = NULL;
-  const auto acsdcmdLine = AcsdCmdLine::parse(args->argc, args->argv);
-  ASSERT_TRUE(acsdcmdLine.readOnly);
-}
-
-} // namespace unitTests
diff --git a/mediachanger/acs/daemon/AcsdConfiguration.cpp b/mediachanger/acs/daemon/AcsdConfiguration.cpp
deleted file mode 100644
index b5d5b42117a7a5d2f21db124c24d14aab5edd8c2..0000000000000000000000000000000000000000
--- a/mediachanger/acs/daemon/AcsdConfiguration.cpp
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * 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 "AcsdConfiguration.hpp"
-#include "common/ConfigurationFile.hpp"
-#include "Tpconfig.hpp"
-#include <time.h>
-
-
-//------------------------------------------------------------------------------
-// GlobalConfiguration::createFromCtaConf w path
-//------------------------------------------------------------------------------
-cta::mediachanger::acs::daemon::AcsdConfiguration cta::mediachanger::acs::daemon::AcsdConfiguration::createFromCtaConf(
-  const std::string& generalConfigPath, cta::log::Logger& log) {
-  AcsdConfiguration ret;
-  // Parse config file
-  ConfigurationFile cf(generalConfigPath);
-  // Extract configuration from parsed config file TpConfig
-  ret.port.setFromConfigurationFile(cf, generalConfigPath);
-  ret.QueryInterval.setFromConfigurationFile(cf, generalConfigPath);
-  ret.CmdTimeout.setFromConfigurationFile(cf, generalConfigPath);
-  ret.daemonUserName.setFromConfigurationFile(cf, generalConfigPath);
-  ret.daemonGroupName.setFromConfigurationFile(cf, generalConfigPath);
-
-  // If we get here, the configuration file is good enough to be logged.
-  ret.port.log(log);
-  ret.QueryInterval.log(log);
-  ret.CmdTimeout.log(log);
-  ret.daemonUserName.log(log);
-  ret.daemonGroupName.log(log);
-  
-  return ret;
-}
-
-//------------------------------------------------------------------------------
-// GlobalConfiguration::gDummyLogger (static member)
-//------------------------------------------------------------------------------
-cta::log::DummyLogger cta::mediachanger::acs::daemon::AcsdConfiguration::gDummyLogger("","");
-
diff --git a/mediachanger/acs/daemon/AcsdConfiguration.hpp b/mediachanger/acs/daemon/AcsdConfiguration.hpp
deleted file mode 100644
index 61f70f714e299bd7ee059aef75e11e454a5b3233..0000000000000000000000000000000000000000
--- a/mediachanger/acs/daemon/AcsdConfiguration.hpp
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * 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/>.
- */
-
-#pragma once
-#include <string>
-#include <map>
-#include <type_traits>
-#include <limits>
-#include "common/log/DummyLogger.hpp"
-#include "common/exception/Exception.hpp"
-#include "common/SourcedParameter.hpp"
-#include "Tpconfig.hpp"
-#include "mediachanger/acs/Constants.hpp"
-#include "common/ConfigurationFile.hpp"
-
-#include <time.h>
-
-namespace cta {
-namespace mediachanger { 
-namespace acs	{
-namespace daemon {
-/**
- * Class containing all the parameters needed by the watchdog process
- * to spawn a transfer session per drive.
- */
-struct AcsdConfiguration {
-  static AcsdConfiguration createFromCtaConf(
-          const std::string & generalConfigPath,
-          cta::log::Logger & log = gDummyLogger);
- 
-  SourcedParameter<uint64_t> port{
-    "acsd", "Port", (uint64_t)ACS_PORT, "Compile time default"};
-  SourcedParameter<uint64_t> QueryInterval{ 
-    "acsd", "QueryInterval", (long unsigned int)ACS_QUERY_INTERVAL, "Compile time default"};
-  SourcedParameter<uint64_t> CmdTimeout{
-    "acsd", "CmdTimeout",(long unsigned int) ACS_CMD_TIMEOUT, "Compile time default"};
-  SourcedParameter<std::string> daemonUserName{
-    "acsd", "DaemonUserName", "cta", "Compile time default"};
-  SourcedParameter<std::string> daemonGroupName{
-    "acsd", "DaemonGroupName", "tape", "Compile time default"};
-private:
-  /** A private dummy logger which will simplify the implementation of the 
-   * functions (just unconditionally log things). */
-  static cta::log::DummyLogger gDummyLogger;
-} ;
-} // namespace daemon
-} // namespace acs
-} // namespace mediachanger
-} // namespace cta
diff --git a/mediachanger/acs/daemon/CMakeLists.txt b/mediachanger/acs/daemon/CMakeLists.txt
deleted file mode 100644
index 814accaca1a43abc17e47203afba65552d533737..0000000000000000000000000000000000000000
--- a/mediachanger/acs/daemon/CMakeLists.txt
+++ /dev/null
@@ -1,62 +0,0 @@
-cmake_minimum_required (VERSION 2.6)
-
-find_package(Protobuf3 REQUIRED)
-find_package(openssl REQUIRED)
-find_package(zeromq REQUIRED)
-
-include_directories (${PROTOBUF3_INCLUDE_DIRS})
-
-
-PROTOBUF3_GENERATE_CPP(WDMsgSources WDMsgHeaders WatchdogMessage.proto)
-
-SET_SOURCE_FILES_PROPERTIES(${WDMsgHeaders} PROPERTIES HEADER_FILE_ONLY TRUE)
-
-
-set (ACS_DAEMON_SRC_FILES
-  AcsDaemon.cpp
-  AcsDaemonMain.cpp
-  AcsdConfiguration.cpp
-  AcsRequest.cpp
-  AcsPendingRequests.cpp
-  AcsdCmdLine.cpp
-  AcsDismountTape.cpp
-  AcsMessageHandler.cpp
-  AcsMountTapeReadWrite.cpp 
-  AcsMountTapeReadOnly.cpp
-  AcsForceDismountTape.cpp
-  Constants.cpp
-  AcsRequestDismountTape.cpp
-)
-add_executable (cta-acsd ${ACS_DAEMON_SRC_FILES})
-
-set_target_properties (cta-acsd PROPERTIES
-  COMPILE_FLAGS -I/usr/include/CDK
-  COMPILE_DEFINITIONS LINUX)
-
-target_link_libraries(
-  cta-acsd
-  ctacommon
-  ctareactor 
-  cta-acs
-  ctamediachanger 
-  zmq
-  ${STK_LIBRARIES})
-
-set_property (TARGET cta-acsd APPEND PROPERTY INSTALL_RPATH ${PROTOBUF3_RPATH})
-
-install (FILES cta-acsd.conf DESTINATION ${CMAKE_INSTALL_SYSCONFDIR}/cta)
-install (TARGETS cta-acsd DESTINATION /usr/bin)
-install (FILES cta-acsd.logrotate DESTINATION /etc/logrotate.d RENAME cta-acsd)
-install (FILES cta-acsd.service DESTINATION /etc/systemd/system)
-
-add_library (ctamediachangeracsdaemonunittests SHARED AcsdCmdLineTest.cpp AcsdCmdLine.cpp)
-set_property(TARGET ctamediachangeracsdaemonunittests PROPERTY SOVERSION "${CTA_SOVERSION}")
-set_property(TARGET ctamediachangeracsdaemonunittests PROPERTY   VERSION "${CTA_LIBVERSION}")
-
-target_link_libraries (ctamediachangeracsdaemonunittests
- ctamediachangerunittests)
-
-install (TARGETS ctamediachangeracsdaemonunittests DESTINATION usr/${CMAKE_INSTALL_LIBDIR})
-
-
-
diff --git a/mediachanger/acs/daemon/Constants.cpp b/mediachanger/acs/daemon/Constants.cpp
deleted file mode 100644
index cc522d158afd519eadfe5d42969c2c2149fdcdec..0000000000000000000000000000000000000000
--- a/mediachanger/acs/daemon/Constants.cpp
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * 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 "Constants.hpp"
-
-//------------------------------------------------------------------------------
-// msgTypeToString
-//------------------------------------------------------------------------------
-const char *cta::mediachanger::acs::daemon::msgTypeToString(const cta::mediachanger::acs::daemon::MsgType msgType) {
-  switch(msgType) {
-  case MSG_TYPE_NONE:
-    return "None";
-  case MSG_TYPE_EXCEPTION:
-    return "Exception";
-  case MSG_TYPE_FORKCLEANER:
-    return "ForkCleaner";
-  case MSG_TYPE_FORKDATATRANSFER:
-    return "ForkDataTransfer";
-  case MSG_TYPE_FORKLABEL:
-    return "ForkLabel";
-  case MSG_TYPE_FORKSUCCEEDED:
-    return "ForkSucceeded";
-  case MSG_TYPE_HEARTBEAT:
-    return "Heartbeat";
-  case MSG_TYPE_MIGRATIONJOBFROMTAPEGATEWAY:
-    return "MigrationJobFromTapeGateway";
-  case MSG_TYPE_MIGRATIONJOBFROMWRITETP:
-    return "MigrationJobFromWriteTp";
-  case MSG_TYPE_NBFILESONTAPE:
-    return "NbFilesOnTape";
-  case MSG_TYPE_PROCESSCRASHED:
-    return "ProcessCrashed";
-  case MSG_TYPE_PROCESSEXITED:
-    return "ProcessExited";
-  case MSG_TYPE_RECALLJOBFROMREADTP:
-    return "RecallJobFromReadTp";
-  case MSG_TYPE_RECALLJOBFROMTAPEGATEWAY:
-    return "RecallJobFromTapeGAteway";
-  case MSG_TYPE_RETURNVALUE:
-    return "ReturnValue";
-  case MSG_TYPE_STOPPROCESSFORKER:
-    return "StopProcessForker";
-  case MSG_TYPE_TAPEMOUNTEDFORMIGRATION:
-    return "TapeMountedForMigration";
-  case MSG_TYPE_TAPEMOUNTEDFORRECALL:
-    return "TapeMountedForRecall";
-  case MSG_TYPE_LABELERROR:
-    return "LabelError";
-  case MSG_TYPE_ACSMOUNTTAPEREADONLY:
-    return "AcsMountTapeReadOnly";
-  case MSG_TYPE_ACSMOUNTTAPEREADWRITE:
-    return "AcsMountTapeReadWrite";        
-  case MSG_TYPE_ACSDISMOUNTTAPE:
-    return "AcsDismountTape";
-  case MSG_TYPE_ACSFORCEDISMOUNTTAPE:
-    return "AcsForceDismountTape";
-  case MSG_TYPE_ADDLOGPARAMS:
-    return "AddLogParams";
-  case MSG_TYPE_DELETELOGPARAMS:
-    return "DeleteLogParams";
-  default:
-    return "Unknown";
-  }
-} // msgTypeToString()
diff --git a/mediachanger/acs/daemon/Constants.hpp b/mediachanger/acs/daemon/Constants.hpp
deleted file mode 100644
index ddf702056245f532a8ae7dd757892ef445ff0ff1..0000000000000000000000000000000000000000
--- a/mediachanger/acs/daemon/Constants.hpp
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * 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/>.
- */
-
-#pragma once
-
-namespace cta {
-namespace mediachanger {
-namespace acs {
-namespace daemon {
-
-enum ProtocolType {
-  PROTOCOL_TYPE_NONE,
-  PROTOCOL_TYPE_TAPE
-};
-
-enum MsgType {
-  /*  0 */ MSG_TYPE_NONE                        =  0,
-  /*  1 */ MSG_TYPE_EXCEPTION                   =  1,
-  /*  2 */ MSG_TYPE_FORKCLEANER                 =  2,
-  /*  3 */ MSG_TYPE_FORKDATATRANSFER            =  3,
-  /*  4 */ MSG_TYPE_FORKLABEL                   =  4,
-  /*  5 */ MSG_TYPE_FORKSUCCEEDED               =  5,
-  /*  6 */ MSG_TYPE_HEARTBEAT                   =  6,
-  /*  7 */ MSG_TYPE_MIGRATIONJOBFROMTAPEGATEWAY =  7,
-  /*  8 */ MSG_TYPE_MIGRATIONJOBFROMWRITETP     =  8,
-  /*  9 */ MSG_TYPE_NBFILESONTAPE               =  9,
-  /* 10 */ MSG_TYPE_PROCESSCRASHED              = 10,
-  /* 11 */ MSG_TYPE_PROCESSEXITED               = 11,
-  /* 12 */ MSG_TYPE_RECALLJOBFROMREADTP         = 12,
-  /* 13 */ MSG_TYPE_RECALLJOBFROMTAPEGATEWAY    = 13,
-  /* 14 */ MSG_TYPE_RETURNVALUE                 = 14,
-  /* 15 */ MSG_TYPE_STOPPROCESSFORKER           = 15,
-  /* 16 */ MSG_TYPE_TAPEMOUNTEDFORMIGRATION     = 16,
-  /* 17 */ MSG_TYPE_TAPEMOUNTEDFORRECALL        = 17,
-  /* 18 */ MSG_TYPE_TAPEUNMOUNTSTARTED          = 18,
-  /* 19 */ MSG_TYPE_TAPEUNMOUNTED               = 19,
-  /* 20 */ MSG_TYPE_LABELERROR                  = 20,
-  /* 21 */ MSG_TYPE_ACSMOUNTTAPEREADONLY        = 21,
-  /* 22 */ MSG_TYPE_ACSMOUNTTAPEREADWRITE       = 22,
-  /* 23 */ MSG_TYPE_ACSDISMOUNTTAPE             = 23,
-  /* 24 */ MSG_TYPE_ACSFORCEDISMOUNTTAPE        = 24,
-  /* 25 */ MSG_TYPE_ADDLOGPARAMS                = 25,
-  /* 26 */ MSG_TYPE_DELETELOGPARAMS             = 26,
-  /* 27 */ MSG_TYPE_ARCHIVEJOBFROMCTA           = 27,
-  /* 28 */ MSG_TYPE_RETRIEVEJOBFROMCTA          = 28
-};
-
-enum ProtocolVersion {
-  PROTOCOL_VERSION_NONE,
-  PROTOCOL_VERSION_1
-};
-
-/**
- * Returns the string representation of the specified message type.
- *
- * This method is thread safe because it only returns pointers to string
- * literals.
- *
- * In the case where the specified message type is unknown this method does not
- * throw an exception, instead is returns a string literal that explains the
- * message type is unknown.
- */
-const char *msgTypeToString(const MsgType msgType);
-
-} // namespace daemon
-} // namespace acs
-} // namespace mediachanger
-} // namespace cta
diff --git a/mediachanger/acs/daemon/Tpconfig.hpp b/mediachanger/acs/daemon/Tpconfig.hpp
deleted file mode 100644
index 47fafa56aa2fcc65e5aaf84a121c5e76d3db4a21..0000000000000000000000000000000000000000
--- a/mediachanger/acs/daemon/Tpconfig.hpp
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * 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/>.
- */
-
-#pragma once
-
-#include "TpconfigLine.hpp"
-#include "common/SourcedParameter.hpp"
-#include "common/exception/Exception.hpp"
-
-#include <map>
-
-namespace cta { namespace mediachanger { namespace acs { namespace daemon {
-
-/**
- * A map of lines parsed from a TPCONFIG file (key is the drive name)
- */
-class Tpconfig: public std::map<std::string, SourcedParameter<cta::mediachanger::acs::daemon::TpconfigLine>> {
-public:
-
-  CTA_GENERATE_EXCEPTION_CLASS(InvalidArgument);
-  CTA_GENERATE_EXCEPTION_CLASS(DuplicateEntry);
-  /**
-   * Parses the specified TPCONFIG file.
-   *
-   * @param filename The filename of the TPCONFIG file.
-   * @return The result of parsing the TPCONFIG file.
-   */
-  static Tpconfig parseFile(const std::string &filename);
-}; // class TpconfigLines
-
-}}}} // namespace cta::tape::daemon
diff --git a/mediachanger/acs/daemon/TpconfigLine.hpp b/mediachanger/acs/daemon/TpconfigLine.hpp
deleted file mode 100644
index 4b7a74b4cbd9bc969d1acb415b86237808c01cdb..0000000000000000000000000000000000000000
--- a/mediachanger/acs/daemon/TpconfigLine.hpp
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * 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/>.
- */
-
-#pragma once
-
-#include <string>
-#include "mediachanger/LibrarySlot.hpp"
-#include <memory>
-
-namespace cta {
-namespace mediachanger {
-namespace acs {
-namespace daemon {
-
-/**
- * The data stored in a data-line (as opposed to a comment-line) from a
- * TPCONFIG file (/etc/cta/TPCONFIG).
- */
-class TpconfigLine {
-public:
-  /**
-   * The unit name of the tape drive.
-   */
-  std::string unitName;
-
-  /**
-   * The logical library of the tape drive.
-   */
-  std::string logicalLibrary;
-
-  /**
-   * The filename of the device file of the tape drive.
-   */
-  std::string devFilename;
-
-  /**
-   * The slot in the tape library that contains the tape drive (string encoded).
-   */
-  std::string rawLibrarySlot;
-  
-  /**
-   * Accessor method to the library slot strcuture.
-   * @return reference to the library slot.
-   */
-  const cta::mediachanger::LibrarySlot & librarySlot() const;
-  
-private:
-  /**
-   * The library slot structure.
-   */
-  std::unique_ptr <cta::mediachanger::LibrarySlot> m_librarySlot;
-
-public:
-  /**
-   * Trivial constructor (used in unit tests).
-   */
-  TpconfigLine();
-  
-  /**
-   * Constructor.
-   *
-   * @param unitName The unit name of the tape drive.
-   * @param dgn The Device Group Name (DGN) of the tape drive.
-   * @param devFilename The filename of the device file of the tape drive.
-   * @param librarySlot The slot in the tape library that contains the tape
-   * drive.
-   */
-  TpconfigLine(
-    const std::string &unitName,
-    const std::string &logicalLibrary,
-    const std::string &devFilename,
-    const std::string &librarySlot);
-
-  /**
-   * Copy constructor
-   * @param o the other TpConfigLine to be copied.
-   */
-  TpconfigLine(const TpconfigLine& o);
-  
-  /**
-   * Copy operator
-   * @param o the other TpConfigLine to copy.
-   * @return a reference to the object
-   */
-  TpconfigLine& operator=(const TpconfigLine& o);
-  static const size_t maxNameLen = 100;
-}; // struct TpconfigLine
-
-}}}} // namespace cta::mediachanger::acs::daemon
diff --git a/mediachanger/acs/daemon/cta-acsd.conf b/mediachanger/acs/daemon/cta-acsd.conf
deleted file mode 100644
index e97d8b4096ae2f3df65004ff221f7b5043042c5c..0000000000000000000000000000000000000000
--- a/mediachanger/acs/daemon/cta-acsd.conf
+++ /dev/null
@@ -1,38 +0,0 @@
-# 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/>.
-
-################################################################################
-#
-# CTA Sample Configuration File
-#
-################################################################################
-
-# The log mask.  Logs with a level lower than this value will be masked.
-# Possible values are:
-#   EMERG
-#   ALERT
-#   CRIT
-#   ERR
-#   WARNING
-#   NOTICE
-#   INFO
-#   DEBUG
-#   USERERR
-#
-# Please note that the USERERR log level is equivalent to NOTICE because it is
-# a convention of CTA to use log level NOTICE to label user errors.
-#
-# taped LogMask INFO
diff --git a/mediachanger/acs/daemon/cta-acsd.logrotate b/mediachanger/acs/daemon/cta-acsd.logrotate
deleted file mode 100644
index de8fd8ac53024552e0a710d8d6f87ba5a832de3f..0000000000000000000000000000000000000000
--- a/mediachanger/acs/daemon/cta-acsd.logrotate
+++ /dev/null
@@ -1,10 +0,0 @@
-/var/log/cta/cta-acsd*.log {
-    compress
-    daily
-    missingok
-    rotate 500
-    delaycompress
-    postrotate
-        /bin/kill -HUP `cat /var/run/syslogd.pid 2> /dev/null` 2> /dev/null || true
-    endscript
-}
diff --git a/mediachanger/acs/daemon/cta-acsd.service b/mediachanger/acs/daemon/cta-acsd.service
deleted file mode 100644
index c2ce4f78eda5a7790feb5590c98105f5a4b94bc1..0000000000000000000000000000000000000000
--- a/mediachanger/acs/daemon/cta-acsd.service
+++ /dev/null
@@ -1,12 +0,0 @@
-[Unit]
-Description=CERN Tape Archive (CTA) acsd daemon
-After=syslog.target network-online.target
-
-[Service]
-ExecStart=/usr/bin/cta-acsd
-LimitCORE=infinity
-Type=forking
-Restart=no
-
-[Install]
-WantedBy=default.target
diff --git a/objectstore/ArchiveRequest.cpp b/objectstore/ArchiveRequest.cpp
index 69299a0ba772b5c52474e25f26ade808d382477a..b7be789eb1ed98b234b500d15646a1a3a6bdc3c9 100644
--- a/objectstore/ArchiveRequest.cpp
+++ b/objectstore/ArchiveRequest.cpp
@@ -218,7 +218,7 @@ void ArchiveRequest::setArchiveFile(const cta::common::dataStructures::ArchiveFi
   m_payload.mutable_diskfileinfo()->set_group(archiveFile.diskFileInfo.group);
   m_payload.mutable_diskfileinfo()->set_owner(archiveFile.diskFileInfo.owner);
   m_payload.mutable_diskfileinfo()->set_path(archiveFile.diskFileInfo.path);
-  m_payload.mutable_diskfileinfo()->set_recoveryblob(archiveFile.diskFileInfo.recoveryBlob);
+  m_payload.mutable_diskfileinfo()->set_recoveryblob("");
   m_payload.set_diskinstance(archiveFile.diskInstance);
   m_payload.set_filesize(archiveFile.fileSize);
   m_payload.set_reconcilationtime(archiveFile.reconciliationTime);
@@ -239,7 +239,6 @@ cta::common::dataStructures::ArchiveFile ArchiveRequest::getArchiveFile() {
   ret.diskFileInfo.group = m_payload.diskfileinfo().group();
   ret.diskFileInfo.owner = m_payload.diskfileinfo().owner();
   ret.diskFileInfo.path = m_payload.diskfileinfo().path();
-  ret.diskFileInfo.recoveryBlob = m_payload.diskfileinfo().recoveryblob();
   ret.diskInstance = m_payload.diskinstance();
   ret.fileSize = m_payload.filesize();
   ret.reconciliationTime = m_payload.reconcilationtime();
@@ -552,7 +551,6 @@ ArchiveRequest::AsyncJobOwnerUpdater* ArchiveRequest::asyncUpdateJobOwner(uint32
             retRef.m_archiveFile.diskFileInfo.group = payload.diskfileinfo().group();
             retRef.m_archiveFile.diskFileInfo.owner = payload.diskfileinfo().owner();
             retRef.m_archiveFile.diskFileInfo.path = payload.diskfileinfo().path();
-            retRef.m_archiveFile.diskFileInfo.recoveryBlob = payload.diskfileinfo().recoveryblob();
             retRef.m_archiveFile.diskInstance = payload.diskinstance();
             retRef.m_archiveFile.fileSize = payload.filesize();
             retRef.m_archiveFile.reconciliationTime = payload.reconcilationtime();
diff --git a/objectstore/DiskFileInfoSerDeser.hpp b/objectstore/DiskFileInfoSerDeser.hpp
index a3bdcd80d6c9640f5c7f6816ea3901d9a32807e6..b8564fa6528665f6eaa259a0d26bd1e8bd06cadb 100644
--- a/objectstore/DiskFileInfoSerDeser.hpp
+++ b/objectstore/DiskFileInfoSerDeser.hpp
@@ -34,13 +34,11 @@ class DiskFileInfoSerDeser: public cta::common::dataStructures::DiskFileInfo {
 public:
   DiskFileInfoSerDeser (): cta::common::dataStructures::DiskFileInfo() {}
   DiskFileInfoSerDeser (const cta::common::dataStructures::DiskFileInfo & dfi): cta::common::dataStructures::DiskFileInfo(dfi) {}
-  DiskFileInfoSerDeser (const std::string & path, const std::string & owner, 
-  const std::string & group, const std::string &recoveryBlob): 
+  DiskFileInfoSerDeser (const std::string & path, const std::string & owner, const std::string & group): 
     cta::common::dataStructures::DiskFileInfo() {
     this->path=path;
     this->owner=owner;
     this->group=group;
-    this->recoveryBlob=recoveryBlob;
   }
   operator cta::common::dataStructures::DiskFileInfo() {
     return cta::common::dataStructures::DiskFileInfo(*this);
@@ -49,13 +47,12 @@ public:
     osdfi.set_path(path);
     osdfi.set_owner(owner);
     osdfi.set_group(group);
-    osdfi.set_recoveryblob(recoveryBlob);
+    osdfi.set_recoveryblob("");
   }
   void deserialize (const cta::objectstore::serializers::DiskFileInfo & osdfi) {
     path=osdfi.path();
     owner=osdfi.owner();
     group=osdfi.group();
-    recoveryBlob=osdfi.recoveryblob();
   }
 };
   
diff --git a/rdbms/ConnAndStmts.hpp b/rdbms/ConnAndStmts.hpp
index b5aa5d20dd84043fb70e86493a0be1b38b99cbdd..6bdcce2cbe0b704fac5bef6a0c9f783bf086d927 100644
--- a/rdbms/ConnAndStmts.hpp
+++ b/rdbms/ConnAndStmts.hpp
@@ -19,7 +19,7 @@
 #pragma once
 
 #include "rdbms/StmtPool.hpp"
-#include "rdbms/wrapper/Conn.hpp"
+#include "rdbms/wrapper/ConnWrapper.hpp"
 
 #include <iostream>
 #include <memory>
@@ -81,7 +81,7 @@ struct ConnAndStmts {
    * prepared statements.  This means the conn member-variable must be declared
    * before the stmtPool member-variable.
    */
-  std::unique_ptr<wrapper::Conn> conn;
+  std::unique_ptr<wrapper::ConnWrapper> conn;
 
   /**
    * Pool of prepared statements.
diff --git a/rdbms/ConnPool.hpp b/rdbms/ConnPool.hpp
index 68d7ee6e7ccf5704bcbfd40dd97d5c37d5cc3b05..aa210e08ce19a1df87ff04038fa55cf022a4095d 100644
--- a/rdbms/ConnPool.hpp
+++ b/rdbms/ConnPool.hpp
@@ -22,7 +22,7 @@
 #include "common/threading/Mutex.hpp"
 #include "rdbms/ConnAndStmts.hpp"
 #include "rdbms/Conn.hpp"
-#include "rdbms/wrapper/Conn.hpp"
+#include "rdbms/wrapper/ConnWrapper.hpp"
 #include "rdbms/wrapper/ConnFactory.hpp"
 
 #include <list>
diff --git a/rdbms/Login.cpp b/rdbms/Login.cpp
index ef03428279194c1d98fd4cb7ae02b9d7c47618e8..511947ebb4a1f9ca9543a9dbdb944ac28e3e51a9 100644
--- a/rdbms/Login.cpp
+++ b/rdbms/Login.cpp
@@ -30,7 +30,12 @@ namespace rdbms {
 //------------------------------------------------------------------------------
 // s_fileFormat
 //------------------------------------------------------------------------------
-const char *Login::s_fileFormat = "either in_memory or oracle:username/password@database or sqlite:filename";
+const char *Login::s_fileFormat = "one of "
+  "in_memory, "
+  "oracle:username/password@database, "
+  "sqlite:filename, "
+  "mysql://<username>:<password>@<host>:<port>/<db_name> or "
+  "postgresql:[connectinfo | URI]";
 
 //------------------------------------------------------------------------------
 // constructor
@@ -348,8 +353,7 @@ Login Login::parseMySql(const std::string &connectionDetails) {
 // parsePostgresql
 //------------------------------------------------------------------------------
 Login Login::parsePostgresql(const std::string &connectionDetails) {
-  //return Login(DBTYPE_POSTGRESQL, "", "", connectionDetails, "", 0);
-  throw exception::Exception(std::string(__FUNCTION__) + " not implemented");
+  return Login(DBTYPE_POSTGRESQL, "", "", connectionDetails, "", 0);
 }
 
 } // namespace catalogue
diff --git a/rdbms/Login.hpp b/rdbms/Login.hpp
index c568b21a8d96d6b0a90d4a636d028ae89380e52b..22ab4e5522d91cf7ff03b40f438c6e0ea740a514 100644
--- a/rdbms/Login.hpp
+++ b/rdbms/Login.hpp
@@ -215,7 +215,25 @@ struct Login {
   static Login parseMySql(const std::string &connectionDetails);
 
   /**
-   * Parses the specified connection details.
+   * Parses the specified connection details for the Postgres database.
+   * The postgres selection type in the config file is "postgres".
+   *
+   * Possible database login configuration lines for postgres:
+   *
+   *     postgresql:[connectinfo]
+   * or
+   *     postgresql:[URI]
+   *
+   * connectinfo or URI are the connectionDetails and may be empty.
+   * Otherwise connectinfo is a series of 1 or more keyword=value
+   * separated by whitespace. See doucmentaion, e.g.
+   * https://www.postgresql.org/docs/11/libpq-connect.html#LIBPQ-CONNSTRING
+   *
+   * an example configuraiton using the URI is
+   * postgresql:postgresql://user:secret@localhost/mydb
+   *
+   * an example configuraiton using connect info
+   * postgresql:user=user password=secret host=localhost dbname=mydb
    *
    * @param connectionDetails The database connection details.
    */
diff --git a/rdbms/Rset.cpp b/rdbms/Rset.cpp
index df390212897e5ed0f2e7aa5f4f647764bb9f76ac..065afe071ad04a65ac5b393d8f2aa1b8e373e5e5 100644
--- a/rdbms/Rset.cpp
+++ b/rdbms/Rset.cpp
@@ -18,7 +18,7 @@
 
 #include "rdbms/NullDbValue.hpp"
 #include "rdbms/Rset.hpp"
-#include "rdbms/wrapper/Rset.hpp"
+#include "rdbms/wrapper/RsetWrapper.hpp"
 
 namespace cta {
 namespace rdbms {
@@ -33,7 +33,7 @@ Rset::Rset():
 //------------------------------------------------------------------------------
 // constructor
 //------------------------------------------------------------------------------
-Rset::Rset(std::unique_ptr<wrapper::Rset> impl):
+Rset::Rset(std::unique_ptr<wrapper::RsetWrapper> impl):
   m_impl(std::move(impl)) {
   if(nullptr == m_impl.get()) {
     throw exception::Exception(std::string(__FUNCTION__) + " failed: Pointer to implementation object is null");
diff --git a/rdbms/Rset.hpp b/rdbms/Rset.hpp
index b8c9d1c4e9b1dd14e39bd0d2e06dec8997beff35..12818d2747f22cb2ddda43321046c081d0ef096c 100644
--- a/rdbms/Rset.hpp
+++ b/rdbms/Rset.hpp
@@ -28,7 +28,7 @@ namespace cta {
 namespace rdbms {
 
 namespace wrapper {
-  class Rset;
+  class RsetWrapper;
 }
 
 /**
@@ -50,7 +50,7 @@ public:
    *
    * @param impl The object actually implementing this result set.
    */
-  Rset(std::unique_ptr<wrapper::Rset> impl);
+  Rset(std::unique_ptr<wrapper::RsetWrapper> impl);
 
   /**
    * Deletion of copy constructor.
@@ -171,7 +171,7 @@ private:
   /**
    * The object actually implementing this result set.
    */
-  std::unique_ptr<wrapper::Rset> m_impl;
+  std::unique_ptr<wrapper::RsetWrapper> m_impl;
 
 }; // class Rset
 
diff --git a/rdbms/Stmt.cpp b/rdbms/Stmt.cpp
index 34eac226fb333327990dc6024344896c9c576410..aa99fe1c5d247a1ceddc69cb46720fe15cade972 100644
--- a/rdbms/Stmt.cpp
+++ b/rdbms/Stmt.cpp
@@ -19,7 +19,7 @@
 #include "common/exception/Exception.hpp"
 #include "rdbms/Stmt.hpp"
 #include "rdbms/StmtPool.hpp"
-#include "rdbms/wrapper/Stmt.hpp"
+#include "rdbms/wrapper/StmtWrapper.hpp"
 
 namespace cta {
 namespace rdbms {
@@ -34,7 +34,7 @@ Stmt::Stmt():
 //-----------------------------------------------------------------------------
 // constructor
 //-----------------------------------------------------------------------------
-Stmt::Stmt(std::unique_ptr<wrapper::Stmt> stmt, StmtPool &stmtPool):
+Stmt::Stmt(std::unique_ptr<wrapper::StmtWrapper> stmt, StmtPool &stmtPool):
   m_stmt(std::move(stmt)),
   m_stmtPool(&stmtPool) {
 }
@@ -208,7 +208,7 @@ uint64_t Stmt::getNbAffectedRows() const {
 //-----------------------------------------------------------------------------
 // getStmt
 //-----------------------------------------------------------------------------
-wrapper::Stmt &Stmt::getStmt() {
+wrapper::StmtWrapper &Stmt::getStmt() {
   if(nullptr != m_stmt) {
     return *m_stmt;
   } else {
diff --git a/rdbms/Stmt.hpp b/rdbms/Stmt.hpp
index fc416c4210426f694e4f52207e1d3f5d07820a9f..cc4f406781e32a0f5156f0e058ee9c10c3f00855 100644
--- a/rdbms/Stmt.hpp
+++ b/rdbms/Stmt.hpp
@@ -30,7 +30,7 @@ namespace cta {
 namespace rdbms {
 
 namespace wrapper {
-  class Stmt;
+  class StmtWrapper;
 }
 
 class StmtPool;
@@ -54,7 +54,7 @@ public:
    * @param stmt The database statement.
    * @param stmtPool The database statement pool to which the m_stmt should be returned.
    */
-  Stmt(std::unique_ptr<wrapper::Stmt> stmt, StmtPool &stmtPool);
+  Stmt(std::unique_ptr<wrapper::StmtWrapper> stmt, StmtPool &stmtPool);
 
   /**
    * Deletion of the copy constructor.
@@ -183,14 +183,14 @@ public:
    * Returns a reference to the underlying statement object that is not pool
    * aware.
    */
-  wrapper::Stmt &getStmt();
+  wrapper::StmtWrapper &getStmt();
 
 private:
 
   /**
    * The database statement.
    */
-  std::unique_ptr<wrapper::Stmt> m_stmt;
+  std::unique_ptr<wrapper::StmtWrapper> m_stmt;
 
   /**
    * The database statement pool to which the m_stmt should be returned.
diff --git a/rdbms/StmtPool.cpp b/rdbms/StmtPool.cpp
index 5e0795580afbc277897c74fba7cd3bede5d4eb8b..87dea14b5b13b2ceba13c67edae1c862b8d96ad8 100644
--- a/rdbms/StmtPool.cpp
+++ b/rdbms/StmtPool.cpp
@@ -18,7 +18,7 @@
 
 #include "common/exception/Exception.hpp"
 #include "common/threading/MutexLocker.hpp"
-#include "rdbms/wrapper/Conn.hpp"
+#include "rdbms/wrapper/ConnWrapper.hpp"
 #include "rdbms/StmtPool.hpp"
 
 namespace cta {
@@ -27,7 +27,7 @@ namespace rdbms {
 //------------------------------------------------------------------------------
 // getStmt
 //------------------------------------------------------------------------------
-Stmt StmtPool::getStmt(wrapper::Conn &conn, const std::string &sql) {
+Stmt StmtPool::getStmt(wrapper::ConnWrapper &conn, const std::string &sql) {
   threading::MutexLocker locker(m_stmtsMutex);
 
   auto itor = m_stmts.find(sql);
@@ -70,7 +70,7 @@ uint64_t StmtPool::getNbStmts() const {
 //------------------------------------------------------------------------------
 // returnStmt
 //------------------------------------------------------------------------------
-void StmtPool::returnStmt(std::unique_ptr<wrapper::Stmt> stmt) {
+void StmtPool::returnStmt(std::unique_ptr<wrapper::StmtWrapper> stmt) {
   threading::MutexLocker locker(m_stmtsMutex);
 
   stmt->clear();
diff --git a/rdbms/StmtPool.hpp b/rdbms/StmtPool.hpp
index 1cdcadf233a3fde7793bc632cb132176f394e3fc..e23351ef0ef0412b5c5205aaba1b5087be78b4b9 100644
--- a/rdbms/StmtPool.hpp
+++ b/rdbms/StmtPool.hpp
@@ -33,8 +33,8 @@ namespace cta {
 namespace rdbms {
 
 namespace wrapper {
-  class Conn;
-  class Stmt;
+  class ConnWrapper;
+  class StmtWrapper;
 }
 
 /**
@@ -51,7 +51,7 @@ public:
    * @param sql The SQL statement.
    * @return The prepared statement.
    */
-  Stmt getStmt(wrapper::Conn &conn, const std::string &sql);
+  Stmt getStmt(wrapper::ConnWrapper &conn, const std::string &sql);
 
   /**
    * Returns the number of cached statements currently in the pool.
@@ -75,7 +75,7 @@ private:
    *
    * @param stmt The database statement to be returned to the pool.
    */
-  void returnStmt(std::unique_ptr<wrapper::Stmt> stmt);
+  void returnStmt(std::unique_ptr<wrapper::StmtWrapper> stmt);
 
   /**
    * Mutex used to serialize access to the database statements within the pool.
@@ -88,7 +88,7 @@ private:
    * Please note that for a single key there maybe more than one cached
    * statement, hence the map to list of statements.
    */
-  std::map<std::string, std::list< std::unique_ptr<wrapper::Stmt> > > m_stmts;
+  std::map<std::string, std::list< std::unique_ptr<wrapper::StmtWrapper> > > m_stmts;
 
 }; // class StmtPool
 
diff --git a/rdbms/wrapper/CMakeLists.txt b/rdbms/wrapper/CMakeLists.txt
index 7e1340e484e6506eec01f09c24d07890d1c9b21b..2d046b6e6097a3767c3eff08878b59092347fe33 100644
--- a/rdbms/wrapper/CMakeLists.txt
+++ b/rdbms/wrapper/CMakeLists.txt
@@ -19,17 +19,19 @@ set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wshadow")
 
 find_package (sqlite REQUIRED)
 find_package (mysql REQUIRED)
+find_package (postgres REQUIRED)
 find_package (oracle-instantclient REQUIRED)
 include_directories (${MYSQL_INCLUDE_DIRS})
+include_directories (${POSTGRES_INCLUDE_DIRS})
 include_directories (${ORACLE-INSTANTCLIENT_INCLUDE_DIRS})
 
 set (RDBMS_WRAPPER_LIB_SRC_FILES
   ColumnNameToIdx.cpp
   ColumnNameToIdxAndType.cpp
-  Conn.cpp
+        ConnWrapper.cpp
   ConnFactory.cpp
-  Rset.cpp
-  Stmt.cpp
+        RsetWrapper.cpp
+        StmtWrapper.cpp
   ParamNameToIdx.cpp
   Sqlite.cpp
   SqliteConn.cpp
@@ -45,6 +47,14 @@ set (RDBMS_WRAPPER_LIB_SRC_FILES
   MysqlRset.cpp
   MysqlStmt.cpp)
 
+set (RDBMS_WRAPPER_LIB_SRC_FILES
+  ${RDBMS_WRAPPER_LIB_SRC_FILES}
+  PostgresConn.cpp
+  PostgresConnFactory.cpp
+  PostgresRset.cpp
+  PostgresStmt.cpp
+  PostgresColumn.cpp)
+
 set (RDBMS_WRAPPER_LIB_SRC_FILES
   ${RDBMS_WRAPPER_LIB_SRC_FILES}
   ConnFactoryFactory.cpp
@@ -65,6 +75,7 @@ target_link_libraries (ctardbmswrapper
   ctacommon
   ${SQLITE_LIBRARIES}
   ${MYSQL_LIBRARIES}
+  ${POSTGRES_LIBRARIES}
   ${ORACLE-INSTANTCLIENT_LIBRARIES})
 
 install (TARGETS ctardbmswrapper DESTINATION usr/${CMAKE_INSTALL_LIBDIR})
@@ -73,6 +84,7 @@ set(RDBMS_WRAPPER_UNIT_TESTS_LIB_SRC_FILES
   ConnTest.cpp
   OcciColumnTest.cpp
   ParamNameToIdxTest.cpp
+  PostgresStmtTest.cpp
   SqliteStmtTest.cpp)
 
 add_library (ctardbmswrapperunittests SHARED
diff --git a/rdbms/wrapper/ConnFactory.hpp b/rdbms/wrapper/ConnFactory.hpp
index a2658538735f286f70e691adb941af0c27e0a0b0..0544f4e59873cc750f18aaae584aad735e0df368 100644
--- a/rdbms/wrapper/ConnFactory.hpp
+++ b/rdbms/wrapper/ConnFactory.hpp
@@ -18,7 +18,7 @@
 
 #pragma once
 
-#include "rdbms/wrapper/Conn.hpp"
+#include "rdbms/wrapper/ConnWrapper.hpp"
 
 #include <memory>
 
@@ -42,7 +42,7 @@ public:
    *
    * @return A newly created database connection.
    */
-  virtual std::unique_ptr<Conn> create() = 0;
+  virtual std::unique_ptr<ConnWrapper> create() = 0;
 
 }; // class ConnFactory
 
diff --git a/rdbms/wrapper/ConnFactoryFactory.cpp b/rdbms/wrapper/ConnFactoryFactory.cpp
index 2c8153815e6242c5daeb23ad994bcd56c6b95299..e1083acb3cb5ad5cea783deda50824aeac5f9926 100644
--- a/rdbms/wrapper/ConnFactoryFactory.cpp
+++ b/rdbms/wrapper/ConnFactoryFactory.cpp
@@ -22,6 +22,7 @@
 #include "rdbms/wrapper/OcciConnFactory.hpp"
 #include "rdbms/wrapper/SqliteConnFactory.hpp"
 #include "rdbms/wrapper/MysqlConnFactory.hpp"
+#include "rdbms/wrapper/PostgresConnFactory.hpp"
 
 namespace cta {
 namespace rdbms {
@@ -41,6 +42,8 @@ std::unique_ptr<ConnFactory> ConnFactoryFactory::create(const Login &login) {
       return cta::make_unique<SqliteConnFactory>(login.database);
     case Login::DBTYPE_MYSQL:
       return cta::make_unique<MysqlConnFactory>(login.hostname, login.username, login.password, login.database, login.port);
+    case Login::DBTYPE_POSTGRESQL:
+      return cta::make_unique<PostgresConnFactory>(login.database);
     case Login::DBTYPE_NONE:
       throw exception::Exception("Cannot create a catalogue without a database type");
     default:
diff --git a/rdbms/wrapper/Conn.cpp b/rdbms/wrapper/ConnWrapper.cpp
similarity index 93%
rename from rdbms/wrapper/Conn.cpp
rename to rdbms/wrapper/ConnWrapper.cpp
index 05f39bab4b0df1624dfe00149cc4e580aa02afc5..ca9fae17b7955a20cef2eac1d8de45a10ad1e5cb 100644
--- a/rdbms/wrapper/Conn.cpp
+++ b/rdbms/wrapper/ConnWrapper.cpp
@@ -18,7 +18,7 @@
 
 #include "common/exception/Exception.hpp"
 #include "common/utils/utils.hpp"
-#include "rdbms/wrapper/Conn.hpp"
+#include "rdbms/wrapper/ConnWrapper.hpp"
 
 namespace cta {
 namespace rdbms {
@@ -27,7 +27,7 @@ namespace wrapper {
 //------------------------------------------------------------------------------
 // destructor
 //------------------------------------------------------------------------------
-Conn::~Conn() {
+ConnWrapper::~ConnWrapper() {
 }
 
 } // namespace wrapper
diff --git a/rdbms/wrapper/Conn.hpp b/rdbms/wrapper/ConnWrapper.hpp
similarity index 93%
rename from rdbms/wrapper/Conn.hpp
rename to rdbms/wrapper/ConnWrapper.hpp
index a5caaa26cdb10baf0c8e5c3af32e090ad5d6578d..3192ce8fb5d6524306c2ff8b37b82e54725f7983 100644
--- a/rdbms/wrapper/Conn.hpp
+++ b/rdbms/wrapper/ConnWrapper.hpp
@@ -19,7 +19,7 @@
 #pragma once
 
 #include "rdbms/AutocommitMode.hpp"
-#include "rdbms/wrapper/Stmt.hpp"
+#include "rdbms/wrapper/StmtWrapper.hpp"
 
 #include <atomic>
 #include <list>
@@ -33,13 +33,13 @@ namespace wrapper {
 /**
  * Abstract class that specifies the interface to a database connection.
  */
-class Conn {
+class ConnWrapper {
 public:
 
   /**
    * Destructor.
    */
-  virtual ~Conn() = 0;
+  virtual ~ConnWrapper() = 0;
 
   /**
    * Idempotent close() method.  The destructor calls this method.
@@ -75,7 +75,7 @@ public:
    * @param sql The SQL statement.
    * @return The prepared statement.
    */
-  virtual std::unique_ptr<Stmt> createStmt(const std::string &sql) = 0;
+  virtual std::unique_ptr<StmtWrapper> createStmt(const std::string &sql) = 0;
 
   /**
    * Commits the current transaction.
@@ -113,7 +113,7 @@ public:
    */
   virtual std::list<std::string> getSequenceNames()  = 0;
 
-}; // class Conn
+}; // class ConnWrapper
 
 } // namespace wrapper
 } // namespace rdbms
diff --git a/rdbms/wrapper/MysqlConn.cpp b/rdbms/wrapper/MysqlConn.cpp
index ea8cf2a86c48fa0a579b647bc1ff3b3e11bff4e0..a0a35d663ac32877539860d91f7adda285929e69 100644
--- a/rdbms/wrapper/MysqlConn.cpp
+++ b/rdbms/wrapper/MysqlConn.cpp
@@ -140,7 +140,7 @@ void MysqlConn::executeNonQuery(const std::string &sql) {
 //------------------------------------------------------------------------------
 // createStmt
 //------------------------------------------------------------------------------
-std::unique_ptr<Stmt> MysqlConn::createStmt(const std::string &sql) {
+std::unique_ptr<StmtWrapper> MysqlConn::createStmt(const std::string &sql) {
 
   try {
     threading::MutexLocker locker(m_mutex);
diff --git a/rdbms/wrapper/MysqlConn.hpp b/rdbms/wrapper/MysqlConn.hpp
index 4ee5d2faca3fb8f4ebfd432968c409e265f46184..302a5c792aa7ff4565fd112cc39949cef454fb47 100644
--- a/rdbms/wrapper/MysqlConn.hpp
+++ b/rdbms/wrapper/MysqlConn.hpp
@@ -19,7 +19,7 @@
 #pragma once
 
 #include "common/threading/Mutex.hpp"
-#include "rdbms/wrapper/Conn.hpp"
+#include "rdbms/wrapper/ConnWrapper.hpp"
 
 struct st_mysql;
 typedef st_mysql MYSQL;
@@ -30,7 +30,7 @@ namespace wrapper {
 
 class MysqlStmt;
 
-class MysqlConn: public Conn {
+class MysqlConn: public ConnWrapper {
 public:
 
   /**
@@ -96,7 +96,7 @@ public:
    * @param autocommitMode The autocommit mode of the statement.
    * @return The prepared statement.
    */
-  std::unique_ptr<Stmt> createStmt(const std::string &sql) override;
+  std::unique_ptr<StmtWrapper> createStmt(const std::string &sql) override;
 
   /**
    * Execute a SQL statement directly, used for non prepared statement.
diff --git a/rdbms/wrapper/MysqlConnFactory.cpp b/rdbms/wrapper/MysqlConnFactory.cpp
index 22ac9c5717ca94c4ce74d4dc2771195ed34419a2..85d7b591b217e28beba54790db309cbe6752932b 100644
--- a/rdbms/wrapper/MysqlConnFactory.cpp
+++ b/rdbms/wrapper/MysqlConnFactory.cpp
@@ -45,7 +45,7 @@ MysqlConnFactory::~MysqlConnFactory() {
 //------------------------------------------------------------------------------
 // create
 //------------------------------------------------------------------------------
-std::unique_ptr<Conn> MysqlConnFactory::create() {
+std::unique_ptr<ConnWrapper> MysqlConnFactory::create() {
   try {
     return cta::make_unique<MysqlConn>(m_host, m_user, m_passwd, m_db, m_port);
   } catch(exception::Exception &ex) {
diff --git a/rdbms/wrapper/MysqlConnFactory.hpp b/rdbms/wrapper/MysqlConnFactory.hpp
index f08a83bc2b21c26f4fe803ca4c657729e4048308..2f083501e3c8671ae87b1a1e28345ffafe33c2c3 100644
--- a/rdbms/wrapper/MysqlConnFactory.hpp
+++ b/rdbms/wrapper/MysqlConnFactory.hpp
@@ -56,7 +56,7 @@ public:
    *
    * @return A newly created database connection.
    */
-  std::unique_ptr<Conn> create() override;
+  std::unique_ptr<ConnWrapper> create() override;
 
 private:
 
diff --git a/rdbms/wrapper/MysqlRset.hpp b/rdbms/wrapper/MysqlRset.hpp
index 2045e8d77068a6e35d4667889802c2518d62d7a6..27a77879da5d7341756f1afb995ab4874b9558ce 100644
--- a/rdbms/wrapper/MysqlRset.hpp
+++ b/rdbms/wrapper/MysqlRset.hpp
@@ -19,7 +19,7 @@
 #pragma once
 
 #include "rdbms/wrapper/ColumnNameToIdxAndType.hpp"
-#include "rdbms/wrapper/Rset.hpp"
+#include "rdbms/wrapper/RsetWrapper.hpp"
 
 #include <memory>
 #include <stdint.h>
@@ -38,7 +38,7 @@ class MysqlStmt;
 /**
  * The result set of an sql query.
  */
-class MysqlRset: public Rset {
+class MysqlRset: public RsetWrapper {
 public:
 
   /**
diff --git a/rdbms/wrapper/MysqlStmt.cpp b/rdbms/wrapper/MysqlStmt.cpp
index 4d42fa346810b428a374d0efeaa1f54aa06137fd..8a3811424425462242980a20ce1c82cd0610b6b6 100644
--- a/rdbms/wrapper/MysqlStmt.cpp
+++ b/rdbms/wrapper/MysqlStmt.cpp
@@ -48,7 +48,7 @@ namespace wrapper {
 MysqlStmt::MysqlStmt(
   MysqlConn &conn,
   const std::string &sql):
-  Stmt(sql),
+  StmtWrapper(sql),
   m_conn(conn),
   m_stmt(nullptr), m_param_count(0),
   m_fields_info(nullptr),
@@ -282,7 +282,7 @@ void MysqlStmt::bindOptionalString(const std::string &paramName, const optional<
 //------------------------------------------------------------------------------
 // executeQuery
 //------------------------------------------------------------------------------
-std::unique_ptr<Rset> MysqlStmt::executeQuery() {
+std::unique_ptr<RsetWrapper> MysqlStmt::executeQuery() {
   // bind values before execute
   do_bind();
 
diff --git a/rdbms/wrapper/MysqlStmt.hpp b/rdbms/wrapper/MysqlStmt.hpp
index 1dde1dbb8d72c1a70d5df4ca636bb55c97e704a7..96bca5374b42d6f5bf1c7472e0170acb16f7e7d1 100644
--- a/rdbms/wrapper/MysqlStmt.hpp
+++ b/rdbms/wrapper/MysqlStmt.hpp
@@ -19,7 +19,7 @@
 #pragma once
 
 #include "common/threading/Mutex.hpp"
-#include "rdbms/wrapper/Stmt.hpp"
+#include "rdbms/wrapper/StmtWrapper.hpp"
 
 #include <vector>
 #include <map>
@@ -44,7 +44,7 @@ class MysqlRset;
 /**
  * A convenience wrapper around an SQLite prepared statement.
  */
-class MysqlStmt: public Stmt {
+class MysqlStmt: public StmtWrapper {
 public:
 
   /**
@@ -129,7 +129,7 @@ public:
    *
    * @return The result set.
    */
-  std::unique_ptr<Rset> executeQuery() override;
+  std::unique_ptr<RsetWrapper> executeQuery() override;
 
   /**
    * Executes the statement.
diff --git a/rdbms/wrapper/OcciConn.cpp b/rdbms/wrapper/OcciConn.cpp
index 3f0744256d492e54128e09b5208e69a24f4a30d6..c710555e3ed1c9c7018deb3bce03176687cd7f52 100644
--- a/rdbms/wrapper/OcciConn.cpp
+++ b/rdbms/wrapper/OcciConn.cpp
@@ -102,7 +102,7 @@ void OcciConn::executeNonQuery(const std::string &sql) {
 //------------------------------------------------------------------------------
 // createStmt
 //------------------------------------------------------------------------------
-std::unique_ptr<Stmt> OcciConn::createStmt(const std::string &sql) {
+std::unique_ptr<StmtWrapper> OcciConn::createStmt(const std::string &sql) {
   try {
     threading::MutexLocker locker(m_mutex);
 
diff --git a/rdbms/wrapper/OcciConn.hpp b/rdbms/wrapper/OcciConn.hpp
index 9071c7f687e43bcb2a453cf206fb384c94add79d..d7f09f54a3ec00b0fca25bf7f07566c4f6e92159 100644
--- a/rdbms/wrapper/OcciConn.hpp
+++ b/rdbms/wrapper/OcciConn.hpp
@@ -20,7 +20,7 @@
 
 #include "common/threading/MutexLocker.hpp"
 #include "common/threading/RWLock.hpp"
-#include "rdbms/wrapper/Conn.hpp"
+#include "rdbms/wrapper/ConnWrapper.hpp"
 
 #include <occi.h>
 
@@ -37,7 +37,7 @@ class OcciStmt;
 /**
  * A convenience wrapper around a connection to an OCCI database.
  */
-class OcciConn: public Conn {
+class OcciConn: public ConnWrapper {
 public:
 
   /**
@@ -90,7 +90,7 @@ public:
    * @param sql The SQL statement.
    * @return The prepared statement.
    */
-  std::unique_ptr<Stmt> createStmt(const std::string &sql) override;
+  std::unique_ptr<StmtWrapper> createStmt(const std::string &sql) override;
 
   /**
    * Commits the current transaction.
diff --git a/rdbms/wrapper/OcciConnFactory.cpp b/rdbms/wrapper/OcciConnFactory.cpp
index 072b228d8d82be463ecc26d6ef3fa094c94b1903..fbd77457ad813ab4e1b35c9e8fd453bcc8b8a21e 100644
--- a/rdbms/wrapper/OcciConnFactory.cpp
+++ b/rdbms/wrapper/OcciConnFactory.cpp
@@ -46,7 +46,7 @@ OcciConnFactory::~OcciConnFactory() {
 //------------------------------------------------------------------------------
 // create
 //------------------------------------------------------------------------------
-std::unique_ptr<Conn> OcciConnFactory::create() {
+std::unique_ptr<ConnWrapper> OcciConnFactory::create() {
   try {
     return OcciEnvSingleton::instance().createConn(m_username, m_password, m_database);
   } catch(exception::Exception &ex) {
diff --git a/rdbms/wrapper/OcciConnFactory.hpp b/rdbms/wrapper/OcciConnFactory.hpp
index 92b19b268ada79252826ac26fd59e3114b0fe68f..6c7f4aaf0af19a0ce1c55fc728e9c9bbb17e7beb 100644
--- a/rdbms/wrapper/OcciConnFactory.hpp
+++ b/rdbms/wrapper/OcciConnFactory.hpp
@@ -52,7 +52,7 @@ public:
    *
    * @return A newly created database connection.
    */
-  std::unique_ptr<Conn> create() override;
+  std::unique_ptr<ConnWrapper> create() override;
 
 private:
 
diff --git a/rdbms/wrapper/OcciEnv.cpp b/rdbms/wrapper/OcciEnv.cpp
index 7389fd7753c076e6fb1a2c4872345c0522654b67..587794c4a5a3a428fbc043842d984d16dc9b1d47 100644
--- a/rdbms/wrapper/OcciEnv.cpp
+++ b/rdbms/wrapper/OcciEnv.cpp
@@ -49,7 +49,7 @@ OcciEnv::~OcciEnv() {
 //------------------------------------------------------------------------------
 // createConn
 //------------------------------------------------------------------------------
-std::unique_ptr<Conn> OcciEnv::createConn(
+std::unique_ptr<ConnWrapper> OcciEnv::createConn(
   const std::string &username,
   const std::string &password,
   const std::string &database) {
diff --git a/rdbms/wrapper/OcciEnv.hpp b/rdbms/wrapper/OcciEnv.hpp
index f14d28615b6f9726c4afdb3d28cb67264a92141b..75819e05154bb8e040ffc49118b8bdfda62378ab 100644
--- a/rdbms/wrapper/OcciEnv.hpp
+++ b/rdbms/wrapper/OcciEnv.hpp
@@ -18,7 +18,7 @@
 
 #pragma once
 
-#include "rdbms/wrapper/Conn.hpp"
+#include "rdbms/wrapper/ConnWrapper.hpp"
 
 #include <memory>
 #include <occi.h>
@@ -58,7 +58,7 @@ public:
    * @param database The name of the database.
    * @return The newly created OCCI connection.
    */
-  std::unique_ptr<Conn> createConn(
+  std::unique_ptr<ConnWrapper> createConn(
     const std::string &username,
     const std::string &password,
     const std::string &database);
diff --git a/rdbms/wrapper/OcciRset.hpp b/rdbms/wrapper/OcciRset.hpp
index 2b59c620de6c86d18eba4f3aa69b3bb89194ffa1..4750b9cee2d9a915ecd9cd4a1f25336eedcb56a1 100644
--- a/rdbms/wrapper/OcciRset.hpp
+++ b/rdbms/wrapper/OcciRset.hpp
@@ -20,7 +20,7 @@
 
 #include "common/threading/Mutex.hpp"
 #include "rdbms/wrapper/ColumnNameToIdx.hpp"
-#include "rdbms/wrapper/Rset.hpp"
+#include "rdbms/wrapper/RsetWrapper.hpp"
 
 #include <memory>
 #include <occi.h>
@@ -38,7 +38,7 @@ class OcciStmt;
 /**
  * A convenience wrapper around an OCCI result set.
  */
-class OcciRset: public Rset {
+class OcciRset: public RsetWrapper {
 public:
 
   /**
diff --git a/rdbms/wrapper/OcciStmt.cpp b/rdbms/wrapper/OcciStmt.cpp
index 7cc514589e28a43a9a1913cd60600b5cf0f57c67..4cb0d3b2d6a48bca3156e231e859fb021140f01a 100644
--- a/rdbms/wrapper/OcciStmt.cpp
+++ b/rdbms/wrapper/OcciStmt.cpp
@@ -41,7 +41,7 @@ OcciStmt::OcciStmt(
   const std::string &sql,
   OcciConn &conn,
   oracle::occi::Statement *const stmt) :
-  Stmt(sql),
+  StmtWrapper(sql),
   m_conn(conn),
   m_stmt(stmt) {
 }
@@ -154,7 +154,7 @@ void OcciStmt::bindOptionalString(const std::string &paramName, const optional<s
 //------------------------------------------------------------------------------
 // executeQuery
 //------------------------------------------------------------------------------
-std::unique_ptr<Rset> OcciStmt::executeQuery() {
+std::unique_ptr<RsetWrapper> OcciStmt::executeQuery() {
   using namespace oracle;
 
   const auto autocommitMode = m_conn.getAutocommitMode();
diff --git a/rdbms/wrapper/OcciStmt.hpp b/rdbms/wrapper/OcciStmt.hpp
index 14a6909d0ad92cbadd812446f876842b6faf9413..b95a715542df24bd1fe655439fa60534dcebd124 100644
--- a/rdbms/wrapper/OcciStmt.hpp
+++ b/rdbms/wrapper/OcciStmt.hpp
@@ -19,7 +19,7 @@
 #pragma once
 
 #include "common/threading/Mutex.hpp"
-#include "rdbms/wrapper/Stmt.hpp"
+#include "rdbms/wrapper/StmtWrapper.hpp"
 
 #include <memory>
 #include <occi.h>
@@ -46,7 +46,7 @@ class OcciColumn;
 /**
  * A convenience wrapper around an OCCI prepared statement.
  */
-class OcciStmt: public Stmt {
+class OcciStmt: public StmtWrapper {
 public:
 
   /**
@@ -126,7 +126,7 @@ public:
    *
    * @return The result set.
    */
-  std::unique_ptr<Rset> executeQuery() override;
+  std::unique_ptr<RsetWrapper> executeQuery() override;
 
   /**
    * Executes the statement.
diff --git a/rdbms/wrapper/ParamNameToIdx.hpp b/rdbms/wrapper/ParamNameToIdx.hpp
index 79c79eb6c910a5484998bf267a335a1005a635bc..e0a3d9d16471f3b2d53d6393d784bf37a5ea3cc2 100644
--- a/rdbms/wrapper/ParamNameToIdx.hpp
+++ b/rdbms/wrapper/ParamNameToIdx.hpp
@@ -47,13 +47,6 @@ public:
    */
   uint32_t getIdx(const std::string &paramName) const;
 
-private:
-
-  /**
-   * Map from SQL parameter name to parameter index.
-   */
-  std::map<std::string, uint32_t> m_nameToIdx;
-
   /**
    * Returns true if the specified character is a valid parameter name
    * character.
@@ -62,7 +55,14 @@ private:
    * @return True if the specified character is a valid parameter name
    * character.
    */
-  bool isValidParamNameChar(const char c);
+  static bool isValidParamNameChar(const char c);
+
+private:
+
+  /**
+   * Map from SQL parameter name to parameter index.
+   */
+  std::map<std::string, uint32_t> m_nameToIdx;
 
 }; // class ParamNameToIdx
 
diff --git a/rdbms/wrapper/Postgres.hpp b/rdbms/wrapper/Postgres.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..b630cbfe8c6f082cc5cd2c65a08ba0153fa45ae5
--- /dev/null
+++ b/rdbms/wrapper/Postgres.hpp
@@ -0,0 +1,254 @@
+/*
+ * The CERN Tape Archive (CTA) project
+ * Copyright (C) 2019  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/>.
+ */
+
+#pragma once
+
+#include "common/exception/Exception.hpp"
+#include "common/exception/LostDatabaseConnection.hpp"
+#include <libpq-fe.h>
+#include <string>
+#include <algorithm>
+
+namespace cta {
+namespace rdbms {
+namespace wrapper {
+
+/**
+ * A convenience class containing some utilities used by the postgres rdbms wrapper classes.
+ */
+class Postgres {
+public:
+
+  /**
+   * A method to throw a DB related error with an informative string obtained from the connection and/or
+   * request status. The exception will be a LostDatabaseConnection() if the postgres connection structure
+   * indicates that the connection is no longer valid.
+   */
+  [[noreturn]] static void ThrowInfo(const PGconn *conn, const PGresult *res, const std::string &prefix) {
+    const char *const pgcstr = PQerrorMessage(conn);
+    std::string pgstr;
+    if (nullptr != pgcstr) {
+      pgstr = pgcstr;
+      pgstr.erase(std::remove(pgstr.begin(), pgstr.end(), '\n'), pgstr.end());
+    }
+    std::string resstr;
+    if (nullptr != res) {
+      resstr = "DB Result Status:" + std::to_string(PQresultStatus(res));
+      const char *const e = PQresultErrorField(res, PG_DIAG_SQLSTATE);
+      if (nullptr != e && '\0' != *e) {
+        resstr += " SQLState:" + std::string(e);
+      }
+    }
+    std::string dbmsg;
+    if (!pgstr.empty()) {
+      dbmsg = pgstr;
+      if (!resstr.empty()) {
+        dbmsg += " ("+resstr+")";
+      }
+    } else {
+      dbmsg = resstr;
+    }
+
+    if (!dbmsg.empty()) {
+      dbmsg = "Database library reported: " + dbmsg;
+    }
+    if (!prefix.empty()) {
+      if (!dbmsg.empty()) {
+        dbmsg = prefix + ": " + dbmsg;
+      } else {
+        dbmsg = prefix;
+      }
+    }
+
+    bool badconn = false;
+    if (nullptr != conn) {
+      if (CONNECTION_OK != PQstatus(conn)) {
+        badconn = true;
+      }
+    }
+
+    if (badconn) {
+      throw exception::LostDatabaseConnection(dbmsg);
+    }
+    throw exception::Exception(dbmsg);
+  }
+
+  /**
+   * A class to help managing the lifetime of a postgres result.
+   */
+  class Result {
+  public:
+
+    Result( const Result& ) = delete; // non construction-copyable
+    Result& operator=( const Result& ) = delete; // non copyable
+
+    /**
+     * Constructor.
+     * The Result object will manage a single result.
+     * A single result may contain 0 or more rows.
+     *
+     * @param res A libpq result.
+     */
+    Result(PGresult *res) : m_res(res), m_rcode(PQresultStatus(res)) {
+    }
+
+   /**
+    * Destructor.
+    */
+    ~Result() {
+      clear();
+    }
+
+    /**
+     * Relases the single result or ensures the conneciton has no pending results.
+     */
+    void clear() {
+      PQclear(m_res);
+      m_res = nullptr;
+    }
+
+    /**
+     * Gets the current result.
+     *
+     * @return The libpq result.
+     */
+    PGresult *get() const {
+      return m_res;
+    }
+
+    /**
+     * Gets the current result code.
+     *
+     * @return The libpq result rcode.
+     */
+    ExecStatusType rcode() const {
+      return m_rcode;
+    }
+
+  private:
+    /**
+     * The result as a libpq result.
+     */
+    PGresult *m_res;
+
+    /**
+     * rcode of current result.
+     */
+    ExecStatusType m_rcode;
+
+  }; // class Result
+
+  /**
+   * A class to help managing a sequence of results from a postgres connection.
+   * Each result in the sequence may in tern contain 0 or more rows.
+   */
+  class ResultItr {
+  public:
+
+    ResultItr( const ResultItr& ) = delete; // non construction-copyable
+    ResultItr& operator=( const ResultItr& ) = delete; // non copyable
+
+    /**
+     * Constructor.
+     * The ResultItr object will manage a sequence of results, the first of which
+     * is only available after calling next().
+     *
+     * @param conn A libpq connection.
+     */
+    ResultItr(PGconn *conn) :
+      m_conn(conn), m_res(nullptr), m_finished(false), m_rcode(PGRES_FATAL_ERROR) {
+    }
+
+   /**
+    * Destructor.
+    */
+    ~ResultItr() {
+      clear();
+    }
+
+    /**
+     * Relases the single result or ensures the conneciton has no pending results.
+     */
+    void clear() {
+      while(nullptr != next());
+    }
+
+    /**
+     * Gets the current result.
+     *
+     * @return The libpq result.
+     */
+    PGresult *get() const {
+      return m_res;
+    }
+
+    /**
+     * Moves to the next result available.
+     *
+     * @return  The libpq result of the next result or nullptr if none is available.
+     */
+    PGresult *next() {
+      if (m_finished) {
+        return nullptr;
+      }
+      PQclear(m_res);
+      m_res = PQgetResult(m_conn);
+      m_rcode = PQresultStatus(m_res);
+      if (nullptr == m_res) {
+        m_finished = true;
+      }
+      return m_res;
+    }
+
+    /**
+     * Gets the current result code.
+     *
+     * @return The libpq result rcode.
+     */
+    ExecStatusType rcode() const {
+      return m_rcode;
+    }
+
+  private:
+    /**
+     * The libpq postgres connection from which to fetch results
+     */
+    PGconn *m_conn;
+
+    /**
+     * The current result as a libpq result.
+     */
+    PGresult *m_res;
+
+    /**
+     * Indicates that the end of result series has been detected on the connection.
+     */
+    bool m_finished;
+
+    /**
+     * rcode of	current	result.
+     */
+    ExecStatusType m_rcode;
+
+  }; // class ResultItr
+
+}; // class Postgres
+
+} // namespace wrapper
+} // namespace rdbms
+} // namespace cta
diff --git a/rdbms/wrapper/PostgresColumn.cpp b/rdbms/wrapper/PostgresColumn.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..90636678b28f4165b9e4a9a3d37842ca037dd058
--- /dev/null
+++ b/rdbms/wrapper/PostgresColumn.cpp
@@ -0,0 +1,92 @@
+/*
+ * The CERN Tape Archive(CTA) project
+ * Copyright(C) 2019  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 "common/exception/Exception.hpp"
+#include "rdbms/wrapper/PostgresColumn.hpp"
+
+namespace cta {
+namespace rdbms {
+namespace wrapper {
+
+//------------------------------------------------------------------------------
+// constructor
+//------------------------------------------------------------------------------
+PostgresColumn::PostgresColumn(const std::string &colName, const size_t nbRows):
+  m_colName(colName),
+  m_nbRows(nbRows),
+  m_fieldValues(nbRows,std::make_pair(false, std::string())) {
+}
+
+//------------------------------------------------------------------------------
+// getColName
+//------------------------------------------------------------------------------
+const std::string &PostgresColumn::getColName() const {
+  return m_colName;
+}
+
+//------------------------------------------------------------------------------
+// getNbRows
+//------------------------------------------------------------------------------
+size_t PostgresColumn::getNbRows() const {
+  return m_nbRows;
+}
+
+//------------------------------------------------------------------------------
+// getValue
+//------------------------------------------------------------------------------
+const char *PostgresColumn::getValue(size_t index) const {
+  try {
+    if(index >= m_nbRows) {
+      exception::Exception ex;
+      ex.getMessage() << "Field index is outside the available rows:"
+        " index=" << index << " m_nbRows=" << m_nbRows;
+      throw ex;
+    }
+    if (m_fieldValues[index].first) {
+      return m_fieldValues[index].second.c_str();
+    } else {
+      return nullptr;
+    }
+  } catch(exception::Exception &ex) {
+    throw exception::Exception(std::string(__FUNCTION__) + " failed: colName=" + m_colName + ": " +
+      ex.getMessage().str());
+  }
+}
+
+//------------------------------------------------------------------------------
+// copyStrIntoField
+//------------------------------------------------------------------------------
+void PostgresColumn::copyStrIntoField(const size_t index, const std::string &str) {
+  try {
+    if(index >= m_nbRows) {
+      exception::Exception ex;
+      ex.getMessage() << "Field index is outside the available rows:"
+        " index=" << index << " m_nbRows=" << m_nbRows;
+      throw ex;
+    }
+    m_fieldValues[index].first = true;
+    m_fieldValues[index].second = str;
+  } catch(exception::Exception &ex) {
+    throw exception::Exception(std::string(__FUNCTION__) + " failed: colName=" + m_colName + ": " +
+      ex.getMessage().str());
+  }
+}
+
+} // namespace wrapper
+} // namespace rdbms
+} // namespace cta
diff --git a/rdbms/wrapper/PostgresColumn.hpp b/rdbms/wrapper/PostgresColumn.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..741f9d4348ecc7e25aaf5e9c0727c0a1efcb7d3b
--- /dev/null
+++ b/rdbms/wrapper/PostgresColumn.hpp
@@ -0,0 +1,131 @@
+/*
+ * The CERN Tape Archive(CTA) project
+ * Copyright(C) 2019  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/>.
+ */
+
+#pragma once
+
+#include <memory>
+#include <string.h>
+#include <typeinfo>
+#include <vector>
+
+namespace cta {
+namespace rdbms {
+namespace wrapper {
+
+/**
+ * A class to help with preparing COPY FROM inserts with postgres.
+ */
+class PostgresColumn {
+public:
+  /**
+   * Constructor.
+   *
+   * @param colName The name of the column.
+   * @param nbRows The number of rows in the column.
+   */
+  PostgresColumn(const std::string &colName, const size_t nbRows);
+
+  /**
+   * Returns the name of the column.
+   *
+   * @return The name of the column.
+   */
+  const std::string &getColName() const;
+
+  /**
+   * Returns the number of rows in the column.
+   *
+   * @return The number of rows in the column.
+   */
+  size_t getNbRows() const;
+
+  /**
+   * Returns a pointer to the column field value at the specified index.
+   *
+   * @return The pointer to the row value.
+   */
+  const char *getValue(size_t index) const;
+
+  /**
+   * Sets the field at the specified index to the specified value.
+   *
+   * This method tag dispatches using std::is_integral.
+   *
+   * @param index The index of the field.
+   * @param value The value of the field.
+   */
+  template<typename T> void setFieldValue(const size_t index, const T &value) {
+    setFieldValue(index, value, std::is_integral<T>());
+  }
+
+private:
+
+  /**
+   * Sets the field at the specified index to the specified value.
+   *
+   * The third unnamed parameter of this method is used to implement tag
+   * dispatching with std::is_integral.
+   *
+   * @param index The index of the field.
+   * @param value The value of the field.
+   */
+  template<typename T> void setFieldValue(const size_t index, const T &value, std::true_type) {
+    copyStrIntoField(index, std::to_string(value));
+  }
+
+  /**
+   * Sets the field at the specified index to the specified value.
+   *
+   * The third unnamed parameter of this method is used to implement tag
+   * dispatching with std::is_integral.
+   *
+   * @param index The index of the field.
+   * @param value The value of the field.
+   */
+  template<typename T> void setFieldValue(const size_t index, const T &value, std::false_type) {
+    copyStrIntoField(index, value);
+  }
+
+  /**
+   * Copies the specified string value into the field at the specified index.
+   *
+   * @param index The index of the field.
+   * @param str The string value.
+   */
+  void copyStrIntoField(const size_t index, const std::string &str);
+
+  /**
+   * The name of the column.
+   */
+  std::string m_colName;
+
+  /**
+   * The number of rows in the column.
+   */
+  size_t m_nbRows;
+
+  /**
+   * The array of field values.
+   */
+  std::vector<std::pair<bool, std::string> > m_fieldValues;
+
+}; // PostgresColumn
+
+} // namespace wrapper
+} // namespace rdbms
+} // namespace cta
diff --git a/rdbms/wrapper/PostgresConn.cpp b/rdbms/wrapper/PostgresConn.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..5f7ec82aa94929601350745560a1de78e43d8878
--- /dev/null
+++ b/rdbms/wrapper/PostgresConn.cpp
@@ -0,0 +1,351 @@
+/*
+ * The CERN Tape Archive (CTA) project
+ * Copyright (C) 2019  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 "common/utils/utils.hpp"
+#include "common/exception/Exception.hpp"
+#include "common/exception/LostDatabaseConnection.hpp"
+#include "common/make_unique.hpp"
+#include "common/threading/RWLockRdLocker.hpp"
+#include "common/threading/RWLockWrLocker.hpp"
+
+#include "rdbms/Conn.hpp"
+#include "rdbms/wrapper/PostgresConn.hpp"
+#include "rdbms/wrapper/PostgresStmt.hpp"
+
+#include <stdio.h>
+#include <sstream>
+#include <exception>
+
+namespace cta {
+namespace rdbms {
+namespace wrapper {
+
+
+//------------------------------------------------------------------------------
+// constructor
+//------------------------------------------------------------------------------
+PostgresConn::PostgresConn(const std::string &conninfo)
+  : m_pgsqlConn(nullptr), m_asyncInProgress(false), m_nStmts(0) {
+
+  // establish the connection and create the PGconn data structure
+
+  m_pgsqlConn = PQconnectdb(conninfo.c_str());
+
+  if (PQstatus(m_pgsqlConn) != CONNECTION_OK) {
+    const std::string pqmsgstr = PQerrorMessage(m_pgsqlConn);
+    PQfinish(m_pgsqlConn);
+    m_pgsqlConn = nullptr;
+    throw exception::Exception(std::string(__FUNCTION__) + " connection failed: " + pqmsgstr);
+  }
+
+  const int sVer = PQserverVersion(m_pgsqlConn);
+  if (sVer < 90500) {
+    PQfinish(m_pgsqlConn);
+    m_pgsqlConn = nullptr;
+    const int maj = (sVer/10000) % 100;
+    const int min = (sVer/100) % 100;
+    const int rel = sVer % 100;
+    std::ostringstream msg;
+    msg << maj << "." << min << "." << rel;
+    throw exception::Exception(std::string(__FUNCTION__) +
+      " requires postgres server version be at least 9.5: the server is " + msg.str());
+  }
+
+  PQsetNoticeProcessor(m_pgsqlConn, PostgresConn::noticeProcessor, nullptr);
+}
+
+//------------------------------------------------------------------------------
+// destructor
+//------------------------------------------------------------------------------
+PostgresConn::~PostgresConn() {
+  try {
+    close();
+  } catch (...) {
+    // Destructor should not throw any exceptions
+  }
+}
+
+//------------------------------------------------------------------------------
+// close
+//------------------------------------------------------------------------------
+void PostgresConn::close() {
+  threading::RWLockWrLocker locker(m_lock);
+
+  closeAssumeLocked();
+}
+
+//------------------------------------------------------------------------------
+// commit
+//------------------------------------------------------------------------------
+void PostgresConn::commit() 
+{
+  threading::RWLockWrLocker locker(m_lock);
+
+  if (!isOpenAssumeLocked()) {
+    throw exception::Exception(std::string(__FUNCTION__) + " failed: Connection is closed");
+  }
+
+  if (isAsyncInProgress()) {
+    // if a Conn object is freeded and its ConnAndStmts object returned to its ConnPool while
+    // async is in progress, this exception will be thrown during the commit() in returnConn.
+    // The ConnAndStmts will be destroyed, and consequently this wrapper::Conn also
+    throw exception::Exception(std::string(__FUNCTION__) + " can not execute sql, another query is in progress");
+  }
+
+  Postgres::Result res(PQexec(m_pgsqlConn, "COMMIT"));
+  throwDBIfNotStatus(res.get(), PGRES_COMMAND_OK, std::string(__FUNCTION__) + " problem committing the DB transaction");
+}
+
+//------------------------------------------------------------------------------
+// createStmt
+//------------------------------------------------------------------------------
+std::unique_ptr<StmtWrapper> PostgresConn::createStmt(const std::string &sql) {
+
+  threading::RWLockRdLocker locker(m_lock);
+
+  try {
+    if(!isOpenAssumeLocked()) {
+      throw exception::Exception("Connection is closed");
+    }
+
+  } catch(exception::Exception &ex) {
+    throw exception::Exception(std::string(__FUNCTION__) + " failed: " + ex.getMessage().str());
+  }
+
+  // PostgresStmt constructor assumes conneciton is rd locked
+  return cta::make_unique<PostgresStmt>(*this, sql);
+}
+
+//------------------------------------------------------------------------------
+// executeNonQuery
+//------------------------------------------------------------------------------
+void PostgresConn::executeNonQuery(const std::string &sql) {
+  threading::RWLockWrLocker locker(m_lock);
+
+  if(!isOpenAssumeLocked()) {
+    throw exception::Exception(std::string(__FUNCTION__) + " failed: Connection is closed");
+  }
+
+  Postgres::Result res(PQexec(m_pgsqlConn, sql.c_str()));
+
+  // If this method is used for a query we will get PGRES_TUPLES_OK here
+  throwDBIfNotStatus(res.get(), PGRES_COMMAND_OK, std::string(__FUNCTION__) + " problem executing " + sql);
+}
+
+//------------------------------------------------------------------------------
+// getAutocommitMode
+//------------------------------------------------------------------------------
+AutocommitMode PostgresConn::getAutocommitMode() const noexcept{
+  return AutocommitMode::AUTOCOMMIT_ON;
+}
+
+//------------------------------------------------------------------------------
+// getSequenceNames
+//------------------------------------------------------------------------------
+std::list<std::string> PostgresConn::getSequenceNames() {
+  std::list<std::string> names;
+
+  threading::RWLockWrLocker locker(m_lock);
+
+  try {
+    if (!isOpenAssumeLocked()) {
+      throw exception::Exception("Connection is closed");
+    }
+
+    if (isAsyncInProgress()) {
+      throw exception::Exception("can not execute sql, another query is in progress");
+    }
+
+    Postgres::Result res(PQexec(m_pgsqlConn,
+       "SELECT c.relname AS SEQUENCE_NAME FROM pg_class c "
+         "WHERE c.relkind = 'S' ORDER BY SEQUENCE_NAME"
+       ));
+
+    throwDBIfNotStatus(res.get(), PGRES_TUPLES_OK, "Listing Sequences in the DB");
+
+    const int num_fields = PQnfields(res.get());
+    if (1 != num_fields) {
+      throw exception::Exception("number fields wrong during list sequences: Got " + std::to_string(num_fields));
+    }
+
+    for(int i=0;i<PQntuples(res.get());++i) {
+      std::string name = PQgetvalue(res.get(), i, 0);
+      utils::toUpper(name);
+      names.push_back(name);
+    }
+  } catch(exception::LostDatabaseConnection &ex) {
+    throw exception::LostDatabaseConnection(std::string(__FUNCTION__) + " detected lost connection: " + ex.getMessage().str());
+  } catch(exception::Exception &ex) {
+    throw exception::Exception(std::string(__FUNCTION__) + " failed: " + ex.getMessage().str());
+  }
+
+  return names;
+}
+
+//------------------------------------------------------------------------------
+// getTableNames
+//------------------------------------------------------------------------------
+std::list<std::string> PostgresConn::getTableNames() {
+  std::list<std::string> names;
+
+  threading::RWLockWrLocker locker(m_lock);
+
+  try {
+    if (!isOpenAssumeLocked()) {
+      throw exception::Exception("Connection is closed");
+    }
+
+    if (isAsyncInProgress()) {
+      throw exception::Exception("can not execute sql, another query is in progress");
+    }
+
+    Postgres::Result res(PQexec(m_pgsqlConn,
+       "SELECT c.tablename AS TABLE_NAME FROM pg_catalog.pg_tables c "
+         "WHERE c.schemaname NOT IN ('pg_catalog', 'information_schema') "
+         "ORDER BY TABLE_NAME"
+       ));
+
+    throwDBIfNotStatus(res.get(), PGRES_TUPLES_OK, "Listing table names in the DB");
+
+    const int num_fields = PQnfields(res.get());
+    if (1 != num_fields) {
+      throw exception::Exception("number fields wrong during list tables: Got " + std::to_string(num_fields));
+    }
+
+    for(int i=0;i<PQntuples(res.get());++i) {
+      std::string name = PQgetvalue(res.get(), i, 0);
+      utils::toUpper(name);
+      names.push_back(name);
+    }
+  } catch(exception::LostDatabaseConnection &ex) {
+    throw exception::LostDatabaseConnection(std::string(__FUNCTION__) + " detected lost connection: " + ex.getMessage().str());
+  } catch(exception::Exception &ex) {
+    throw exception::Exception(std::string(__FUNCTION__) + " failed: " + ex.getMessage().str());
+  }
+
+  return names;
+}
+
+//------------------------------------------------------------------------------
+// isOpen
+//------------------------------------------------------------------------------
+bool PostgresConn::isOpen() const {
+  threading::RWLockRdLocker locker(m_lock);
+  return isOpenAssumeLocked();
+}
+
+//------------------------------------------------------------------------------
+// rollback
+//------------------------------------------------------------------------------
+void PostgresConn::rollback() {
+  threading::RWLockWrLocker locker(m_lock);
+
+  if (!isOpenAssumeLocked()) {
+    throw exception::Exception(std::string(__FUNCTION__) + " failed: Connection is closed");
+  }
+
+  if (isAsyncInProgress()) {
+    throw exception::Exception(std::string(__FUNCTION__) + " can not execute sql, another query is in progress");
+  }
+
+  Postgres::Result res(PQexec(m_pgsqlConn, "ROLLBACK"));
+  throwDBIfNotStatus(res.get(), PGRES_COMMAND_OK, std::string(__FUNCTION__) + " problem rolling back the DB transaction");
+}
+
+//------------------------------------------------------------------------------
+// setAutocommitMode
+//------------------------------------------------------------------------------
+void PostgresConn::setAutocommitMode(const AutocommitMode autocommitMode) {
+  if(AutocommitMode::AUTOCOMMIT_OFF == autocommitMode) {
+    throw rdbms::Conn::AutocommitModeNotSupported("Failed to set autocommit mode to AUTOCOMMIT_OFF: PostgresConn only"
+      " supports AUTOCOMMIT_ON");
+  }
+}
+
+//------------------------------------------------------------------------------
+// closeAssumeLocked
+//------------------------------------------------------------------------------
+void PostgresConn::closeAssumeLocked() {
+  // assumes wr locked
+  if (isOpenAssumeLocked()) {
+    // this is an implicit rollback if there is a transaction ongoing
+    PQfinish(m_pgsqlConn);
+    m_pgsqlConn = nullptr;
+  }
+}
+
+//------------------------------------------------------------------------------
+// decallocateStmt
+//------------------------------------------------------------------------------
+void PostgresConn::deallocateStmt(const std::string &stmt) {
+  // assumes connection lock is held
+
+  std::ostringstream s;
+  s << "DEALLOCATE " << stmt;
+
+  Postgres::Result res(PQexec(m_pgsqlConn, s.str().c_str()));
+  throwDBIfNotStatus(res.get(), PGRES_COMMAND_OK, std::string(__FUNCTION__) + " failed to DEALLOCATE statement " + stmt);
+}
+
+//------------------------------------------------------------------------------
+// isOpenAssumeLocked
+//------------------------------------------------------------------------------
+
+bool PostgresConn::isOpenAssumeLocked() const {
+  // assumes rd locked
+  return CONNECTION_OK == PQstatus(m_pgsqlConn);
+}
+
+//------------------------------------------------------------------------------
+// nextStmtName
+//------------------------------------------------------------------------------
+std::string PostgresConn::nextStmtName() {
+  // assumes we have connection object wr lock
+  ++m_nStmts;
+  return "s" + std::to_string(m_nStmts);
+}
+
+//------------------------------------------------------------------------------
+// noticeProcessor
+//------------------------------------------------------------------------------
+void PostgresConn::noticeProcessor(void *arg, const char *message) {
+  //fprintf(stderr, "%s", message);
+}
+
+//------------------------------------------------------------------------------
+// throwDBIfNotStatus
+//------------------------------------------------------------------------------
+void PostgresConn::throwDBIfNotStatus(const PGresult *res,
+            const ExecStatusType requiredStatus, const std::string &prefix) {
+  // assumes connection wr lock held
+  if (PQresultStatus(res) != requiredStatus) {
+    try {
+      Postgres::ThrowInfo(m_pgsqlConn,res,prefix);
+    } catch(exception::LostDatabaseConnection &) {
+      try {
+        closeAssumeLocked();
+      } catch(std::exception &) {
+      }
+      throw;
+    }
+  } 
+}
+
+} // namespace wrapper
+} // namespace rdbms
+} // namespace cta
diff --git a/rdbms/wrapper/PostgresConn.hpp b/rdbms/wrapper/PostgresConn.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..373f03b92453b03d2da0f65823cdd3dfa16c815f
--- /dev/null
+++ b/rdbms/wrapper/PostgresConn.hpp
@@ -0,0 +1,223 @@
+/*
+ * The CERN Tape Archive (CTA) project
+ * Copyright (C) 2019  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/>.
+ */
+
+#pragma once
+
+#include "common/threading/RWLock.hpp"
+#include "rdbms/wrapper/ConnWrapper.hpp"
+#include "rdbms/wrapper/Postgres.hpp"
+
+#include <list>
+#include <memory>
+#include <string>
+#include <cstdint>
+
+namespace cta {
+namespace rdbms {
+namespace wrapper {
+
+class PostgresStmt;
+class PostgresRset;
+
+class PostgresConn: public ConnWrapper {
+public:
+
+  /**
+   * The PostgresStmt and PostgresRset classes need to use the RWLock in this class and use various private methods.
+   */
+  friend PostgresStmt;
+  friend PostgresRset;
+
+
+  /**
+   * Constructor.
+   *
+   * @param conninfo The conninfo string to pass to PQconnectdb. This is a postgres URI or a series of key=value pairs separated by white space.
+   * 
+   */
+  PostgresConn(const std::string &conninfo);
+
+  /**
+   * Destructor.
+   */
+  ~PostgresConn() override;
+
+  /**
+   * Idempotent close() method.  The destructor calls this method.
+   */
+  void close() override;
+
+  /**
+   * Commits the current transaction.
+   */
+  void commit() override;
+
+  /**
+   * Creates a prepared statement.
+   *
+   * @param sql The SQL statement.
+   * @return The prepared statement.
+   */
+  std::unique_ptr<StmtWrapper> createStmt(const std::string &sql) override;
+
+  /**
+   * Executes the sql string, without returning any result set.
+   *
+   * @param sql The SQL statement.
+   */
+  void executeNonQuery(const std::string &sql) override;
+
+  /**
+   * Returns the autocommit mode of the connection.
+   *
+   * @return The autocommit mode of the connection.
+   */
+  AutocommitMode getAutocommitMode() const noexcept override;
+
+  /**
+   * Returns the names of all the sequences in the database schema in
+   * alphabetical order.
+   *
+   * @return The names of all the sequences in the database schema in
+   * alphabetical order.
+   */
+  std::list<std::string> getSequenceNames() override;
+
+  /**
+   * Returns the names of all the tables in the database schema in alphabetical
+   * order.
+   *
+   * @return The names of all the tables in the database schema in alphabetical
+   * order.
+   */
+  std::list<std::string> getTableNames() override;
+
+  /**
+   * Returns true if this connection is open.
+   */
+  bool isOpen() const override;
+
+  /**
+   * Rolls back the current transaction.
+   */
+  void rollback() override;
+
+  /**
+   * Sets the autocommit mode of the connection.
+   *
+   * @param autocommitMode The autocommit mode of the connection.
+   * @throw AutocommitModeNotSupported If the specified autocommit mode is not
+   * supported.
+   */
+  void setAutocommitMode(const AutocommitMode autocommitMode) override;
+
+private:
+
+  /**
+   * Closes the conneciton, freeing the underlying libpq conneciton.
+   * Used by the public close() mehtod, without locking.
+   */
+  void closeAssumeLocked();
+
+  /**
+   * Deallocates the specified statement.
+   *
+   * @param stmt The name of the statement to be closed.
+   */
+  void deallocateStmt(const std::string &stmt);
+
+  /**
+   * Get the libpq postgres connection
+   */
+   PGconn* get() { return m_pgsqlConn; }
+
+  /**
+   * Getter for m_asyncInProgress
+   *
+   * @return m_asyncInProgress
+   */
+   bool isAsyncInProgress() const { return m_asyncInProgress; }
+
+  /**
+   * Indicates if this connection is open. This is an internal funciton,
+   * used by the public isOpen() method, without locking.
+   *
+   * @return true if this connection is open.
+   */
+  bool isOpenAssumeLocked() const;
+
+  /**
+   * Returns the name to be used for the next statement on this connection
+   *
+   * @return Name for next statement
+   */
+   std::string nextStmtName();
+
+  /**
+   * Function for handling postgres notices.
+   * This is a static member function.
+   */
+  static void noticeProcessor(void *arg, const char *message);
+
+  /**
+   * Setter for m_asyncInProgress
+   *
+   * @val Indicates if async command is ongoing.
+   */
+   void setAsyncInProgress(const bool val) { m_asyncInProgress=val; }
+
+  /**
+   * Conditionally throws a DB related exception if the result status is not the expected one
+   *
+   * @param res The PGresult
+   * @parm requiredStatus The required status
+   * @param prefix A prefix to place in the message if it is thrown
+   */
+  void throwDBIfNotStatus(const PGresult *res, const ExecStatusType requiredStatus, const std::string &prefix);
+
+  /**
+   * RW lock used to serialize access to the database connection or access to connection parameters.
+   */
+  mutable threading::RWLock m_lock;
+
+  /**
+   * represent postgres connection, used by libpq
+   */
+  PGconn* m_pgsqlConn;
+
+  /**
+   * indicate if we have sent a command that will send results or take data while
+   * it is processed by the server.
+   * New async (PQSend.. or a COPY) requests can not be started during this time, and
+   * if new sync commands are sent they will interrupt communiction with the
+   * ongoing async command.
+   */
+   bool m_asyncInProgress;
+
+  /**
+   * Counter for number of statements ever created.
+   * Used to ensure unique statement naming on the conneciton.
+   */
+   uint64_t m_nStmts;
+
+}; // class PostgresConn
+
+
+} // namespace wrapper
+} // namespace rdbms
+} // namespace cta
diff --git a/mediachanger/acs/CmdLineTool.cpp b/rdbms/wrapper/PostgresConnFactory.cpp
similarity index 57%
rename from mediachanger/acs/CmdLineTool.cpp
rename to rdbms/wrapper/PostgresConnFactory.cpp
index a3e7153c64c96ababd3773c047777cc61dbb3d2c..511359d50f279f55b6ed9b7e5b99b02e320bb6a2 100644
--- a/mediachanger/acs/CmdLineTool.cpp
+++ b/rdbms/wrapper/PostgresConnFactory.cpp
@@ -1,11 +1,11 @@
 /*
- * The CERN Tape Archive(CTA) project
- * Copyright(C) 2015  CERN
+ * The CERN Tape Archive (CTA) project
+ * Copyright (C) 2018  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.
+ * (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
@@ -16,26 +16,41 @@
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-#include "CmdLineTool.hpp"
+#include "common/exception/Exception.hpp"
+#include "common/make_unique.hpp"
+#include "rdbms/wrapper/PostgresConn.hpp"
+#include "rdbms/wrapper/PostgresConnFactory.hpp"
+
+#include <sstream>
+
+namespace cta {
+namespace rdbms {
+namespace wrapper {
 
 //------------------------------------------------------------------------------
 // constructor
 //------------------------------------------------------------------------------
-cta::mediachanger::acs::CmdLineTool::CmdLineTool(std::istream &inStream,
-  std::ostream &outStream, std::ostream &errStream):
-  m_in(inStream), m_out(outStream), m_err(errStream), m_debugBuf(outStream),
-  m_dbg(&m_debugBuf) {
+PostgresConnFactory::PostgresConnFactory(const std::string& conninfo)
+    : m_conninfo(conninfo) {
 }
 
 //------------------------------------------------------------------------------
 // destructor
 //------------------------------------------------------------------------------
-cta::mediachanger::acs::CmdLineTool::~CmdLineTool() {
+PostgresConnFactory::~PostgresConnFactory() {
 }
 
 //------------------------------------------------------------------------------
-// bool2Str
+// create
 //------------------------------------------------------------------------------
-std::string cta::mediachanger::acs::CmdLineTool::bool2Str(const bool value) const {
-  return value ? "TRUE" : "FALSE";
+std::unique_ptr<ConnWrapper> PostgresConnFactory::create() {
+  try {
+    return cta::make_unique<PostgresConn>(m_conninfo);
+  } catch(exception::Exception &ex) {
+    throw exception::Exception(std::string(__FUNCTION__) + " failed: " + ex.getMessage().str());
+  }
 }
+
+} // namespace wrapper
+} // namespace rdbms
+} // namespace cta
diff --git a/rdbms/wrapper/PostgresConnFactory.hpp b/rdbms/wrapper/PostgresConnFactory.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..5ea1caf4204a040e0f4b46b49d232430d159c0e4
--- /dev/null
+++ b/rdbms/wrapper/PostgresConnFactory.hpp
@@ -0,0 +1,66 @@
+/*
+ * The CERN Tape Archive (CTA) project
+ * Copyright (C) 2018  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/>.
+ */
+
+#pragma once
+
+#include "rdbms/wrapper/ConnFactory.hpp"
+
+#include <vector>
+
+namespace cta {
+namespace rdbms {
+namespace wrapper {
+
+/**
+ * A concrete factory of Conn objects.
+ */
+class PostgresConnFactory: public ConnFactory {
+public:
+
+  /**
+   * Constructor.
+   *
+   * @param conninfo The conninfo string to pass to PQconnectdb. This is a series of key=value pairs separated by white space.
+   *
+   */
+  PostgresConnFactory(const std::string& conninfo);
+
+  /**
+   * Destructor.
+   */
+  ~PostgresConnFactory() override;
+
+  /**
+   * Returns a newly created database connection.
+   *
+   * @return A newly created database connection.
+   */
+  std::unique_ptr<ConnWrapper> create() override;
+
+private:
+
+  /**
+   * The conninfo string
+   */
+  std::string m_conninfo;
+
+}; // class PostgresConnFactory
+
+} // namespace wrapper
+} // namespace rdbms
+} // namespace cta
diff --git a/rdbms/wrapper/PostgresRset.cpp b/rdbms/wrapper/PostgresRset.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..3ba8ab0de5ff793ac34709f0ab75231de8407a49
--- /dev/null
+++ b/rdbms/wrapper/PostgresRset.cpp
@@ -0,0 +1,187 @@
+/*
+ * The CERN Tape Archive (CTA) project
+ * Copyright (C) 2019  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 "common/utils/utils.hpp"
+#include "common/exception/Exception.hpp"
+#include "rdbms/wrapper/PostgresRset.hpp"
+#include "rdbms/wrapper/PostgresStmt.hpp"
+#include "rdbms/wrapper/PostgresConn.hpp"
+#include "common/threading/RWLockWrLocker.hpp"
+
+#include <utility>
+
+namespace cta {
+namespace rdbms {
+namespace wrapper {
+
+//------------------------------------------------------------------------------
+// constructor
+//------------------------------------------------------------------------------
+PostgresRset::PostgresRset(PostgresConn &conn, PostgresStmt &stmt, std::unique_ptr<Postgres::ResultItr> resItr)
+  : m_conn(conn), m_stmt(stmt), m_resItr(std::move(resItr)), m_asyncCleared(false), m_nfetched(0) {
+
+  // assumes statement and connection locks have already been taken
+  if (!m_conn.isAsyncInProgress()) {
+    throw exception::Exception(std::string(__FUNCTION__) + " unexpected: async flag not set");
+  }
+}
+
+//------------------------------------------------------------------------------
+// destructor.
+//------------------------------------------------------------------------------
+PostgresRset::~PostgresRset() {
+
+  try {
+    threading::RWLockWrLocker locker(m_conn.m_lock);
+
+    m_resItr->clear();
+    doClearAsync();
+  } catch(...) {
+    // Destructor should not throw any exceptions
+  }
+}
+
+//------------------------------------------------------------------------------
+// columnIsNull
+//------------------------------------------------------------------------------
+bool PostgresRset::columnIsNull(const std::string &colName) const {
+
+  if (nullptr == m_resItr->get()) {
+    throw exception::Exception(std::string(__FUNCTION__) + " no row available");
+  }
+
+  const int ifield = PQfnumber(m_resItr->get(), colName.c_str());
+  if (ifield < 0) {
+    throw exception::Exception(std::string(__FUNCTION__) + " column does not exist: " + colName);
+  }
+
+  return PQgetisnull(m_resItr->get(), 0, ifield);
+}
+
+//------------------------------------------------------------------------------
+// columnOptionalString
+//------------------------------------------------------------------------------
+optional<std::string> PostgresRset::columnOptionalString(const std::string &colName) const {
+
+  if (nullptr == m_resItr->get()) {
+    throw exception::Exception(std::string(__FUNCTION__) + " no row available");
+  }
+
+  const int ifield = PQfnumber(m_resItr->get(), colName.c_str());
+  if (ifield < 0) {
+    throw exception::Exception(std::string(__FUNCTION__) + " column does not exist: " + colName);
+  }
+
+  // the value can be null
+  if (PQgetisnull(m_resItr->get(), 0, ifield)) {
+    return nullopt;
+  }
+
+  return optional<std::string>(PQgetvalue(m_resItr->get(), 0, ifield));
+}
+
+//------------------------------------------------------------------------------
+// columnOptionalUint64
+//------------------------------------------------------------------------------
+optional<uint64_t> PostgresRset::columnOptionalUint64(const std::string &colName) const {
+
+  if (nullptr == m_resItr->get()) {
+    throw exception::Exception(std::string(__FUNCTION__) + " no row available");
+  }
+
+  const int ifield = PQfnumber(m_resItr->get(), colName.c_str());
+  if (ifield < 0) {
+    throw exception::Exception(std::string(__FUNCTION__) + " column does not exist: " + colName);
+  }
+
+  // the value can be null
+  if (PQgetisnull(m_resItr->get(), 0, ifield)) {
+    return nullopt;
+  }
+
+  const std::string stringValue(PQgetvalue(m_resItr->get(), 0, ifield));
+
+  if(!utils::isValidUInt(stringValue)) {
+    throw exception::Exception(std::string("Column ") + colName + " contains the value " + stringValue +
+      " which is not a valid unsigned integer");
+  }
+
+  return utils::toUint64(stringValue);
+}
+
+//------------------------------------------------------------------------------
+// getSql
+//------------------------------------------------------------------------------
+const std::string &PostgresRset::getSql() const {
+  return m_stmt.getSql();
+}
+
+//------------------------------------------------------------------------------
+// next
+//------------------------------------------------------------------------------
+bool PostgresRset::next() {
+
+  // always locks in order statement and then connection
+  threading::RWLockWrLocker locker2(m_stmt.m_lock);
+  threading::RWLockWrLocker locker(m_conn.m_lock);
+
+  if (m_resItr->next()) {
+
+    // For queries expect rcode PGRES_SINGLE_TUPLE with ntuples=1 for each row,
+    // followed by PGRES_TUPLES_OK and ntuples=0 at the end.
+    // A non query would give PGRES_COMMAND_OK but we don't accept this here
+    // as a Rset is intended for an executeQuery only.
+
+    if (PGRES_TUPLES_OK == m_resItr->rcode() && 0 == PQntuples(m_resItr->get())) {
+      const std::string stringValue = PQcmdTuples(m_resItr->get());
+      if (!stringValue.empty()) {
+        m_stmt.setAffectedRows(utils::toUint64(stringValue));
+      }
+      m_resItr->clear();
+      doClearAsync();
+      return false;
+    }
+    if (PGRES_SINGLE_TUPLE == m_resItr->rcode() && 1 == PQntuples(m_resItr->get())) {
+      ++m_nfetched;
+      m_stmt.setAffectedRows(m_nfetched);
+      return true;
+    }
+    m_resItr->clear();
+    doClearAsync();
+    m_stmt.throwDB(m_resItr->get(), std::string(__FUNCTION__) + " failed while fetching results");
+  }
+  doClearAsync();
+  m_stmt.doConnectionCheck();
+  return false;
+}
+
+//------------------------------------------------------------------------------
+// doClearAsync
+//------------------------------------------------------------------------------
+void PostgresRset::doClearAsync() {
+  // assumes we have lock on connection
+  if (!m_asyncCleared) {
+    m_conn.setAsyncInProgress(false);
+    m_asyncCleared = true;
+  }
+}
+
+
+} // namespace wrapper
+} // namespace rdbms
+} // namespace cta
diff --git a/rdbms/wrapper/PostgresRset.hpp b/rdbms/wrapper/PostgresRset.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..1abc4fa9c2cae01731905c59d066e82c5d253a7e
--- /dev/null
+++ b/rdbms/wrapper/PostgresRset.hpp
@@ -0,0 +1,136 @@
+/*
+ * The CERN Tape Archive (CTA) project
+ * Copyright (C) 2019  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/>.
+ */
+
+#pragma once
+
+#include "common/optional.hpp"
+#include "rdbms/wrapper/RsetWrapper.hpp"
+#include "rdbms/wrapper/Postgres.hpp"
+#include "rdbms/wrapper/PostgresConn.hpp"
+#include "rdbms/wrapper/PostgresStmt.hpp"
+
+#include <string>
+#include <cstdint>
+#include <memory>
+
+namespace cta {
+namespace rdbms {
+namespace wrapper {
+
+/**
+ * The result set of an sql query.
+ */
+class PostgresRset: public RsetWrapper {
+public:
+
+  /**
+   * Constructor.
+   *
+   * @param conn The Conn
+   * @param stmt The prepared statement.
+   * @param res The result set.
+   */
+  PostgresRset(PostgresConn &conn, PostgresStmt &stmt, std::unique_ptr<Postgres::ResultItr> resitr);
+
+  /**
+   * Destructor.
+   */
+  ~PostgresRset() override;
+
+  /**
+   * Returns true if the specified column contains a null value.
+   *
+   * @param colName The name of the column.
+   * @return True if the specified column contains a null value.
+   */
+  bool columnIsNull(const std::string &colName) const override;
+
+  /**
+   * Returns the value of the specified column as a string.
+   *
+   * This method will return a null column value as an optional with no value.
+   *
+   * @param colName The name of the column.
+   * @return The string value of the specified column.
+   */
+  optional<std::string> columnOptionalString(const std::string &colName) const override;
+
+  /**
+   * Returns the value of the specified column as an integer.
+   *
+   * This method will return a null column value as an optional with no value.
+   *
+   * @param colName The name of the column.
+   * @return The value of the specified column.
+   */
+  optional<uint64_t> columnOptionalUint64(const std::string &colName) const override;
+
+  /**
+   * Returns the SQL statement.
+   *
+   * @return The SQL statement.
+   */
+  const std::string &getSql() const override;
+
+  /**
+   * Attempts to get the next row of the result set.
+   *
+   * @return True if a row has been retrieved else false if there are no more
+   * rows in the result set.
+   */
+  bool next() override;
+
+private:
+
+  /**
+   * Clears the async command in process indicator on our conneciton,
+   * if we haven't done so already.
+   */
+  void doClearAsync();
+
+  /**
+   * The SQL connection.
+   */
+  PostgresConn &m_conn;
+
+  /**
+   * The prepared statement.
+   */
+  PostgresStmt &m_stmt;
+
+  /**
+   * The result set iterator
+   */
+  std::unique_ptr<Postgres::ResultItr> m_resItr;
+
+  /**
+   * Indicates we have cleared the async in progress flag of the conneciton.
+   * This is to make sure we don't clear it more than once
+   */
+  bool m_asyncCleared;
+
+  /**
+   * Number fetched, used for setting the number of affected rows of the statement.
+   */
+  uint64_t m_nfetched;
+
+}; // class PostgresRset
+
+} // namespace wrapper
+} // namespace rdbms
+} // namespace cta
diff --git a/rdbms/wrapper/PostgresStmt.cpp b/rdbms/wrapper/PostgresStmt.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..2c3882516a1451702d089e889aa8d1b94b5ff4ca
--- /dev/null
+++ b/rdbms/wrapper/PostgresStmt.cpp
@@ -0,0 +1,585 @@
+/*
+ * The CERN Tape Archive (CTA) project
+ * Copyright (C) 2019  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 "common/utils/utils.hpp"
+#include "common/exception/Exception.hpp"
+#include "common/exception/LostDatabaseConnection.hpp"
+#include "common/make_unique.hpp"
+#include "common/threading/RWLockWrLocker.hpp"
+#include "common/threading/RWLockRdLocker.hpp"
+
+#include "rdbms/wrapper/PostgresColumn.hpp"
+#include "rdbms/wrapper/PostgresConn.hpp"
+#include "rdbms/wrapper/PostgresRset.hpp"
+#include "rdbms/wrapper/PostgresStmt.hpp"
+
+#include <exception>
+#include <sstream>
+#include <utility>
+#include <algorithm>
+
+namespace cta {
+namespace rdbms {
+namespace wrapper {
+
+//------------------------------------------------------------------------------
+// constructor
+//------------------------------------------------------------------------------
+PostgresStmt::PostgresStmt(
+  PostgresConn &conn,
+  const std::string &sql):
+  StmtWrapper(sql),
+  m_conn(conn),
+  m_nParams(0),
+  m_nbAffectedRows(0) {
+
+  // connection is rd locked
+
+  CountAndReformatSqlBinds(sql,m_pgsql,m_nParams);
+
+  m_paramValues = std::vector<std::string>(m_nParams);
+  m_paramValuesPtrs = std::vector<const char*>(m_nParams);
+  m_columnPtrs = std::vector<PostgresColumn*>(m_nParams);
+}
+
+//------------------------------------------------------------------------------
+// destructor
+//------------------------------------------------------------------------------
+PostgresStmt::~PostgresStmt() {
+  try {
+    close(); // Idempotent close() method
+  } catch(...) {
+    // Destructor does not throw
+  }
+}
+
+//------------------------------------------------------------------------------
+// bindOptionalString
+//------------------------------------------------------------------------------
+void PostgresStmt::bindOptionalString(const std::string &paramName, const optional<std::string> &paramValue) {
+  threading::RWLockWrLocker locker(m_lock);
+  try {
+    if(paramValue && paramValue.value().empty()) {
+      throw exception::Exception(std::string("Optional string parameter ") + paramName + " is an empty string. "
+        "An optional string parameter should either have a non-empty string value or no value at all.");
+    }
+
+    const unsigned int paramIdx = getParamIdx(paramName); // starts from 1.
+
+    if (paramIdx==0 || paramIdx>m_paramValues.size()) {
+      throw exception::Exception(std::string("Bad index for paramName ") + paramName);
+    }
+
+    const unsigned int idx = paramIdx - 1;
+
+    if (paramValue) {
+      // we must not cause the vector m_paramValues to resize, otherwise the c-pointers can be invalidated
+      m_paramValues[idx] = paramValue.value();
+      m_paramValuesPtrs[idx] = m_paramValues[idx].c_str();
+    } else {
+      m_paramValues[idx].clear();
+      m_paramValuesPtrs[idx] = nullptr;
+    }
+
+  } catch(exception::Exception &ex) {
+    throw exception::Exception(std::string(__FUNCTION__) + " failed for SQL statement " +
+      getSqlForException() + ": " + ex.getMessage().str()); 
+  }
+}
+
+//------------------------------------------------------------------------------
+// bindOptionalUint64
+//------------------------------------------------------------------------------
+void PostgresStmt::bindOptionalUint64(const std::string &paramName, const optional<uint64_t> &paramValue) {
+  threading::RWLockWrLocker locker(m_lock);
+
+  try {
+    const unsigned int paramIdx = getParamIdx(paramName); // starts from 1.
+
+    if (paramIdx==0 || paramIdx>m_paramValues.size()) {
+      throw exception::Exception(std::string("Bad index for paramName ") + paramName);
+    }
+
+    const unsigned int idx = paramIdx - 1;
+    if (paramValue) {
+      // we must not cause the vector m_paramValues to resize, otherwise the c-pointers can be invalidated
+      m_paramValues[idx] = std::to_string(paramValue.value());
+      m_paramValuesPtrs[idx] = m_paramValues[idx].c_str();
+    } else {
+      m_paramValues[idx].clear();
+      m_paramValuesPtrs[idx] = nullptr;
+    }
+  } catch(exception::Exception &ex) {
+    throw exception::Exception(std::string(__FUNCTION__) + " failed for SQL statement " +
+      getSqlForException() + ": " + ex.getMessage().str());
+  }
+}
+
+//------------------------------------------------------------------------------
+// bindString
+//------------------------------------------------------------------------------
+void PostgresStmt::bindString(const std::string &paramName, const std::string &paramValue) {
+  try {
+    bindOptionalString(paramName, paramValue);
+  } catch(exception::Exception &ex) {
+    throw exception::Exception(std::string(__FUNCTION__) + " failed: " + ex.getMessage().str());
+  }
+}
+
+//------------------------------------------------------------------------------
+// bindUint64
+//------------------------------------------------------------------------------
+void PostgresStmt::bindUint64(const std::string &paramName, const uint64_t paramValue) {
+  try {
+    bindOptionalUint64(paramName, paramValue);
+  } catch(exception::Exception &ex) {
+    throw exception::Exception(std::string(__FUNCTION__) + " failed: " + ex.getMessage().str());
+  }
+}
+
+//------------------------------------------------------------------------------
+// clear
+//------------------------------------------------------------------------------
+void PostgresStmt::clear() {
+  threading::RWLockWrLocker locker(m_lock);
+
+  clearAssumeLocked();
+}
+
+//------------------------------------------------------------------------------
+// close
+//------------------------------------------------------------------------------
+void PostgresStmt::close() {
+
+  // always take statement lock first
+  threading::RWLockWrLocker locker2(m_lock);
+  threading::RWLockWrLocker locker(m_conn.m_lock);
+
+  closeAssumeLocked();
+}
+
+//------------------------------------------------------------------------------
+// executeCopyInsert
+//------------------------------------------------------------------------------
+void PostgresStmt::executeCopyInsert(const size_t rows) {
+  // always take statement lock first
+  threading::RWLockWrLocker locker2(m_lock);
+  threading::RWLockWrLocker locker(m_conn.m_lock);
+
+  try {
+    // check connection first
+    if (!m_conn.isOpenAssumeLocked()) {
+      throw exception::Exception("Connection is closed");
+    }
+
+    if (m_conn.isAsyncInProgress()) {
+      throw exception::Exception("can not execute sql, another query is in progress");
+    }
+
+    for(const auto p: m_columnPtrs) {
+      if (nullptr == p) {
+        throw exception::Exception("not all columns have been set with setColumn");
+      }
+      if (p->getNbRows() < rows) {
+        std::ostringstream msg;
+        msg << "Column " << p->getColName() << " has " << p->getNbRows()
+          << " rows, which is less than the requested number " << rows;
+        throw exception::Exception(msg.str());
+      }
+    }
+
+    int nfields=0, binType=0;
+    {
+      Postgres::Result res(PQexec(m_conn.get(), m_pgsql.c_str()));
+      throwDBIfNotStatus(res.get(), PGRES_COPY_IN, "Starting COPY (bulk insert)");
+      nfields = PQnfields(res.get());
+      binType = PQbinaryTuples(res.get());
+    }
+
+    std::ostringstream msg;
+    if (nfields != m_nParams) {
+      msg << "Wrong number of fields: Copy expected " << nfields << ", we have " << m_nParams;
+    } else if (0 != binType) {
+      msg << "COPY is expecting binary data, not textual data";
+    } else {
+      try {
+        doCopyData(rows);
+      } catch(exception::Exception &ex) {
+        msg << "PQputCopyData failed: " << ex.getMessage().str();
+      }
+    }
+
+    bool err = false;
+    std::string pqmsgstr;
+    int iret=0;
+
+    if (msg.str().empty()) {
+      iret = PQputCopyEnd(m_conn.get(), nullptr);
+      doConnectionCheck();
+    } else {
+      iret = PQputCopyEnd(m_conn.get(), msg.str().c_str());
+      err = true;
+      pqmsgstr = msg.str();
+    }
+
+    if (iret<0 && !err) {
+      err = true;
+      pqmsgstr = PQerrorMessage(m_conn.get());
+    }
+
+    Postgres::ResultItr resItr(m_conn.get());
+    // check first result
+    resItr.next();
+    doConnectionCheck();
+    if (!err) {
+      if (PGRES_COMMAND_OK != resItr.rcode()) {
+        pqmsgstr = PQerrorMessage(m_conn.get());
+        err = true;
+      }
+    }
+    if (err) {
+      throw exception::Exception(pqmsgstr);
+    }
+
+    m_nbAffectedRows = 0;
+    const std::string stringValue = PQcmdTuples(resItr.get());
+    if (!stringValue.empty()) {
+      m_nbAffectedRows = utils::toUint64(stringValue);
+    }
+
+  } catch(exception::LostDatabaseConnection &ex) {
+    throw exception::LostDatabaseConnection(std::string(__FUNCTION__) +
+      " detected lost connection for SQL statement " + getSqlForException() + ": " + ex.getMessage().str());
+  } catch(exception::Exception &ex) {
+    throw exception::Exception(std::string(__FUNCTION__) + " failed for SQL statement " +
+      getSqlForException() + ": " + ex.getMessage().str());
+  }
+}
+
+//------------------------------------------------------------------------------
+// executeNonQuery
+//------------------------------------------------------------------------------
+void PostgresStmt::executeNonQuery() {
+
+  // always take statement lock first
+  threading::RWLockWrLocker locker2(m_lock);
+  threading::RWLockWrLocker locker(m_conn.m_lock);
+
+  try {
+    // check connection first
+    if (!m_conn.isOpenAssumeLocked()) {
+      throw exception::Exception("Connection is closed");
+    }
+
+    if (m_conn.isAsyncInProgress()) {
+      throw exception::Exception("can not execute sql, another query is in progress");
+    }
+
+    if (m_stmt.empty()) {
+      doPrepare();
+    }
+
+    doPQsendPrepared();
+    Postgres::ResultItr resItr(m_conn.get());
+
+    m_nbAffectedRows = 0;
+    resItr.next();
+
+    // If this method is used for a query we will get PGRES_TUPLES_OK here
+    throwDBIfNotStatus(resItr.get(), PGRES_COMMAND_OK, "Executing non query statement");
+
+    const std::string stringValue = PQcmdTuples(resItr.get());
+    if (!stringValue.empty()) {
+      m_nbAffectedRows = utils::toUint64(stringValue);
+    }
+
+  } catch(exception::LostDatabaseConnection &ex) {
+    throw exception::LostDatabaseConnection(std::string(__FUNCTION__) +
+      " detected lost connection for SQL statement " + getSqlForException() + ": " + ex.getMessage().str());
+  } catch(exception::Exception &ex) {
+    throw exception::Exception(std::string(__FUNCTION__) + " failed for SQL statement " +
+      getSqlForException() + ": " + ex.getMessage().str());
+  }
+}
+
+//------------------------------------------------------------------------------
+// executeQuery
+//------------------------------------------------------------------------------
+std::unique_ptr<RsetWrapper> PostgresStmt::executeQuery() {
+
+  // always take statement lock first
+  threading::RWLockWrLocker locker2(m_lock);
+  threading::RWLockWrLocker locker(m_conn.m_lock);
+
+  bool isasync = m_conn.isAsyncInProgress();
+
+  try {
+    // check connection first
+    if (!m_conn.isOpenAssumeLocked()) {
+      throw exception::Exception("Connection is closed");
+    }
+
+    if (m_conn.isAsyncInProgress()) {
+      throw exception::Exception("can not execute sql, another query is in progress");
+    }
+
+    if (m_stmt.empty()) {
+      doPrepare();
+    }
+
+    doPQsendPrepared();
+    const int iret = PQsetSingleRowMode(m_conn.get());
+    auto resItr = cta::make_unique<Postgres::ResultItr>(m_conn.get());
+
+    if (1 != iret) {
+      throwDB(nullptr, "Executing query statement");
+    }
+
+    m_nbAffectedRows = 0;
+    m_conn.setAsyncInProgress(true);
+
+    return cta::make_unique<PostgresRset>(m_conn, *this, std::move(resItr));
+  } catch(exception::LostDatabaseConnection &ex) {
+    // reset to initial value
+    m_conn.setAsyncInProgress(isasync);
+    throw exception::LostDatabaseConnection(std::string(__FUNCTION__) +
+      " detected lost connection for SQL statement " + getSqlForException() + ": " + ex.getMessage().str());
+  } catch(exception::Exception &ex) {
+    // reset to initial value
+    m_conn.setAsyncInProgress(isasync);
+    throw exception::Exception(std::string(__FUNCTION__) + " failed for SQL statement " +
+      getSqlForException() + ": " + ex.getMessage().str());
+  } catch(std::exception &) {
+    // reset to initial value
+    m_conn.setAsyncInProgress(isasync);
+    throw;
+  }
+}
+
+//------------------------------------------------------------------------------
+// getNbAffectedRows
+//------------------------------------------------------------------------------
+uint64_t PostgresStmt::getNbAffectedRows() const {
+  threading::RWLockRdLocker locker(m_lock);
+  return m_nbAffectedRows;
+}
+
+//------------------------------------------------------------------------------
+// setColumn
+//------------------------------------------------------------------------------
+void PostgresStmt::setColumn(PostgresColumn &col) {
+  threading::RWLockWrLocker locker(m_lock);
+  try {
+    const std::string paramName = std::string(":") + col.getColName();
+    const auto paramIdx = getParamIdx(paramName);
+    if (paramIdx==0 || paramIdx>m_columnPtrs.size()) {
+      throw exception::Exception(std::string("Bad index for paramName ") + paramName);
+    }
+    const unsigned int idx = paramIdx - 1;
+    m_columnPtrs[idx] = &col;
+  } catch(exception::Exception &ex) {
+    throw exception::Exception(std::string(__FUNCTION__) + " failed for SQL statement " +
+      getSqlForException() + ": " + ex.getMessage().str());
+  }
+}
+
+//------------------------------------------------------------------------------
+// clearAssumeLocked
+//------------------------------------------------------------------------------
+void PostgresStmt::clearAssumeLocked() {
+  // assumes statement lock is taken rw
+
+  m_paramValues = std::vector<std::string>(m_nParams);
+  m_paramValuesPtrs = std::vector<const char*>(m_nParams);
+  m_columnPtrs = std::vector<PostgresColumn*>(m_nParams);
+}
+
+//------------------------------------------------------------------------------
+// closeAssumeLocked
+//------------------------------------------------------------------------------
+void PostgresStmt::closeAssumeLocked() {
+
+  // assumes both statement and connection locks held rw
+
+  if (m_stmt.empty()) {
+    return;
+  }
+
+  try {
+    clearAssumeLocked();
+    const std::string stmt = m_stmt;
+    m_stmt.clear();
+    m_conn.deallocateStmt(stmt);
+
+  } catch(exception::Exception &ex) {
+    throw exception::Exception(std::string(__FUNCTION__) + " failed for SQL statement " +
+      getSqlForException() + ": " + ex.getMessage().str());
+  }
+}
+
+//------------------------------------------------------------------------------
+// closeBoth
+//------------------------------------------------------------------------------
+void PostgresStmt::closeBoth() {
+  // assumes both statement and connection locks held
+  try {
+    closeAssumeLocked();
+  } catch(std::exception &) {
+    // nothing
+  }
+  try {
+    m_conn.closeAssumeLocked();
+  } catch(std::exception &) {
+    // nothing
+  }
+}
+
+//------------------------------------------------------------------------------
+// CountAndReformatSqlBinds
+//------------------------------------------------------------------------------
+void PostgresStmt::CountAndReformatSqlBinds(const std::string &common_sql, std::string &pg_sql, int &nParams) const {
+  nParams = 0;
+  pg_sql = common_sql;
+  // if found :name, replace it with '$<n>'
+  while (true) {
+    // find start of :name
+    const auto itr = std::find(pg_sql.begin(),pg_sql.end(),':');
+    if (itr == pg_sql.end()) {
+      break;
+    }
+    // find end of :name
+    const auto itr2 = std::find_if_not(itr+1,pg_sql.end(),ParamNameToIdx::isValidParamNameChar);
+    ++nParams;
+    const std::string r = "$" + std::to_string(nParams);
+    pg_sql.replace(itr,itr2,r);
+  }
+}
+
+//------------------------------------------------------------------------------
+// doPQsendPrepared
+//------------------------------------------------------------------------------
+void PostgresStmt::doPQsendPrepared() {
+  // assumes the connection and statement locks have been taken
+
+  const char **params = nullptr;
+  if (m_nParams>0) {
+    params = &m_paramValuesPtrs[0];
+  }
+
+  const int iret = PQsendQueryPrepared(m_conn.get(), m_stmt.c_str(), m_nParams, params, nullptr, nullptr, 0);
+  if (1 != iret) {
+    throwDB(nullptr, "Executing a prepared statement");
+  }
+}
+
+//------------------------------------------------------------------------------
+// doConnectionCheck
+//------------------------------------------------------------------------------
+void PostgresStmt::doConnectionCheck() {
+  // assumes both statement and connection are locked
+  if ( !m_conn.isOpenAssumeLocked() ) {
+    closeBoth();
+    throw exception::LostDatabaseConnection("Database connection has been lost");
+  }
+}
+
+//------------------------------------------------------------------------------
+// doCopyData
+//------------------------------------------------------------------------------
+void PostgresStmt::doCopyData(const size_t rows) {
+  for(size_t i=0;i<rows;++i) {
+    m_copyRow.clear();
+    for(int j=0;j<m_nParams;++j) {
+      const char *const val = m_columnPtrs[j]->getValue(i);
+      std::string field;
+      if (nullptr != val) {
+        field = val;
+        replaceAll(field, "\\", "\\\\");
+        replaceAll(field, "\n", "\\\n");
+        replaceAll(field, "\r", "\\\r");
+        replaceAll(field, "\t", "\\\t");
+      } else {
+        field = "\\N";
+      }
+      if (!m_copyRow.empty()) {
+        m_copyRow += "\t";
+      }
+      m_copyRow += field;
+    }
+    m_copyRow += "\n";
+    const int iret = PQputCopyData(m_conn.get(), m_copyRow.c_str(), m_copyRow.size());
+    if (iret < 0) {
+      throwDB(nullptr, "Writing bulk insert data to the database");
+    }
+  }
+}
+
+//------------------------------------------------------------------------------
+// doPrepare
+//------------------------------------------------------------------------------
+void PostgresStmt::doPrepare() {
+  // assumes the connection object is aleady rw locked, and open and not in async
+
+  const std::string stmtName = m_conn.nextStmtName();
+
+  Postgres::Result res(PQprepare(m_conn.get(), stmtName.c_str(), m_pgsql.c_str(), m_nParams, nullptr));
+  throwDBIfNotStatus(res.get(), PGRES_COMMAND_OK, "Preparing a statement");
+
+  m_stmt = stmtName;
+}
+
+//------------------------------------------------------------------------------
+// replaceAll
+//------------------------------------------------------------------------------
+void PostgresStmt::replaceAll(std::string& str, const std::string& from, const std::string& to) const {
+  if(from.empty()) {
+    return;
+  }
+  size_t start_pos = 0;
+  while((start_pos = str.find(from, start_pos)) != std::string::npos) {
+    str.replace(start_pos, from.length(), to);
+    start_pos += to.length(); // In case to contains from
+  }
+}
+
+//------------------------------------------------------------------------------
+// throwDB
+//------------------------------------------------------------------------------
+void PostgresStmt::throwDB(const PGresult *res, const std::string &prefix) {
+  // assums both statement and connection lock held
+  try {
+    Postgres::ThrowInfo(m_conn.get(),res,prefix);
+  } catch(exception::LostDatabaseConnection &) {
+    closeBoth();
+    throw;
+  }
+}
+
+//------------------------------------------------------------------------------
+// throwDBIfNotStatus
+//------------------------------------------------------------------------------
+void PostgresStmt::throwDBIfNotStatus(const PGresult *res,
+          const ExecStatusType requiredStatus, const std::string &prefix) {
+  if (PQresultStatus(res) != requiredStatus) {
+    throwDB(res, prefix);
+  }
+}
+
+} // Namespace wrapper
+} // namespace rdbms
+} // namespace cta
diff --git a/rdbms/wrapper/PostgresStmt.hpp b/rdbms/wrapper/PostgresStmt.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..e0e91648a471753e6985f11cf63875ef15ce0286
--- /dev/null
+++ b/rdbms/wrapper/PostgresStmt.hpp
@@ -0,0 +1,291 @@
+/*
+ * The CERN Tape Archive (CTA) project
+ * Copyright (C) 2019  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/>.
+ */
+
+#pragma once
+
+#include "common/optional.hpp"
+#include "common/threading/RWLock.hpp"
+#include "rdbms/wrapper/StmtWrapper.hpp"
+#include "rdbms/wrapper/Postgres.hpp"
+#include "rdbms/wrapper/PostgresConn.hpp"
+#include "rdbms/wrapper/PostgresColumn.hpp"
+
+#include <vector>
+#include <string>
+#include <memory>
+#include <cstdint>
+
+namespace cta {
+namespace rdbms {
+namespace wrapper {
+
+class PostgresRset;
+
+/**
+ * A convenience wrapper around a postgres prepared statement.
+ */
+class PostgresStmt: public StmtWrapper {
+public:
+
+  /**
+   * The PostgresRset class needs to use the lock in this class and a private method.
+   */
+  friend PostgresRset;
+
+  /**
+   * Constructor.
+   *
+   * This method is called by the PostgresConn::createStmt() method and assumes
+   * that a rd lock has already been taken on PostgresConn lock.
+   *
+   * @param conn The database connection.
+   * @param sql The SQL statement.
+   */
+  PostgresStmt(PostgresConn &conn, const std::string &sql);
+
+  /**
+   * Destructor.
+   */
+  ~PostgresStmt() override;
+
+  /** 
+   * Binds an SQL parameter of type optional-string.
+   *
+   * Please note that this method will throw an exception if the optional string
+   * parameter has the empty string as its value.  An optional string parameter
+   * should either have a non-empty string value or no value at all.
+   *
+   * @param paramName The name of the parameter.
+   * @param paramValue The value to be bound.
+   */ 
+  void bindOptionalString(const std::string &paramName, const optional<std::string> &paramValue) override;
+
+  /**
+   * Binds an SQL parameter.
+   *
+   * @param paramName The name of the parameter.
+   * @param paramValue The value to be bound.
+   */
+  void bindOptionalUint64(const std::string &paramName, const optional<uint64_t> &paramValue) override;
+
+  /** 
+   * Binds an SQL parameter of type string.
+   *
+   * Please note that this method will throw an exception if the string
+   * parameter is empty.  If a null value is to be bound then the
+   * bindOptionalString() method should be used.
+   *
+   * @param paramName The name of the parameter.
+   * @param paramValue The value to be bound.
+   */ 
+  void bindString(const std::string &paramName, const std::string &paramValue) override;
+
+  /**
+   * Binds an SQL parameter.
+   *
+   * @param paramName The name of the parameter.
+   * @param paramValue The value to be bound.
+   */
+  void bindUint64(const std::string &paramName, const uint64_t paramValue) override;
+
+  /**
+   * Clears the prepared statement so that it is ready to be reused.
+   */
+  void clear() override;
+
+  /**
+   * Idempotent close() method.  The destructor calls this method.
+   */
+  void close() override;
+
+  /**
+   * Runs the statements command, which could be a COPY FROM command,
+   * to do a batch insert rows using the columns set with calls to setColumn
+   *
+   * @param rows The number of rows
+   */
+  void executeCopyInsert(const size_t rows);
+
+  /**
+   * Executes the statement.
+   */
+  void executeNonQuery() override;
+
+  /**
+   * Executes the statement and returns the result set.
+   *
+   * @return The result set.
+   */
+  std::unique_ptr<RsetWrapper> executeQuery() override;
+
+  /**
+   * Returns the number of rows affected by the last execution of this
+   * statement.
+   *
+   * @return The number of affected rows.
+   */
+  uint64_t getNbAffectedRows() const override;
+
+  /**
+   * Sets the specified column data for a batch-based database access.
+   * Does not take ownership of the PostgresColumn object, the column
+   * object must remain valid until after executeCopyInsert has returned.
+   *
+   * @param col The column data.
+   */
+  void setColumn(PostgresColumn &col);
+
+private:
+
+  /**
+   * Similar to the public clear() method, but without locking.
+   */
+  void clearAssumeLocked();
+
+  /**
+   * Similar to the public close() method, but without locking.
+   */
+  void closeAssumeLocked();
+
+  /**
+   * Close both statement and then connection. Used if the conneciton is broken.
+   */
+  void closeBoth();
+
+  /**
+   * tranforms the sql to format needed for postgres's prepared statements
+   * e.g. changes named bind paramters to $1, $2, ... format and counts the bind variables.
+   *
+   * @param common_sql The sql in the common format, i.e. :VAR_NAME, :VAR2_NAME format.
+   * @param pg_sql The transformed SQL, i.e. with $1, $2 format.
+   * @param nParams Output the counted number of bind variables.
+   */
+  void CountAndReformatSqlBinds(const std::string &common_sql, std::string &pg_sql, int &nParams) const;
+
+  /**
+   * Throws a LostDatabaseConnection exception if it can determine the
+   * the connection has been lost.
+   */
+  void doConnectionCheck();
+
+  /**
+   * Copies the data from the supplied PostgresColumns and sends to PQputCopyData
+   * in the appropriate format.
+   *
+   * @oaran rows The number of rows to be sent to the DB connection
+   */
+  void doCopyData(const size_t rows);
+
+  /**
+   * Starts async execution of prepared tatement on the postgres connection.
+   */
+  void doPQsendPrepared();
+
+  /**
+   * Sends the statement's SQL to the server along with a statement name to be created.
+   */
+  void doPrepare();
+
+  /**
+   * Utility to replace all occurances of a substring in a string
+   *
+   * @parm str The string to be modified.
+   * @parm from The substring to be replaced.
+   * @parm to The string to replace with.
+   */
+  void replaceAll(std::string& str, const std::string& from, const std::string& to) const;
+
+  /**
+   * Sets m_nbAffectedRows. Used during PostgresRset iteration.
+   */
+  void setAffectedRows(const uint64_t val) { m_nbAffectedRows = val; }
+
+  /**
+   * Called on DB error to generate error message and exception
+   *
+   * @param res The PGresult
+   * @param prefix A prefix to place in the message thrown
+   */
+  [[noreturn]] void throwDB(const PGresult *res, const std::string &prefix);
+
+  /**
+   * Conditionally throws a DB related exception if the result status is not the expected one
+   *
+   * @param res The PGresult
+   * @parm requiredStatus The required status
+   * @param prefix A prefix to place in the message if it is thrown
+   */
+  void throwDBIfNotStatus(const PGresult *res, const ExecStatusType requiredStatus, const std::string &prefix);
+
+  /**
+   * Lock used to serialize access to the prepared statement and properies.
+   */
+  mutable threading::RWLock m_lock;
+
+  /**
+   * The SQL connection.
+   */
+  PostgresConn &m_conn;
+
+  /**
+   * The SQL of the statement with the bind variable format transformed.
+   */
+  std::string m_pgsql;
+
+  /**
+   * The prepared statement name as sent to the server.
+   */
+  std::string m_stmt;
+
+  /**
+   * The parameter count of prepared statement.
+   */
+  int m_nParams;
+
+  /**
+   * Used as an array of characeter pointers to C-string needed by libpq
+   * to supply paramters on execution of a prepared statement.
+   */
+  std::vector<const char *> m_paramValuesPtrs;
+
+  /**
+   * Vector of strings. Used as the store of string data to which pointers will be
+   * passed to libpq during statement execution.
+   */
+  std::vector<std::string> m_paramValues;
+
+  /**
+   * Used as storage for a row to send to PQputCopyData
+   */
+  std::string m_copyRow;
+
+  /**
+   * Associates column index to PostgresColumn objects
+   */
+  std::vector<PostgresColumn *> m_columnPtrs;
+
+  /**
+   * The number of rows affected by the last execution of this statement.
+   */
+  uint64_t m_nbAffectedRows;
+
+}; // class PostgresStmt
+
+} // namespace wrapper
+} // namespace rdbms
+} // namespace cta
diff --git a/rdbms/wrapper/PostgresStmtTest.cpp b/rdbms/wrapper/PostgresStmtTest.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..8d27cd91fadf925acc0350ba677c92048f376d6b
--- /dev/null
+++ b/rdbms/wrapper/PostgresStmtTest.cpp
@@ -0,0 +1,689 @@
+/*
+ * The CERN Tape Archive (CTA) project
+ * Copyright (C) 2019  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 "common/exception/DatabaseConstraintError.hpp"
+#include "common/make_unique.hpp"
+#include "rdbms/wrapper/PostgresConn.hpp"
+#include "rdbms/wrapper/PostgresRset.hpp"
+#include "rdbms/wrapper/PostgresStmt.hpp"
+
+#include <gtest/gtest.h>
+#include <memory>
+#include <string>
+#include <cstdint>
+
+namespace unitTests {
+
+/**
+ *  To enable the test case, just set environment variable GTEST_FILTER
+ *  and GTEST_ALSO_RUN_DISABLED_TESTS
+ *
+ * $ export GTEST_ALSO_RUN_DISABLED_TESTS=1
+ * $ export GTEST_FILTER=*Postgres*
+ * $ ./tests/cta-unitTests
+ */
+
+class DISABLED_cta_rdbms_wrapper_PostgresStmtTest : public ::testing::Test {
+protected:
+
+  virtual void SetUp() {
+    m_connstring = "postgresql://ctaunittest:ctaunittest@localhost/ctaunittest";
+    m_conn = cta::make_unique<cta::rdbms::wrapper::PostgresConn>(m_connstring);
+    // Try to drop anything owned by ctaunittest currently in the db
+    m_conn->executeNonQuery("drop owned by ctaunittest");
+    ASSERT_TRUE(m_conn->getTableNames().empty());
+  }
+
+  virtual void TearDown() {
+    m_conn.reset();
+  }
+
+  std::string m_connstring;
+  std::unique_ptr<cta::rdbms::wrapper::PostgresConn> m_conn;
+};
+
+TEST_F(DISABLED_cta_rdbms_wrapper_PostgresStmtTest, create_table) {
+  using namespace cta;
+  using namespace cta::rdbms::wrapper;
+
+  // Create a test table
+  {
+    const char *const sql =
+      "CREATE TABLE TEST1("
+        "COL1 VARCHAR(100),"
+        "COL2 VARCHAR(100),"
+        "COL3 NUMERIC(20,0));";
+    auto stmt = m_conn->createStmt(sql);
+    stmt->executeNonQuery();
+  }
+
+  // Test for the existence of the test table
+  {
+    const char *const sql =
+       "SELECT COUNT(*) NB_TABLES FROM pg_catalog.pg_tables c "
+         "WHERE c.schemaname NOT IN ('pg_catalog', 'information_schema') "
+         "AND c.tablename = 'test1'";
+    auto stmt = m_conn->createStmt(sql);
+    auto rset = stmt->executeQuery();
+    ASSERT_TRUE(rset->next());
+    const auto nbTables = rset->columnOptionalUint64("NB_TABLES");
+    ASSERT_TRUE((bool)nbTables);
+    ASSERT_EQ(1, nbTables.value());
+    ASSERT_FALSE(rset->next());
+    ASSERT_EQ(1, m_conn->getTableNames().size());
+    ASSERT_EQ("TEST1", m_conn->getTableNames().front());
+  }
+
+  // Create a second test table
+  {
+    const char *const sql =
+      "CREATE TABLE TEST2("
+        "COL1 VARCHAR(100),"
+        "COL2 VARCHAR(100),"
+        "COL3 NUMERIC(20,0));";
+    auto stmt = m_conn->createStmt(sql);
+    stmt->executeNonQuery();
+  }
+
+  // Test for the existence of the second test table
+  {
+    const char *const sql =
+       "SELECT COUNT(*) NB_TABLES FROM pg_catalog.pg_tables c "
+         "WHERE c.schemaname NOT IN ('pg_catalog', 'information_schema') "
+         "AND c.tablename = 'test2'";
+    auto stmt = m_conn->createStmt(sql);
+    auto rset = stmt->executeQuery();
+    ASSERT_TRUE(rset->next());
+    const auto nbTables = rset->columnOptionalUint64("NB_TABLES");
+    ASSERT_TRUE((bool)nbTables);
+    ASSERT_EQ(1, nbTables.value());
+    ASSERT_FALSE(rset->next());
+    const auto tableNames = m_conn->getTableNames();
+    ASSERT_EQ(2, tableNames.size());
+    auto nameItor = tableNames.begin();
+    ASSERT_EQ("TEST1", *nameItor);
+    nameItor++;
+    ASSERT_EQ("TEST2", *nameItor);
+    nameItor++;
+    ASSERT_EQ(tableNames.end(), nameItor);
+  }
+}
+
+TEST_F(DISABLED_cta_rdbms_wrapper_PostgresStmtTest, select_from_empty_table) {
+  using namespace cta;
+  using namespace cta::rdbms::wrapper;
+
+  // Create a test table
+  {
+    const char *const sql =
+      "CREATE TABLE TEST("
+        "COL1 VARCHAR(100),"
+        "COL2 VARCHAR(100),"
+        "COL3 NUMERIC(20,0))";
+    auto stmt = m_conn->createStmt(sql);
+    stmt->executeNonQuery();
+    ASSERT_EQ(1, m_conn->getTableNames().size());
+    ASSERT_EQ("TEST", m_conn->getTableNames().front());
+  }
+
+  // Select from the empty table
+  {
+    const char *const sql =
+      "SELECT "
+        "COL1,"
+        "COL2,"
+        "COL3 "
+      "FROM "
+        "TEST;";
+    auto stmt = m_conn->createStmt(sql);
+    auto rset = stmt->executeQuery();
+    ASSERT_FALSE(rset->next());
+  }
+}
+
+TEST_F(DISABLED_cta_rdbms_wrapper_PostgresStmtTest, insert_without_bind) {
+  using namespace cta;
+  using namespace cta::rdbms::wrapper;
+
+  ASSERT_TRUE(m_conn->getTableNames().empty());
+
+  // Create a test table
+  {
+    const char *const sql =
+      "CREATE TABLE TEST("
+        "COL1 VARCHAR(100),"
+        "COL2 VARCHAR(100),"
+        "COL3 NUMERIC(20,0));";
+    auto stmt = m_conn->createStmt(sql);
+    stmt->executeNonQuery();
+    ASSERT_EQ(1, m_conn->getTableNames().size());
+    ASSERT_EQ("TEST", m_conn->getTableNames().front());
+  }
+
+  // Insert a row into the test table
+  {
+    const char *const sql =
+      "INSERT INTO TEST("
+        "COL1,"
+        "COL2,"
+        "COL3)"
+      "VALUES("
+        "'one',"
+        "'two',"
+        "3);";
+    auto stmt = m_conn->createStmt(sql);
+    stmt->executeNonQuery();
+  }
+
+  // Select the row back from the table
+  {
+    const char *const sql =
+      "SELECT "
+        "COL1 AS COL1,"
+        "COL2 AS COL2,"
+        "COL3 AS COL3 "
+      "FROM "
+        "TEST;";
+    auto stmt = m_conn->createStmt(sql);
+    auto rset = stmt->executeQuery();
+    ASSERT_TRUE(rset->next());
+
+    const auto col1 = rset->columnOptionalString("COL1");
+    const auto col2 = rset->columnOptionalString("COL2");
+    const auto col3 = rset->columnOptionalUint64("COL3");
+
+    ASSERT_TRUE((bool)col1);
+    ASSERT_TRUE((bool)col2);
+    ASSERT_TRUE((bool)col3);
+
+    ASSERT_EQ("one", col1.value());
+    ASSERT_EQ("two", col2.value());
+    ASSERT_EQ(3, col3.value());
+
+    ASSERT_FALSE(rset->next());
+  }
+}
+
+TEST_F(DISABLED_cta_rdbms_wrapper_PostgresStmtTest, insert_with_bind) {
+  using namespace cta;
+  using namespace cta::rdbms::wrapper;
+
+  ASSERT_TRUE(m_conn->getTableNames().empty());
+
+  // Create a test table
+  {
+    const char *const sql =
+      "CREATE TABLE TEST("
+        "COL1 VARCHAR(100),"
+        "COL2 VARCHAR(100),"
+        "COL3 NUMERIC(20,0));";
+    auto stmt = m_conn->createStmt(sql);
+    stmt->executeNonQuery();
+    ASSERT_EQ(1, m_conn->getTableNames().size());
+    ASSERT_EQ("TEST", m_conn->getTableNames().front());
+  }
+
+  // Insert a row into the test table
+  {
+    const char *const sql =
+      "INSERT INTO TEST("
+        "COL1,"
+        "COL2,"
+        "COL3)"
+      "VALUES("
+        ":COL1,"
+        ":COL2,"
+        ":COL3);";
+    auto stmt = m_conn->createStmt(sql);
+    stmt->bindString(":COL1", "one");
+    stmt->bindString(":COL2", "two");
+    stmt->bindUint64(":COL3", 3);
+    stmt->executeNonQuery();
+  }
+
+  // Select the row back from the table
+  {
+    const char *const sql =
+      "SELECT "
+        "COL1 AS COL1,"
+        "COL2 AS COL2,"
+        "COL3 AS COL3 "
+      "FROM "
+        "TEST;";
+    auto stmt = m_conn->createStmt(sql);
+    auto rset = stmt->executeQuery();
+    ASSERT_TRUE(rset->next());
+
+    const auto col1 = rset->columnOptionalString("COL1");
+    const auto col2 = rset->columnOptionalString("COL2");
+    const auto col3 = rset->columnOptionalUint64("COL3");
+
+    ASSERT_TRUE((bool)col1);
+    ASSERT_TRUE((bool)col2);
+    ASSERT_TRUE((bool)col3);
+
+    ASSERT_EQ("one", col1.value());
+    ASSERT_EQ("two", col2.value());
+    ASSERT_EQ(3, col3.value());
+
+    ASSERT_FALSE(rset->next());
+  }
+}
+
+TEST_F(DISABLED_cta_rdbms_wrapper_PostgresStmtTest, isolated_transaction) {
+  using namespace cta;
+  using namespace cta::rdbms::wrapper;
+
+  // The fiest connection, to be used for creating a table
+  PostgresConn &connForCreate = *m_conn;
+
+  // Create a table
+  ASSERT_TRUE(connForCreate.getTableNames().empty());
+  {
+    const char *const sql =
+      "CREATE TABLE TEST("
+        "COL1 VARCHAR(100),"
+        "COL2 VARCHAR(100),"
+        "COL3 NUMERIC(20,0));";
+    auto stmt = connForCreate.createStmt(sql);
+    stmt->executeNonQuery();
+    ASSERT_EQ(1, connForCreate.getTableNames().size());
+    ASSERT_EQ("TEST", connForCreate.getTableNames().front());
+  }
+
+  // Create second connection to a local database
+  // Insert a row but do not commit using the separate connection
+  PostgresConn connForInsert(m_connstring);
+  {
+    const char *const sql =
+      "INSERT INTO TEST("
+        "COL1,"
+        "COL2,"
+        "COL3)"
+      "VALUES("
+        "'one',"
+        "'two',"
+        "3);";
+    connForInsert.executeNonQuery("BEGIN");
+    auto stmt = connForInsert.createStmt(sql);
+    stmt->executeNonQuery();
+  }
+
+  // Count the number of rows in the table from within another connection: should be 0
+  PostgresConn connForSelect(m_connstring);
+  ASSERT_EQ(1, connForSelect.getTableNames().size());
+  ASSERT_EQ("TEST", connForSelect.getTableNames().front());
+  {
+    const char *const sql =
+      "SELECT "
+        "COUNT(*) AS NB_ROWS "
+      "FROM "
+        "TEST;";
+    auto stmt = connForSelect.createStmt(sql);
+    auto rset = stmt->executeQuery();
+    ASSERT_TRUE(rset->next());
+
+    const auto nbRows = rset->columnOptionalUint64("NB_ROWS");
+    ASSERT_TRUE((bool)nbRows);
+    ASSERT_EQ((uint64_t)0, nbRows.value());
+
+    ASSERT_FALSE(rset->next());
+  }
+
+  //commit on the insert connection
+  connForInsert.commit();
+
+  // count the rows again on the select connection: should be 1
+  {
+    const char *const sql =
+      "SELECT "
+        "COUNT(*) AS NB_ROWS "
+      "FROM "
+        "TEST;";
+    auto stmt = connForSelect.createStmt(sql);
+    auto rset = stmt->executeQuery();
+    ASSERT_TRUE(rset->next());
+
+    const auto nbRows = rset->columnOptionalUint64("NB_ROWS");
+    ASSERT_TRUE((bool)nbRows);
+    ASSERT_EQ((uint64_t)1, nbRows.value());
+
+    ASSERT_FALSE(rset->next());
+  }
+
+}
+
+TEST_F(DISABLED_cta_rdbms_wrapper_PostgresStmtTest, executeNonQuery_insert_violating_primary_key) {
+  using namespace cta;
+  using namespace cta::rdbms::wrapper;
+
+  // Create a connection to a local database
+  PostgresConn conn(m_connstring);
+
+  // Try to drop anything owned by ctaunittest currently in the db
+  {
+    conn.executeNonQuery("drop owned by ctaunittest");
+  }
+
+  ASSERT_TRUE(conn.getTableNames().empty());
+
+  // Create a test table
+  {
+    const char *const sql =
+      "CREATE TABLE TEST("
+        "COL1 NUMERIC(20,0),"
+        "CONSTRAINT TEST_COL1_PK PRIMARY KEY(COL1));";
+    auto stmt = conn.createStmt(sql);
+    stmt->executeNonQuery();
+    ASSERT_EQ(1, conn.getTableNames().size());
+    ASSERT_EQ("TEST", conn.getTableNames().front());
+  }
+
+  // Insert a row into the test table
+  {
+    const char *const sql =
+      "INSERT INTO TEST("
+        "COL1)"
+      "VALUES("
+        ":COL1);";
+    auto stmt = conn.createStmt(sql);
+    stmt->bindUint64(":COL1", 1);
+    stmt->executeNonQuery();
+  }
+
+  // Try to insert an identical row into the test table
+  {
+    const char *const sql =
+      "INSERT INTO TEST("
+        "COL1)"
+      "VALUES("
+        ":COL1);";
+    auto stmt = conn.createStmt(sql);
+    stmt->bindUint64(":COL1", 1);
+    ASSERT_THROW(stmt->executeNonQuery(), exception::Exception);
+  }
+}
+
+TEST_F(DISABLED_cta_rdbms_wrapper_PostgresStmtTest, executeQuery_insert_violating_primary_key) {
+  using namespace cta;
+  using namespace cta::rdbms::wrapper;
+
+  ASSERT_TRUE(m_conn->getTableNames().empty());
+
+  // Create a test table
+  {
+    const char *const sql =
+      "CREATE TABLE TEST("
+        "COL1 NUMERIC(20,0),"
+        "CONSTRAINT TEST_COL1_PK PRIMARY KEY(COL1));";
+    auto stmt = m_conn->createStmt(sql);
+    stmt->executeNonQuery();
+    ASSERT_EQ(1, m_conn->getTableNames().size());
+    ASSERT_EQ("TEST", m_conn->getTableNames().front());
+  }
+
+  // Insert a row into the test table
+  {
+    const char *const sql =
+      "INSERT INTO TEST("
+        "COL1)"
+      "VALUES("
+        ":COL1);";
+    auto stmt = m_conn->createStmt(sql);
+    stmt->bindUint64(":COL1", 1);
+    stmt->executeNonQuery();
+  }
+
+  // Try to insert an identical row into the test table
+  {
+    const char *const sql =
+      "INSERT INTO TEST("
+        "COL1)"
+      "VALUES("
+        ":COL1);";
+    auto stmt = m_conn->createStmt(sql);
+    stmt->bindUint64(":COL1", 1);
+    auto rset = stmt->executeQuery();
+    ASSERT_THROW(rset->next(), exception::Exception);
+  }
+}
+
+TEST_F(DISABLED_cta_rdbms_wrapper_PostgresStmtTest, insert_with_large_uint64) {
+  using namespace cta;
+  using namespace cta::rdbms::wrapper;
+
+  ASSERT_TRUE(m_conn->getTableNames().empty());
+
+  // Create a test table
+  {
+    const char *const sql =
+      "CREATE TABLE TEST("
+        "COL1 NUMERIC(20,0));";
+    auto stmt = m_conn->createStmt(sql);
+    stmt->executeNonQuery();
+    ASSERT_EQ(1, m_conn->getTableNames().size());
+    ASSERT_EQ("TEST", m_conn->getTableNames().front());
+  }
+
+  uint64_t val = 0xFFFFFFFFFFFFFFF0ULL;
+  // Insert uint64_t with top bit set into a row into the test table
+  {
+    const char *const sql =
+      "INSERT INTO TEST("
+        "COL1)"
+      "VALUES("
+        ":COL1);";
+    auto stmt = m_conn->createStmt(sql);
+    stmt->bindUint64(":COL1", val);
+
+    stmt->executeNonQuery();
+  }
+
+  // Select the row back from the table
+  {
+    const char *const sql =
+      "SELECT "
+        "COL1 AS COL1 "
+      "FROM "
+        "TEST;";
+    auto stmt = m_conn->createStmt(sql);
+    auto rset = stmt->executeQuery();
+    ASSERT_TRUE(rset->next());
+
+    const auto col1 = rset->columnOptionalUint64("COL1");
+
+    ASSERT_TRUE((bool)col1);
+
+    ASSERT_EQ(val, col1.value());
+
+    ASSERT_FALSE(rset->next());
+  }
+}
+
+TEST_F(DISABLED_cta_rdbms_wrapper_PostgresStmtTest, executeCopyInsert_10000_rows) {
+  using namespace cta;
+  using namespace cta::rdbms::wrapper;
+
+  ASSERT_TRUE(m_conn->getTableNames().empty());
+
+  // Create a test table
+  {
+    const char *const sql =
+      "CREATE TABLE TEST("
+        "COL1 VARCHAR(100),"
+        "COL2 VARCHAR(100),"
+        "COL3 NUMERIC(20,0));";
+    auto stmt = m_conn->createStmt(sql);
+    stmt->executeNonQuery();
+    ASSERT_EQ(1, m_conn->getTableNames().size());
+    ASSERT_EQ("TEST", m_conn->getTableNames().front());
+  }
+
+  const size_t nbBulkRows = 10000;
+  // Insert a rows into the test table using a bulk method
+  {
+    PostgresColumn c1("MYCOL1",nbBulkRows);
+    PostgresColumn c2("MYCOL2",nbBulkRows);
+    PostgresColumn c3("MYCOL3",nbBulkRows);
+
+    for(size_t i=0;i<nbBulkRows;++i) {
+      std::string s = "column1 string \" \' \\ \n\r\t for row " + std::to_string(i);
+      c1.setFieldValue(i, s);
+      uint64_t rval = 123ULL * i;
+      s = "column2 string for row " +  std::to_string(i);
+      if ((i % 2) == 0) {
+        c2.setFieldValue(i, s);
+      }
+      c3.setFieldValue(i, rval);
+    }
+
+    const char *const sql = 
+      "COPY TEST("
+        "COL1,"       
+        "COL2,"       
+        "COL3) "
+      "FROM STDIN --"
+        ":MYCOL1,"
+        ":MYCOL2,"
+        ":MYCOL3";
+    auto stmt = m_conn->createStmt(sql);
+    PostgresStmt &pgStmt = dynamic_cast<PostgresStmt &>(*stmt);
+    pgStmt.setColumn(c3);
+    pgStmt.setColumn(c1);
+    pgStmt.setColumn(c2);
+
+    pgStmt.executeCopyInsert(nbBulkRows);
+    ASSERT_EQ(nbBulkRows, stmt->getNbAffectedRows());
+  }
+
+  {
+    const char *const sql =
+      "SELECT "
+        "COUNT(*) AS NB_ROWS "
+      "FROM "
+        "TEST;";
+    auto stmt = m_conn->createStmt(sql);
+    auto rset = stmt->executeQuery();
+    ASSERT_TRUE(rset->next());
+
+    const auto nbRows = rset->columnOptionalUint64("NB_ROWS");
+    ASSERT_TRUE((bool)nbRows);
+    ASSERT_EQ((uint64_t)nbBulkRows, nbRows.value());
+
+    ASSERT_FALSE(rset->next());
+  }
+
+  {
+    const char *const sql =
+      "SELECT "
+        "COL1 AS COL1,"
+        "COL2 AS COL2,"
+        "COL3 AS COL3 "
+      "FROM "
+        "TEST;";
+    auto stmt = m_conn->createStmt(sql);
+    auto rset = stmt->executeQuery();
+
+    size_t nbrows = 0;
+    while(rset->next()) {
+
+      const auto col1 = rset->columnOptionalString("COL1");
+      const auto col2 = rset->columnOptionalString("COL2");
+      const auto col3 = rset->columnOptionalUint64("COL3");
+
+      ASSERT_TRUE((bool)col1);
+      if ((nbrows % 2) == 0) {
+        ASSERT_TRUE((bool)col2);
+      } else {
+        ASSERT_FALSE((bool)col2);
+      }
+      ASSERT_TRUE((bool)col3);
+
+      std::string s1exp = "column1 string \" \' \\ \n\r\t for row " + std::to_string(nbrows);
+      std::string s2exp = "column2 string for row " + std::to_string(nbrows);
+      uint64_t rval_exp = 123ULL * nbrows;
+
+
+      ASSERT_EQ(s1exp.c_str(), col1.value());
+      if ((nbrows %2) == 0) {
+        ASSERT_EQ(s2exp.c_str(), col2.value());
+      }
+      ASSERT_EQ(rval_exp, col3.value());
+
+      ++nbrows;
+    }
+    ASSERT_EQ(nbrows, nbBulkRows);
+  }
+}
+
+TEST_F(DISABLED_cta_rdbms_wrapper_PostgresStmtTest, nbaffected) {
+  using namespace cta;
+  using namespace cta::rdbms::wrapper;
+
+  // Create a test table and insert some rows
+  {
+    const char *const sql =
+      "CREATE TABLE TEST("
+        "COL1 VARCHAR(100),"
+        "COL2 VARCHAR(100),"
+        "COL3 NUMERIC(20,0));";
+    auto stmt = m_conn->createStmt(sql);
+    stmt->executeNonQuery();
+    ASSERT_EQ(1, m_conn->getTableNames().size());
+    ASSERT_EQ("TEST", m_conn->getTableNames().front());
+
+    const char *const sql_populate =
+      "INSERT INTO TEST(COL1,COL2,COL3) VALUES "
+        "('val1',NULL,55),"
+        "('val1',NULL,56),"
+        "('val2',NULL,56),"
+        "('val2','yyy',10),"
+        "('val2','yyy',11)";
+
+    m_conn->executeNonQuery(sql_populate);
+  }
+
+  // UPDATE and check affected row count
+  {
+    const char *const sql =
+      "UPDATE TEST SET COL1=:NEWVAL WHERE COL1=:OLDVAL";
+
+    auto stmt = m_conn->createStmt(sql);
+    stmt->bindString(":NEWVAL", "val3");
+    stmt->bindString(":OLDVAL", "val1");
+    stmt->executeNonQuery();
+    ASSERT_EQ(2, stmt->getNbAffectedRows());
+  }
+
+  // SELECT and check affected row count
+  {
+    const char *const sql = "SELECT COL1 FROM TEST WHERE COL1='val2'";
+    auto stmt = m_conn->createStmt(sql);
+    auto rset = stmt->executeQuery();
+    size_t nr=0;
+    while(rset->next()) {
+      ++nr;
+      ASSERT_EQ(nr, stmt->getNbAffectedRows());
+    }
+    ASSERT_EQ(3, nr);
+    ASSERT_EQ(3, stmt->getNbAffectedRows());
+  }
+      
+}
+
+} // namespace unitTests
diff --git a/rdbms/wrapper/Rset.cpp b/rdbms/wrapper/RsetWrapper.cpp
similarity index 93%
rename from rdbms/wrapper/Rset.cpp
rename to rdbms/wrapper/RsetWrapper.cpp
index d712226131b1e042eaad9a33ff465f0997f47cf8..b735973ae6891e2114a0f017d63398b682233777 100644
--- a/rdbms/wrapper/Rset.cpp
+++ b/rdbms/wrapper/RsetWrapper.cpp
@@ -16,7 +16,7 @@
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-#include "rdbms/wrapper/Rset.hpp"
+#include "rdbms/wrapper/RsetWrapper.hpp"
 
 namespace cta {
 namespace rdbms {
@@ -25,7 +25,7 @@ namespace wrapper {
 //------------------------------------------------------------------------------
 // destructor
 //------------------------------------------------------------------------------
-Rset::~Rset() {
+RsetWrapper::~RsetWrapper() {
 }
 
 } // namespace wrapper
diff --git a/rdbms/wrapper/Rset.hpp b/rdbms/wrapper/RsetWrapper.hpp
similarity index 96%
rename from rdbms/wrapper/Rset.hpp
rename to rdbms/wrapper/RsetWrapper.hpp
index a4a6cc5db10f69a39ca66fb767ac7e37c4f1af33..88a210a59c6ce5e587db80933e24e9dfa3670e14 100644
--- a/rdbms/wrapper/Rset.hpp
+++ b/rdbms/wrapper/RsetWrapper.hpp
@@ -31,13 +31,13 @@ namespace wrapper {
  * Abstract class specifying the interface to an implementation of the result
  * set of an sql query.
  */
-class Rset {
+class RsetWrapper {
 public:
 
   /**
    * Destructor.
    */
-  virtual ~Rset() = 0;
+  virtual ~RsetWrapper() = 0;
 
   /**
    * Returns the SQL statement.
@@ -82,7 +82,7 @@ public:
    */
   virtual optional<uint64_t> columnOptionalUint64(const std::string &colName) const = 0;
 
-}; // class Rset
+}; // class RsetWrapper
 
 } // namespace wrapper
 } // namespace rdbms
diff --git a/rdbms/wrapper/SqliteConn.cpp b/rdbms/wrapper/SqliteConn.cpp
index 09fe893aa19a832e9a1d067f7d3faf0b1fe64bf5..12c99643f6ccd0ed3383af3a5edb87002776af8c 100644
--- a/rdbms/wrapper/SqliteConn.cpp
+++ b/rdbms/wrapper/SqliteConn.cpp
@@ -129,7 +129,7 @@ void SqliteConn::executeNonQuery(const std::string &sql) {
 //------------------------------------------------------------------------------
 // createStmt
 //------------------------------------------------------------------------------
-std::unique_ptr<Stmt> SqliteConn::createStmt(const std::string &sql) {
+std::unique_ptr<StmtWrapper> SqliteConn::createStmt(const std::string &sql) {
   try {
     threading::MutexLocker locker(m_mutex);
 
diff --git a/rdbms/wrapper/SqliteConn.hpp b/rdbms/wrapper/SqliteConn.hpp
index 74f8b62f4a4b85539aaa3d8ef25854f129dea8ec..fcac608091cd396c1618d6a6652cbc0a2f027c19 100644
--- a/rdbms/wrapper/SqliteConn.hpp
+++ b/rdbms/wrapper/SqliteConn.hpp
@@ -19,7 +19,7 @@
 #pragma once
 
 #include "common/threading/Mutex.hpp"
-#include "rdbms/wrapper/Conn.hpp"
+#include "rdbms/wrapper/ConnWrapper.hpp"
 
 #include <sqlite3.h>
 
@@ -36,7 +36,7 @@ class SqliteStmt;
 /**
  * A convenience wrapper around a connection to an SQLite database.
  */
-class SqliteConn: public Conn {
+class SqliteConn: public ConnWrapper {
 public:
 
   /**
@@ -91,7 +91,7 @@ public:
    * @param sql The SQL statement.
    * @return The prepared statement.
    */
-  std::unique_ptr<Stmt> createStmt(const std::string &sql) override;
+  std::unique_ptr<StmtWrapper> createStmt(const std::string &sql) override;
 
   /**
    * Commits the current transaction.
diff --git a/rdbms/wrapper/SqliteConnFactory.cpp b/rdbms/wrapper/SqliteConnFactory.cpp
index 14182efa46117d2b57c639184a860ccea26e327e..8872047a0b2b3f13cfb8f341a05401e0a85cb5d2 100644
--- a/rdbms/wrapper/SqliteConnFactory.cpp
+++ b/rdbms/wrapper/SqliteConnFactory.cpp
@@ -41,7 +41,7 @@ SqliteConnFactory::~SqliteConnFactory() {
 //------------------------------------------------------------------------------
 // create
 //------------------------------------------------------------------------------
-std::unique_ptr<Conn> SqliteConnFactory::create() {
+std::unique_ptr<ConnWrapper> SqliteConnFactory::create() {
   try {
     return cta::make_unique<SqliteConn>(m_filename);
   } catch(exception::Exception &ex) {
diff --git a/rdbms/wrapper/SqliteConnFactory.hpp b/rdbms/wrapper/SqliteConnFactory.hpp
index 273dbd92c27411a0e9c11a28c43331b04dcc34ea..0328f2ca2808c934cfdab2527e711fca65029227 100644
--- a/rdbms/wrapper/SqliteConnFactory.hpp
+++ b/rdbms/wrapper/SqliteConnFactory.hpp
@@ -47,7 +47,7 @@ public:
    *
    * @return A newly created database connection.
    */
-  std::unique_ptr<Conn> create() override;
+  std::unique_ptr<ConnWrapper> create() override;
 
 private:
 
diff --git a/rdbms/wrapper/SqliteRset.hpp b/rdbms/wrapper/SqliteRset.hpp
index e90ac1da26e4039d85658da523d4a7d3d86be451..d9e7cdeabe10021601aae59d29c659dd42d224ff 100644
--- a/rdbms/wrapper/SqliteRset.hpp
+++ b/rdbms/wrapper/SqliteRset.hpp
@@ -19,7 +19,7 @@
 #pragma once
 
 #include "rdbms/wrapper/ColumnNameToIdxAndType.hpp"
-#include "rdbms/wrapper/Rset.hpp"
+#include "rdbms/wrapper/RsetWrapper.hpp"
 
 #include <memory>
 #include <stdint.h>
@@ -37,7 +37,7 @@ class SqliteStmt;
 /**
  * The result set of an sql query.
  */
-class SqliteRset: public Rset {
+class SqliteRset: public RsetWrapper {
 public:
 
   /**
diff --git a/rdbms/wrapper/SqliteStmt.cpp b/rdbms/wrapper/SqliteStmt.cpp
index 7089d81cc1925dcfb551339477a80628ecf28eb9..059b60aed4947c4afd603cffd8553479dcb567cc 100644
--- a/rdbms/wrapper/SqliteStmt.cpp
+++ b/rdbms/wrapper/SqliteStmt.cpp
@@ -44,7 +44,7 @@ namespace wrapper {
 SqliteStmt::SqliteStmt(
   SqliteConn &conn,
   const std::string &sql):
-  Stmt(sql),
+  StmtWrapper(sql),
   m_conn(conn),
   m_nbAffectedRows(0) {
   m_stmt = nullptr;
@@ -223,7 +223,7 @@ void SqliteStmt::bindOptionalString(const std::string &paramName, const optional
 //------------------------------------------------------------------------------
 // executeQuery
 //------------------------------------------------------------------------------
-std::unique_ptr<Rset> SqliteStmt::executeQuery() {
+std::unique_ptr<RsetWrapper> SqliteStmt::executeQuery() {
   threading::MutexLocker connLocker(m_conn.m_mutex);
 
   return cta::make_unique<SqliteRset>(*this);
diff --git a/rdbms/wrapper/SqliteStmt.hpp b/rdbms/wrapper/SqliteStmt.hpp
index 0e868a3d3bec956d5e6582aeb406d5c9d5f9b69a..0bb632fa6d3e9ca0b811c5fa9d13c751ed9d3524 100644
--- a/rdbms/wrapper/SqliteStmt.hpp
+++ b/rdbms/wrapper/SqliteStmt.hpp
@@ -19,7 +19,7 @@
 #pragma once
 
 #include "common/threading/Mutex.hpp"
-#include "rdbms/wrapper/Stmt.hpp"
+#include "rdbms/wrapper/StmtWrapper.hpp"
 
 #include <map>
 #include <memory>
@@ -36,7 +36,7 @@ class SqliteRset;
 /**
  * A convenience wrapper around an SQLite prepared statement.
  */
-class SqliteStmt: public Stmt {
+class SqliteStmt: public StmtWrapper {
 public:
 
   /**
@@ -121,7 +121,7 @@ public:
    * @param autocommitMode The autocommit mode of the statement.
    * @return The result set.
    */
-  std::unique_ptr<Rset> executeQuery() override;
+  std::unique_ptr<RsetWrapper> executeQuery() override;
 
   /**
    * Executes the statement.
diff --git a/rdbms/wrapper/Stmt.cpp b/rdbms/wrapper/StmtWrapper.cpp
similarity index 78%
rename from rdbms/wrapper/Stmt.cpp
rename to rdbms/wrapper/StmtWrapper.cpp
index 33f73b81e4eeb637d5d022ac0c553e53c0caa1cb..fa448244629bd916a4b7d55ff1ab664cf1419400 100644
--- a/rdbms/wrapper/Stmt.cpp
+++ b/rdbms/wrapper/StmtWrapper.cpp
@@ -17,7 +17,7 @@
  */
 
 #include "rdbms/rdbms.hpp"
-#include "rdbms/wrapper/Stmt.hpp"
+#include "rdbms/wrapper/StmtWrapper.hpp"
 
 namespace cta {
 namespace rdbms {
@@ -26,7 +26,7 @@ namespace wrapper {
 //------------------------------------------------------------------------------
 // constructor
 //------------------------------------------------------------------------------
-Stmt::Stmt(const std::string &sql):
+StmtWrapper::StmtWrapper(const std::string &sql):
   m_sql(sql),
   m_paramNameToIdx(sql) {
 }
@@ -34,45 +34,45 @@ Stmt::Stmt(const std::string &sql):
 //------------------------------------------------------------------------------
 // destructor
 //------------------------------------------------------------------------------
-Stmt::~Stmt() {
+StmtWrapper::~StmtWrapper() {
 }
 
 //------------------------------------------------------------------------------
 // getSql
 //------------------------------------------------------------------------------
-const std::string &Stmt::getSql() const {
+const std::string &StmtWrapper::getSql() const {
   return m_sql;
 }
 
 //------------------------------------------------------------------------------
 // getParamIdx
 //------------------------------------------------------------------------------
-uint32_t Stmt::getParamIdx(const std::string &paramName) const {
+uint32_t StmtWrapper::getParamIdx(const std::string &paramName) const {
   return m_paramNameToIdx.getIdx(paramName);
 }
 
 //------------------------------------------------------------------------------
 // getSqlForException
 //------------------------------------------------------------------------------
-std::string Stmt::getSqlForException(const std::string::size_type maxSqlLenInExceptions) const {
+std::string StmtWrapper::getSqlForException(const std::string::size_type maxSqlLenInExceptions) const {
   return rdbms::getSqlForException(m_sql, maxSqlLenInExceptions);
 }
 
 //------------------------------------------------------------------------------
 // bindBool
 //------------------------------------------------------------------------------
-void Stmt::bindBool(const std::string &paramName, const bool paramValue) {
+void StmtWrapper::bindBool(const std::string &paramName, const bool paramValue) {
   bindOptionalBool(paramName, paramValue);
 }
 
 //------------------------------------------------------------------------------
 // bindOptionalBool
 //------------------------------------------------------------------------------
-void Stmt::bindOptionalBool(const std::string &paramName, const optional<bool> &paramValue) {
+void StmtWrapper::bindOptionalBool(const std::string &paramName, const optional<bool> &paramValue) {
   if(paramValue) {
-    bindOptionalUint64(paramName, paramValue.value() ? 1 : 0);
+    bindOptionalString(paramName, std::string(paramValue.value() ? "1" : "0"));
   } else {
-    bindOptionalUint64(paramName, nullopt);
+    bindOptionalString(paramName, nullopt);
   }
 }
 
diff --git a/rdbms/wrapper/Stmt.hpp b/rdbms/wrapper/StmtWrapper.hpp
similarity index 92%
rename from rdbms/wrapper/Stmt.hpp
rename to rdbms/wrapper/StmtWrapper.hpp
index 5199a016c496ea24dc532ac2e5686f4a5961b58d..f3472a74f0d066431342950fc4d1b112f9021513 100644
--- a/rdbms/wrapper/Stmt.hpp
+++ b/rdbms/wrapper/StmtWrapper.hpp
@@ -22,7 +22,7 @@
 #include "rdbms/AutocommitMode.hpp"
 #include "rdbms/Constants.hpp"
 #include "rdbms/wrapper/ParamNameToIdx.hpp"
-#include "rdbms/wrapper/Rset.hpp"
+#include "rdbms/wrapper/RsetWrapper.hpp"
 
 #include <memory>
 #include <stdint.h>
@@ -35,7 +35,7 @@ namespace wrapper {
 /**
  * Abstract class specifying the interface to a database statement.
  */
-class Stmt {
+class StmtWrapper {
 public:
 
   /**
@@ -43,32 +43,32 @@ public:
    *
    * @param sql The SQL statement.
    */
-  Stmt(const std::string &sql);
+  StmtWrapper(const std::string &sql);
 
   /**
    * Destructor.
    */
-  virtual ~Stmt() = 0;
+  virtual ~StmtWrapper() = 0;
 
   /**
    * Deletion of the copy constructor.
    */
-  Stmt(Stmt &) = delete;
+  StmtWrapper(StmtWrapper &) = delete;
 
   /**
    * Deletion of the move constructor.
    */
-  Stmt(Stmt &&) = delete;
+  StmtWrapper(StmtWrapper &&) = delete;
 
   /**
    * Deletion of the copy assignment operator.
    */
-  Stmt &operator=(const Stmt &) = delete;
+  StmtWrapper &operator=(const StmtWrapper &) = delete;
 
   /**
    * Deletion of the move assignment operator.
    */
-  Stmt &operator=(Stmt &&) = delete;
+  StmtWrapper &operator=(StmtWrapper &&) = delete;
 
   /**
    * Clears the prepared statement so that it is ready to be reused.
@@ -156,7 +156,7 @@ public:
    *
    *  @return The result set.
    */
-  virtual std::unique_ptr<Rset> executeQuery() = 0;
+  virtual std::unique_ptr<RsetWrapper> executeQuery() = 0;
 
   /**
    * Executes the statement.
@@ -197,7 +197,7 @@ private:
    */
   ParamNameToIdx m_paramNameToIdx;
 
-}; // class Stmt
+}; // class StmtWrapper
 
 } // namespace wrapper
 } // namespace rdbms
diff --git a/scheduler/ArchiveJob.cpp b/scheduler/ArchiveJob.cpp
index 7bee1953dcb14c5502a6bb92c8faf70235fbdf72..ee2cb7c24a0effa032949d1f87a2722387641a05 100644
--- a/scheduler/ArchiveJob.cpp
+++ b/scheduler/ArchiveJob.cpp
@@ -66,7 +66,6 @@ cta::catalogue::TapeItemWrittenPointer cta::ArchiveJob::validateAndGetTapeFileWr
   fileReport.diskFileUser = archiveFile.diskFileInfo.owner;
   fileReport.diskFileGroup = archiveFile.diskFileInfo.group;
   fileReport.diskFilePath = archiveFile.diskFileInfo.path;
-  fileReport.diskFileRecoveryBlob = archiveFile.diskFileInfo.recoveryBlob;
   fileReport.diskInstance = archiveFile.diskInstance;
   fileReport.fSeq = tapeFile.fSeq;
   fileReport.size = archiveFile.fileSize;
diff --git a/scheduler/DiskReportRunner.cpp b/scheduler/DiskReportRunner.cpp
index fdb9e2aaf3bde4614e84f4799ac1de858c8d239b..74095e1c2823b644a11935c0d049249d6323a171 100644
--- a/scheduler/DiskReportRunner.cpp
+++ b/scheduler/DiskReportRunner.cpp
@@ -57,7 +57,7 @@ void DiskReportRunner::runOnePass(log::LogContext& lc) {
       params.add("jobsToReport", retrieveJobsToReport.size());
       lc.log(cta::log::DEBUG,"In DiskReportRunner::runOnePass(): ready to process retrieve reports.");
     }
-    is_done = retrieveJobsToReport.empty();
+    is_done = is_done && retrieveJobsToReport.empty();
     if(!retrieveJobsToReport.empty()) {
       timings.insertAndReset("getRetrieveJobsToReportTime", t2);
       m_scheduler.reportRetrieveJobsBatch(retrieveJobsToReport, m_reporterFactory, timings, t2, lc);
diff --git a/scheduler/Scheduler.cpp b/scheduler/Scheduler.cpp
index 0e1b260de3d4d71323f3740ab1e17305d0b8b29e..088ca4dd9bb41e94c9fa72e2103a549ce2621b4c 100644
--- a/scheduler/Scheduler.cpp
+++ b/scheduler/Scheduler.cpp
@@ -157,7 +157,6 @@ void Scheduler::queueArchiveWithGivenId(const uint64_t archiveFileId, const std:
      .add("diskFilePath", request.diskFileInfo.path)
      .add("diskFileOwner", request.diskFileInfo.owner)
      .add("diskFileGroup", request.diskFileInfo.group)
-     .add("diskFileRecoveryBlob", postEllipsis(request.diskFileInfo.recoveryBlob, 20))
      .add("checksumValue", request.checksumValue)
      .add("checksumType", request.checksumType)
      .add("archiveReportURL", midEllipsis(request.archiveReportURL, 50, 15))
@@ -219,7 +218,6 @@ void Scheduler::queueRetrieve(
      .add("diskFilePath", request.diskFileInfo.path)
      .add("diskFileOwner", request.diskFileInfo.owner)
      .add("diskFileGroup", request.diskFileInfo.group)
-     .add("diskFileRecoveryBlob", postEllipsis(request.diskFileInfo.recoveryBlob, 20))
      .add("dstURL", request.dstURL)
      .add("errorReportURL", request.errorReportURL)
      .add("creationHost", request.creationLog.host)
@@ -234,7 +232,6 @@ void Scheduler::queueRetrieve(
      .add("criteriaDiskFileId", queueCriteria.archiveFile.diskFileId)
      .add("criteriaDiskFilePath", queueCriteria.archiveFile.diskFileInfo.path)
      .add("criteriaDiskFileOwner", queueCriteria.archiveFile.diskFileInfo.owner)
-     .add("criteriaDiskRecoveryBlob", postEllipsis(queueCriteria.archiveFile.diskFileInfo.recoveryBlob, 20))
      .add("criteriaDiskInstance", queueCriteria.archiveFile.diskInstance)
      .add("criteriaFileSize", queueCriteria.archiveFile.fileSize)
      .add("reconciliationTime", queueCriteria.archiveFile.reconciliationTime)
@@ -314,7 +311,7 @@ std::list<common::dataStructures::StorageClass> Scheduler::listStorageClass(cons
 //------------------------------------------------------------------------------
 // labelTape
 //------------------------------------------------------------------------------
-void Scheduler::queueLabel(const common::dataStructures::SecurityIdentity &cliIdentity, const std::string &vid, const bool force, const bool lbp) {
+void Scheduler::queueLabel(const common::dataStructures::SecurityIdentity &cliIdentity, const std::string &vid, const bool force) {
   throw exception::Exception(std::string("Not implemented: ") + __PRETTY_FUNCTION__);
 }
 
diff --git a/scheduler/Scheduler.hpp b/scheduler/Scheduler.hpp
index 98c73c2bdcfea456364c33aa26afff6597f18f85..9da22e8fd221cb39f888a79ba68f5e250be3974e 100644
--- a/scheduler/Scheduler.hpp
+++ b/scheduler/Scheduler.hpp
@@ -198,7 +198,7 @@ public:
    * accomplish it will dequeue it.
    */
   void queueLabel(const cta::common::dataStructures::SecurityIdentity &cliIdentity, const std::string &vid,
-    const bool force, const bool lbp);
+    const bool force);
 
   void queueRepack(const common::dataStructures::SecurityIdentity &cliIdentity, const std::string &vid, 
     const std::string & bufferURL, const common::dataStructures::RepackInfo::Type repackType, log::LogContext & lc);
diff --git a/scheduler/SchedulerDatabaseTest.cpp b/scheduler/SchedulerDatabaseTest.cpp
index 0d072c8e4e88442c03d0a76f90dab83183ba9ef7..3617fd07949434f2163711b0bfd84429f27600d5 100644
--- a/scheduler/SchedulerDatabaseTest.cpp
+++ b/scheduler/SchedulerDatabaseTest.cpp
@@ -174,8 +174,6 @@ TEST_P(SchedulerDatabaseTest, createManyArchiveJobs) {
       ar.diskFileInfo.path = std::string("/uuid/")+fileUUIDStr;
       ar.diskFileInfo.owner = "user";
       ar.diskFileInfo.group = "group";
-      // Attempt to create a no valid UTF8 string.
-      ar.diskFileInfo.recoveryBlob = std::string("recoveryBlob") + "\xc3\xb1";
       ar.fileSize = 1000;
       ar.requester = { "user", "group" };
       ar.srcURL = std::string("root:/") + ar.diskFileInfo.path;
@@ -256,8 +254,6 @@ TEST_P(SchedulerDatabaseTest, createManyArchiveJobs) {
       ar.diskFileInfo.path = std::string("/uuid/")+fileUUIDStr;
       ar.diskFileInfo.owner = "user";
       ar.diskFileInfo.group = "group";
-      // Attempt to create a no valid UTF8 string.
-      ar.diskFileInfo.recoveryBlob = std::string("recoveryBlob") + "\xc3\xb1";
       ar.fileSize = 1000;
       ar.requester = { "user", "group" };
       ar.srcURL = std::string("root:/") + ar.diskFileInfo.path;
diff --git a/scheduler/SchedulerTest.cpp b/scheduler/SchedulerTest.cpp
index d9b93ec872da5c02f4405588bb438129ba75b3f3..ccda870be625939415cc286770c056c279c0249d 100644
--- a/scheduler/SchedulerTest.cpp
+++ b/scheduler/SchedulerTest.cpp
@@ -260,7 +260,6 @@ TEST_P(SchedulerTest, archive_to_new_file) {
   creationLog.time=0;
   creationLog.username="admin1";
   cta::common::dataStructures::DiskFileInfo diskFileInfo;
-  diskFileInfo.recoveryBlob="blob";
   diskFileInfo.group="group2";
   diskFileInfo.owner="cms_user";
   diskFileInfo.path="path/to/file";
@@ -322,7 +321,6 @@ TEST_P(SchedulerTest, archive_to_new_file) {
 //  creationLog.time=0;
 //  creationLog.username="admin1";
 //  cta::common::dataStructures::DiskFileInfo diskFileInfo;
-//  diskFileInfo.recoveryBlob="blob";
 //  diskFileInfo.group="group2";
 //  diskFileInfo.owner="cms_user";
 //  diskFileInfo.path="path/to/file";
@@ -397,7 +395,6 @@ TEST_P(SchedulerTest, archive_report_and_retrieve_new_file) {
     creationLog.time=0;
     creationLog.username="admin1";
     cta::common::dataStructures::DiskFileInfo diskFileInfo;
-    diskFileInfo.recoveryBlob="blob";
     diskFileInfo.group="group2";
     diskFileInfo.owner="cms_user";
     diskFileInfo.path="path/to/file";
@@ -449,10 +446,9 @@ TEST_P(SchedulerTest, archive_report_and_retrieve_new_file) {
   catalogue.createTape(s_adminOnAdminHost, s_vid, s_mediaType, s_vendor, s_libraryName, s_tapePoolName, capacityInBytes,
     notDisabled, notFull, tapeComment);
 
-  const bool lbpIsOn = true;
   const std::string driveName = "tape_drive";
 
-  catalogue.tapeLabelled(s_vid, "tape_drive", lbpIsOn);
+  catalogue.tapeLabelled(s_vid, "tape_drive");
 
   {
     // Emulate a tape server by asking for a mount and then a file (and succeed the transfer)
@@ -508,7 +504,6 @@ TEST_P(SchedulerTest, archive_report_and_retrieve_new_file) {
     creationLog.time=0;
     creationLog.username="admin1";
     cta::common::dataStructures::DiskFileInfo diskFileInfo;
-    diskFileInfo.recoveryBlob="blob";
     diskFileInfo.group="group2";
     diskFileInfo.owner="cms_user";
     diskFileInfo.path="path/to/file";
@@ -599,7 +594,6 @@ TEST_P(SchedulerTest, archive_and_retrieve_failure) {
     creationLog.time=0;
     creationLog.username="admin1";
     cta::common::dataStructures::DiskFileInfo diskFileInfo;
-    diskFileInfo.recoveryBlob="blob";
     diskFileInfo.group="group2";
     diskFileInfo.owner="cms_user";
     diskFileInfo.path="path/to/file";
@@ -651,10 +645,9 @@ TEST_P(SchedulerTest, archive_and_retrieve_failure) {
   catalogue.createTape(s_adminOnAdminHost, s_vid, s_mediaType, s_vendor, s_libraryName, s_tapePoolName, capacityInBytes,
     notDisabled, notFull, tapeComment);
 
-  const bool lbpIsOn = true;
   const std::string driveName = "tape_drive";
 
-  catalogue.tapeLabelled(s_vid, "tape_drive", lbpIsOn);
+  catalogue.tapeLabelled(s_vid, "tape_drive");
 
   {
     // Emulate a tape server by asking for a mount and then a file (and succeed the transfer)
@@ -710,7 +703,6 @@ TEST_P(SchedulerTest, archive_and_retrieve_failure) {
     creationLog.time=0;
     creationLog.username="admin1";
     cta::common::dataStructures::DiskFileInfo diskFileInfo;
-    diskFileInfo.recoveryBlob="blob";
     diskFileInfo.group="group2";
     diskFileInfo.owner="cms_user";
     diskFileInfo.path="path/to/file";
@@ -852,7 +844,6 @@ TEST_P(SchedulerTest, archive_and_retrieve_report_failure) {
     creationLog.time=0;
     creationLog.username="admin1";
     cta::common::dataStructures::DiskFileInfo diskFileInfo;
-    diskFileInfo.recoveryBlob="blob";
     diskFileInfo.group="group2";
     diskFileInfo.owner="cms_user";
     diskFileInfo.path="path/to/file";
@@ -904,10 +895,9 @@ TEST_P(SchedulerTest, archive_and_retrieve_report_failure) {
   catalogue.createTape(s_adminOnAdminHost, s_vid, "mediatype", "vendor", s_libraryName, s_tapePoolName,
     capacityInBytes, notDisabled, notFull, tapeComment);
 
-  const bool lbpIsOn = true;
   const std::string driveName = "tape_drive";
 
-  catalogue.tapeLabelled(s_vid, "tape_drive", lbpIsOn);
+  catalogue.tapeLabelled(s_vid, "tape_drive");
 
   {
     // Emulate a tape server by asking for a mount and then a file (and succeed the transfer)
@@ -963,7 +953,6 @@ TEST_P(SchedulerTest, archive_and_retrieve_report_failure) {
     creationLog.time=0;
     creationLog.username="admin1";
     cta::common::dataStructures::DiskFileInfo diskFileInfo;
-    diskFileInfo.recoveryBlob="blob";
     diskFileInfo.group="group2";
     diskFileInfo.owner="cms_user";
     diskFileInfo.path="path/to/file";
@@ -1111,7 +1100,6 @@ TEST_P(SchedulerTest, retry_archive_until_max_reached) {
     creationLog.time=0;
     creationLog.username="admin1";
     cta::common::dataStructures::DiskFileInfo diskFileInfo;
-    diskFileInfo.recoveryBlob="blob";
     diskFileInfo.group="group2";
     diskFileInfo.owner="cms_user";
     diskFileInfo.path="path/to/file";
@@ -1151,8 +1139,7 @@ TEST_P(SchedulerTest, retry_archive_until_max_reached) {
   catalogue.createTape(s_adminOnAdminHost, s_vid, s_mediaType, s_vendor, s_libraryName, s_tapePoolName, capacityInBytes,
     notDisabled, notFull, tapeComment);
 
-  const bool lbpIsOn = true;
-  catalogue.tapeLabelled(s_vid, "tape_drive", lbpIsOn);
+  catalogue.tapeLabelled(s_vid, "tape_drive");
 
   {
     // Emulate a tape server by asking for a mount and then a file
@@ -1195,7 +1182,6 @@ TEST_P(SchedulerTest, retrieve_non_existing_file) {
     creationLog.time=0;
     creationLog.username="admin1";
     cta::common::dataStructures::DiskFileInfo diskFileInfo;
-    diskFileInfo.recoveryBlob="blob";
     diskFileInfo.group="group2";
     diskFileInfo.owner="cms_user";
     diskFileInfo.path="path/to/file";
@@ -1228,7 +1214,6 @@ TEST_P(SchedulerTest, showqueues) {
     creationLog.time=0;
     creationLog.username="admin1";
     cta::common::dataStructures::DiskFileInfo diskFileInfo;
-    diskFileInfo.recoveryBlob="blob";
     diskFileInfo.group="group2";
     diskFileInfo.owner="cms_user";
     diskFileInfo.path="path/to/file";
@@ -1373,7 +1358,6 @@ TEST_P(SchedulerTest, expandRepackRequest) {
   admin.host = "admin_host";
   const std::string diskFileUser = "public_disk_user";
   const std::string diskFileGroup = "public_disk_group";
-  const std::string diskFileRecoveryBlob = "opaque_disk_file_recovery_contents";
   
   //Create a logical library in the catalogue
   catalogue.createLogicalLibrary(admin, s_libraryName, "Create logical library");
@@ -1426,7 +1410,6 @@ TEST_P(SchedulerTest, expandRepackRequest) {
         fileWritten.diskFilePath = diskFilePath.str();
         fileWritten.diskFileUser = diskFileUser;
         fileWritten.diskFileGroup = diskFileGroup;
-        fileWritten.diskFileRecoveryBlob = diskFileRecoveryBlob;
         fileWritten.size = archiveFileSize;
         fileWritten.checksumType = checksumType;
         fileWritten.checksumValue = checksumValue;
@@ -1656,7 +1639,6 @@ TEST_P(SchedulerTest, expandRepackRequest) {
         ASSERT_EQ(archiveFile.diskFileInfo.path,diskFilePath.str());
         ASSERT_EQ(archiveFile.diskFileInfo.group,diskFileGroup);
         ASSERT_EQ(archiveFile.diskFileInfo.owner,diskFileUser);
-        ASSERT_EQ(archiveFile.diskFileInfo.recoveryBlob,diskFileRecoveryBlob);
         ASSERT_EQ(archiveFile.fileSize,archiveFileSize);
         ASSERT_EQ(archiveFile.storageClass,s_storageClassName);
         std::stringstream ss;
@@ -1711,7 +1693,6 @@ TEST_P(SchedulerTest, expandRepackRequestFailedRetrieve) {
   admin.host = "admin_host";
   const std::string diskFileUser = "public_disk_user";
   const std::string diskFileGroup = "public_disk_group";
-  const std::string diskFileRecoveryBlob = "opaque_disk_file_recovery_contents";
   
   //Create a logical library in the catalogue
   catalogue.createLogicalLibrary(admin, s_libraryName, "Create logical library");
@@ -1754,7 +1735,6 @@ TEST_P(SchedulerTest, expandRepackRequestFailedRetrieve) {
       fileWritten.diskFilePath = diskFilePath.str();
       fileWritten.diskFileUser = diskFileUser;
       fileWritten.diskFileGroup = diskFileGroup;
-      fileWritten.diskFileRecoveryBlob = diskFileRecoveryBlob;
       fileWritten.size = archiveFileSize;
       fileWritten.checksumType = checksumType;
       fileWritten.checksumValue = checksumValue;
@@ -1954,7 +1934,6 @@ TEST_P(SchedulerTest, expandRepackRequestArchiveSuccess) {
   admin.host = "admin_host";
   const std::string diskFileUser = "public_disk_user";
   const std::string diskFileGroup = "public_disk_group";
-  const std::string diskFileRecoveryBlob = "opaque_disk_file_recovery_contents";
   
   //Create a logical library in the catalogue
   catalogue.createLogicalLibrary(admin, s_libraryName, "Create logical library");
@@ -1997,7 +1976,6 @@ TEST_P(SchedulerTest, expandRepackRequestArchiveSuccess) {
       fileWritten.diskFilePath = diskFilePath.str();
       fileWritten.diskFileUser = diskFileUser;
       fileWritten.diskFileGroup = diskFileGroup;
-      fileWritten.diskFileRecoveryBlob = diskFileRecoveryBlob;
       fileWritten.size = archiveFileSize;
       fileWritten.checksumType = checksumType;
       fileWritten.checksumValue = checksumValue;
diff --git a/scheduler/testingMocks/MockArchiveJob.hpp b/scheduler/testingMocks/MockArchiveJob.hpp
index 3c9e696b7b78dcea714dad2d3c8cd4135d938c71..03a45db8305410edae9fcb186e15df4ed47754ac 100644
--- a/scheduler/testingMocks/MockArchiveJob.hpp
+++ b/scheduler/testingMocks/MockArchiveJob.hpp
@@ -57,7 +57,6 @@ namespace cta {
       fileReport.diskFileUser = archiveFile.diskFileInfo.owner;
       fileReport.diskFileGroup = archiveFile.diskFileInfo.group;
       fileReport.diskFilePath = archiveFile.diskFileInfo.path;
-      fileReport.diskFileRecoveryBlob = archiveFile.diskFileInfo.recoveryBlob;
       fileReport.diskInstance = archiveFile.diskInstance;
       fileReport.fSeq = tapeFile.fSeq;
       fileReport.size = archiveFile.fileSize;
diff --git a/tapeserver/castor/tape/tapeserver/daemon/DataTransferSessionTest.cpp b/tapeserver/castor/tape/tapeserver/daemon/DataTransferSessionTest.cpp
index 673bd7866730167226962a5515421811ccc3d006..1f75a42c24b4e7107ba80a01603c7acf03de3ea1 100644
--- a/tapeserver/castor/tape/tapeserver/daemon/DataTransferSessionTest.cpp
+++ b/tapeserver/castor/tape/tapeserver/daemon/DataTransferSessionTest.cpp
@@ -443,7 +443,6 @@ TEST_P(DataTransferSessionTest, DataTransferSessionGooddayRecall) {
       tapeFileWritten.diskFilePath = remoteFilePath.str();
       tapeFileWritten.diskFileUser = s_userName;
       tapeFileWritten.diskFileGroup = "someGroup";
-      tapeFileWritten.diskFileRecoveryBlob = "B106";
       tapeFileWritten.storageClassName = s_storageClassName;
       tapeFileWritten.tapeDrive = "drive0";
       catalogue.filesWrittenToTape(tapeFileWrittenSet);
@@ -625,7 +624,6 @@ TEST_P(DataTransferSessionTest, DataTransferSessionWrongRecall) {
         tapeFileWritten.diskFilePath = "/somefile";
         tapeFileWritten.diskFileUser = s_userName;
         tapeFileWritten.diskFileGroup = "someGroup";
-        tapeFileWritten.diskFileRecoveryBlob = "B106";
         tapeFileWritten.storageClassName = s_storageClassName;
         tapeFileWritten.tapeDrive = "drive0";
         catalogue.filesWrittenToTape(tapeFileWrittenSet);
@@ -651,7 +649,6 @@ TEST_P(DataTransferSessionTest, DataTransferSessionWrongRecall) {
         tapeFileWritten.diskFilePath = remoteFilePath.str();
         tapeFileWritten.diskFileUser = s_userName;
         tapeFileWritten.diskFileGroup = "someGroup";
-        tapeFileWritten.diskFileRecoveryBlob = "B106";
         tapeFileWritten.storageClassName = s_storageClassName;
         tapeFileWritten.tapeDrive = "drive0";
         catalogue.filesWrittenToTape(tapeFileWrittenSet);
@@ -827,7 +824,6 @@ TEST_P(DataTransferSessionTest, DataTransferSessionRAORecall) {
       tapeFileWritten.diskFilePath = remoteFilePath.str();
       tapeFileWritten.diskFileUser = s_userName;
       tapeFileWritten.diskFileGroup = "someGroup";
-      tapeFileWritten.diskFileRecoveryBlob = "B106";
       tapeFileWritten.storageClassName = s_storageClassName;
       tapeFileWritten.tapeDrive = "drive0";
       catalogue.filesWrittenToTape(tapeFileWrittenSet);
@@ -1038,7 +1034,6 @@ TEST_P(DataTransferSessionTest, DataTransferSessionNoSuchDrive) {
       tapeFileWritten.diskFilePath = remoteFilePath.str();
       tapeFileWritten.diskFileUser = s_userName;
       tapeFileWritten.diskFileGroup = "someGroup";
-      tapeFileWritten.diskFileRecoveryBlob = "B106";
       tapeFileWritten.storageClassName = s_storageClassName;
       tapeFileWritten.tapeDrive = "drive0";
       catalogue.filesWrittenToTape(tapeFileWrittenSet);
@@ -1186,7 +1181,6 @@ TEST_P(DataTransferSessionTest, DataTransferSessionFailtoMount) {
       tapeFileWritten.diskFilePath = remoteFilePath.str();
       tapeFileWritten.diskFileUser = s_userName;
       tapeFileWritten.diskFileGroup = "someGroup";
-      tapeFileWritten.diskFileRecoveryBlob = "B106";
       tapeFileWritten.storageClassName = s_storageClassName;
       tapeFileWritten.tapeDrive = "drive0";
       catalogue.filesWrittenToTape(tapeFileWrittenSet);
@@ -1305,7 +1299,7 @@ TEST_P(DataTransferSessionTest, DataTransferSessionGooddayMigration) {
   {    
     // Label the tape
     castor::tape::tapeFile::LabelSession ls(*mockSys.fake.m_pathToDrive["/dev/nst0"], s_vid, false);
-    catalogue.tapeLabelled(s_vid, "T10D6116", true);
+    catalogue.tapeLabelled(s_vid, "T10D6116");
     mockSys.fake.m_pathToDrive["/dev/nst0"]->rewind();
     
     // Create the files and schedule the archivals
@@ -1327,7 +1321,6 @@ TEST_P(DataTransferSessionTest, DataTransferSessionGooddayMigration) {
       ar.diskFileInfo.path = "y";
       ar.diskFileInfo.owner = "z";
       ar.diskFileInfo.group = "g";
-      ar.diskFileInfo.recoveryBlob = "b";
       const auto archiveFileId = scheduler.checkAndGetNextArchiveFileId(s_diskInstance, ar.storageClass, ar.requester, logContext);
       archiveFileIds.push_back(archiveFileId);
       scheduler.queueArchiveWithGivenId(archiveFileId,s_diskInstance,ar,logContext);
@@ -1448,7 +1441,7 @@ TEST_P(DataTransferSessionTest, DataTransferSessionMissingFilesMigration) {
   {    
     // Label the tape
     castor::tape::tapeFile::LabelSession ls(*mockSys.fake.m_pathToDrive["/dev/nst0"], s_vid, false);
-    catalogue.tapeLabelled(s_vid, "T10D6116", true);
+    catalogue.tapeLabelled(s_vid, "T10D6116");
     mockSys.fake.m_pathToDrive["/dev/nst0"]->rewind();
     
     // Create the files and schedule the archivals
@@ -1471,7 +1464,6 @@ TEST_P(DataTransferSessionTest, DataTransferSessionMissingFilesMigration) {
       ar.diskFileInfo.path = "y";
       ar.diskFileInfo.owner = "z";
       ar.diskFileInfo.group = "g";
-      ar.diskFileInfo.recoveryBlob = "b";
       const auto archiveFileId = scheduler.checkAndGetNextArchiveFileId(s_diskInstance, ar.storageClass, ar.requester, logContext);
       archiveFileIds.push_back(archiveFileId);
       scheduler.queueArchiveWithGivenId(archiveFileId,s_diskInstance,ar,logContext);
@@ -1608,7 +1600,7 @@ TEST_P(DataTransferSessionTest, DataTransferSessionTapeFullMigration) {
   {    
     // Label the tape
     castor::tape::tapeFile::LabelSession ls(*mockSys.fake.m_pathToDrive["/dev/nst0"], s_vid, false);
-    catalogue.tapeLabelled(s_vid, "T10D6116", true);
+    catalogue.tapeLabelled(s_vid, "T10D6116");
     mockSys.fake.m_pathToDrive["/dev/nst0"]->rewind();
     
     // Create the files and schedule the archivals
@@ -1630,7 +1622,6 @@ TEST_P(DataTransferSessionTest, DataTransferSessionTapeFullMigration) {
       ar.diskFileInfo.path = "y";
       ar.diskFileInfo.owner = "z";
       ar.diskFileInfo.group = "g";
-      ar.diskFileInfo.recoveryBlob = "b";
       const auto archiveFileId = scheduler.checkAndGetNextArchiveFileId(s_diskInstance, ar.storageClass, ar.requester, logContext);
       archiveFileIds.push_back(archiveFileId);
       scheduler.queueArchiveWithGivenId(archiveFileId,s_diskInstance,ar,logContext);
@@ -1766,7 +1757,7 @@ TEST_P(DataTransferSessionTest, DataTransferSessionTapeFullOnFlushMigration) {
   {    
     // Label the tape
     castor::tape::tapeFile::LabelSession ls(*mockSys.fake.m_pathToDrive["/dev/nst0"], s_vid, false);
-    catalogue.tapeLabelled(s_vid, "T10D6116", true);
+    catalogue.tapeLabelled(s_vid, "T10D6116");
     mockSys.fake.m_pathToDrive["/dev/nst0"]->rewind();
     
     // Create the files and schedule the archivals
@@ -1788,7 +1779,6 @@ TEST_P(DataTransferSessionTest, DataTransferSessionTapeFullOnFlushMigration) {
       ar.diskFileInfo.path = "y";
       ar.diskFileInfo.owner = "z";
       ar.diskFileInfo.group = "g";
-      ar.diskFileInfo.recoveryBlob = "b";
       const auto archiveFileId = scheduler.checkAndGetNextArchiveFileId(s_diskInstance, ar.storageClass, ar.requester, logContext);
       archiveFileIds.push_back(archiveFileId);
       scheduler.queueArchiveWithGivenId(archiveFileId,s_diskInstance,ar,logContext);
diff --git a/tapeserver/castor/tape/tapeserver/daemon/MigrationReportPackerTest.cpp b/tapeserver/castor/tape/tapeserver/daemon/MigrationReportPackerTest.cpp
index 68754a47752f13ea3c5f2f8a05d8637eade28f55..297d99caa0a5a6eb7ef515d912f2b69f2890a921 100644
--- a/tapeserver/castor/tape/tapeserver/daemon/MigrationReportPackerTest.cpp
+++ b/tapeserver/castor/tape/tapeserver/daemon/MigrationReportPackerTest.cpp
@@ -85,7 +85,6 @@ namespace unitTests {
       fileReport.diskFileUser = archiveFile.diskFileInfo.owner;
       fileReport.diskFileGroup = archiveFile.diskFileInfo.group;
       fileReport.diskFilePath = archiveFile.diskFileInfo.path;
-      fileReport.diskFileRecoveryBlob = archiveFile.diskFileInfo.recoveryBlob;
       fileReport.diskInstance = archiveFile.diskInstance;
       fileReport.fSeq = tapeFile.fSeq;
       fileReport.size = archiveFile.fileSize;
@@ -151,7 +150,6 @@ namespace unitTests {
     job1->archiveFile.diskFileInfo.path="filePath1";
     job1->archiveFile.diskFileInfo.owner="testUser1";
     job1->archiveFile.diskFileInfo.group="testGroup1";
-    job1->archiveFile.diskFileInfo.recoveryBlob="recoveryBlob1";
     job1->archiveFile.fileSize=1024;        
     job1->archiveFile.checksumType="md5";
     job1->archiveFile.checksumValue="b170288bf1f61b26a648358866f4d6c6";
@@ -177,7 +175,6 @@ namespace unitTests {
     job2->archiveFile.diskFileInfo.path="filePath2";
     job2->archiveFile.diskFileInfo.owner="testUser2";
     job2->archiveFile.diskFileInfo.group="testGroup2";
-    job2->archiveFile.diskFileInfo.recoveryBlob="recoveryBlob2";
     job2->archiveFile.fileSize=1024;        
     job2->archiveFile.checksumType="md5";
     job2->archiveFile.checksumValue="b170288bf1f61b26a648358866f4d6c6";
@@ -314,7 +311,6 @@ namespace unitTests {
     migratedBigFile->archiveFile.diskFileInfo.path="filePath2";
     migratedBigFile->archiveFile.diskFileInfo.owner="testUser2";
     migratedBigFile->archiveFile.diskFileInfo.group="testGroup2";
-    migratedBigFile->archiveFile.diskFileInfo.recoveryBlob="recoveryBlob2";
     migratedBigFile->archiveFile.fileSize=100000;        
     migratedBigFile->archiveFile.checksumType="md5";
     migratedBigFile->archiveFile.checksumValue="b170288bf1f61b26a648358866f4d6c6";
@@ -333,7 +329,6 @@ namespace unitTests {
     migratedFileSmall->archiveFile.diskFileInfo.path="filePath3";
     migratedFileSmall->archiveFile.diskFileInfo.owner="testUser2";
     migratedFileSmall->archiveFile.diskFileInfo.group="testGroup2";
-    migratedFileSmall->archiveFile.diskFileInfo.recoveryBlob="recoveryBlob2";
     migratedFileSmall->archiveFile.fileSize=1;        
     migratedFileSmall->archiveFile.checksumType="md5";
     migratedFileSmall->archiveFile.checksumValue="b170288bf1f61b26a648358866f4d6c6";
@@ -352,7 +347,6 @@ namespace unitTests {
     migratedNullFile->archiveFile.diskFileInfo.path="filePath4";
     migratedNullFile->archiveFile.diskFileInfo.owner="testUser2";
     migratedNullFile->archiveFile.diskFileInfo.group="testGroup2";
-    migratedNullFile->archiveFile.diskFileInfo.recoveryBlob="recoveryBlob2";
     migratedNullFile->archiveFile.fileSize=0;        
     migratedNullFile->archiveFile.checksumType="md5";
     migratedNullFile->archiveFile.checksumValue="b170288bf1f61b26a648358866f4d6c6";
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index 4ff01c1e4f476049ad5b016395958eea44cac6b7..f0fbe9917cb541fca68dc6a360dcff135aa08d53 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -43,11 +43,6 @@ target_link_libraries(cta-unitTests
   gtest
   pthread)
 
-if (NOT DEFINED NoACS)
-  target_link_libraries(cta-unitTests
-    ctamediachangeracsdaemonunittests)
-endif (NOT DEFINED NoACS)
-
 set_property (TARGET cta-unitTests APPEND PROPERTY INSTALL_RPATH ${PROTOBUF3_RPATH})
 if (OCCI_SUPPORT)
   set_property (TARGET cta-unitTests APPEND PROPERTY INSTALL_RPATH ${ORACLE-INSTANTCLIENT_RPATH})
diff --git a/xroot_plugins/XrdSsiCtaRequestMessage.cpp b/xroot_plugins/XrdSsiCtaRequestMessage.cpp
index ddb4732fc1fd6ede88042044c2c1d9efd07d2bcc..ebab84f1d8741be9bb6e125f20390b613449d3a5 100644
--- a/xroot_plugins/XrdSsiCtaRequestMessage.cpp
+++ b/xroot_plugins/XrdSsiCtaRequestMessage.cpp
@@ -417,10 +417,6 @@ void RequestMessage::processCLOSEW(const cta::eos::Notification &notification, c
    diskFileInfo.group = notification.file().owner().groupname();
    diskFileInfo.path  = notification.file().lpath();
 
-   // Recovery blob is deprecated. EOS will fill in metadata fields in the protocol buffer
-   // and we need to decide what will be stored in the database.
-   diskFileInfo.recoveryBlob = "deprecated";
-
    std::string checksumtype(notification.file().cks().type());
    if(checksumtype == "adler") checksumtype = "ADLER32";   // replace this with an enum!
 
@@ -497,10 +493,6 @@ void RequestMessage::processPREPARE(const cta::eos::Notification &notification,
    diskFileInfo.group           = notification.file().owner().groupname();
    diskFileInfo.path            = notification.file().lpath();
 
-   // Recovery blob is deprecated. EOS will fill in metadata fields in the protocol buffer
-   // and we need to decide what will be stored in the database.
-   diskFileInfo.recoveryBlob = "deprecated";
-
    cta::common::dataStructures::RetrieveRequest request;
    request.requester            = originator;
    request.dstURL               = notification.transport().dst_url();
@@ -1875,7 +1867,6 @@ void RequestMessage::processTape_Ls(const cta::admin::AdminCmd &admincmd, cta::x
 
       searchCriteria.disabled        = getOptional(OptionBoolean::DISABLED,       &has_any);
       searchCriteria.full            = getOptional(OptionBoolean::FULL,           &has_any);
-      searchCriteria.lbp             = getOptional(OptionBoolean::LBP,            &has_any);
       searchCriteria.capacityInBytes = getOptional(OptionUInt64::CAPACITY,        &has_any);
       searchCriteria.logicalLibrary  = getOptional(OptionString::LOGICAL_LIBRARY, &has_any);
       searchCriteria.tapePool        = getOptional(OptionString::TAPE_POOL,       &has_any);
@@ -1896,7 +1887,7 @@ void RequestMessage::processTape_Ls(const cta::admin::AdminCmd &admincmd, cta::x
       std::vector<std::vector<std::string>> responseTable;
       std::vector<std::string> header = {
          "vid","media type","vendor","logical library","tapepool","vo","encryption key","capacity","occupancy",
-         "last fseq","full","disabled","lbp","label drive","label time","last w drive","last w time",
+         "last fseq","full","disabled","label drive","label time","last w drive","last w time",
          "last r drive","last r time","c.user","c.host","c.time","m.user","m.host","m.time","comment"
       };
       if(has_flag(OptionBoolean::SHOW_HEADER)) responseTable.push_back(header);    
@@ -1914,11 +1905,6 @@ void RequestMessage::processTape_Ls(const cta::admin::AdminCmd &admincmd, cta::x
          currentRow.push_back(std::to_string(static_cast<unsigned long long>(it->lastFSeq)));
          if(it->full) currentRow.push_back("true"); else currentRow.push_back("false");
          if(it->disabled) currentRow.push_back("true"); else currentRow.push_back("false");
-         if(it->lbp) {
-           if(it->lbp.value()) currentRow.push_back("true"); else currentRow.push_back("false");
-         } else {
-           currentRow.push_back("null");
-         }
 
          if(it->labelLog) {
             currentRow.push_back(it->labelLog.value().drive);
@@ -1963,11 +1949,8 @@ void RequestMessage::processTape_Label(const cta::admin::AdminCmd &admincmd, cta
 
    auto &vid   = getRequired(OptionString::VID);
    auto  force = getOptional(OptionBoolean::FORCE);
-   auto  lbp   = getOptional(OptionBoolean::LBP);
 
-   m_scheduler.queueLabel(m_cliIdentity, vid,
-                          force ? force.value() : false,
-                          lbp ? lbp.value() : true);
+   m_scheduler.queueLabel(m_cliIdentity, vid, force ? force.value() : false);
 
    response.set_type(cta::xrd::Response::RSP_SUCCESS);
 }
diff --git a/xroot_plugins/cta-frontend.service b/xroot_plugins/cta-frontend.service
index fdaaa54d4f8f04cd8881bca223ac67409586ad7b..e8cad2eb794c106c0b204f9c47b87a68512eb5d5 100644
--- a/xroot_plugins/cta-frontend.service
+++ b/xroot_plugins/cta-frontend.service
@@ -6,7 +6,10 @@ After=network-online.target
 ExecStart=/usr/bin/xrootd -l /var/log/cta-frontend-xrootd.log -c /etc/cta/cta-frontend-xrootd.conf -k fifo -n cta
 User=cta
 Type=simple
-Restart=no
+Restart=always
+RestartSec=10
+StartLimitInterval=0
+StartLimitBurst=0
 LimitCORE=infinity
 LimitNOFILE=65536