diff --git a/catalogue/CMakeLists.txt b/catalogue/CMakeLists.txt
index b46717c56fa40107568986b89929423588cee423..dffdef2ef4d3f2b3527988b6c9634a094fa0f836 100644
--- a/catalogue/CMakeLists.txt
+++ b/catalogue/CMakeLists.txt
@@ -58,6 +58,7 @@ set (CATALOGUE_LIB_SRC_FILES
   UserSpecifiedAnEmptyStringLogicalLibraryName.cpp
   UserSpecifiedAnEmptyStringMediaType.cpp
   UserSpecifiedAnEmptyStringStorageClassName.cpp
+  UserSpecifiedAnEmptyStringSupply.cpp
   UserSpecifiedAnEmptyStringTapePoolName.cpp
   UserSpecifiedAnEmptyStringUsername.cpp
   UserSpecifiedAnEmptyStringVendor.cpp
diff --git a/catalogue/Catalogue.hpp b/catalogue/Catalogue.hpp
index 3a0a928252cbf654d5f4cab2b777a6973f79e3ab..695eabebfe6c97884d521901eaa82f2ee46c7c1b 100644
--- a/catalogue/Catalogue.hpp
+++ b/catalogue/Catalogue.hpp
@@ -58,6 +58,7 @@
 #include "common/exception/UserError.hpp"
 #include "common/log/LogContext.hpp"
 #include "common/log/Logger.hpp"
+#include "common/optional.hpp"
 
 #include <list>
 #include <map>
@@ -237,13 +238,14 @@ public:
   virtual void modifyStorageClassNbCopies(const common::dataStructures::SecurityIdentity &admin, const std::string &instanceName, const std::string &name, const uint64_t nbCopies) = 0;
   virtual void modifyStorageClassComment(const common::dataStructures::SecurityIdentity &admin, const std::string &instanceName, const std::string &name, const std::string &comment) = 0;
 
-  virtual void createTapePool(const common::dataStructures::SecurityIdentity &admin, const std::string &name, const std::string &vo, const uint64_t nbPartialTapes, const bool encryptionValue, const std::string &comment) = 0;
+  virtual void createTapePool(const common::dataStructures::SecurityIdentity &admin, const std::string &name, const std::string &vo, const uint64_t nbPartialTapes, const bool encryptionValue, const cta::optional<std::string> &supply, const std::string &comment) = 0;
   virtual void deleteTapePool(const std::string &name) = 0;
   virtual std::list<TapePool> getTapePools() const = 0;
   virtual void modifyTapePoolVo(const common::dataStructures::SecurityIdentity &admin, const std::string &name, const std::string &vo) = 0;
   virtual void modifyTapePoolNbPartialTapes(const common::dataStructures::SecurityIdentity &admin, const std::string &name, const uint64_t nbPartialTapes) = 0;
   virtual void modifyTapePoolComment(const common::dataStructures::SecurityIdentity &admin, const std::string &name, const std::string &comment) = 0;
   virtual void setTapePoolEncryption(const common::dataStructures::SecurityIdentity &admin, const std::string &name, const bool encryptionValue) = 0;
+  virtual void modifyTapePoolSupply(const common::dataStructures::SecurityIdentity &admin, const std::string &name, const std::string &supply) = 0;
 
   virtual void createArchiveRoute(
     const common::dataStructures::SecurityIdentity &admin,
@@ -271,10 +273,11 @@ public:
   virtual void modifyArchiveRouteTapePoolName(const common::dataStructures::SecurityIdentity &admin, const std::string &instanceName, const std::string &storageClassName, const uint32_t copyNb, const std::string &tapePoolName) = 0;
   virtual void modifyArchiveRouteComment(const common::dataStructures::SecurityIdentity &admin, const std::string &instanceName, const std::string &storageClassName, const uint32_t copyNb, const std::string &comment) = 0;
 
-  virtual void createLogicalLibrary(const common::dataStructures::SecurityIdentity &admin, const std::string &name, const std::string &comment) = 0;
+  virtual void createLogicalLibrary(const common::dataStructures::SecurityIdentity &admin, const std::string &name, const bool isDisabled, const std::string &comment) = 0;
   virtual void deleteLogicalLibrary(const std::string &name) = 0;
   virtual std::list<common::dataStructures::LogicalLibrary> getLogicalLibraries() const = 0;
   virtual void modifyLogicalLibraryComment(const common::dataStructures::SecurityIdentity &admin, const std::string &name, const std::string &comment) = 0;
+  virtual void setLogicalLibraryDisabled(const common::dataStructures::SecurityIdentity &admin, const std::string &name, const bool disabledValue) = 0;
 
   /**
    * Creates a tape which is assumed to have logical block protection (LBP)
diff --git a/catalogue/CatalogueRetryWrapper.hpp b/catalogue/CatalogueRetryWrapper.hpp
index 9e01f127fefd7d9851fedea3f495087342d5f19b..b9155d69c4b2ddb531286f31a60550cd144fb03b 100644
--- a/catalogue/CatalogueRetryWrapper.hpp
+++ b/catalogue/CatalogueRetryWrapper.hpp
@@ -137,8 +137,8 @@ public:
     return retryOnLostConnection(m_log, [&]{return m_catalogue->modifyStorageClassComment(admin, instanceName, name, comment);}, m_maxTriesToConnect);
   }
 
-  void createTapePool(const common::dataStructures::SecurityIdentity &admin, const std::string &name, const std::string &vo, const uint64_t nbPartialTapes, const bool encryptionValue, const std::string &comment) override {
-    return retryOnLostConnection(m_log, [&]{return m_catalogue->createTapePool(admin, name, vo, nbPartialTapes, encryptionValue, comment);}, m_maxTriesToConnect);
+  void createTapePool(const common::dataStructures::SecurityIdentity &admin, const std::string &name, const std::string &vo, const uint64_t nbPartialTapes, const bool encryptionValue, const cta::optional<std::string> &supply, const std::string &comment) override {
+    return retryOnLostConnection(m_log, [&]{return m_catalogue->createTapePool(admin, name, vo, nbPartialTapes, encryptionValue, supply, comment);}, m_maxTriesToConnect);
   }
 
   void deleteTapePool(const std::string &name) override {
@@ -165,6 +165,10 @@ public:
     return retryOnLostConnection(m_log, [&]{return m_catalogue->setTapePoolEncryption(admin, name, encryptionValue);}, m_maxTriesToConnect);
   }
 
+  void modifyTapePoolSupply(const common::dataStructures::SecurityIdentity &admin, const std::string &name, const std::string &supply) override {
+    return retryOnLostConnection(m_log, [&]{return m_catalogue->modifyTapePoolSupply(admin, name, supply);}, m_maxTriesToConnect);
+  }
+
   void createArchiveRoute(const common::dataStructures::SecurityIdentity &admin, const std::string &diskInstanceName, const std::string &storageClassName, const uint32_t copyNb, const std::string &tapePoolName, const std::string &comment) override {
     return retryOnLostConnection(m_log, [&]{return m_catalogue->createArchiveRoute(admin, diskInstanceName, storageClassName, copyNb, tapePoolName, comment);}, m_maxTriesToConnect);
   }
@@ -185,8 +189,8 @@ public:
     return retryOnLostConnection(m_log, [&]{return m_catalogue->modifyArchiveRouteComment(admin, instanceName, storageClassName, copyNb, comment);}, m_maxTriesToConnect);
   }
 
-  void createLogicalLibrary(const common::dataStructures::SecurityIdentity &admin, const std::string &name, const std::string &comment) override {
-    return retryOnLostConnection(m_log, [&]{return m_catalogue->createLogicalLibrary(admin, name, comment);}, m_maxTriesToConnect);
+  void createLogicalLibrary(const common::dataStructures::SecurityIdentity &admin, const std::string &name, const bool isDisabled, const std::string &comment) override {
+    return retryOnLostConnection(m_log, [&]{return m_catalogue->createLogicalLibrary(admin, name, isDisabled, comment);}, m_maxTriesToConnect);
   }
 
   void deleteLogicalLibrary(const std::string &name) override {
@@ -201,6 +205,10 @@ public:
     return retryOnLostConnection(m_log, [&]{return m_catalogue->modifyLogicalLibraryComment(admin, name, comment);}, m_maxTriesToConnect);
   }
 
+  void setLogicalLibraryDisabled(const common::dataStructures::SecurityIdentity &admin, const std::string &name, const bool disabledValue) override {
+    return retryOnLostConnection(m_log, [&]{return m_catalogue->setLogicalLibraryDisabled(admin, name, disabledValue);}, m_maxTriesToConnect);
+  }
+
   void createTape(const common::dataStructures::SecurityIdentity &admin, const std::string &vid, const std::string &mediaType, const std::string &vendor, const std::string &logicalLibraryName, const std::string &tapePoolName, const uint64_t capacityInBytes, const bool disabled, const bool full, const std::string &comment) override {
     return retryOnLostConnection(m_log, [&]{return m_catalogue->createTape(admin, vid, mediaType, vendor, logicalLibraryName, tapePoolName, capacityInBytes, disabled, full, comment);}, m_maxTriesToConnect);
   }
diff --git a/catalogue/CatalogueTest.cpp b/catalogue/CatalogueTest.cpp
index 5223ea81934496221e67381ebf9f4367b90f58c6..97000ca464a268a50cb3f91811cc32ff7de48fae 100644
--- a/catalogue/CatalogueTest.cpp
+++ b/catalogue/CatalogueTest.cpp
@@ -28,6 +28,7 @@
 #include "catalogue/UserSpecifiedAnEmptyStringLogicalLibraryName.hpp"
 #include "catalogue/UserSpecifiedAnEmptyStringMediaType.hpp"
 #include "catalogue/UserSpecifiedAnEmptyStringStorageClassName.hpp"
+#include "catalogue/UserSpecifiedAnEmptyStringSupply.hpp"
 #include "catalogue/UserSpecifiedAnEmptyStringTapePoolName.hpp"
 #include "catalogue/UserSpecifiedAnEmptyStringUsername.hpp"
 #include "catalogue/UserSpecifiedAnEmptyStringVendor.hpp"
@@ -798,8 +799,9 @@ TEST_P(cta_catalogue_CatalogueTest, createTapePool) {
   const std::string vo = "vo";
   const uint64_t nbPartialTapes = 2;
   const bool isEncrypted = true;
+  const cta::optional<std::string> supply("value for the supply pool mechanism");
   const std::string comment = "Create tape pool";
-  m_catalogue->createTapePool(m_admin, tapePoolName, vo, nbPartialTapes, isEncrypted, comment);
+  m_catalogue->createTapePool(m_admin, tapePoolName, vo, nbPartialTapes, isEncrypted, supply, comment);
 
   ASSERT_TRUE(m_catalogue->tapePoolExists(tapePoolName));
       
@@ -812,6 +814,52 @@ TEST_P(cta_catalogue_CatalogueTest, createTapePool) {
   ASSERT_EQ(vo, pool.vo);
   ASSERT_EQ(nbPartialTapes, pool.nbPartialTapes);
   ASSERT_EQ(isEncrypted, pool.encryption);
+  ASSERT_TRUE((bool)pool.supply);
+  ASSERT_EQ(supply.value(), pool.supply.value());
+  ASSERT_EQ(supply, pool.supply);
+  ASSERT_EQ(0, pool.nbTapes);
+  ASSERT_EQ(0, pool.capacityBytes);
+  ASSERT_EQ(0, pool.dataBytes);
+  ASSERT_EQ(0, pool.nbPhysicalFiles);
+  ASSERT_EQ(comment, pool.comment);
+
+  const common::dataStructures::EntryLog creationLog = pool.creationLog;
+  ASSERT_EQ(m_admin.username, creationLog.username);
+  ASSERT_EQ(m_admin.host, creationLog.host);
+  
+  const common::dataStructures::EntryLog lastModificationLog =
+    pool.lastModificationLog;
+  ASSERT_EQ(creationLog, lastModificationLog);
+}
+
+TEST_P(cta_catalogue_CatalogueTest, createTapePool_null_supply) {
+  using namespace cta;
+      
+  ASSERT_TRUE(m_catalogue->getTapePools().empty());
+      
+  const std::string tapePoolName = "tape_pool";
+
+  ASSERT_FALSE(m_catalogue->tapePoolExists(tapePoolName));
+
+  const std::string vo = "vo";
+  const uint64_t nbPartialTapes = 2;
+  const bool isEncrypted = true;
+  const cta::optional<std::string> supply;
+  const std::string comment = "Create tape pool";
+  m_catalogue->createTapePool(m_admin, tapePoolName, vo, nbPartialTapes, isEncrypted, supply, comment);
+
+  ASSERT_TRUE(m_catalogue->tapePoolExists(tapePoolName));
+      
+  const auto pools = m_catalogue->getTapePools();
+      
+  ASSERT_EQ(1, pools.size());
+      
+  const auto &pool = pools.front();
+  ASSERT_EQ(tapePoolName, pool.name);
+  ASSERT_EQ(vo, pool.vo);
+  ASSERT_EQ(nbPartialTapes, pool.nbPartialTapes);
+  ASSERT_EQ(isEncrypted, pool.encryption);
+  ASSERT_FALSE((bool)pool.supply);
   ASSERT_EQ(0, pool.nbTapes);
   ASSERT_EQ(0, pool.capacityBytes);
   ASSERT_EQ(0, pool.dataBytes);
@@ -834,9 +882,10 @@ TEST_P(cta_catalogue_CatalogueTest, createTapePool_same_twice) {
   const std::string vo = "vo";
   const uint64_t nbPartialTapes = 2;
   const bool isEncrypted = true;
+  const cta::optional<std::string> supply("value for the supply pool mechanism");
   const std::string comment = "Create tape pool";
-  m_catalogue->createTapePool(m_admin, tapePoolName, vo, nbPartialTapes, isEncrypted, comment);
-  ASSERT_THROW(m_catalogue->createTapePool(m_admin, tapePoolName, vo, nbPartialTapes, isEncrypted, comment),
+  m_catalogue->createTapePool(m_admin, tapePoolName, vo, nbPartialTapes, isEncrypted, supply, comment);
+  ASSERT_THROW(m_catalogue->createTapePool(m_admin, tapePoolName, vo, nbPartialTapes, isEncrypted, supply, comment),
     exception::UserError);
 }
 
@@ -849,8 +898,9 @@ TEST_P(cta_catalogue_CatalogueTest, deleteTapePool) {
   const std::string vo = "vo";
   const uint64_t nbPartialTapes = 2;
   const bool isEncrypted = true;
+  const cta::optional<std::string> supply("value for the supply pool mechanism");
   const std::string comment = "Create tape pool";
-  m_catalogue->createTapePool(m_admin, tapePoolName, vo, nbPartialTapes, isEncrypted, comment);
+  m_catalogue->createTapePool(m_admin, tapePoolName, vo, nbPartialTapes, isEncrypted, supply, comment);
 
   const auto pools = m_catalogue->getTapePools();
 
@@ -891,17 +941,21 @@ TEST_P(cta_catalogue_CatalogueTest, deleteTapePool_notEmpty) {
   const std::string mediaType = "media_type";
   const std::string vendor = "vendor";
   const std::string logicalLibraryName = "logical_library_name";
+  const bool logicalLibraryIsDisabled= false;
   const std::string tapePoolName = "tape_pool_name";
   const std::string vo = "vo";
+  const uint64_t nbPartialTapes = 2;
+  const bool isEncrypted = true;
   const uint64_t capacityInBytes = (uint64_t)10 * 1000 * 1000 * 1000 * 1000;
   const bool disabledValue = true;
   const bool fullValue = false;
+  const cta::optional<std::string> supply("value for the supply pool mechanism");
   const std::string comment = "Create tape";
 
-  m_catalogue->createLogicalLibrary(m_admin, logicalLibraryName,
+  m_catalogue->createLogicalLibrary(m_admin, logicalLibraryName, logicalLibraryIsDisabled,
     "Create logical library");
 
-  m_catalogue->createTapePool(m_admin, tapePoolName, vo, 2, true, "Create tape pool");
+  m_catalogue->createTapePool(m_admin, tapePoolName, vo, nbPartialTapes, isEncrypted, supply, "Create tape pool");
   {
     const auto pools = m_catalogue->getTapePools();
     ASSERT_EQ(1, pools.size());
@@ -973,8 +1027,9 @@ TEST_P(cta_catalogue_CatalogueTest, createTapePool_emptyStringTapePoolName) {
   const std::string vo = "vo";
   const uint64_t nbPartialTapes = 2;
   const bool isEncrypted = true;
+  const cta::optional<std::string> supply("value for the supply pool mechanism");
   const std::string comment = "Create tape pool";
-  ASSERT_THROW(m_catalogue->createTapePool(m_admin, tapePoolName, vo, nbPartialTapes, isEncrypted, comment),
+  ASSERT_THROW(m_catalogue->createTapePool(m_admin, tapePoolName, vo, nbPartialTapes, isEncrypted, supply, comment),
     catalogue::UserSpecifiedAnEmptyStringTapePoolName);
 }
 
@@ -990,8 +1045,9 @@ TEST_P(cta_catalogue_CatalogueTest, createTapePool_emptyStringVO) {
   const std::string vo = "";
   const uint64_t nbPartialTapes = 2;
   const bool isEncrypted = true;
+  const cta::optional<std::string> supply("value for the supply pool mechanism");
   const std::string comment = "Create tape pool";
-  ASSERT_THROW(m_catalogue->createTapePool(m_admin, tapePoolName, vo, nbPartialTapes, isEncrypted, comment),
+  ASSERT_THROW(m_catalogue->createTapePool(m_admin, tapePoolName, vo, nbPartialTapes, isEncrypted, supply, comment),
     catalogue::UserSpecifiedAnEmptyStringVo);
 }
 
@@ -1007,8 +1063,9 @@ TEST_P(cta_catalogue_CatalogueTest, createTapePool_emptyStringComment) {
   const std::string vo = "vo";
   const uint64_t nbPartialTapes = 2;
   const bool isEncrypted = true;
+  const cta::optional<std::string> supply("value for the supply pool mechanism");
   const std::string comment = "";
-  ASSERT_THROW(m_catalogue->createTapePool(m_admin, tapePoolName, vo, nbPartialTapes, isEncrypted, comment),
+  ASSERT_THROW(m_catalogue->createTapePool(m_admin, tapePoolName, vo, nbPartialTapes, isEncrypted, supply, comment),
     catalogue::UserSpecifiedAnEmptyStringComment);
 }
 
@@ -1028,8 +1085,9 @@ TEST_P(cta_catalogue_CatalogueTest, modifyTapePoolVo) {
   const std::string vo = "vo";
   const uint64_t nbPartialTapes = 2;
   const bool isEncrypted = true;
+  const cta::optional<std::string> supply("value for the supply pool mechanism");
   const std::string comment = "Create tape pool";
-  m_catalogue->createTapePool(m_admin, tapePoolName, vo, nbPartialTapes, isEncrypted, comment);
+  m_catalogue->createTapePool(m_admin, tapePoolName, vo, nbPartialTapes, isEncrypted, supply, comment);
 
   {
     const auto pools = m_catalogue->getTapePools();
@@ -1100,8 +1158,9 @@ TEST_P(cta_catalogue_CatalogueTest, modifyTapePoolVo_emptyStringVo) {
   const std::string vo = "vo";
   const uint64_t nbPartialTapes = 2;
   const bool isEncrypted = true;
+  const cta::optional<std::string> supply("value for the supply pool mechanism");
   const std::string comment = "Create tape pool";
-  m_catalogue->createTapePool(m_admin, tapePoolName, vo, nbPartialTapes, isEncrypted, comment);
+  m_catalogue->createTapePool(m_admin, tapePoolName, vo, nbPartialTapes, isEncrypted, supply, comment);
 
   {
     const auto pools = m_catalogue->getTapePools();
@@ -1141,8 +1200,9 @@ TEST_P(cta_catalogue_CatalogueTest, modifyTapePoolNbPartialTapes) {
   const std::string vo = "vo";
   const uint64_t nbPartialTapes = 2;
   const bool isEncrypted = true;
+  const cta::optional<std::string> supply("value for the supply pool mechanism");
   const std::string comment = "Create tape pool";
-  m_catalogue->createTapePool(m_admin, tapePoolName, vo, nbPartialTapes, isEncrypted, comment);
+  m_catalogue->createTapePool(m_admin, tapePoolName, vo, nbPartialTapes, isEncrypted, supply, comment);
 
   {
     const auto pools = m_catalogue->getTapePools();
@@ -1224,8 +1284,9 @@ TEST_P(cta_catalogue_CatalogueTest, modifyTapePoolComment) {
   const std::string vo = "vo";
   const uint64_t nbPartialTapes = 2;
   const bool isEncrypted = true;
+  const cta::optional<std::string> supply("value for the supply pool mechanism");
   const std::string comment = "Create tape pool";
-  m_catalogue->createTapePool(m_admin, tapePoolName, vo, nbPartialTapes, isEncrypted, comment);
+  m_catalogue->createTapePool(m_admin, tapePoolName, vo, nbPartialTapes, isEncrypted, supply, comment);
 
   {
     const auto pools = m_catalogue->getTapePools();
@@ -1296,8 +1357,9 @@ TEST_P(cta_catalogue_CatalogueTest, modifyTapePoolComment_emptyStringComment) {
   const std::string vo = "vo";
   const uint64_t nbPartialTapes = 2;
   const bool isEncrypted = true;
+  const cta::optional<std::string> supply("value for the supply pool mechanism");
   const std::string comment = "Create tape pool";
-  m_catalogue->createTapePool(m_admin, tapePoolName, vo, nbPartialTapes, isEncrypted, comment);
+  m_catalogue->createTapePool(m_admin, tapePoolName, vo, nbPartialTapes, isEncrypted, supply, comment);
 
   {
     const auto pools = m_catalogue->getTapePools();
@@ -1347,8 +1409,9 @@ TEST_P(cta_catalogue_CatalogueTest, setTapePoolEncryption) {
   const std::string vo = "vo";
   const uint64_t nbPartialTapes = 2;
   const bool isEncrypted = true;
+  const cta::optional<std::string> supply("value for the supply pool mechanism");
   const std::string comment = "Create tape pool";
-  m_catalogue->createTapePool(m_admin, tapePoolName, vo, nbPartialTapes, isEncrypted, comment);
+  m_catalogue->createTapePool(m_admin, tapePoolName, vo, nbPartialTapes, isEncrypted, supply, comment);
 
   {
     const auto pools = m_catalogue->getTapePools();
@@ -1409,6 +1472,139 @@ TEST_P(cta_catalogue_CatalogueTest, setTapePoolEncryption_nonExistentTapePool) {
   ASSERT_THROW(m_catalogue->setTapePoolEncryption(m_admin, tapePoolName, isEncrypted), exception::UserError);
 }
 
+TEST_P(cta_catalogue_CatalogueTest, modifyTapePoolSupply) {
+  using namespace cta;
+      
+  ASSERT_TRUE(m_catalogue->getTapePools().empty());
+      
+  const std::string tapePoolName = "tape_pool";
+  const std::string vo = "vo";
+  const uint64_t nbPartialTapes = 2;
+  const bool isEncrypted = true;
+  const cta::optional<std::string> supply("value for the supply pool mechanism");
+  const std::string comment = "Create tape pool";
+  m_catalogue->createTapePool(m_admin, tapePoolName, vo, nbPartialTapes, isEncrypted, supply, comment);
+
+  {
+    const auto pools = m_catalogue->getTapePools();
+      
+    ASSERT_EQ(1, pools.size());
+
+    const auto &pool = pools.front();
+    ASSERT_EQ(tapePoolName, pool.name);
+    ASSERT_EQ(vo, pool.vo);
+    ASSERT_EQ(nbPartialTapes, pool.nbPartialTapes);
+    ASSERT_EQ(isEncrypted, pool.encryption);
+    ASSERT_TRUE((bool)supply);
+    ASSERT_EQ(supply.value(), pool.supply.value());
+    ASSERT_EQ(supply, pool.supply);
+    ASSERT_EQ(0, pool.nbTapes);
+    ASSERT_EQ(0, pool.capacityBytes);
+    ASSERT_EQ(0, pool.dataBytes);
+    ASSERT_EQ(0, pool.nbPhysicalFiles);
+    ASSERT_EQ(comment, pool.comment);
+
+    const common::dataStructures::EntryLog creationLog = pool.creationLog;
+    ASSERT_EQ(m_admin.username, creationLog.username);
+    ASSERT_EQ(m_admin.host, creationLog.host);
+  
+    const common::dataStructures::EntryLog lastModificationLog = pool.lastModificationLog;
+    ASSERT_EQ(creationLog, lastModificationLog);
+  }
+
+  const std::string modifiedSupply("Modified supply");
+  m_catalogue->modifyTapePoolSupply(m_admin, tapePoolName, modifiedSupply);
+
+  {
+    const auto pools = m_catalogue->getTapePools();
+      
+    ASSERT_EQ(1, pools.size());
+      
+    const auto &pool = pools.front();
+    ASSERT_EQ(tapePoolName, pool.name);
+    ASSERT_EQ(vo, pool.vo);
+    ASSERT_EQ(nbPartialTapes, pool.nbPartialTapes);
+    ASSERT_EQ(isEncrypted, pool.encryption);
+    ASSERT_TRUE((bool)supply);
+    ASSERT_EQ(modifiedSupply, pool.supply.value());
+    ASSERT_EQ(0, pool.nbTapes);
+    ASSERT_EQ(0, pool.capacityBytes);
+    ASSERT_EQ(0, pool.dataBytes);
+    ASSERT_EQ(0, pool.nbPhysicalFiles);
+    ASSERT_EQ(comment, pool.comment);
+
+    const common::dataStructures::EntryLog creationLog = pool.creationLog;
+    ASSERT_EQ(m_admin.username, creationLog.username);
+    ASSERT_EQ(m_admin.host, creationLog.host);
+  }
+}
+
+TEST_P(cta_catalogue_CatalogueTest, modifyTapePoolSupply_emptyStringTapePoolName) {
+  using namespace cta;
+      
+  ASSERT_TRUE(m_catalogue->getTapePools().empty());
+      
+  const std::string tapePoolName = "";
+  const std::string modifiedSupply = "Modified supply";
+  ASSERT_THROW(m_catalogue->modifyTapePoolSupply(m_admin, tapePoolName, modifiedSupply),
+    catalogue::UserSpecifiedAnEmptyStringTapePoolName);
+}
+
+TEST_P(cta_catalogue_CatalogueTest, modifyTapePoolSupply_emptyStringSupply) {
+  using namespace cta;
+      
+  ASSERT_TRUE(m_catalogue->getTapePools().empty());
+      
+  const std::string tapePoolName = "tape_pool";
+  const std::string vo = "vo";
+  const uint64_t nbPartialTapes = 2;
+  const bool isEncrypted = true;
+  const cta::optional<std::string> supply("value for the supply pool mechanism");
+  const std::string comment = "Create tape pool";
+  m_catalogue->createTapePool(m_admin, tapePoolName, vo, nbPartialTapes, isEncrypted, supply, comment);
+
+  {
+    const auto pools = m_catalogue->getTapePools();
+      
+    ASSERT_EQ(1, pools.size());
+
+    const auto &pool = pools.front();
+    ASSERT_EQ(tapePoolName, pool.name);
+    ASSERT_EQ(vo, pool.vo);
+    ASSERT_EQ(nbPartialTapes, pool.nbPartialTapes);
+    ASSERT_EQ(isEncrypted, pool.encryption);
+    ASSERT_TRUE((bool)supply);
+    ASSERT_EQ(supply.value(), pool.supply.value());
+    ASSERT_EQ(supply, pool.supply);
+    ASSERT_EQ(0, pool.nbTapes);
+    ASSERT_EQ(0, pool.capacityBytes);
+    ASSERT_EQ(0, pool.dataBytes);
+    ASSERT_EQ(0, pool.nbPhysicalFiles);
+    ASSERT_EQ(comment, pool.comment);
+
+    const common::dataStructures::EntryLog creationLog = pool.creationLog;
+    ASSERT_EQ(m_admin.username, creationLog.username);
+    ASSERT_EQ(m_admin.host, creationLog.host);
+  
+    const common::dataStructures::EntryLog lastModificationLog = pool.lastModificationLog;
+    ASSERT_EQ(creationLog, lastModificationLog);
+  }
+
+  const std::string modifiedSupply = "";
+  ASSERT_THROW(m_catalogue->modifyTapePoolSupply(m_admin, tapePoolName, modifiedSupply),
+    catalogue::UserSpecifiedAnEmptyStringSupply);
+}
+
+TEST_P(cta_catalogue_CatalogueTest, modifyTapePoolSupply_nonExistentTapePool) {
+  using namespace cta;
+      
+  ASSERT_TRUE(m_catalogue->getTapePools().empty());
+      
+  const std::string tapePoolName = "tape_pool";
+  const std::string supply = "value for the supply pool mechanism";
+  ASSERT_THROW(m_catalogue->modifyTapePoolSupply(m_admin, tapePoolName, supply), exception::UserError);
+}
+
 TEST_P(cta_catalogue_CatalogueTest, createArchiveRoute) {
   using namespace cta;
       
@@ -1427,7 +1623,8 @@ TEST_P(cta_catalogue_CatalogueTest, createArchiveRoute) {
   const std::string vo = "vo";
   const uint64_t nbPartialTapes = 2;
   const bool isEncrypted = true;
-  m_catalogue->createTapePool(m_admin, tapePoolName, vo, nbPartialTapes, isEncrypted, "Create tape pool");
+  const cta::optional<std::string> supply("value for the supply pool mechanism");
+  m_catalogue->createTapePool(m_admin, tapePoolName, vo, nbPartialTapes, isEncrypted, supply, "Create tape pool");
 
   const uint32_t copyNb = 1;
   const std::string comment = "Create archive route";
@@ -1470,7 +1667,8 @@ TEST_P(cta_catalogue_CatalogueTest, createArchiveRoute_emptyStringDiskInstanceNa
   const std::string vo = "vo";
   const uint64_t nbPartialTapes = 2;
   const bool isEncrypted = true;
-  m_catalogue->createTapePool(m_admin, tapePoolName, vo, nbPartialTapes, isEncrypted, "Create tape pool");
+  const cta::optional<std::string> supply("value for the supply pool mechanism");
+  m_catalogue->createTapePool(m_admin, tapePoolName, vo, nbPartialTapes, isEncrypted, supply, "Create tape pool");
 
   const std::string diskInstanceName = "";
   const uint32_t copyNb = 1;
@@ -1497,7 +1695,8 @@ TEST_P(cta_catalogue_CatalogueTest, createArchiveRoute_emptyStringStorageClassNa
   const std::string vo = "vo";
   const uint64_t nbPartialTapes = 2;
   const bool isEncrypted = true;
-  m_catalogue->createTapePool(m_admin, tapePoolName, vo, nbPartialTapes, isEncrypted, "Create tape pool");
+  const cta::optional<std::string> supply("value for the supply pool mechanism");
+  m_catalogue->createTapePool(m_admin, tapePoolName, vo, nbPartialTapes, isEncrypted, supply, "Create tape pool");
 
   const std::string storageClassName = "";
   const uint32_t copyNb = 1;
@@ -1524,7 +1723,8 @@ TEST_P(cta_catalogue_CatalogueTest, createArchiveRoute_zeroCopyNb) {
   const std::string vo = "vo";
   const uint64_t nbPartialTapes = 2;
   const bool isEncrypted = true;
-  m_catalogue->createTapePool(m_admin, tapePoolName, vo, nbPartialTapes, isEncrypted, "Create tape pool");
+  const cta::optional<std::string> supply("value for the supply pool mechanism");
+  m_catalogue->createTapePool(m_admin, tapePoolName, vo, nbPartialTapes, isEncrypted, supply, "Create tape pool");
 
   const uint32_t copyNb = 0;
   const std::string comment = "Create archive route";
@@ -1571,7 +1771,8 @@ TEST_P(cta_catalogue_CatalogueTest, createArchiveRoute_emptyStringComment) {
   const std::string vo = "vo";
   const uint64_t nbPartialTapes = 2;
   const bool isEncrypted = true;
-  m_catalogue->createTapePool(m_admin, tapePoolName, vo, nbPartialTapes, isEncrypted, "Create tape pool");
+  const cta::optional<std::string> supply("value for the supply pool mechanism");
+  m_catalogue->createTapePool(m_admin, tapePoolName, vo, nbPartialTapes, isEncrypted, supply, "Create tape pool");
 
   const uint32_t copyNb = 1;
   const std::string comment = "";
@@ -1593,7 +1794,8 @@ TEST_P(cta_catalogue_CatalogueTest, createArchiveRoute_non_existent_storage_clas
   const std::string vo = "vo";
   const uint64_t nbPartialTapes = 2;
   const bool isEncrypted = true;
-  m_catalogue->createTapePool(m_admin, tapePoolName, vo, nbPartialTapes, isEncrypted, "Create tape pool");
+  const cta::optional<std::string> supply("value for the supply pool mechanism");
+  m_catalogue->createTapePool(m_admin, tapePoolName, vo, nbPartialTapes, isEncrypted, supply, "Create tape pool");
 
   const uint32_t copyNb = 1;
   const std::string comment = "Create archive route";
@@ -1650,7 +1852,8 @@ TEST_P(cta_catalogue_CatalogueTest, createArchiveRoute_same_name_different_disk_
   const std::string vo = "vo";
   const uint64_t nbPartialTapes = 2;
   const bool isEncrypted = true;
-  m_catalogue->createTapePool(m_admin, tapePoolName, vo, nbPartialTapes, isEncrypted, "Create tape pool");
+  const cta::optional<std::string> supply("value for the supply pool mechanism");
+  m_catalogue->createTapePool(m_admin, tapePoolName, vo, nbPartialTapes, isEncrypted, supply, "Create tape pool");
 
   const uint32_t copyNb = 1;
   const std::string comment = "Create archive route";
@@ -1702,7 +1905,8 @@ TEST_P(cta_catalogue_CatalogueTest, createArchiveRoute_same_twice) {
   const std::string vo = "vo";
   const uint64_t nbPartialTapes = 2;
   const bool isEncrypted = true;
-  m_catalogue->createTapePool(m_admin, tapePoolName, vo, nbPartialTapes, isEncrypted, "Create tape pool");
+  const cta::optional<std::string> supply("value for the supply pool mechanism");
+  m_catalogue->createTapePool(m_admin, tapePoolName, vo, nbPartialTapes, isEncrypted, supply, "Create tape pool");
 
   const uint32_t copyNb = 1;
   const std::string comment = "Create archive route";
@@ -1729,7 +1933,8 @@ TEST_P(cta_catalogue_CatalogueTest, deleteArchiveRoute) {
   const std::string vo = "vo";
   const uint64_t nbPartialTapes = 2;
   const bool isEncrypted = true;
-  m_catalogue->createTapePool(m_admin, tapePoolName, vo, nbPartialTapes, isEncrypted, "Create tape pool");
+  const cta::optional<std::string> supply("value for the supply pool mechanism");
+  m_catalogue->createTapePool(m_admin, tapePoolName, vo, nbPartialTapes, isEncrypted, supply, "Create tape pool");
 
   const uint32_t copyNb = 1;
   const std::string comment = "Create archive route";
@@ -1782,7 +1987,8 @@ TEST_P(cta_catalogue_CatalogueTest, createArchiveRoute_deleteStorageClass) {
   const std::string vo = "vo";
   const uint64_t nbPartialTapes = 2;
   const bool isEncrypted = true;
-  m_catalogue->createTapePool(m_admin, tapePoolName, vo, nbPartialTapes, isEncrypted, "Create tape pool");
+  const cta::optional<std::string> supply("value for the supply pool mechanism");
+  m_catalogue->createTapePool(m_admin, tapePoolName, vo, nbPartialTapes, isEncrypted, supply, "Create tape pool");
 
   const uint32_t copyNb = 1;
   const std::string comment = "Create archive route";
@@ -1828,10 +2034,12 @@ TEST_P(cta_catalogue_CatalogueTest, modifyArchiveRouteTapePoolName) {
   const std::string vo = "vo";
   const uint64_t nbPartialTapes = 2;
   const bool isEncrypted = true;
-  m_catalogue->createTapePool(m_admin, tapePoolName, vo, nbPartialTapes, isEncrypted, "Create tape pool");
+  const cta::optional<std::string> supply("value for the supply pool mechanism");
+  m_catalogue->createTapePool(m_admin, tapePoolName, vo, nbPartialTapes, isEncrypted, supply, "Create tape pool");
 
   const std::string anotherTapePoolName = "another_tape_pool";
-  m_catalogue->createTapePool(m_admin, anotherTapePoolName, vo, nbPartialTapes, isEncrypted, "Create another tape pool");
+  m_catalogue->createTapePool(m_admin, anotherTapePoolName, vo, nbPartialTapes, isEncrypted, supply,
+    "Create another tape pool");
 
   const uint32_t copyNb = 1;
   const std::string comment = "Create archive route";
@@ -1896,7 +2104,8 @@ TEST_P(cta_catalogue_CatalogueTest, modifyArchiveRouteTapePoolName_nonExistentAr
   const std::string vo = "vo";
   const uint64_t nbPartialTapes = 2;
   const bool isEncrypted = true;
-  m_catalogue->createTapePool(m_admin, tapePoolName, vo, nbPartialTapes, isEncrypted, "Create tape pool");
+  const cta::optional<std::string> supply("value for the supply pool mechanism");
+  m_catalogue->createTapePool(m_admin, tapePoolName, vo, nbPartialTapes, isEncrypted, supply, "Create tape pool");
 
   const uint32_t copyNb = 1;
   ASSERT_THROW(m_catalogue->modifyArchiveRouteTapePoolName(m_admin, storageClass.diskInstance, storageClass.name,
@@ -1921,7 +2130,8 @@ TEST_P(cta_catalogue_CatalogueTest, modifyArchiveRouteComment) {
   const std::string vo = "vo";
   const uint64_t nbPartialTapes = 2;
   const bool isEncrypted = true;
-  m_catalogue->createTapePool(m_admin, tapePoolName, vo, nbPartialTapes, isEncrypted, "Create tape pool");
+  const cta::optional<std::string> supply("value for the supply pool mechanism");
+  m_catalogue->createTapePool(m_admin, tapePoolName, vo, nbPartialTapes, isEncrypted, supply, "Create tape pool");
 
   const uint32_t copyNb = 1;
   const std::string comment = "Create archive route";
@@ -1988,7 +2198,8 @@ TEST_P(cta_catalogue_CatalogueTest, modifyArchiveRouteComment_nonExistentArchive
   const std::string vo = "vo";
   const uint64_t nbPartialTapes = 2;
   const bool isEncrypted = true;
-  m_catalogue->createTapePool(m_admin, tapePoolName, vo, nbPartialTapes, isEncrypted, "Create tape pool");
+  const cta::optional<std::string> supply("value for the supply pool mechanism");
+  m_catalogue->createTapePool(m_admin, tapePoolName, vo, nbPartialTapes, isEncrypted, supply, "Create tape pool");
 
   const uint32_t copyNb = 1;
   const std::string comment = "Comment";
@@ -2003,7 +2214,8 @@ TEST_P(cta_catalogue_CatalogueTest, createLogicalLibrary) {
       
   const std::string logicalLibraryName = "logical_library";
   const std::string comment = "Create logical library";
-  m_catalogue->createLogicalLibrary(m_admin, logicalLibraryName, comment);
+  const bool logicalLibraryIsDisabled= false;
+  m_catalogue->createLogicalLibrary(m_admin, logicalLibraryName, logicalLibraryIsDisabled, comment);
       
   const std::list<common::dataStructures::LogicalLibrary> libs =
     m_catalogue->getLogicalLibraries();
@@ -2012,6 +2224,65 @@ TEST_P(cta_catalogue_CatalogueTest, createLogicalLibrary) {
       
   const common::dataStructures::LogicalLibrary lib = libs.front();
   ASSERT_EQ(logicalLibraryName, lib.name);
+  ASSERT_FALSE(lib.isDisabled);
+  ASSERT_EQ(comment, lib.comment);
+
+  const common::dataStructures::EntryLog creationLog = lib.creationLog;
+  ASSERT_EQ(m_admin.username, creationLog.username);
+  ASSERT_EQ(m_admin.host, creationLog.host);
+  
+  const common::dataStructures::EntryLog lastModificationLog =
+    lib.lastModificationLog;
+  ASSERT_EQ(creationLog, lastModificationLog);
+}
+
+TEST_P(cta_catalogue_CatalogueTest, createLogicalLibrary_disabled_true) {
+  using namespace cta;
+      
+  ASSERT_TRUE(m_catalogue->getLogicalLibraries().empty());
+      
+  const std::string logicalLibraryName = "logical_library";
+  const std::string comment = "Create logical library";
+  const bool logicalLibraryIsDisabled(true);
+  m_catalogue->createLogicalLibrary(m_admin, logicalLibraryName, logicalLibraryIsDisabled, comment);
+      
+  const std::list<common::dataStructures::LogicalLibrary> libs =
+    m_catalogue->getLogicalLibraries();
+      
+  ASSERT_EQ(1, libs.size());
+      
+  const common::dataStructures::LogicalLibrary lib = libs.front();
+  ASSERT_EQ(logicalLibraryName, lib.name);
+  ASSERT_TRUE(lib.isDisabled);
+  ASSERT_EQ(comment, lib.comment);
+
+  const common::dataStructures::EntryLog creationLog = lib.creationLog;
+  ASSERT_EQ(m_admin.username, creationLog.username);
+  ASSERT_EQ(m_admin.host, creationLog.host);
+  
+  const common::dataStructures::EntryLog lastModificationLog =
+    lib.lastModificationLog;
+  ASSERT_EQ(creationLog, lastModificationLog);
+}
+
+TEST_P(cta_catalogue_CatalogueTest, createLogicalLibrary_disabled_false) {
+  using namespace cta;
+      
+  ASSERT_TRUE(m_catalogue->getLogicalLibraries().empty());
+      
+  const std::string logicalLibraryName = "logical_library";
+  const std::string comment = "Create logical library";
+  const bool logicalLibraryIsDisabled(false);
+  m_catalogue->createLogicalLibrary(m_admin, logicalLibraryName, logicalLibraryIsDisabled, comment);
+      
+  const std::list<common::dataStructures::LogicalLibrary> libs =
+    m_catalogue->getLogicalLibraries();
+      
+  ASSERT_EQ(1, libs.size());
+      
+  const common::dataStructures::LogicalLibrary lib = libs.front();
+  ASSERT_EQ(logicalLibraryName, lib.name);
+  ASSERT_FALSE(lib.isDisabled);
   ASSERT_EQ(comment, lib.comment);
 
   const common::dataStructures::EntryLog creationLog = lib.creationLog;
@@ -2028,8 +2299,109 @@ TEST_P(cta_catalogue_CatalogueTest, createLogicalLibrary_same_twice) {
   
   const std::string logicalLibraryName = "logical_library";
   const std::string comment = "Create logical library";
-  m_catalogue->createLogicalLibrary(m_admin, logicalLibraryName, comment);
-  ASSERT_THROW(m_catalogue->createLogicalLibrary(m_admin, logicalLibraryName, comment), exception::UserError);
+  const bool logicalLibraryIsDisabled= false;
+  m_catalogue->createLogicalLibrary(m_admin, logicalLibraryName, logicalLibraryIsDisabled, comment);
+  ASSERT_THROW(m_catalogue->createLogicalLibrary(m_admin, logicalLibraryName, logicalLibraryIsDisabled, comment), exception::UserError);
+}
+
+TEST_P(cta_catalogue_CatalogueTest, setLogicalLibraryDisabled_true) {
+  using namespace cta;
+      
+  ASSERT_TRUE(m_catalogue->getLogicalLibraries().empty());
+      
+  const std::string logicalLibraryName = "logical_library";
+  const std::string comment = "Create logical library";
+  const bool logicalLibraryIsDisabled= false;
+  m_catalogue->createLogicalLibrary(m_admin, logicalLibraryName, logicalLibraryIsDisabled, comment);
+      
+  {
+    const std::list<common::dataStructures::LogicalLibrary> libs =
+      m_catalogue->getLogicalLibraries();
+      
+    ASSERT_EQ(1, libs.size());
+      
+    const common::dataStructures::LogicalLibrary lib = libs.front();
+    ASSERT_EQ(logicalLibraryName, lib.name);
+    ASSERT_FALSE(lib.isDisabled);
+    ASSERT_EQ(comment, lib.comment);
+
+    const common::dataStructures::EntryLog creationLog = lib.creationLog;
+    ASSERT_EQ(m_admin.username, creationLog.username);
+    ASSERT_EQ(m_admin.host, creationLog.host);
+  
+    const common::dataStructures::EntryLog lastModificationLog =
+      lib.lastModificationLog;
+    ASSERT_EQ(creationLog, lastModificationLog);
+  }
+
+  const bool modifiedLogicalLibraryIsDisabled= true;
+  m_catalogue->setLogicalLibraryDisabled(m_admin, logicalLibraryName, modifiedLogicalLibraryIsDisabled);
+
+  {
+    const std::list<common::dataStructures::LogicalLibrary> libs =
+      m_catalogue->getLogicalLibraries();
+      
+    ASSERT_EQ(1, libs.size());
+      
+    const common::dataStructures::LogicalLibrary lib = libs.front();
+    ASSERT_EQ(logicalLibraryName, lib.name);
+    ASSERT_EQ(modifiedLogicalLibraryIsDisabled, lib.isDisabled);
+    ASSERT_EQ(comment, lib.comment);
+
+    const common::dataStructures::EntryLog creationLog = lib.creationLog;
+    ASSERT_EQ(m_admin.username, creationLog.username);
+    ASSERT_EQ(m_admin.host, creationLog.host);
+  }
+}
+
+TEST_P(cta_catalogue_CatalogueTest, setLogicalLibraryDisabled_false) {
+  using namespace cta;
+      
+  ASSERT_TRUE(m_catalogue->getLogicalLibraries().empty());
+      
+  const std::string logicalLibraryName = "logical_library";
+  const std::string comment = "Create logical library";
+  const bool logicalLibraryIsDisabled= false;
+  m_catalogue->createLogicalLibrary(m_admin, logicalLibraryName, logicalLibraryIsDisabled, comment);
+      
+  {
+    const std::list<common::dataStructures::LogicalLibrary> libs =
+      m_catalogue->getLogicalLibraries();
+      
+    ASSERT_EQ(1, libs.size());
+      
+    const common::dataStructures::LogicalLibrary lib = libs.front();
+    ASSERT_EQ(logicalLibraryName, lib.name);
+    ASSERT_FALSE(lib.isDisabled);
+    ASSERT_EQ(comment, lib.comment);
+
+    const common::dataStructures::EntryLog creationLog = lib.creationLog;
+    ASSERT_EQ(m_admin.username, creationLog.username);
+    ASSERT_EQ(m_admin.host, creationLog.host);
+  
+    const common::dataStructures::EntryLog lastModificationLog =
+      lib.lastModificationLog;
+    ASSERT_EQ(creationLog, lastModificationLog);
+  }
+
+  const bool modifiedLogicalLibraryIsDisabled= false;
+  m_catalogue->setLogicalLibraryDisabled(m_admin, logicalLibraryName, modifiedLogicalLibraryIsDisabled);
+
+  {
+    const std::list<common::dataStructures::LogicalLibrary> libs =
+      m_catalogue->getLogicalLibraries();
+      
+    ASSERT_EQ(1, libs.size());
+      
+    const common::dataStructures::LogicalLibrary lib = libs.front();
+    ASSERT_EQ(logicalLibraryName, lib.name);
+    ASSERT_EQ(modifiedLogicalLibraryIsDisabled, lib.isDisabled);
+    ASSERT_EQ(comment, lib.comment);
+
+    const common::dataStructures::EntryLog creationLog = lib.creationLog;
+    ASSERT_EQ(m_admin.username, creationLog.username);
+    ASSERT_EQ(m_admin.host, creationLog.host);
+  }
 }
 
 TEST_P(cta_catalogue_CatalogueTest, deleteLogicalLibrary) {
@@ -2039,7 +2411,8 @@ TEST_P(cta_catalogue_CatalogueTest, deleteLogicalLibrary) {
       
   const std::string logicalLibraryName = "logical_library";
   const std::string comment = "Create logical library";
-  m_catalogue->createLogicalLibrary(m_admin, logicalLibraryName, comment);
+  const bool logicalLibraryIsDisabled= false;
+  m_catalogue->createLogicalLibrary(m_admin, logicalLibraryName, logicalLibraryIsDisabled, comment);
       
   const std::list<common::dataStructures::LogicalLibrary> libs =
     m_catalogue->getLogicalLibraries();
@@ -2076,7 +2449,8 @@ TEST_P(cta_catalogue_CatalogueTest, modifyLogicalLibraryComment) {
       
   const std::string logicalLibraryName = "logical_library";
   const std::string comment = "Create logical library";
-  m_catalogue->createLogicalLibrary(m_admin, logicalLibraryName, comment);
+  const bool logicalLibraryIsDisabled= false;
+  m_catalogue->createLogicalLibrary(m_admin, logicalLibraryName, logicalLibraryIsDisabled, comment);
 
   {
     const std::list<common::dataStructures::LogicalLibrary> libs = m_catalogue->getLogicalLibraries();
@@ -2147,17 +2521,20 @@ TEST_P(cta_catalogue_CatalogueTest, createTape) {
   const std::string mediaType = "media_type";
   const std::string vendor = "vendor";
   const std::string logicalLibraryName = "logical_library_name";
+  const bool logicalLibraryIsDisabled= false;
   const std::string tapePoolName = "tape_pool_name";
   const std::string vo = "vo";
+  const uint64_t nbPartialTapes = 2;
+  const bool isEncrypted = true;
+  const cta::optional<std::string> supply("value for the supply pool mechanism");
   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->createLogicalLibrary(m_admin, logicalLibraryName, logicalLibraryIsDisabled, "Create logical library");
 
-  m_catalogue->createTapePool(m_admin, tapePoolName, vo, 2, true, "Create tape pool");
+  m_catalogue->createTapePool(m_admin, tapePoolName, vo, nbPartialTapes, isEncrypted, supply, "Create tape pool");
   {
     const auto pools = m_catalogue->getTapePools();
     ASSERT_EQ(1, pools.size());
@@ -2228,17 +2605,20 @@ TEST_P(cta_catalogue_CatalogueTest, createTape_emptyStringVid) {
   const std::string mediaType = "media_type";
   const std::string vendor = "vendor";
   const std::string logicalLibraryName = "logical_library_name";
+  const bool logicalLibraryIsDisabled= false;
   const std::string tapePoolName = "tape_pool_name";
   const std::string vo = "vo";
+  const uint64_t nbPartialTapes = 2;
+  const bool isEncrypted = true;
+  const cta::optional<std::string> supply("value for the supply pool mechanism");
   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->createLogicalLibrary(m_admin, logicalLibraryName, logicalLibraryIsDisabled, "Create logical library");
 
-  m_catalogue->createTapePool(m_admin, tapePoolName, vo, 2, true, "Create tape pool");
+  m_catalogue->createTapePool(m_admin, tapePoolName, vo, nbPartialTapes, isEncrypted, supply, "Create tape pool");
   {
     const auto pools = m_catalogue->getTapePools();
     ASSERT_EQ(1, pools.size());
@@ -2270,12 +2650,15 @@ TEST_P(cta_catalogue_CatalogueTest, createTape_emptyStringMediaType) {
   const std::string logicalLibraryName = "logical_library_name";
   const std::string tapePoolName = "tape_pool_name";
   const std::string vo = "vo";
+  const uint64_t nbPartialTapes = 2;
+  const bool isEncrypted = true;
+  const cta::optional<std::string> supply("value for the supply pool mechanism");
   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->createTapePool(m_admin, tapePoolName, vo, 2, true, "Create tape pool");
+  m_catalogue->createTapePool(m_admin, tapePoolName, vo, nbPartialTapes, isEncrypted, supply, "Create tape pool");
   {
     const auto pools = m_catalogue->getTapePools();
     ASSERT_EQ(1, pools.size());
@@ -2307,12 +2690,15 @@ TEST_P(cta_catalogue_CatalogueTest, createTape_emptyStringVendor) {
   const std::string logicalLibraryName = "logical_library_name";
   const std::string tapePoolName = "tape_pool_name";
   const std::string vo = "vo";
+  const uint64_t nbPartialTapes = 2;
+  const bool isEncrypted = true;
+  const cta::optional<std::string> supply("value for the supply pool mechanism");
   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->createTapePool(m_admin, tapePoolName, vo, 2, true, "Create tape pool");
+  m_catalogue->createTapePool(m_admin, tapePoolName, vo, nbPartialTapes, isEncrypted, supply, "Create tape pool");
   {
     const auto pools = m_catalogue->getTapePools();
     ASSERT_EQ(1, pools.size());
@@ -2344,12 +2730,15 @@ TEST_P(cta_catalogue_CatalogueTest, createTape_emptyStringLogicalLibraryName) {
   const std::string logicalLibraryName = "";
   const std::string tapePoolName = "tape_pool_name";
   const std::string vo = "vo";
+  const uint64_t nbPartialTapes = 2;
+  const bool isEncrypted = true;
+  const cta::optional<std::string> supply("value for the supply pool mechanism");
   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->createTapePool(m_admin, tapePoolName, vo, 2, true, "Create tape pool");
+  m_catalogue->createTapePool(m_admin, tapePoolName, vo, nbPartialTapes, isEncrypted, supply, "Create tape pool");
   {
     const auto pools = m_catalogue->getTapePools();
     ASSERT_EQ(1, pools.size());
@@ -2379,6 +2768,7 @@ TEST_P(cta_catalogue_CatalogueTest, createTape_emptyStringTapePoolName) {
   const std::string mediaType = "media_type";
   const std::string vendor = "vendor";
   const std::string logicalLibraryName = "logical_library_name";
+  const bool logicalLibraryIsDisabled= false;
   const std::string tapePoolName = "";
   const std::string vo = "vo";
   const uint64_t capacityInBytes = (uint64_t)10 * 1000 * 1000 * 1000 * 1000;
@@ -2386,8 +2776,7 @@ TEST_P(cta_catalogue_CatalogueTest, createTape_emptyStringTapePoolName) {
   const bool fullValue = false;
   const std::string comment = "Create tape";
 
-  m_catalogue->createLogicalLibrary(m_admin, logicalLibraryName,
-    "Create logical library");
+  m_catalogue->createLogicalLibrary(m_admin, logicalLibraryName, logicalLibraryIsDisabled, "Create logical library");
 
   ASSERT_THROW(m_catalogue->createTape(m_admin, vid, mediaType, vendor, logicalLibraryName, tapePoolName,
     capacityInBytes, disabledValue, fullValue, comment), catalogue::UserSpecifiedAnEmptyStringTapePoolName);
@@ -2405,17 +2794,20 @@ TEST_P(cta_catalogue_CatalogueTest, createTape_zeroCapacity) {
   const std::string mediaType = "media_type";
   const std::string vendor = "vendor";
   const std::string logicalLibraryName = "logical_library_name";
+  const bool logicalLibraryIsDisabled= false;
   const std::string tapePoolName = "tape_pool_name";
   const std::string vo = "vo";
+  const uint64_t nbPartialTapes = 2;
+  const bool isEncrypted = true;
+  const cta::optional<std::string> supply("value for the supply pool mechanism");
   const uint64_t capacityInBytes = 0;
   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->createLogicalLibrary(m_admin, logicalLibraryName, logicalLibraryIsDisabled, "Create logical library");
 
-  m_catalogue->createTapePool(m_admin, tapePoolName, vo, 2, true, "Create tape pool");
+  m_catalogue->createTapePool(m_admin, tapePoolName, vo, nbPartialTapes, isEncrypted, supply, "Create tape pool");
   {
     const auto pools = m_catalogue->getTapePools();
     ASSERT_EQ(1, pools.size());
@@ -2445,17 +2837,20 @@ TEST_P(cta_catalogue_CatalogueTest, createTape_emptyStringComment) {
   const std::string mediaType = "media_type";
   const std::string vendor = "vendor";
   const std::string logicalLibraryName = "logical_library_name";
+  const bool logicalLibraryIsDisabled= false;
   const std::string tapePoolName = "tape_pool_name";
   const std::string vo = "vo";
+  const uint64_t nbPartialTapes = 2;
+  const bool isEncrypted = true;
+  const cta::optional<std::string> supply("value for the supply pool mechanism");
   const uint64_t capacityInBytes = (uint64_t)10 * 1000 * 1000 * 1000 * 1000;
   const bool disabledValue = true;
   const bool fullValue = false;
   const std::string comment = "";
 
-  m_catalogue->createLogicalLibrary(m_admin, logicalLibraryName,
-    "Create logical library");
+  m_catalogue->createLogicalLibrary(m_admin, logicalLibraryName, logicalLibraryIsDisabled, "Create logical library");
 
-  m_catalogue->createTapePool(m_admin, tapePoolName, vo, 2, true, "Create tape pool");
+  m_catalogue->createTapePool(m_admin, tapePoolName, vo, nbPartialTapes, isEncrypted, supply, "Create tape pool");
   {
     const auto pools = m_catalogue->getTapePools();
     ASSERT_EQ(1, pools.size());
@@ -2484,12 +2879,15 @@ TEST_P(cta_catalogue_CatalogueTest, createTape_non_existent_logical_library) {
   const std::string logicalLibraryName = "logical_library_name";
   const std::string tapePoolName = "tape_pool_name";
   const std::string vo = "vo";
+  const uint64_t nbPartialTapes = 2;
+  const bool isEncrypted = true;
+  const cta::optional<std::string> supply("value for the supply pool mechanism");
   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->createTapePool(m_admin, tapePoolName, vo, 2, true, "Create tape pool");
+  m_catalogue->createTapePool(m_admin, tapePoolName, vo, nbPartialTapes, isEncrypted, supply, "Create tape pool");
   ASSERT_THROW(m_catalogue->createTape(m_admin, vid, mediaType, vendor, logicalLibraryName, tapePoolName,
     capacityInBytes, disabledValue, fullValue, comment), exception::UserError);
 }
@@ -2503,14 +2901,14 @@ TEST_P(cta_catalogue_CatalogueTest, createTape_non_existent_tape_pool) {
   const std::string vendor = "vendor";
   const std::string vid = "vid";
   const std::string logicalLibraryName = "logical_library_name";
+  const bool logicalLibraryIsDisabled= false;
   const std::string tapePoolName = "tape_pool_name";
   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->createLogicalLibrary(m_admin, logicalLibraryName, logicalLibraryIsDisabled, "Create logical library");
   ASSERT_THROW(m_catalogue->createTape(m_admin, vid, mediaType, vendor, logicalLibraryName, tapePoolName,
     capacityInBytes, disabledValue, fullValue, comment), exception::UserError);
 }
@@ -2524,17 +2922,21 @@ TEST_P(cta_catalogue_CatalogueTest, createTape_9_exabytes_capacity) {
   const std::string vendor = "vendor";
   const std::string vid = "vid";
   const std::string logicalLibraryName = "logical_library_name";
+  const bool logicalLibraryIsDisabled= false;
   const std::string tapePoolName = "tape_pool_name";
   const std::string vo = "vo";
+  const uint64_t nbPartialTapes = 2;
+  const bool isEncrypted = true;
+  const cta::optional<std::string> supply("value for the supply pool mechanism");
   // The maximum size of an SQLite integer is a signed 64-bit integer
   const uint64_t capacityInBytes = 9L * 1000 * 1000 * 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->createLogicalLibrary(m_admin, logicalLibraryName, logicalLibraryIsDisabled, "Create logical library");
 
-  m_catalogue->createTapePool(m_admin, tapePoolName, vo, 2, true, "Create tape pool");
+  m_catalogue->createTapePool(m_admin, tapePoolName, vo, nbPartialTapes, isEncrypted, supply, "Create tape pool");
   {
     const auto pools = m_catalogue->getTapePools();
     ASSERT_EQ(1, pools.size());
@@ -2600,17 +3002,20 @@ TEST_P(cta_catalogue_CatalogueTest, createTape_same_twice) {
   const std::string vendor = "vendor";
   const std::string vid = "vid";
   const std::string logicalLibraryName = "logical_library_name";
+  const bool logicalLibraryIsDisabled= false;
   const std::string tapePoolName = "tape_pool_name";
   const std::string vo = "vo";
+  const uint64_t nbPartialTapes = 2;
+  const bool isEncrypted = true;
+  const cta::optional<std::string> supply("value for the supply pool mechanism");
   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->createLogicalLibrary(m_admin, logicalLibraryName, logicalLibraryIsDisabled, "Create logical library");
 
-  m_catalogue->createTapePool(m_admin, tapePoolName, vo, 2, true, "Create tape pool");
+  m_catalogue->createTapePool(m_admin, tapePoolName, vo, nbPartialTapes, isEncrypted, supply, "Create tape pool");
   {
     const auto pools = m_catalogue->getTapePools();
     ASSERT_EQ(1, pools.size());
@@ -2664,18 +3069,22 @@ TEST_P(cta_catalogue_CatalogueTest, createTape_many_tapes) {
   const std::string mediaType = "media_type";
   const std::string vendor = "vendor";
   const std::string logicalLibrary = "logical_library_name";
+  const bool logicalLibraryIsDisabled= false;
   const std::string tapePoolName = "tape_pool_name";
   const std::string vo = "vo";
+  const uint64_t nbPartialTapes = 2;
+  const bool isEncrypted = true;
+  const cta::optional<std::string> supply("value for the supply pool mechanism");
   const uint64_t capacityInBytes = (uint64_t) 10 * 1000 * 1000 * 1000 * 1000;
   const bool disabled = true;
   const bool full = false;
   const std::string comment = "Create tape";
 
   ASSERT_TRUE(m_catalogue->getLogicalLibraries().empty());
-  m_catalogue->createLogicalLibrary(m_admin, logicalLibrary, "Create logical library");
+  m_catalogue->createLogicalLibrary(m_admin, logicalLibrary, logicalLibraryIsDisabled, "Create logical library");
 
   ASSERT_TRUE(m_catalogue->getTapePools().empty());
-  m_catalogue->createTapePool(m_admin, tapePoolName, vo, 2, true, "Create tape pool");
+  m_catalogue->createTapePool(m_admin, tapePoolName, vo, nbPartialTapes, isEncrypted, supply, "Create tape pool");
   {
     const auto pools = m_catalogue->getTapePools();
     ASSERT_EQ(1, pools.size());
@@ -2928,15 +3337,19 @@ TEST_P(cta_catalogue_CatalogueTest, createTape_1_tape_with_write_log_1_tape_with
   const std::string mediaType = "media_type";
   const std::string vendor = "vendor";
   const std::string logicalLibraryName = "logical_library_name";
+  const bool logicalLibraryIsDisabled= false;
   const std::string tapePoolName = "tape_pool_name";
   const std::string vo = "vo";
+  const uint64_t nbPartialTapes = 2;
+  const bool isEncrypted = true;
+  const cta::optional<std::string> supply("value for the supply pool mechanism");
   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, tapePoolName, vo, 2, true, "Create tape pool");
+  m_catalogue->createLogicalLibrary(m_admin, logicalLibraryName, logicalLibraryIsDisabled, "Create logical library");
+  m_catalogue->createTapePool(m_admin, tapePoolName, vo, nbPartialTapes, isEncrypted, supply, "Create tape pool");
 
   {
     const auto pools = m_catalogue->getTapePools();
@@ -3091,16 +3504,19 @@ TEST_P(cta_catalogue_CatalogueTest, deleteTape) {
   const std::string mediaType = "media_type";
   const std::string vendor = "vendor";
   const std::string logicalLibraryName = "logical_library_name";
+  const bool logicalLibraryIsDisabled= false;
   const std::string tapePoolName = "tape_pool_name";
   const std::string vo = "vo";
+  const uint64_t nbPartialTapes = 2;
+  const bool isEncrypted = true;
+  const cta::optional<std::string> supply("value for the supply pool mechanism");
   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, tapePoolName, vo, 2, true, "Create tape pool");
+  m_catalogue->createLogicalLibrary(m_admin, logicalLibraryName, logicalLibraryIsDisabled, "Create logical library");
+  m_catalogue->createTapePool(m_admin, tapePoolName, vo, nbPartialTapes, isEncrypted, supply, "Create tape pool");
   m_catalogue->createTape(m_admin, vid, mediaType, vendor, logicalLibraryName, tapePoolName,
     capacityInBytes, disabledValue, fullValue,
     comment);
@@ -3153,16 +3569,19 @@ TEST_P(cta_catalogue_CatalogueTest, deleteNonEmptyTape) {
   const std::string mediaType = "media_type";
   const std::string vendor = "vendor";
   const std::string logicalLibraryName = "logical_library_name";
+  const bool logicalLibraryIsDisabled= false;
   const std::string tapePoolName = "tape_pool_name";
   const std::string vo = "vo";
+  const uint64_t nbPartialTapes = 2;
+  const bool isEncrypted = true;
+  const cta::optional<std::string> supply("value for the supply pool mechanism");
   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, tapePoolName, vo, 2, true, "Create tape pool");
+  m_catalogue->createLogicalLibrary(m_admin, logicalLibraryName, logicalLibraryIsDisabled, "Create logical library");
+  m_catalogue->createTapePool(m_admin, tapePoolName, vo, nbPartialTapes, isEncrypted, supply, "Create tape pool");
   m_catalogue->createTape(m_admin, vid, mediaType, vendor, logicalLibraryName, tapePoolName, capacityInBytes, disabledValue, fullValue,
     comment);
 
@@ -3272,16 +3691,20 @@ TEST_P(cta_catalogue_CatalogueTest, modifyTapeMediaType) {
   const std::string anotherMediaType = "another_media_type";
   const std::string vendor = "vendor";
   const std::string logicalLibraryName = "logical_library_name";
+  const bool logicalLibraryIsDisabled= false;
   const std::string tapePoolName = "tape_pool_name";
   const std::string vo = "vo";
+  const uint64_t nbPartialTapes = 2;
+  const bool isEncrypted = true;
+  const cta::optional<std::string> supply("value for the supply pool mechanism");
   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->createLogicalLibrary(m_admin, logicalLibraryName, logicalLibraryIsDisabled, "Create logical library");
 
-  m_catalogue->createTapePool(m_admin, tapePoolName, vo, 2, true, "Create tape pool");
+  m_catalogue->createTapePool(m_admin, tapePoolName, vo, nbPartialTapes, isEncrypted, supply, "Create tape pool");
   m_catalogue->createTape(m_admin, vid, mediaType, vendor, logicalLibraryName, tapePoolName, capacityInBytes,
     disabledValue, fullValue, comment);
 
@@ -3350,16 +3773,20 @@ TEST_P(cta_catalogue_CatalogueTest, modifyTapeVendor) {
   const std::string vendor = "vendor";
   const std::string anotherVendor = "another_vendor";
   const std::string logicalLibraryName = "logical_library_name";
+  const bool logicalLibraryIsDisabled= false;
   const std::string tapePoolName = "tape_pool_name";
   const std::string vo = "vo";
+  const uint64_t nbPartialTapes = 2;
+  const bool isEncrypted = true;
+  const cta::optional<std::string> supply("value for the supply pool mechanism");
   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->createLogicalLibrary(m_admin, logicalLibraryName, logicalLibraryIsDisabled, "Create logical library");
 
-  m_catalogue->createTapePool(m_admin, tapePoolName, vo, 2, true, "Create tape pool");
+  m_catalogue->createTapePool(m_admin, tapePoolName, vo, nbPartialTapes, isEncrypted, supply, "Create tape pool");
   m_catalogue->createTape(m_admin, vid, mediaType, vendor, logicalLibraryName, tapePoolName, capacityInBytes,
     disabledValue, fullValue, comment);
 
@@ -3428,18 +3855,23 @@ TEST_P(cta_catalogue_CatalogueTest, modifyTapeLogicalLibraryName) {
   const std::string mediaType = "mediaType";
   const std::string vendor = "vendor";
   const std::string logicalLibraryName = "logical_library_name";
+  const bool logicalLibraryIsDisabled= false;
   const std::string anotherLogicalLibraryName = "another_logical_library_name";
   const std::string tapePoolName = "tape_pool_name";
   const std::string vo = "vo";
+  const uint64_t nbPartialTapes = 2;
+  const bool isEncrypted = true;
+  const cta::optional<std::string> supply("value for the supply pool mechanism");
   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->createLogicalLibrary(m_admin, anotherLogicalLibraryName, "Create another logical library");
+  m_catalogue->createLogicalLibrary(m_admin, logicalLibraryName, logicalLibraryIsDisabled, "Create logical library");
+  m_catalogue->createLogicalLibrary(m_admin, anotherLogicalLibraryName, logicalLibraryIsDisabled,
+    "Create another logical library");
 
-  m_catalogue->createTapePool(m_admin, tapePoolName, vo, 2, true, "Create tape pool");
+  m_catalogue->createTapePool(m_admin, tapePoolName, vo, nbPartialTapes, isEncrypted, supply, "Create tape pool");
   m_catalogue->createTape(m_admin, vid, mediaType, vendor, logicalLibraryName, tapePoolName, capacityInBytes,
     disabledValue, fullValue, comment);
 
@@ -3506,8 +3938,9 @@ TEST_P(cta_catalogue_CatalogueTest, modifyTapeLogicalLibraryName_nonExistentTape
 
   const std::string vid = "vid";
   const std::string logicalLibraryName = "logical_library_name";
+  const bool logicalLibraryIsDisabled= false;
 
-  m_catalogue->createLogicalLibrary(m_admin, logicalLibraryName, "Create logical library");
+  m_catalogue->createLogicalLibrary(m_admin, logicalLibraryName, logicalLibraryIsDisabled, "Create logical library");
 
   ASSERT_THROW(m_catalogue->modifyTapeLogicalLibraryName(m_admin, vid, logicalLibraryName), exception::UserError);
 }
@@ -3521,18 +3954,22 @@ TEST_P(cta_catalogue_CatalogueTest, modifyTapeTapePoolName) {
   const std::string mediaType = "mediaType";
   const std::string vendor = "vendor";
   const std::string logicalLibraryName = "logical_library_name";
+  const bool logicalLibraryIsDisabled= false;
   const std::string tapePoolName = "tape_pool_name";
   const std::string vo = "vo";
+  const uint64_t nbPartialTapes = 2;
+  const bool isEncrypted = true;
+  const cta::optional<std::string> supply("value for the supply pool mechanism");
   const std::string anotherTapePoolName = "another_tape_pool_name";
   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->createLogicalLibrary(m_admin, logicalLibraryName, logicalLibraryIsDisabled, "Create logical library");
 
-  m_catalogue->createTapePool(m_admin, tapePoolName, vo, 2, true, "Create tape pool");
-  m_catalogue->createTapePool(m_admin, anotherTapePoolName, vo, 2, true, "Create another tape pool");
+  m_catalogue->createTapePool(m_admin, tapePoolName, vo, nbPartialTapes, isEncrypted, supply, "Create tape pool");
+  m_catalogue->createTapePool(m_admin, anotherTapePoolName, vo, nbPartialTapes, isEncrypted, supply, "Create another tape pool");
 
   m_catalogue->createTape(m_admin, vid, mediaType, vendor, logicalLibraryName, tapePoolName, capacityInBytes,
     disabledValue, fullValue, comment);
@@ -3600,11 +4037,15 @@ TEST_P(cta_catalogue_CatalogueTest, modifyTapeTapePoolName_nonExistentTape) {
 
   const std::string vid = "vid";
   const std::string logicalLibraryName = "logical_library_name";
+  const bool logicalLibraryIsDisabled= false;
   const std::string tapePoolName = "tape_pool_name";
   const std::string vo = "vo";
+  const uint64_t nbPartialTapes = 2;
+  const bool isEncrypted = true;
+  const cta::optional<std::string> supply("value for the supply pool mechanism");
 
-  m_catalogue->createLogicalLibrary(m_admin, logicalLibraryName, "Create logical library");
-  m_catalogue->createTapePool(m_admin, tapePoolName, vo, 2, true, "Create tape pool");
+  m_catalogue->createLogicalLibrary(m_admin, logicalLibraryName, logicalLibraryIsDisabled, "Create logical library");
+  m_catalogue->createTapePool(m_admin, tapePoolName, vo, nbPartialTapes, isEncrypted, supply, "Create tape pool");
 
   ASSERT_THROW(m_catalogue->modifyTapeTapePoolName(m_admin, vid, tapePoolName), exception::UserError);
 }
@@ -3618,16 +4059,20 @@ TEST_P(cta_catalogue_CatalogueTest, modifyTapeCapacityInBytes) {
   const std::string mediaType = "media_type";
   const std::string vendor = "vendor";
   const std::string logicalLibraryName = "logical_library_name";
+  const bool logicalLibraryIsDisabled= false;
   const std::string tapePoolName = "tape_pool_name";
   const std::string vo = "vo";
+  const uint64_t nbPartialTapes = 2;
+  const bool isEncrypted = true;
+  const cta::optional<std::string> supply("value for the supply pool mechanism");
   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->createLogicalLibrary(m_admin, logicalLibraryName, logicalLibraryIsDisabled, "Create logical library");
 
-  m_catalogue->createTapePool(m_admin, tapePoolName, vo, 2, true, "Create tape pool");
+  m_catalogue->createTapePool(m_admin, tapePoolName, vo, nbPartialTapes, isEncrypted, supply, "Create tape pool");
 
   m_catalogue->createTape(m_admin, vid, mediaType, vendor, logicalLibraryName, tapePoolName, capacityInBytes,
     disabledValue, fullValue, comment);
@@ -3709,16 +4154,20 @@ TEST_P(cta_catalogue_CatalogueTest, modifyTapeEncryptionKey) {
   const std::string mediaType = "media_type";
   const std::string vendor = "vendor";
   const std::string logicalLibraryName = "logical_library_name";
+  const bool logicalLibraryIsDisabled= false;
   const std::string tapePoolName = "tape_pool_name";
   const std::string vo = "vo";
+  const uint64_t nbPartialTapes = 2;
+  const bool isEncrypted = true;
+  const cta::optional<std::string> supply("value for the supply pool mechanism");
   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->createLogicalLibrary(m_admin, logicalLibraryName, logicalLibraryIsDisabled, "Create logical library");
 
-  m_catalogue->createTapePool(m_admin, tapePoolName, vo, 2, true, "Create tape pool");
+  m_catalogue->createTapePool(m_admin, tapePoolName, vo, nbPartialTapes, isEncrypted, supply, "Create tape pool");
 
   m_catalogue->createTape(m_admin, vid, mediaType, vendor, logicalLibraryName, tapePoolName, capacityInBytes,
     disabledValue, fullValue, comment);
@@ -3801,16 +4250,20 @@ TEST_P(cta_catalogue_CatalogueTest, tapeLabelled) {
   const std::string mediaType = "media_type";
   const std::string vendor = "vendor";
   const std::string logicalLibraryName = "logical_library_name";
+  const bool logicalLibraryIsDisabled= false;
   const std::string tapePoolName = "tape_pool_name";
   const std::string vo = "vo";
+  const uint64_t nbPartialTapes = 2;
+  const bool isEncrypted = true;
+  const cta::optional<std::string> supply("value for the supply pool mechanism");
   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->createLogicalLibrary(m_admin, logicalLibraryName, logicalLibraryIsDisabled, "Create logical library");
 
-  m_catalogue->createTapePool(m_admin, tapePoolName, vo, 2, true, "Create tape pool");
+  m_catalogue->createTapePool(m_admin, tapePoolName, vo, nbPartialTapes, isEncrypted, supply, "Create tape pool");
 
   m_catalogue->createTape(m_admin, vid, mediaType, vendor, logicalLibraryName, tapePoolName, capacityInBytes,
     disabledValue, fullValue, comment);
@@ -3893,16 +4346,20 @@ TEST_P(cta_catalogue_CatalogueTest, tapeMountedForArchive) {
   const std::string mediaType = "media_type";
   const std::string vendor = "vendor";
   const std::string logicalLibraryName = "logical_library_name";
+  const bool logicalLibraryIsDisabled= false;
   const std::string tapePoolName = "tape_pool_name";
   const std::string vo = "vo";
+  const uint64_t nbPartialTapes = 2;
+  const bool isEncrypted = true;
+  const cta::optional<std::string> supply("value for the supply pool mechanism");
   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->createLogicalLibrary(m_admin, logicalLibraryName, logicalLibraryIsDisabled, "Create logical library");
 
-  m_catalogue->createTapePool(m_admin, tapePoolName, vo, 2, true, "Create tape pool");
+  m_catalogue->createTapePool(m_admin, tapePoolName, vo, nbPartialTapes, isEncrypted, supply, "Create tape pool");
 
   m_catalogue->createTape(m_admin, vid, mediaType, vendor, logicalLibraryName, tapePoolName, capacityInBytes,
     disabledValue, fullValue, comment);
@@ -3985,16 +4442,20 @@ TEST_P(cta_catalogue_CatalogueTest, tapeMountedForRetrieve) {
   const std::string mediaType = "media_type";
   const std::string vendor = "vendor";
   const std::string logicalLibraryName = "logical_library_name";
+  const bool logicalLibraryIsDisabled= false;
   const std::string tapePoolName = "tape_pool_name";
   const std::string vo = "vo";
+  const uint64_t nbPartialTapes = 2;
+  const bool isEncrypted = true;
+  const cta::optional<std::string> supply("value for the supply pool mechanism");
   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->createLogicalLibrary(m_admin, logicalLibraryName, logicalLibraryIsDisabled, "Create logical library");
 
-  m_catalogue->createTapePool(m_admin, tapePoolName, vo, 2, true, "Create tape pool");
+  m_catalogue->createTapePool(m_admin, tapePoolName, vo, nbPartialTapes, isEncrypted, supply, "Create tape pool");
 
   m_catalogue->createTape(m_admin, vid, mediaType, vendor, logicalLibraryName, tapePoolName, capacityInBytes,
     disabledValue, fullValue, comment);
@@ -4077,16 +4538,20 @@ TEST_P(cta_catalogue_CatalogueTest, setTapeFull) {
   const std::string mediaType = "media_type";
   const std::string vendor = "vendor";
   const std::string logicalLibraryName = "logical_library_name";
+  const bool logicalLibraryIsDisabled= false;
   const std::string tapePoolName = "tape_pool_name";
   const std::string vo = "vo";
+  const uint64_t nbPartialTapes = 2;
+  const bool isEncrypted = true;
+  const cta::optional<std::string> supply("value for the supply pool mechanism");
   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->createLogicalLibrary(m_admin, logicalLibraryName, logicalLibraryIsDisabled, "Create logical library");
 
-  m_catalogue->createTapePool(m_admin, tapePoolName, vo, 2, true, "Create tape pool");
+  m_catalogue->createTapePool(m_admin, tapePoolName, vo, nbPartialTapes, isEncrypted, supply, "Create tape pool");
 
   m_catalogue->createTape(m_admin, vid, mediaType, vendor, logicalLibraryName, tapePoolName, capacityInBytes,
     disabledValue, fullValue, comment);
@@ -4166,16 +4631,20 @@ TEST_P(cta_catalogue_CatalogueTest, noSpaceLeftOnTape) {
   const std::string mediaType = "media_type";
   const std::string vendor = "vendor";
   const std::string logicalLibraryName = "logical_library_name";
+  const bool logicalLibraryIsDisabled= false;
   const std::string tapePoolName = "tape_pool_name";
   const std::string vo = "vo";
+  const uint64_t nbPartialTapes = 2;
+  const bool isEncrypted = true;
+  const cta::optional<std::string> supply("value for the supply pool mechanism");
   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->createLogicalLibrary(m_admin, logicalLibraryName, logicalLibraryIsDisabled, "Create logical library");
 
-  m_catalogue->createTapePool(m_admin, tapePoolName, vo, 2, true, "Create tape pool");
+  m_catalogue->createTapePool(m_admin, tapePoolName, vo, nbPartialTapes, isEncrypted, supply, "Create tape pool");
 
   m_catalogue->createTape(m_admin, vid, mediaType, vendor, logicalLibraryName, tapePoolName, capacityInBytes,
     disabledValue, fullValue, comment);
@@ -4255,16 +4724,20 @@ TEST_P(cta_catalogue_CatalogueTest, setTapeDisabled) {
   const std::string mediaType = "media_type";
   const std::string vendor = "vendor";
   const std::string logicalLibraryName = "logical_library_name";
+  const bool logicalLibraryIsDisabled= false;
   const std::string tapePoolName = "tape_pool_name";
   const std::string vo = "vo";
+  const uint64_t nbPartialTapes = 2;
+  const bool isEncrypted = true;
+  const cta::optional<std::string> supply("value for the supply pool mechanism");
   const uint64_t capacityInBytes = (uint64_t)10 * 1000 * 1000 * 1000 * 1000;
   const bool disabledValue = false;
   const bool fullValue = false;
   const std::string comment = "Create tape";
 
-  m_catalogue->createLogicalLibrary(m_admin, logicalLibraryName, "Create logical library");
+  m_catalogue->createLogicalLibrary(m_admin, logicalLibraryName, logicalLibraryIsDisabled, "Create logical library");
 
-  m_catalogue->createTapePool(m_admin, tapePoolName, vo, 2, true, "Create tape pool");
+  m_catalogue->createTapePool(m_admin, tapePoolName, vo, nbPartialTapes, isEncrypted, supply, "Create tape pool");
 
   m_catalogue->createTape(m_admin, vid, mediaType, vendor, logicalLibraryName, tapePoolName, capacityInBytes,
     disabledValue, fullValue, comment);
@@ -4344,15 +4817,19 @@ TEST_P(cta_catalogue_CatalogueTest, getTapesForWriting) {
   const std::string mediaType = "media_type";
   const std::string vendor = "vendor";
   const std::string logicalLibraryName = "logical_library_name";
+  const bool logicalLibraryIsDisabled= false;
   const std::string tapePoolName = "tape_pool_name";
   const std::string vo = "vo";
+  const uint64_t nbPartialTapes = 2;
+  const bool isEncrypted = true;
+  const cta::optional<std::string> supply("value for the supply pool mechanism");
   const uint64_t capacityInBytes = (uint64_t)10 * 1000 * 1000 * 1000 * 1000;
   const bool disabledValue = false;
   const bool fullValue = false;
   const std::string comment = "Create tape";
 
-  m_catalogue->createLogicalLibrary(m_admin, logicalLibraryName, "Create logical library");
-  m_catalogue->createTapePool(m_admin, tapePoolName, vo, 2, true, "Create tape pool");
+  m_catalogue->createLogicalLibrary(m_admin, logicalLibraryName, logicalLibraryIsDisabled, "Create logical library");
+  m_catalogue->createTapePool(m_admin, tapePoolName, vo, nbPartialTapes, isEncrypted, supply, "Create tape pool");
   m_catalogue->createTape(m_admin, vid, mediaType, vendor, logicalLibraryName, tapePoolName, capacityInBytes,
    disabledValue, fullValue, comment);
   m_catalogue->tapeLabelled(vid, "tape_drive");
@@ -4381,15 +4858,19 @@ TEST_P(cta_catalogue_CatalogueTest, DISABLED_getTapesForWriting_no_labelled_tape
   const std::string mediaType = "media_type";
   const std::string vendor = "vendor";
   const std::string logicalLibraryName = "logical_library_name";
+  const bool logicalLibraryIsDisabled= false;
   const std::string tapePoolName = "tape_pool_name";
   const std::string vo = "vo";
+  const uint64_t nbPartialTapes = 2;
+  const bool isEncrypted = true;
+  const cta::optional<std::string> supply("value for the supply pool mechanism");
   const uint64_t capacityInBytes = (uint64_t)10 * 1000 * 1000 * 1000 * 1000;
   const bool disabledValue = false;
   const bool fullValue = false;
   const std::string comment = "Create tape";
 
-  m_catalogue->createLogicalLibrary(m_admin, logicalLibraryName, "Create logical library");
-  m_catalogue->createTapePool(m_admin, tapePoolName, vo, 2, true, "Create tape pool");
+  m_catalogue->createLogicalLibrary(m_admin, logicalLibraryName, logicalLibraryIsDisabled, "Create logical library");
+  m_catalogue->createTapePool(m_admin, tapePoolName, vo, nbPartialTapes, isEncrypted, supply, "Create tape pool");
   m_catalogue->createTape(m_admin, vid, mediaType, vendor, logicalLibraryName, tapePoolName, capacityInBytes,
    disabledValue, fullValue, comment);
 
@@ -5753,7 +6234,8 @@ TEST_P(cta_catalogue_CatalogueTest, checkAndGetNextArchiveFileId_no_mount_rules)
   const std::string vo = "vo";
   const uint64_t nbPartialTapes = 2;
   const bool isEncrypted = true;
-  m_catalogue->createTapePool(m_admin, tapePoolName, vo, nbPartialTapes, isEncrypted, "Create tape pool");
+  const cta::optional<std::string> supply("value for the supply pool mechanism");
+  m_catalogue->createTapePool(m_admin, tapePoolName, vo, nbPartialTapes, isEncrypted, supply, "Create tape pool");
 
   const uint32_t copyNb = 1;
   const std::string archiveRouteComment = "Create archive route";
@@ -5838,7 +6320,8 @@ TEST_P(cta_catalogue_CatalogueTest, checkAndGetNextArchiveFileId_requester_mount
   const std::string vo = "vo";
   const uint64_t nbPartialTapes = 2;
   const bool isEncrypted = true;
-  m_catalogue->createTapePool(m_admin, tapePoolName, vo, nbPartialTapes, isEncrypted, "Create tape pool");
+  const cta::optional<std::string> supply("value for the supply pool mechanism");
+  m_catalogue->createTapePool(m_admin, tapePoolName, vo, nbPartialTapes, isEncrypted, supply, "Create tape pool");
 
   const uint32_t copyNb = 1;
   const std::string archiveRouteComment = "Create archive route";
@@ -5928,7 +6411,8 @@ TEST_P(cta_catalogue_CatalogueTest, checkAndGetNextArchiveFileId_requester_group
   const std::string vo = "vo";
   const uint64_t nbPartialTapes = 2;
   const bool isEncrypted = true;
-  m_catalogue->createTapePool(m_admin, tapePoolName, vo, nbPartialTapes, isEncrypted, "Create tape pool");
+  const cta::optional<std::string> supply("value for the supply pool mechanism");
+  m_catalogue->createTapePool(m_admin, tapePoolName, vo, nbPartialTapes, isEncrypted, supply, "Create tape pool");
 
   const uint32_t copyNb = 1;
   const std::string archiveRouteComment = "Create archive route";
@@ -6037,7 +6521,8 @@ TEST_P(cta_catalogue_CatalogueTest, checkAndGetNextArchiveFileId_requester_mount
   const std::string vo = "vo";
   const uint64_t nbPartialTapes = 2;
   const bool isEncrypted = true;
-  m_catalogue->createTapePool(m_admin, tapePoolName, vo, nbPartialTapes, isEncrypted, "Create tape pool");
+  const cta::optional<std::string> supply("value for the supply pool mechanism");
+  m_catalogue->createTapePool(m_admin, tapePoolName, vo, nbPartialTapes, isEncrypted, supply, "Create tape pool");
 
   const uint32_t copyNb = 1;
   const std::string archiveRouteComment = "Create archive route";
@@ -6186,7 +6671,8 @@ TEST_P(cta_catalogue_CatalogueTest, getArchiveFileQueueCriteria_requester_mount_
   const std::string vo = "vo";
   const uint64_t nbPartialTapes = 2;
   const bool isEncrypted = true;
-  m_catalogue->createTapePool(m_admin, tapePoolName, vo, nbPartialTapes, isEncrypted, "Create tape pool");
+  const cta::optional<std::string> supply("value for the supply pool mechanism");
+  m_catalogue->createTapePool(m_admin, tapePoolName, vo, nbPartialTapes, isEncrypted, supply, "Create tape pool");
 
   const uint32_t copyNb = 1;
   const std::string archiveRouteComment = "Create archive route";
@@ -6268,7 +6754,8 @@ TEST_P(cta_catalogue_CatalogueTest, getArchiveFileQueueCriteria_requester_group_
   const std::string vo = "vo";
   const uint64_t nbPartialTapes = 2;
   const bool isEncrypted = true;
-  m_catalogue->createTapePool(m_admin, tapePoolName, vo, nbPartialTapes, isEncrypted, "Create tape pool");
+  const cta::optional<std::string> supply("value for the supply pool mechanism");
+  m_catalogue->createTapePool(m_admin, tapePoolName, vo, nbPartialTapes, isEncrypted, supply, "Create tape pool");
 
   const uint32_t copyNb = 1;
   const std::string archiveRouteComment = "Create archive route";
@@ -6369,7 +6856,8 @@ TEST_P(cta_catalogue_CatalogueTest, getArchiveFileQueueCriteria_requester_mount_
   const std::string vo = "vo";
   const uint64_t nbPartialTapes = 2;
   const bool isEncrypted = true;
-  m_catalogue->createTapePool(m_admin, tapePoolName, vo, nbPartialTapes, isEncrypted, "Create tape pool");
+  const cta::optional<std::string> supply("value for the supply pool mechanism");
+  m_catalogue->createTapePool(m_admin, tapePoolName, vo, nbPartialTapes, isEncrypted, supply, "Create tape pool");
 
   const uint32_t copyNb = 1;
   const std::string archiveRouteComment = "Create archive route";
@@ -6412,15 +6900,19 @@ TEST_P(cta_catalogue_CatalogueTest, prepareToRetrieveFileUsingArchiveFileId) {
   const std::string mediaType = "media_type";
   const std::string vendor = "vendor";
   const std::string logicalLibraryName = "logical_library_name";
+  const bool logicalLibraryIsDisabled= false;
   const std::string tapePoolName = "tape_pool_name";
   const std::string vo = "vo";
+  const uint64_t nbPartialTapes = 2;
+  const bool isEncrypted = true;
+  const cta::optional<std::string> supply("value for the supply pool mechanism");
   const uint64_t capacityInBytes = (uint64_t)10 * 1000 * 1000 * 1000 * 1000;
   const bool disabledValue = false;
   const bool fullValue = false;
   const std::string createTapeComment = "Create tape";
 
-  m_catalogue->createLogicalLibrary(m_admin, logicalLibraryName, "Create logical library");
-  m_catalogue->createTapePool(m_admin, tapePoolName, vo, 2, true, "Create tape pool");
+  m_catalogue->createLogicalLibrary(m_admin, logicalLibraryName, logicalLibraryIsDisabled, "Create logical library");
+  m_catalogue->createTapePool(m_admin, tapePoolName, vo, nbPartialTapes, isEncrypted, supply, "Create tape pool");
   m_catalogue->createTape(m_admin, vid1, mediaType, vendor, logicalLibraryName, tapePoolName, capacityInBytes,
     disabledValue, fullValue, createTapeComment);
   m_catalogue->createTape(m_admin, vid2, mediaType, vendor, logicalLibraryName, tapePoolName, capacityInBytes,
@@ -6670,15 +7162,19 @@ TEST_P(cta_catalogue_CatalogueTest, prepareToRetrieveFileUsingArchiveFileId_disa
   const std::string mediaType = "media_type";
   const std::string vendor = "vendor";
   const std::string logicalLibraryName = "logical_library_name";
+  const bool logicalLibraryIsDisabled= false;
   const std::string tapePoolName = "tape_pool_name";
   const std::string vo = "vo";
+  const uint64_t nbPartialTapes = 2;
+  const bool isEncrypted = true;
+  const cta::optional<std::string> supply("value for the supply pool mechanism");
   const uint64_t capacityInBytes = (uint64_t)10 * 1000 * 1000 * 1000 * 1000;
   const bool disabledValue = false;
   const bool fullValue = false;
   const std::string createTapeComment = "Create tape";
 
-  m_catalogue->createLogicalLibrary(m_admin, logicalLibraryName, "Create logical library");
-  m_catalogue->createTapePool(m_admin, tapePoolName, vo, 2, true, "Create tape pool");
+  m_catalogue->createLogicalLibrary(m_admin, logicalLibraryName, logicalLibraryIsDisabled, "Create logical library");
+  m_catalogue->createTapePool(m_admin, tapePoolName, vo, nbPartialTapes, isEncrypted, supply, "Create tape pool");
   m_catalogue->createTape(m_admin, vid1, mediaType, vendor, logicalLibraryName, tapePoolName, capacityInBytes,
     disabledValue, fullValue, createTapeComment);
   m_catalogue->createTape(m_admin, vid2, mediaType, vendor, logicalLibraryName, tapePoolName, capacityInBytes,
@@ -7145,17 +7641,21 @@ TEST_P(cta_catalogue_CatalogueTest, filesWrittenToTape_many_archive_files) {
   const std::string mediaType = "media_type";
   const std::string vendor = "vendor";
   const std::string logicalLibraryName = "logical_library_name";
+  const bool logicalLibraryIsDisabled= false;
   const std::string tapePoolName1 = "tape_pool_name_1";
   const std::string tapePoolName2 = "tape_pool_name_2";
   const std::string vo = "vo";
+  const uint64_t nbPartialTapes = 1;
+  const bool isEncrypted = true;
+  const cta::optional<std::string> supply("value for the supply pool mechanism");
   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->createLogicalLibrary(m_admin, logicalLibraryName, logicalLibraryIsDisabled, "Create logical library");
 
-  m_catalogue->createTapePool(m_admin, tapePoolName1, vo, 1, true, "Create tape pool");
+  m_catalogue->createTapePool(m_admin, tapePoolName1, vo, nbPartialTapes, isEncrypted, supply, "Create tape pool");
   {
     const auto pools = m_catalogue->getTapePools();
     ASSERT_EQ(1, pools.size());
@@ -7172,7 +7672,7 @@ TEST_P(cta_catalogue_CatalogueTest, filesWrittenToTape_many_archive_files) {
     ASSERT_EQ(0, pool.nbPhysicalFiles);
   }
 
-  m_catalogue->createTapePool(m_admin, tapePoolName2, vo, 1, true, "Create tape pool");
+  m_catalogue->createTapePool(m_admin, tapePoolName2, vo, nbPartialTapes, isEncrypted, supply, "Create tape pool");
   {
     const auto pools = m_catalogue->getTapePools();
     ASSERT_EQ(2, pools.size());
@@ -8130,17 +8630,21 @@ TEST_P(cta_catalogue_CatalogueTest, DISABLED_concurrent_filesWrittenToTape_many_
   const std::string mediaType = "media_type";
   const std::string vendor = "vendor";
   const std::string logicalLibraryName = "logical_library_name";
+  const bool logicalLibraryIsDisabled= false;
   const std::string tapePoolName1 = "tape_pool_name_1";
   const std::string tapePoolName2 = "tape_pool_name_2";
   const std::string vo = "vo";
+  const uint64_t nbPartialTapes = 1;
+  const bool isEncrypted = true;
+  const cta::optional<std::string> supply("value for the supply pool mechanism");
   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->createLogicalLibrary(m_admin, logicalLibraryName, logicalLibraryIsDisabled, "Create logical library");
 
-  m_catalogue->createTapePool(m_admin, tapePoolName1, vo, 1, true, "Create tape pool");
+  m_catalogue->createTapePool(m_admin, tapePoolName1, vo, nbPartialTapes, isEncrypted, supply, "Create tape pool");
   {
     const auto pools = m_catalogue->getTapePools();
     ASSERT_EQ(1, pools.size());
@@ -8157,7 +8661,7 @@ TEST_P(cta_catalogue_CatalogueTest, DISABLED_concurrent_filesWrittenToTape_many_
     ASSERT_EQ(0, pool.nbPhysicalFiles);
   }
 
-  m_catalogue->createTapePool(m_admin, tapePoolName2, vo, 1, true, "Create tape pool");
+  m_catalogue->createTapePool(m_admin, tapePoolName2, vo, nbPartialTapes, isEncrypted, supply, "Create tape pool");
   {
     const auto pools = m_catalogue->getTapePools();
     ASSERT_EQ(2, pools.size());
@@ -8951,15 +9455,19 @@ TEST_P(cta_catalogue_CatalogueTest, filesWrittenToTape_1_archive_file_2_tape_cop
   const std::string mediaType = "media_type";
   const std::string vendor = "vendor";
   const std::string logicalLibraryName = "logical_library_name";
+  const bool logicalLibraryIsDisabled= false;
   const std::string tapePoolName = "tape_pool_name";
   const std::string vo = "vo";
+  const uint64_t nbPartialTapes = 2;
+  const bool isEncrypted = true;
+  const cta::optional<std::string> supply("value for the supply pool mechanism");
   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, tapePoolName, vo, 2, true, "Create tape pool");
+  m_catalogue->createLogicalLibrary(m_admin, logicalLibraryName, logicalLibraryIsDisabled, "Create logical library");
+  m_catalogue->createTapePool(m_admin, tapePoolName, vo, nbPartialTapes, isEncrypted, supply, "Create tape pool");
   m_catalogue->createTape(m_admin, vid1, mediaType, vendor, logicalLibraryName, tapePoolName, capacityInBytes,
     disabledValue, fullValue, comment);
   m_catalogue->createTape(m_admin, vid2, mediaType, vendor, logicalLibraryName, tapePoolName, capacityInBytes,
@@ -9180,15 +9688,19 @@ TEST_P(cta_catalogue_CatalogueTest, filesWrittenToTape_1_archive_file_2_tape_cop
   const std::string mediaType = "media_type";
   const std::string vendor = "vendor";
   const std::string logicalLibraryName = "logical_library_name";
+  const bool logicalLibraryIsDisabled= false;
   const std::string tapePoolName = "tape_pool_name";
   const std::string vo = "vo";
+  const uint64_t nbPartialTapes = 2;
+  const bool isEncrypted = true;
+  const cta::optional<std::string> supply("value for the supply pool mechanism");
   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, tapePoolName, vo, 2, true, "Create tape pool");
+  m_catalogue->createLogicalLibrary(m_admin, logicalLibraryName, logicalLibraryIsDisabled, "Create logical library");
+  m_catalogue->createTapePool(m_admin, tapePoolName, vo, nbPartialTapes, isEncrypted, supply, "Create tape pool");
   m_catalogue->createTape(m_admin, vid1, mediaType, vendor, logicalLibraryName, tapePoolName, capacityInBytes,
     disabledValue, fullValue, comment);
   m_catalogue->createTape(m_admin, vid2, mediaType, vendor, logicalLibraryName, tapePoolName, capacityInBytes,
@@ -9405,15 +9917,19 @@ TEST_P(cta_catalogue_CatalogueTest, filesWrittenToTape_1_archive_file_2_tape_cop
   const std::string mediaType = "media_type";
   const std::string vendor = "vendor";
   const std::string logicalLibraryName = "logical_library_name";
+  const bool logicalLibraryIsDisabled= false;
   const std::string tapePoolName = "tape_pool_name";
   const std::string vo = "vo";
+  const uint64_t nbPartialTapes = 2;
+  const bool isEncrypted = true;
+  const cta::optional<std::string> supply("value for the supply pool mechanism");
   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, tapePoolName, vo, 2, true, "Create tape pool");
+  m_catalogue->createLogicalLibrary(m_admin, logicalLibraryName, logicalLibraryIsDisabled, "Create logical library");
+  m_catalogue->createTapePool(m_admin, tapePoolName, vo, nbPartialTapes, isEncrypted, supply, "Create tape pool");
   m_catalogue->createTape(m_admin, vid1, mediaType, vendor, logicalLibraryName, tapePoolName, capacityInBytes,
     disabledValue, fullValue, comment);
 
@@ -9604,15 +10120,19 @@ TEST_P(cta_catalogue_CatalogueTest, filesWrittenToTape_1_archive_file_2_tape_cop
   const std::string mediaType = "media_type";
   const std::string vendor = "vendor";
   const std::string logicalLibraryName = "logical_library_name";
+  const bool logicalLibraryIsDisabled= false;
   const std::string tapePoolName = "tape_pool_name";
   const std::string vo = "vo";
+  const uint64_t nbPartialTapes = 2;
+  const bool isEncrypted = true;
+  const cta::optional<std::string> supply("value for the supply pool mechanism");
   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, tapePoolName, vo, 2, true, "Create tape pool");
+  m_catalogue->createLogicalLibrary(m_admin, logicalLibraryName, logicalLibraryIsDisabled, "Create logical library");
+  m_catalogue->createTapePool(m_admin, tapePoolName, vo, nbPartialTapes, isEncrypted, supply, "Create tape pool");
   m_catalogue->createTape(m_admin, vid1, mediaType, vendor, logicalLibraryName, tapePoolName, capacityInBytes,
     disabledValue, fullValue, comment);
   m_catalogue->createTape(m_admin, vid2, mediaType, vendor, logicalLibraryName, tapePoolName, capacityInBytes,
@@ -9786,15 +10306,19 @@ TEST_P(cta_catalogue_CatalogueTest, filesWrittenToTape_1_archive_file_2_tape_cop
   const std::string mediaType = "media_type";
   const std::string vendor = "vendor";
   const std::string logicalLibraryName = "logical_library_name";
+  const bool logicalLibraryIsDisabled= false;
   const std::string tapePoolName = "tape_pool_name";
   const std::string vo = "vo";
+  const uint64_t nbPartialTapes = 2;
+  const bool isEncrypted = true;
+  const cta::optional<std::string> supply("value for the supply pool mechanism");
   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, tapePoolName, vo, 2, true, "Create tape pool");
+  m_catalogue->createLogicalLibrary(m_admin, logicalLibraryName, logicalLibraryIsDisabled, "Create logical library");
+  m_catalogue->createTapePool(m_admin, tapePoolName, vo, nbPartialTapes, isEncrypted, supply, "Create tape pool");
   m_catalogue->createTape(m_admin, vid1, mediaType, vendor, logicalLibraryName, tapePoolName, capacityInBytes,
     disabledValue, fullValue, comment);
   m_catalogue->createTape(m_admin, vid2, mediaType, vendor, logicalLibraryName, tapePoolName, capacityInBytes,
@@ -9968,15 +10492,19 @@ TEST_P(cta_catalogue_CatalogueTest, filesWrittenToTape_1_archive_file_2_tape_cop
   const std::string mediaType = "mediaType";
   const std::string vendor = "vendor";
   const std::string logicalLibraryName = "logical_library_name";
+  const bool logicalLibraryIsDisabled= false;
   const std::string tapePoolName = "tape_pool_name";
   const std::string vo = "vo";
+  const uint64_t nbPartialTapes = 2;
+  const bool isEncrypted = true;
+  const cta::optional<std::string> supply("value for the supply pool mechanism");
   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, tapePoolName, vo, 2, true, "Create tape pool");
+  m_catalogue->createLogicalLibrary(m_admin, logicalLibraryName, logicalLibraryIsDisabled, "Create logical library");
+  m_catalogue->createTapePool(m_admin, tapePoolName, vo, nbPartialTapes, isEncrypted, supply, "Create tape pool");
   m_catalogue->createTape(m_admin, vid1, mediaType, vendor, logicalLibraryName, tapePoolName, capacityInBytes,
     disabledValue, fullValue, comment);
   m_catalogue->createTape(m_admin, vid2, mediaType, vendor, logicalLibraryName, tapePoolName, capacityInBytes,
@@ -10150,15 +10678,19 @@ TEST_P(cta_catalogue_CatalogueTest, deleteArchiveFile) {
   const std::string mediaType = "media_type";
   const std::string vendor = "vendor";
   const std::string logicalLibraryName = "logical_library_name";
+  const bool logicalLibraryIsDisabled= false;
   const std::string tapePoolName = "tape_pool_name";
   const std::string vo = "vo";
+  const uint64_t nbPartialTapes = 2;
+  const bool isEncrypted = true;
+  const cta::optional<std::string> supply("value for the supply pool mechanism");
   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, tapePoolName, vo, 2, true, "Create tape pool");
+  m_catalogue->createLogicalLibrary(m_admin, logicalLibraryName, logicalLibraryIsDisabled, "Create logical library");
+  m_catalogue->createTapePool(m_admin, tapePoolName, vo, nbPartialTapes, isEncrypted, supply, "Create tape pool");
   m_catalogue->createTape(m_admin, vid1, mediaType, vendor, logicalLibraryName, tapePoolName, capacityInBytes,
     disabledValue, fullValue, comment);
   m_catalogue->createTape(m_admin, vid2, mediaType, vendor, logicalLibraryName, tapePoolName, capacityInBytes,
@@ -10467,15 +10999,19 @@ TEST_P(cta_catalogue_CatalogueTest, deleteArchiveFile_by_archive_file_id_of_anot
   const std::string mediaType = "media_type";
   const std::string vendor = "vendor";
   const std::string logicalLibraryName = "logical_library_name";
+  const bool logicalLibraryIsDisabled= false;
   const std::string tapePoolName = "tape_pool_name";
   const std::string vo = "vo";
+  const uint64_t nbPartialTapes = 2;
+  const bool isEncrypted = true;
+  const cta::optional<std::string> supply("value for the supply pool mechanism");
   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, tapePoolName, vo, 2, true, "Create tape pool");
+  m_catalogue->createLogicalLibrary(m_admin, logicalLibraryName, logicalLibraryIsDisabled, "Create logical library");
+  m_catalogue->createTapePool(m_admin, tapePoolName, vo, nbPartialTapes, isEncrypted, supply, "Create tape pool");
   m_catalogue->createTape(m_admin, vid1, mediaType, vendor, logicalLibraryName, tapePoolName, capacityInBytes,
     disabledValue, fullValue, comment);
   m_catalogue->createTape(m_admin, vid2, mediaType, vendor, logicalLibraryName, tapePoolName, capacityInBytes,
@@ -10812,15 +11348,18 @@ TEST_P(cta_catalogue_CatalogueTest, getAllTapes_many_tapes) {
   const std::string mediaType = "media_type";
   const std::string vendor = "vendor";
   const std::string logicalLibraryName = "logical_library_name";
+  const bool logicalLibraryIsDisabled= false;
   const std::string tapePoolName = "tape_pool_name";
   const std::string vo = "vo";
   const uint64_t nbPartialTapes = 2;
+  const bool isEncrypted = true;
+  const cta::optional<std::string> supply("value for the supply pool mechanism");
   const uint64_t capacityInBytes = (uint64_t)10 * 1000 * 1000 * 1000 * 1000;
   const bool disabledValue = true;
   const bool fullValue = false;
 
-  m_catalogue->createLogicalLibrary(m_admin, logicalLibraryName, "Create logical library");
-  m_catalogue->createTapePool(m_admin, tapePoolName, vo, nbPartialTapes, true, "Create tape pool");
+  m_catalogue->createLogicalLibrary(m_admin, logicalLibraryName, logicalLibraryIsDisabled, "Create logical library");
+  m_catalogue->createTapePool(m_admin, tapePoolName, vo, nbPartialTapes, isEncrypted, supply, "Create tape pool");
 
   const uint32_t nbTapes = 10;
 
@@ -10865,15 +11404,19 @@ TEST_P(cta_catalogue_CatalogueTest, reclaimTape_full_lastFSeq_0_no_tape_files) {
   const std::string vendor = "vendor";
   const std::string vid = "vid";
   const std::string logicalLibraryName = "logical_library_name";
+  const bool logicalLibraryIsDisabled= false;
   const std::string tapePoolName = "tape_pool_name";
   const std::string vo = "vo";
+  const uint64_t nbPartialTapes = 2;
+  const bool isEncrypted = true;
+  const cta::optional<std::string> supply("value for the supply pool mechanism");
   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, tapePoolName, vo, 2, true, "Create tape pool");
+  m_catalogue->createLogicalLibrary(m_admin, logicalLibraryName, logicalLibraryIsDisabled, "Create logical library");
+  m_catalogue->createTapePool(m_admin, tapePoolName, vo, nbPartialTapes, isEncrypted, supply, "Create tape pool");
   m_catalogue->createTape(m_admin, vid, mediaType, vendor, logicalLibraryName, tapePoolName, capacityInBytes,
     disabledValue, fullValue, comment);
 
@@ -10946,15 +11489,19 @@ TEST_P(cta_catalogue_CatalogueTest, reclaimTape_not_full_lastFSeq_0_no_tape_file
   const std::string vendor = "vendor";
   const std::string vid = "vid";
   const std::string logicalLibraryName = "logical_library_name";
+  const bool logicalLibraryIsDisabled= false;
   const std::string tapePoolName = "tape_pool_name";
   const std::string vo = "vo";
+  const uint64_t nbPartialTapes = 2;
+  const bool isEncrypted = true;
+  const cta::optional<std::string> supply("value for the supply pool mechanism");
   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, tapePoolName, vo, 2, true, "Create tape pool");
+  m_catalogue->createLogicalLibrary(m_admin, logicalLibraryName, logicalLibraryIsDisabled, "Create logical library");
+  m_catalogue->createTapePool(m_admin, tapePoolName, vo, nbPartialTapes, isEncrypted, supply, "Create tape pool");
   m_catalogue->createTape(m_admin, vid, mediaType, vendor, logicalLibraryName, tapePoolName, capacityInBytes,
     disabledValue, fullValue, comment);
 
@@ -11002,15 +11549,19 @@ TEST_P(cta_catalogue_CatalogueTest, reclaimTape_full_lastFSeq_1_no_tape_files) {
   const std::string mediaType = "media_type";
   const std::string vendor = "vendor";
   const std::string logicalLibraryName = "logical_library_name";
+  const bool logicalLibraryIsDisabled= false;
   const std::string tapePoolName = "tape_pool_name";
   const std::string vo = "vo";
+  const uint64_t nbPartialTapes = 2;
+  const bool isEncrypted = true;
+  const cta::optional<std::string> supply("value for the supply pool mechanism");
   const uint64_t capacityInBytes = (uint64_t)10 * 1000 * 1000 * 1000 * 1000;
   const bool disabledValue = true;
   const bool fullValue = false;
   const std::string createTapeComment = "Create tape";
 
-  m_catalogue->createLogicalLibrary(m_admin, logicalLibraryName, "Create logical library");
-  m_catalogue->createTapePool(m_admin, tapePoolName, vo, 2, true, "Create tape pool");
+  m_catalogue->createLogicalLibrary(m_admin, logicalLibraryName, logicalLibraryIsDisabled, "Create logical library");
+  m_catalogue->createTapePool(m_admin, tapePoolName, vo, nbPartialTapes, isEncrypted, supply, "Create tape pool");
   m_catalogue->createTape(m_admin, vid1, mediaType, vendor, logicalLibraryName, tapePoolName, capacityInBytes,
     disabledValue, fullValue, createTapeComment);
 
@@ -11225,15 +11776,19 @@ TEST_P(cta_catalogue_CatalogueTest, reclaimTape_full_lastFSeq_1_one_tape_file) {
   const std::string mediaType = "media_type";
   const std::string vendor = "vendor";
   const std::string logicalLibraryName = "logical_library_name";
+  const bool logicalLibraryIsDisabled= false;
   const std::string tapePoolName = "tape_pool_name";
   const std::string vo = "vo";
+  const uint64_t nbPartialTapes = 2;
+  const bool isEncrypted = true;
+  const cta::optional<std::string> supply("value for the supply pool mechanism");
   const uint64_t capacityInBytes = (uint64_t)10 * 1000 * 1000 * 1000 * 1000;
   const bool disabledValue = true;
   const bool fullValue = false;
   const std::string createTapeComment = "Create tape";
 
-  m_catalogue->createLogicalLibrary(m_admin, logicalLibraryName, "Create logical library");
-  m_catalogue->createTapePool(m_admin, tapePoolName, vo, 2, true, "Create tape pool");
+  m_catalogue->createLogicalLibrary(m_admin, logicalLibraryName, logicalLibraryIsDisabled, "Create logical library");
+  m_catalogue->createTapePool(m_admin, tapePoolName, vo, nbPartialTapes, isEncrypted, supply, "Create tape pool");
   m_catalogue->createTape(m_admin, vid1, mediaType, vendor, logicalLibraryName, tapePoolName, capacityInBytes,
     disabledValue, fullValue, createTapeComment);
 
@@ -11385,15 +11940,19 @@ TEST_P(cta_catalogue_CatalogueTest, reclaimTape_full_lastFSeq_1_one_tape_file_su
   const std::string mediaType = "media_type";
   const std::string vendor = "vendor";
   const std::string logicalLibraryName = "logical_library_name";
+  const bool logicalLibraryIsDisabled= false;
   const std::string tapePoolName = "tape_pool_name";
   const std::string vo = "vo";
+  const uint64_t nbPartialTapes = 2;
+  const bool isEncrypted = true;
+  const cta::optional<std::string> supply("value for the supply pool mechanism");
   const uint64_t capacityInBytes = (uint64_t)10 * 1000 * 1000 * 1000 * 1000;
   const bool disabledValue = true;
   const bool fullValue = false;
   const std::string createTapeComment = "Create tape";
 
-  m_catalogue->createLogicalLibrary(m_admin, logicalLibraryName, "Create logical library");
-  m_catalogue->createTapePool(m_admin, tapePoolName, vo, 2, true, "Create tape pool");
+  m_catalogue->createLogicalLibrary(m_admin, logicalLibraryName, logicalLibraryIsDisabled, "Create logical library");
+  m_catalogue->createTapePool(m_admin, tapePoolName, vo, nbPartialTapes, isEncrypted, supply, "Create tape pool");
   m_catalogue->createTape(m_admin, vid1, mediaType, vendor, logicalLibraryName, tapePoolName, capacityInBytes,
     disabledValue, fullValue, createTapeComment);
   m_catalogue->createTape(m_admin, vid2, mediaType, vendor, logicalLibraryName, tapePoolName, capacityInBytes,
@@ -11604,15 +12163,19 @@ TEST_P(cta_catalogue_CatalogueTest, exist_non_superseded_files_after_fseq) {
   const std::string mediaType = "media_type";
   const std::string vendor = "vendor";
   const std::string logicalLibraryName = "logical_library_name";
+  const bool logicalLibraryIsDisabled= false;
   const std::string tapePoolName = "tape_pool_name";
   const std::string vo = "vo";
+  const uint64_t nbPartialTapes = 2;
+  const bool isEncrypted = true;
+  const cta::optional<std::string> supply("value for the supply pool mechanism");
   const uint64_t capacityInBytes = (uint64_t)10 * 1000 * 1000 * 1000 * 1000;
   const bool disabledValue = true;
   const bool fullValue = false;
   const std::string createTapeComment = "Create tape";
   
-  m_catalogue->createLogicalLibrary(m_admin, logicalLibraryName, "Create logical library");
-  m_catalogue->createTapePool(m_admin, tapePoolName, vo, 2, true, "Create tape pool");
+  m_catalogue->createLogicalLibrary(m_admin, logicalLibraryName, logicalLibraryIsDisabled, "Create logical library");
+  m_catalogue->createTapePool(m_admin, tapePoolName, vo, nbPartialTapes, isEncrypted, supply, "Create tape pool");
   m_catalogue->createTape(m_admin, vid1, mediaType, vendor, logicalLibraryName, tapePoolName, capacityInBytes,
     disabledValue, fullValue, createTapeComment);
   
diff --git a/catalogue/DropSchemaCmd.cpp b/catalogue/DropSchemaCmd.cpp
index 607e254eeef3446704026e3edc30b813c5c8fa0f..a73dd2f84110d16f701dc55b8ed5b36c41bc601d 100644
--- a/catalogue/DropSchemaCmd.cpp
+++ b/catalogue/DropSchemaCmd.cpp
@@ -184,7 +184,9 @@ void DropSchemaCmd::dropMysqlCatalogueSchema(rdbms::Conn &conn) {
       "CHECK_TAPE_BEFORE_INSERT",
       "CHECK_TAPE_BEFORE_UPDATE",
       "TAPE_FILE_COPY_NB_GT_ZERO_BEFORE_INSERT",
-      "TAPE_FILE_COPY_NB_GT_ZERO_BEFORE_UPDATE"
+      "TAPE_FILE_COPY_NB_GT_ZERO_BEFORE_UPDATE",
+      "CHECK_LOGICAL_LIBRARY_BEFORE_INSERT",
+      "CHECK_LOGICAL_LIBRARY_BEFORE_UPDATE"
     };
     for (auto triggerToDrop: triggersToDrop) {
       conn.executeNonQuery(std::string("DROP TRIGGER IF EXISTS ") + triggerToDrop);
diff --git a/catalogue/DummyCatalogue.hpp b/catalogue/DummyCatalogue.hpp
index 506f2678be937730c3d379057fe412f230c7ed52..a67b479e1710340e5726459b69beefbe4aebda3f 100644
--- a/catalogue/DummyCatalogue.hpp
+++ b/catalogue/DummyCatalogue.hpp
@@ -36,13 +36,13 @@ public:
 
   void createAdminUser(const common::dataStructures::SecurityIdentity& admin, const std::string& username, const std::string& comment) override { throw exception::Exception(std::string("In ")+__PRETTY_FUNCTION__+": not implemented"); }
   void createArchiveRoute(const common::dataStructures::SecurityIdentity& admin, const std::string& diskInstanceName, const std::string& storageClassName, const uint32_t copyNb, const std::string& tapePoolName, const std::string& comment) override { throw exception::Exception(std::string("In ")+__PRETTY_FUNCTION__+": not implemented"); }
-  void createLogicalLibrary(const common::dataStructures::SecurityIdentity& admin, const std::string& name, const std::string& comment) override { throw exception::Exception(std::string("In ")+__PRETTY_FUNCTION__+": not implemented"); }
+  void createLogicalLibrary(const common::dataStructures::SecurityIdentity& admin, const std::string& name, const bool isDisabled, const std::string& comment) override { throw exception::Exception(std::string("In ")+__PRETTY_FUNCTION__+": not implemented"); }
   void createMountPolicy(const common::dataStructures::SecurityIdentity& admin, const std::string& name, const uint64_t archivePriority, const uint64_t minArchiveRequestAge, const uint64_t retrievePriority, const uint64_t minRetrieveRequestAge, const uint64_t maxDrivesAllowed, const std::string& comment) override { throw exception::Exception(std::string("In ")+__PRETTY_FUNCTION__+": not implemented"); }
   void createRequesterGroupMountRule(const common::dataStructures::SecurityIdentity& admin, const std::string& mountPolicyName, const std::string& diskInstanceName, const std::string& requesterGroupName, const std::string& comment) override { throw exception::Exception(std::string("In ")+__PRETTY_FUNCTION__+": not implemented"); }
   void createRequesterMountRule(const common::dataStructures::SecurityIdentity& admin, const std::string& mountPolicyName, const std::string& diskInstance, const std::string& requesterName, const std::string& comment) override { throw exception::Exception(std::string("In ")+__PRETTY_FUNCTION__+": not implemented"); }
   void createStorageClass(const common::dataStructures::SecurityIdentity& admin, const common::dataStructures::StorageClass& storageClass) override { throw exception::Exception(std::string("In ")+__PRETTY_FUNCTION__+": not implemented"); }
   void createTape(const common::dataStructures::SecurityIdentity& admin, const std::string& vid, const std::string &mediaType, const std::string &vendor, const std::string& logicalLibraryName, const std::string& tapePoolName, const uint64_t capacityInBytes, const bool disabled, const bool full, const std::string& comment) override { throw exception::Exception(std::string("In ")+__PRETTY_FUNCTION__+": not implemented"); }
-  void createTapePool(const common::dataStructures::SecurityIdentity& admin, const std::string& name, const std::string & vo, const uint64_t nbPartialTapes, const bool encryptionValue, const std::string& comment) override { throw exception::Exception(std::string("In ")+__PRETTY_FUNCTION__+": not implemented"); }
+  void createTapePool(const common::dataStructures::SecurityIdentity& admin, const std::string& name, const std::string & vo, const uint64_t nbPartialTapes, const bool encryptionValue, const cta::optional<std::string> &supply, const std::string& comment) override { throw exception::Exception(std::string("In ")+__PRETTY_FUNCTION__+": not implemented"); }
   void deleteAdminUser(const std::string& username) override { throw exception::Exception(std::string("In ")+__PRETTY_FUNCTION__+": not implemented"); }
   void deleteArchiveFile(const std::string& instanceName, const uint64_t archiveFileId, log::LogContext &lc) override { throw exception::Exception(std::string("In ")+__PRETTY_FUNCTION__+": not implemented"); }
   void deleteArchiveRoute(const std::string& diskInstanceName, const std::string& storageClassName, const uint32_t copyNb) override { throw exception::Exception(std::string("In ")+__PRETTY_FUNCTION__+": not implemented"); }
@@ -76,6 +76,7 @@ public:
   void modifyArchiveRouteComment(const common::dataStructures::SecurityIdentity& admin, const std::string& instanceName, const std::string& storageClassName, const uint32_t copyNb, const std::string& comment) override { throw exception::Exception(std::string("In ")+__PRETTY_FUNCTION__+": not implemented"); }
   void modifyArchiveRouteTapePoolName(const common::dataStructures::SecurityIdentity& admin, const std::string& instanceName, const std::string& storageClassName, const uint32_t copyNb, const std::string& tapePoolName) override { throw exception::Exception(std::string("In ")+__PRETTY_FUNCTION__+": not implemented"); }
   void modifyLogicalLibraryComment(const common::dataStructures::SecurityIdentity& admin, const std::string& name, const std::string& comment) override { throw exception::Exception(std::string("In ")+__PRETTY_FUNCTION__+": not implemented"); }
+  void setLogicalLibraryDisabled(const common::dataStructures::SecurityIdentity &admin, const std::string &name, const bool disabledValue) override { throw exception::Exception(std::string("In ")+__PRETTY_FUNCTION__+": not implemented"); }
   void modifyMountPolicyArchiveMinRequestAge(const common::dataStructures::SecurityIdentity& admin, const std::string& name, const uint64_t minArchiveRequestAge) override { throw exception::Exception(std::string("In ")+__PRETTY_FUNCTION__+": not implemented"); }
   void modifyMountPolicyArchivePriority(const common::dataStructures::SecurityIdentity& admin, const std::string& name, const uint64_t archivePriority) override { throw exception::Exception(std::string("In ")+__PRETTY_FUNCTION__+": not implemented"); }
   void modifyMountPolicyComment(const common::dataStructures::SecurityIdentity& admin, const std::string& name, const std::string& comment) override { throw exception::Exception(std::string("In ")+__PRETTY_FUNCTION__+": not implemented"); }
@@ -97,6 +98,7 @@ public:
   void modifyTapePoolComment(const common::dataStructures::SecurityIdentity& admin, const std::string& name, const std::string& comment) override { throw exception::Exception(std::string("In ")+__PRETTY_FUNCTION__+": not implemented"); }
   void modifyTapePoolVo(const common::dataStructures::SecurityIdentity &admin, const std::string &name, const std::string &vo) override { throw exception::Exception(std::string("In ")+__PRETTY_FUNCTION__+": not implemented"); }
   void modifyTapePoolNbPartialTapes(const common::dataStructures::SecurityIdentity& admin, const std::string& name, const uint64_t nbPartialTapes) override { throw exception::Exception(std::string("In ")+__PRETTY_FUNCTION__+": not implemented"); }
+  void modifyTapePoolSupply(const common::dataStructures::SecurityIdentity& admin, const std::string& name, const std::string& supply) override { throw exception::Exception(std::string("In ")+__PRETTY_FUNCTION__+": not implemented"); }
   void modifyTapeTapePoolName(const common::dataStructures::SecurityIdentity& admin, const std::string& vid, const std::string& tapePoolName) override { throw exception::Exception(std::string("In ")+__PRETTY_FUNCTION__+": not implemented"); }
   void noSpaceLeftOnTape(const std::string& vid) override { throw exception::Exception(std::string("In ")+__PRETTY_FUNCTION__+": not implemented"); }
   void ping() override { throw exception::Exception(std::string("In ")+__PRETTY_FUNCTION__+": not implemented"); }
diff --git a/catalogue/RdbmsCatalogue.cpp b/catalogue/RdbmsCatalogue.cpp
index 0db0322496b58c634e1c2eae803d846cca660378..4ad7b64be62195aac45f256293e23f88be420e48 100644
--- a/catalogue/RdbmsCatalogue.cpp
+++ b/catalogue/RdbmsCatalogue.cpp
@@ -29,6 +29,7 @@
 #include "catalogue/UserSpecifiedAnEmptyStringLogicalLibraryName.hpp"
 #include "catalogue/UserSpecifiedAnEmptyStringMediaType.hpp"
 #include "catalogue/UserSpecifiedAnEmptyStringStorageClassName.hpp"
+#include "catalogue/UserSpecifiedAnEmptyStringSupply.hpp"
 #include "catalogue/UserSpecifiedAnEmptyStringTapePoolName.hpp"
 #include "catalogue/UserSpecifiedAnEmptyStringUsername.hpp"
 #include "catalogue/UserSpecifiedAnEmptyStringVendor.hpp"
@@ -568,6 +569,7 @@ void RdbmsCatalogue::createTapePool(
   const std::string &vo,
   const uint64_t nbPartialTapes,
   const bool encryptionValue,
+  const cta::optional<std::string> &supply,
   const std::string &comment) {
   try {
     if(name.empty()) {
@@ -595,6 +597,7 @@ void RdbmsCatalogue::createTapePool(
         "VO,"
         "NB_PARTIAL_TAPES,"
         "IS_ENCRYPTED,"
+        "SUPPLY,"
 
         "USER_COMMENT,"
 
@@ -610,6 +613,7 @@ void RdbmsCatalogue::createTapePool(
         ":VO,"
         ":NB_PARTIAL_TAPES,"
         ":IS_ENCRYPTED,"
+        ":SUPPLY,"
 
         ":USER_COMMENT,"
 
@@ -626,6 +630,7 @@ void RdbmsCatalogue::createTapePool(
     stmt.bindString(":VO", vo);
     stmt.bindUint64(":NB_PARTIAL_TAPES", nbPartialTapes);
     stmt.bindBool(":IS_ENCRYPTED", encryptionValue);
+    stmt.bindOptionalString(":SUPPLY", supply);
 
     stmt.bindString(":USER_COMMENT", comment);
 
@@ -893,6 +898,7 @@ std::list<TapePool> RdbmsCatalogue::getTapePools() const {
         "COALESCE(TAPE_POOL.VO, 'NONE') AS VO," // TBD Remove COALESCE
         "TAPE_POOL.NB_PARTIAL_TAPES AS NB_PARTIAL_TAPES,"
         "TAPE_POOL.IS_ENCRYPTED AS IS_ENCRYPTED,"
+        "TAPE_POOL.SUPPLY AS SUPPLY,"
 
         "COALESCE(COUNT(TAPE.VID), 0) AS NB_TAPES,"
         "COALESCE(SUM(TAPE.CAPACITY_IN_BYTES), 0) AS CAPACITY_IN_BYTES,"
@@ -917,6 +923,7 @@ std::list<TapePool> RdbmsCatalogue::getTapePools() const {
         "TAPE_POOL.VO,"
         "TAPE_POOL.NB_PARTIAL_TAPES,"
         "TAPE_POOL.IS_ENCRYPTED,"
+        "TAPE_POOL.SUPPLY,"
         "TAPE_POOL.USER_COMMENT,"
         "TAPE_POOL.CREATION_LOG_USER_NAME,"
         "TAPE_POOL.CREATION_LOG_HOST_NAME,"
@@ -937,6 +944,7 @@ std::list<TapePool> RdbmsCatalogue::getTapePools() const {
       pool.vo = rset.columnString("VO");
       pool.nbPartialTapes = rset.columnUint64("NB_PARTIAL_TAPES");
       pool.encryption = rset.columnBool("IS_ENCRYPTED");
+      pool.supply = rset.columnOptionalString("SUPPLY");
       pool.nbTapes = rset.columnUint64("NB_TAPES");
       pool.capacityBytes = rset.columnUint64("CAPACITY_IN_BYTES");
       pool.dataBytes = rset.columnUint64("DATA_IN_BYTES");
@@ -1124,6 +1132,51 @@ void RdbmsCatalogue::setTapePoolEncryption(const common::dataStructures::Securit
   }
 }
 
+//------------------------------------------------------------------------------
+// modifyTapePoolSupply
+//------------------------------------------------------------------------------
+void RdbmsCatalogue::modifyTapePoolSupply(const common::dataStructures::SecurityIdentity &admin,
+  const std::string &name, const std::string &supply) {
+  try {
+    if(name.empty()) {
+      throw UserSpecifiedAnEmptyStringTapePoolName("Cannot modify tape pool because the tape pool name is an empty"
+        " string");
+    }
+
+    if(supply.empty()) {
+      throw UserSpecifiedAnEmptyStringSupply("Cannot modify tape pool because the new supply value is an empty"
+        " string");
+    }
+
+    const time_t now = time(nullptr);
+    const char *const sql =
+      "UPDATE TAPE_POOL SET "
+        "SUPPLY = :SUPPLY,"
+        "LAST_UPDATE_USER_NAME = :LAST_UPDATE_USER_NAME,"
+        "LAST_UPDATE_HOST_NAME = :LAST_UPDATE_HOST_NAME,"
+        "LAST_UPDATE_TIME = :LAST_UPDATE_TIME "
+      "WHERE "
+        "TAPE_POOL_NAME = :TAPE_POOL_NAME";
+    auto conn = m_connPool.getConn();
+    auto stmt = conn.createStmt(sql);
+    stmt.bindString(":SUPPLY", supply);
+    stmt.bindString(":LAST_UPDATE_USER_NAME", admin.username);
+    stmt.bindString(":LAST_UPDATE_HOST_NAME", admin.host);
+    stmt.bindUint64(":LAST_UPDATE_TIME", now);
+    stmt.bindString(":TAPE_POOL_NAME", name);
+    stmt.executeNonQuery();
+
+    if(0 == stmt.getNbAffectedRows()) {
+      throw exception::UserError(std::string("Cannot modify tape pool ") + name + " because it does not exist");
+    }
+  } catch(exception::UserError &) {
+    throw;
+  } catch(exception::Exception &ex) {
+    ex.getMessage().str(std::string(__FUNCTION__) + ": " + ex.getMessage().str());
+    throw;
+  }
+}
+
 //------------------------------------------------------------------------------
 // createArchiveRoute
 //------------------------------------------------------------------------------
@@ -1438,6 +1491,7 @@ void RdbmsCatalogue::modifyArchiveRouteComment(const common::dataStructures::Sec
 void RdbmsCatalogue::createLogicalLibrary(
   const common::dataStructures::SecurityIdentity &admin,
   const std::string &name,
+  const bool isDisabled,
   const std::string &comment) {
   try {
     auto conn = m_connPool.getConn();
@@ -1449,6 +1503,7 @@ void RdbmsCatalogue::createLogicalLibrary(
     const char *const sql =
       "INSERT INTO LOGICAL_LIBRARY("
         "LOGICAL_LIBRARY_NAME,"
+        "IS_DISABLED,"
 
         "USER_COMMENT,"
 
@@ -1461,6 +1516,7 @@ void RdbmsCatalogue::createLogicalLibrary(
         "LAST_UPDATE_TIME)"
       "VALUES("
         ":LOGICAL_LIBRARY_NAME,"
+        ":IS_DISABLED,"
 
         ":USER_COMMENT,"
 
@@ -1474,6 +1530,7 @@ void RdbmsCatalogue::createLogicalLibrary(
     auto stmt = conn.createStmt(sql);
 
     stmt.bindString(":LOGICAL_LIBRARY_NAME", name);
+    stmt.bindBool(":IS_DISABLED", isDisabled);
 
     stmt.bindString(":USER_COMMENT", comment);
 
@@ -1549,6 +1606,7 @@ std::list<common::dataStructures::LogicalLibrary> RdbmsCatalogue::getLogicalLibr
     const char *const sql =
       "SELECT "
         "LOGICAL_LIBRARY_NAME AS LOGICAL_LIBRARY_NAME,"
+        "IS_DISABLED AS IS_DISABLED,"
 
         "USER_COMMENT AS USER_COMMENT,"
 
@@ -1570,6 +1628,7 @@ std::list<common::dataStructures::LogicalLibrary> RdbmsCatalogue::getLogicalLibr
       common::dataStructures::LogicalLibrary lib;
 
       lib.name = rset.columnString("LOGICAL_LIBRARY_NAME");
+      lib.isDisabled = rset.columnBool("IS_DISABLED");
       lib.comment = rset.columnString("USER_COMMENT");
       lib.creationLog.username = rset.columnString("CREATION_LOG_USER_NAME");
       lib.creationLog.host = rset.columnString("CREATION_LOG_HOST_NAME");
@@ -1625,6 +1684,41 @@ void RdbmsCatalogue::modifyLogicalLibraryComment(const common::dataStructures::S
   }
 }
 
+//------------------------------------------------------------------------------
+// setLogicalLibraryDisabled
+//------------------------------------------------------------------------------
+void RdbmsCatalogue::setLogicalLibraryDisabled(const common::dataStructures::SecurityIdentity &admin,
+  const std::string &name, const bool disabledValue) {
+  try {
+    const time_t now = time(nullptr);
+    const char *const sql =
+      "UPDATE LOGICAL_LIBRARY SET "
+        "IS_DISABLED = :IS_DISABLED,"
+        "LAST_UPDATE_USER_NAME = :LAST_UPDATE_USER_NAME,"
+        "LAST_UPDATE_HOST_NAME = :LAST_UPDATE_HOST_NAME,"
+        "LAST_UPDATE_TIME = :LAST_UPDATE_TIME "
+      "WHERE "
+        "LOGICAL_LIBRARY_NAME = :LOGICAL_LIBRARY_NAME";
+    auto conn = m_connPool.getConn();
+    auto stmt = conn.createStmt(sql);
+    stmt.bindBool(":IS_DISABLED", disabledValue);
+    stmt.bindString(":LAST_UPDATE_USER_NAME", admin.username);
+    stmt.bindString(":LAST_UPDATE_HOST_NAME", admin.host);
+    stmt.bindUint64(":LAST_UPDATE_TIME", now);
+    stmt.bindString(":LOGICAL_LIBRARY_NAME", name);
+    stmt.executeNonQuery();
+
+    if(0 == stmt.getNbAffectedRows()) {
+      throw exception::UserError(std::string("Cannot modify logical library ") + name + " because it does not exist");
+    }
+  } catch(exception::UserError &) {
+    throw;
+  } catch(exception::Exception &ex) {
+    ex.getMessage().str(std::string(__FUNCTION__) + ": " + ex.getMessage().str());
+    throw;
+  }
+}
+
 //------------------------------------------------------------------------------
 // createTape
 //------------------------------------------------------------------------------
@@ -4152,7 +4246,8 @@ std::list<common::dataStructures::ArchiveFile> RdbmsCatalogue::getFilesForRepack
         "TAPE_FILE.VID = TAPE.VID "
        "WHERE "
          "TAPE_FILE.VID = :VID AND "
-         "TAPE_FILE.FSEQ >= :START_FSEQ "
+         "TAPE_FILE.FSEQ >= :START_FSEQ AND "
+         "TAPE_FILE.SUPERSEDED_BY_VID IS NULL "
        "ORDER BY FSEQ";
 
     auto conn = m_connPool.getConn();
diff --git a/catalogue/RdbmsCatalogue.hpp b/catalogue/RdbmsCatalogue.hpp
index 44deff7e839b7bea95974ca93fc7c0f9c9b042c3..766dca01f7390bd4176adcd2e7535998b8a3431b 100644
--- a/catalogue/RdbmsCatalogue.hpp
+++ b/catalogue/RdbmsCatalogue.hpp
@@ -233,13 +233,14 @@ public:
   void modifyStorageClassNbCopies(const common::dataStructures::SecurityIdentity &admin, const std::string &instanceName, const std::string &name, const uint64_t nbCopies) override;
   void modifyStorageClassComment(const common::dataStructures::SecurityIdentity &admin, const std::string &instanceName, const std::string &name, const std::string &comment) override;
 
-  void createTapePool(const common::dataStructures::SecurityIdentity &admin, const std::string &name, const std::string &vo, const uint64_t nbPartialTapes, const bool encryptionValue, const std::string &comment) override;
+  void createTapePool(const common::dataStructures::SecurityIdentity &admin, const std::string &name, const std::string &vo, const uint64_t nbPartialTapes, const bool encryptionValue, const cta::optional<std::string> &supply, const std::string &comment) override;
   void deleteTapePool(const std::string &name) override;
   std::list<TapePool> getTapePools() const override;
   void modifyTapePoolVo(const common::dataStructures::SecurityIdentity &admin, const std::string &name, const std::string &vo) override;
   void modifyTapePoolNbPartialTapes(const common::dataStructures::SecurityIdentity &admin, const std::string &name, const uint64_t nbPartialTapes) override;
   void modifyTapePoolComment(const common::dataStructures::SecurityIdentity &admin, const std::string &name, const std::string &comment) override;
   void setTapePoolEncryption(const common::dataStructures::SecurityIdentity &admin, const std::string &name, const bool encryptionValue) override;
+  void modifyTapePoolSupply(const common::dataStructures::SecurityIdentity &admin, const std::string &name, const std::string &supply) override;
 
   void createArchiveRoute(
     const common::dataStructures::SecurityIdentity &admin,
@@ -268,10 +269,11 @@ public:
   void modifyArchiveRouteTapePoolName(const common::dataStructures::SecurityIdentity &admin, const std::string &instanceName, const std::string &storageClassName, const uint32_t copyNb, const std::string &tapePoolName) override;
   void modifyArchiveRouteComment(const common::dataStructures::SecurityIdentity &admin, const std::string &instanceName, const std::string &storageClassName, const uint32_t copyNb, const std::string &comment) override;
 
-  void createLogicalLibrary(const common::dataStructures::SecurityIdentity &admin, const std::string &name, const std::string &comment) override;
+  void createLogicalLibrary(const common::dataStructures::SecurityIdentity &admin, const std::string &name, const bool isDisabled, const std::string &comment) override;
   void deleteLogicalLibrary(const std::string &name) override;
   std::list<common::dataStructures::LogicalLibrary> getLogicalLibraries() const override;
   void modifyLogicalLibraryComment(const common::dataStructures::SecurityIdentity &admin, const std::string &name, const std::string &comment) override;
+  virtual void setLogicalLibraryDisabled(const common::dataStructures::SecurityIdentity &admin, const std::string &name, const bool disabledValue) override;
 
   /**
    * Creates a tape.
diff --git a/catalogue/TapePool.hpp b/catalogue/TapePool.hpp
index 7ca30f058e493943f219c121a38d07c4f6449f80..5de6f27e89aa695668ed74772266eb97ff9ae15a 100644
--- a/catalogue/TapePool.hpp
+++ b/catalogue/TapePool.hpp
@@ -23,6 +23,7 @@
 #include <string>
 
 #include "common/dataStructures/EntryLog.hpp"
+#include "common/optional.hpp"
 
 namespace cta {
 namespace catalogue {
@@ -99,6 +100,11 @@ struct TapePool {
    */
   uint64_t nbPhysicalFiles;
 
+  /**
+   * Optional value used by the tape pool supply mechanism.
+   */
+  cta::optional<std::string> supply;
+
   /**
    * The creation log.
    */
diff --git a/catalogue/UserSpecifiedAnEmptyStringSupply.cpp b/catalogue/UserSpecifiedAnEmptyStringSupply.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..dee220acbdda2094afaba2686ae51321d11264c1
--- /dev/null
+++ b/catalogue/UserSpecifiedAnEmptyStringSupply.cpp
@@ -0,0 +1,39 @@
+/*
+ * 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 "catalogue/UserSpecifiedAnEmptyStringSupply.hpp"
+
+namespace cta {
+namespace catalogue {
+
+
+//------------------------------------------------------------------------------
+// constructor
+//------------------------------------------------------------------------------
+UserSpecifiedAnEmptyStringSupply::UserSpecifiedAnEmptyStringSupply(const std::string &context,
+  const bool embedBacktrace): cta::exception::UserError(context, embedBacktrace) {
+}
+
+//------------------------------------------------------------------------------
+// destructor
+//------------------------------------------------------------------------------
+UserSpecifiedAnEmptyStringSupply::~UserSpecifiedAnEmptyStringSupply() {
+}
+
+} // namespace catalogue
+} // namespace cta
diff --git a/catalogue/UserSpecifiedAnEmptyStringSupply.hpp b/catalogue/UserSpecifiedAnEmptyStringSupply.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..12803e2c96497cf8af9e850831a3f0aefe8f1796
--- /dev/null
+++ b/catalogue/UserSpecifiedAnEmptyStringSupply.hpp
@@ -0,0 +1,48 @@
+/*
+ * 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/UserError.hpp"
+
+namespace cta {
+namespace catalogue {
+
+/**
+ * User specified an empty string for a supply value when this is not permitted.
+ */
+class UserSpecifiedAnEmptyStringSupply: public exception::UserError {
+public:
+  /**
+   * Constructor.
+   *
+   * @param context optional context string added to the message
+   * at initialisation time.
+   * @param embedBacktrace whether to embed a backtrace of where the
+   * exception was throw in the message
+   */
+  UserSpecifiedAnEmptyStringSupply(const std::string &context = "", const bool embedBacktrace = true);
+
+  /**
+   * Destructor.
+   */
+  ~UserSpecifiedAnEmptyStringSupply() override;
+}; // class UserSpecifiedAnEmptyStringSupply
+
+} // namespace catalogue
+} // namespace cta
diff --git a/catalogue/common_catalogue_schema.sql b/catalogue/common_catalogue_schema.sql
index 26468f8986bfa91a51928f06264fabe68e04ce31..e37a2d5022b9a3b87d071002acff2f1171485b29 100644
--- a/catalogue/common_catalogue_schema.sql
+++ b/catalogue/common_catalogue_schema.sql
@@ -33,6 +33,7 @@ CREATE TABLE TAPE_POOL(
   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            CHAR(1)         CONSTRAINT TAPE_POOL_IE_NN   NOT NULL,
+  SUPPLY                  VARCHAR(100),
   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,
@@ -62,6 +63,7 @@ CREATE TABLE ARCHIVE_ROUTE(
 );
 CREATE TABLE LOGICAL_LIBRARY(
   LOGICAL_LIBRARY_NAME    VARCHAR(100)    CONSTRAINT LOGICAL_LIBRARY_LLL_NN  NOT NULL,
+  IS_DISABLED             CHAR(1)         DEFAULT '0' CONSTRAINT LOGICAL_LIBRARY_ID_NN NOT NULL,
   USER_COMMENT            VARCHAR(1000)   CONSTRAINT LOGICAL_LIBRARY_UC_NN   NOT NULL,
   CREATION_LOG_USER_NAME  VARCHAR(100)    CONSTRAINT LOGICAL_LIBRARY_CLUN_NN NOT NULL,
   CREATION_LOG_HOST_NAME  VARCHAR(100)    CONSTRAINT LOGICAL_LIBRARY_CLHN_NN NOT NULL,
@@ -69,7 +71,8 @@ CREATE TABLE LOGICAL_LIBRARY(
   LAST_UPDATE_USER_NAME   VARCHAR(100)    CONSTRAINT LOGICAL_LIBRARY_LUUN_NN NOT NULL,
   LAST_UPDATE_HOST_NAME   VARCHAR(100)    CONSTRAINT LOGICAL_LIBRARY_LUHN_NN NOT NULL,
   LAST_UPDATE_TIME        NUMERIC(20, 0)  CONSTRAINT LOGICAL_LIBRARY_LUT_NN  NOT NULL,
-  CONSTRAINT LOGICAL_LIBRARY_PK PRIMARY KEY(LOGICAL_LIBRARY_NAME)
+  CONSTRAINT LOGICAL_LIBRARY_PK PRIMARY KEY(LOGICAL_LIBRARY_NAME),
+  CONSTRAINT LOGICAL_LIBRARY_ID_BOOL_CK CHECK(IS_DISABLED IN ('0', '1'))
 );
 CREATE TABLE TAPE(
   VID                     VARCHAR(100)    CONSTRAINT TAPE_V_UN    NOT NULL,
@@ -89,8 +92,8 @@ CREATE TABLE TAPE(
   LAST_READ_TIME          NUMERIC(20, 0),
   LAST_WRITE_DRIVE        VARCHAR(100),
   LAST_WRITE_TIME         NUMERIC(20, 0),
-  READ_MOUNT_COUNT        NUMERIC(20, 0)  DEFAULT 0,
-  WRITE_MOUNT_COUNT       NUMERIC(20, 0)  DEFAULT 0,
+  READ_MOUNT_COUNT        NUMERIC(20, 0)  DEFAULT 0 CONSTRAINT TAPE_RMC_NN NOT NULL,
+  WRITE_MOUNT_COUNT       NUMERIC(20, 0)  DEFAULT 0 CONSTRAINT TAPE_WMC_NN NOT NULL,
   USER_COMMENT            VARCHAR(1000)   CONSTRAINT TAPE_UC_UN   NOT NULL,
   CREATION_LOG_USER_NAME  VARCHAR(100)    CONSTRAINT TAPE_CLUN_UN NOT NULL,
   CREATION_LOG_HOST_NAME  VARCHAR(100)    CONSTRAINT TAPE_CLHN_UN NOT NULL,
@@ -180,7 +183,7 @@ CREATE TABLE TAPE_FILE(
   CREATION_TIME            NUMERIC(20, 0) CONSTRAINT TAPE_FILE_CT_NN   NOT NULL,
   ARCHIVE_FILE_ID          NUMERIC(20, 0) CONSTRAINT TAPE_FILE_AFI_NN  NOT NULL,
   SUPERSEDED_BY_VID        VARCHAR(100),
-  SUPERSEDED_BY_FSEQ       INTEGER,
+  SUPERSEDED_BY_FSEQ       NUMERIC(20, 0),
   CONSTRAINT TAPE_FILE_PK PRIMARY KEY(VID, FSEQ),
   CONSTRAINT TAPE_FILE_TAPE_FK FOREIGN KEY(VID)
     REFERENCES TAPE(VID),
@@ -188,7 +191,7 @@ CREATE TABLE TAPE_FILE(
     REFERENCES ARCHIVE_FILE(ARCHIVE_FILE_ID),
   CONSTRAINT TAPE_FILE_VID_BLOCK_ID_UN UNIQUE(VID, BLOCK_ID),
   CONSTRAINT TAPE_FILE_COPY_NB_GT_ZERO CHECK(COPY_NB > 0),
-  CONSTRAINT TAPE_FILE_SS_VID_FSEQ FOREIGN KEY(SUPERSEDED_BY_VID, SUPERSEDED_BY_FSEQ)
+  CONSTRAINT TAPE_FILE_SS_VID_FSEQ_FK FOREIGN KEY(SUPERSEDED_BY_VID, SUPERSEDED_BY_FSEQ)
     REFERENCES TAPE_FILE(VID, FSEQ)
 );
 CREATE INDEX TAPE_FILE_VID_IDX ON TAPE_FILE(VID);
diff --git a/catalogue/mysql_catalogue_schema_trigger.sql b/catalogue/mysql_catalogue_schema_trigger.sql
index 694c27a8800727de03dd306bee20cd9670a4418f..16ac8b0277bac899c3bf6f0ebf86dec36d43753a 100644
--- a/catalogue/mysql_catalogue_schema_trigger.sql
+++ b/catalogue/mysql_catalogue_schema_trigger.sql
@@ -78,7 +78,20 @@ CREATE TRIGGER `TAPE_FILE_COPY_NB_GT_ZERO_BEFORE_UPDATE` BEFORE UPDATE ON `TAPE_
     END IF;
   END;
 
+CREATE TRIGGER `CHECK_LOGICAL_LIBRARY_BEFORE_INSERT` BEFORE INSERT ON `LOGICAL_LIBRARY`
+  FOR EACH ROW
+  BEGIN
+    IF new.IS_DISABLED not in ('0','1') THEN
+      SIGNAL SQLSTATE '45000'
+      SET MESSAGE_TEXT = 'LOGICAL_LIBRARY.IS_DISABLED should be 0 or 1';       
+    END IF;
+  END;
 
-
-
-
+CREATE TRIGGER `CHECK_LOGICAL_LIBRARY_BEFORE_UPDATE` BEFORE UPDATE ON `LOGICAL_LIBRARY`
+  FOR EACH ROW
+  BEGIN
+    IF new.IS_DISABLED not in ('0','1') THEN
+      SIGNAL SQLSTATE '45000'
+      SET MESSAGE_TEXT = 'LOGICAL_LIBRARY.IS_DISABLED should be 0 or 1';       
+    END IF;
+  END;
diff --git a/cmdline/CtaAdminCmd.cpp b/cmdline/CtaAdminCmd.cpp
index 6cd287a263c1006748a2a3b2ba16a67acea95e38..338e2a25083fd2df654a64e461716522ecd139c6 100644
--- a/cmdline/CtaAdminCmd.cpp
+++ b/cmdline/CtaAdminCmd.cpp
@@ -646,6 +646,7 @@ void CtaAdminCmd::printTpLsHeader()
              << std::setfill(' ') << std::setw(6)  << std::right << "avail"       << ' '
              << std::setfill(' ') << std::setw(6)  << std::right << "use%"        << ' '
              << std::setfill(' ') << std::setw(8)  << std::right << "encrypt"     << ' '
+             << std::setfill(' ') << std::setw(20) << std::right << "supply"      << ' '
              << std::setfill(' ') << std::setw(8)  << std::right << "c.user"      << ' '
              << std::setfill(' ') << std::setw(25) << std::right << "c.host"      << ' '
              << std::setfill(' ') << std::setw(24) << std::right << "c.time"      << ' '
@@ -748,6 +749,7 @@ void CtaAdminCmd::print(const cta::admin::TapePoolLsItem &tpls_item)
              << std::setfill(' ') << std::setw(5)  << std::right << avail                      / 1000000000   << "G "
              << std::setfill(' ') << std::setw(5)  << std::right << std::fixed << std::setprecision(1) << use_percent << "% "
              << std::setfill(' ') << std::setw(8)  << std::right << encrypt_str                               << ' '
+             << std::setfill(' ') << std::setw(20) << std::right << tpls_item.supply()                        << ' '
              << std::setfill(' ') << std::setw(8)  << std::right << tpls_item.created().username()            << ' '
              << std::setfill(' ') << std::setw(25) << std::right << tpls_item.created().host()                << ' '
              << std::setfill(' ') << std::setw(24) << std::right << timeToString(tpls_item.created().time())  << ' '
diff --git a/cmdline/CtaAdminCmdParse.hpp b/cmdline/CtaAdminCmdParse.hpp
index 11ef3897eb5ab19ec0e1bc013885cf8130a080a0..20d4fa207729ca14577dcc7dfce3efdaa320ff03 100644
--- a/cmdline/CtaAdminCmdParse.hpp
+++ b/cmdline/CtaAdminCmdParse.hpp
@@ -302,6 +302,7 @@ const std::map<std::string, OptionString::Key> strOptions = {
    { "--owner",                 OptionString::OWNER },
    { "--path",                  OptionString::PATH },
    { "--storageclass",          OptionString::STORAGE_CLASS },
+   { "--supply",                OptionString::SUPPLY },
    { "--tapepool",              OptionString::TAPE_POOL },
    { "--username",              OptionString::USERNAME },
    { "--vendor",                OptionString::VENDOR },
@@ -408,6 +409,7 @@ const Option opt_storageclass         { Option::OPT_STR,  "--storageclass",
 const Option opt_storageclass_alias   { Option::OPT_STR,  "--name",                  "-n",   " <storage_class_name>",
                                         "--storageclass" };
 const Option opt_summary              { Option::OPT_FLAG, "--summary",               "-S",   "" };
+const Option opt_supply               { Option::OPT_STR,  "--supply",                "-s",   " <supply_value>" };
 const Option opt_tapepool             { Option::OPT_STR,  "--tapepool",              "-t",   " <tapepool_name>" };
 const Option opt_tapepool_alias       { Option::OPT_STR,  "--name",                  "-n",   " <tapepool_name>",
                                         "--tapepool" };
@@ -469,8 +471,10 @@ const std::map<cmd_key_t, cmd_val_t> cmdOptions = {
    {{ AdminCmd::CMD_LISTPENDINGRETRIEVES, AdminCmd::SUBCMD_NONE  },
       { opt_header.optional(), opt_vid.optional(), opt_extended.optional() }},
    /*----------------------------------------------------------------------------------------------------*/
-   {{ AdminCmd::CMD_LOGICALLIBRARY,       AdminCmd::SUBCMD_ADD   }, { opt_logicallibrary_alias, opt_comment }},
-   {{ AdminCmd::CMD_LOGICALLIBRARY,       AdminCmd::SUBCMD_CH    }, { opt_logicallibrary_alias, opt_comment }},
+   {{ AdminCmd::CMD_LOGICALLIBRARY,       AdminCmd::SUBCMD_ADD   },
+      { opt_logicallibrary_alias, opt_disabled.optional(), opt_comment }},
+   {{ AdminCmd::CMD_LOGICALLIBRARY,       AdminCmd::SUBCMD_CH    },
+      { opt_logicallibrary_alias, opt_disabled.optional(), opt_comment.optional() }},
    {{ AdminCmd::CMD_LOGICALLIBRARY,       AdminCmd::SUBCMD_RM    }, { opt_logicallibrary_alias }},
    {{ AdminCmd::CMD_LOGICALLIBRARY,       AdminCmd::SUBCMD_LS    }, { opt_header.optional() }},
    /*----------------------------------------------------------------------------------------------------*/
@@ -523,9 +527,10 @@ const std::map<cmd_key_t, cmd_val_t> cmdOptions = {
       { opt_vid, opt_force.optional(), opt_lbp.optional() }},
    /*----------------------------------------------------------------------------------------------------*/
    {{ AdminCmd::CMD_TAPEPOOL,             AdminCmd::SUBCMD_ADD   },
-      { opt_tapepool_alias, opt_vo, opt_partialtapes, opt_encrypted, opt_comment }},
+      { opt_tapepool_alias, opt_vo, opt_partialtapes, opt_encrypted, opt_supply.optional(), opt_comment }},
    {{ AdminCmd::CMD_TAPEPOOL,             AdminCmd::SUBCMD_CH    },
-      { opt_tapepool_alias, opt_vo.optional(), opt_partialtapes.optional(), opt_encrypted.optional(), opt_comment.optional() }},
+      { opt_tapepool_alias, opt_vo.optional(), opt_partialtapes.optional(), opt_encrypted.optional(),
+        opt_supply.optional(), opt_comment.optional() }},
    {{ AdminCmd::CMD_TAPEPOOL,             AdminCmd::SUBCMD_RM    }, { opt_tapepool_alias }},
    {{ AdminCmd::CMD_TAPEPOOL,             AdminCmd::SUBCMD_LS    }, { opt_header.optional() }},
 };
diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt
index 6e36d11b42b64b812a598fdc56fd5f6118a8a235..cac4940c7d4f676c836f2ce81f6b685080f50330 100644
--- a/common/CMakeLists.txt
+++ b/common/CMakeLists.txt
@@ -166,6 +166,7 @@ set (COMMON_UNIT_TESTS_LIB_SRC_FILES
   ConfigurationFileTests.cpp
   SourcedParameterTests.cpp
   dataStructures/ArchiveFileTest.cpp
+  dataStructures/LogicalLibraryTest.cpp
   dataStructures/StorageClassTest.cpp
   processCap/SmartCapTest.cpp
   log/FileLoggerTest.cpp
diff --git a/common/dataStructures/LogicalLibrary.cpp b/common/dataStructures/LogicalLibrary.cpp
index 1e6efaf6fb4562e3ded9f08eb586aa36987baffc..339ad78da4e2adba8ffd4cf91d1fc1c40de11344 100644
--- a/common/dataStructures/LogicalLibrary.cpp
+++ b/common/dataStructures/LogicalLibrary.cpp
@@ -27,7 +27,8 @@ namespace dataStructures {
 //------------------------------------------------------------------------------
 // constructor
 //------------------------------------------------------------------------------
-LogicalLibrary::LogicalLibrary() {}
+LogicalLibrary::LogicalLibrary(): isDisabled(false) {
+}
 
 //------------------------------------------------------------------------------
 // operator==
diff --git a/common/dataStructures/LogicalLibrary.hpp b/common/dataStructures/LogicalLibrary.hpp
index 8ab20e4334022158a147f47af91c3fff049dc66b..6a70f7c2e8d855829d74f405426e85f6721abc0b 100644
--- a/common/dataStructures/LogicalLibrary.hpp
+++ b/common/dataStructures/LogicalLibrary.hpp
@@ -35,6 +35,11 @@ namespace dataStructures {
  */
 struct LogicalLibrary {
 
+  /**
+   * Constructor.
+   *
+   * Initialises isDisabled to false.
+   */
   LogicalLibrary();
 
   bool operator==(const LogicalLibrary &rhs) const;
@@ -42,6 +47,7 @@ struct LogicalLibrary {
   bool operator!=(const LogicalLibrary &rhs) const;
 
   std::string name;
+  bool isDisabled;
   EntryLog creationLog;
   EntryLog lastModificationLog;
   std::string comment;
diff --git a/common/dataStructures/LogicalLibraryTest.cpp b/common/dataStructures/LogicalLibraryTest.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..88117c709096161b481c5efa4d93f206d3cccc00
--- /dev/null
+++ b/common/dataStructures/LogicalLibraryTest.cpp
@@ -0,0 +1,43 @@
+/*
+ * 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/dataStructures/LogicalLibrary.hpp"
+
+#include <gtest/gtest.h>
+#include <algorithm>
+
+namespace unitTests {
+
+class cta_common_dataStructures_LogicalLibraryTest : public ::testing::Test {
+protected:
+
+  virtual void SetUp() {
+  }
+
+  virtual void TearDown() {
+  }
+};
+
+TEST_F(cta_common_dataStructures_LogicalLibraryTest, constructor) {
+  using namespace cta::common::dataStructures;
+
+  LogicalLibrary logicalLibrary;
+  ASSERT_FALSE(logicalLibrary.isDisabled);
+}
+
+} // namespace unitTests
diff --git a/common/exception/Backtrace.cpp b/common/exception/Backtrace.cpp
index 6561aabfe5ae4a1dc4ac96ce52d893323c66c1de..bdbf67bcdace96c00f0516404a0b904e703fe661 100644
--- a/common/exception/Backtrace.cpp
+++ b/common/exception/Backtrace.cpp
@@ -117,7 +117,6 @@ cta::exception::Backtrace::Backtrace(bool fake): m_trace() {
   void * array[200];
   g_lock.lock();  
   size_t depth = ::backtrace(array, sizeof(array)/sizeof(void*));
-  g_lock.unlock();
   char ** strings = ::backtrace_symbols(array, depth);
 
   if (!strings)
@@ -158,6 +157,7 @@ cta::exception::Backtrace::Backtrace(bool fake): m_trace() {
     }
     free (strings);
   }
+  g_lock.unlock();
 }
 
 /* Implementation of the singleton lock */
diff --git a/common/utils/UtilsTest.cpp b/common/utils/UtilsTest.cpp
index 2f30fc2c37ab2ab1c0f48c9fa479689e3bc8a467..e3f1f0b0c2db0def7395f95a59f1c3907c6f9581 100644
--- a/common/utils/UtilsTest.cpp
+++ b/common/utils/UtilsTest.cpp
@@ -429,7 +429,7 @@ TEST_F(cta_UtilsTest, toGid_too_big) {
   ASSERT_THROW(utils::toGid(oss.str()), std::exception);
 }
 
-TEST_F(cta_UtilsTest, isValidUInt_unsigned_int) {
+TEST_F(cta_UtilsTest, isValidUInt) {
   using namespace cta;
 
   ASSERT_TRUE(utils::isValidUInt("12345"));
@@ -441,7 +441,7 @@ TEST_F(cta_UtilsTest, isValidUInt_empty_string) {
   ASSERT_FALSE(utils::isValidUInt(""));
 }
 
-TEST_F(cta_UtilsTest, isValidUInt_signed_int) {
+TEST_F(cta_UtilsTest, isValidUInt_negative) {
   using namespace cta;
 
   ASSERT_FALSE(utils::isValidUInt("-12345"));
@@ -453,7 +453,7 @@ TEST_F(cta_UtilsTest, isValidUInt_not_a_number) {
   ASSERT_FALSE(utils::isValidUInt("one"));
 }
 
-TEST_F(cta_UtilsTest, toUint64_unsigned_int) {
+TEST_F(cta_UtilsTest, toUint64) {
   using namespace cta;
 
   ASSERT_EQ((uint64_t)12345, utils::toUint64("12345"));
@@ -484,6 +484,67 @@ TEST_F(cta_UtilsTest, toUint64_not_a_number) {
   ASSERT_THROW(utils::toUint64("one"), exception::Exception);
 }
 
+TEST_F(cta_UtilsTest, isValidDecimal) {
+  using namespace cta;
+
+  ASSERT_TRUE(utils::isValidDecimal("1.234"));
+}
+
+TEST_F(cta_UtilsTest, isValidDecimal_empty_string) {
+  using namespace cta;
+
+  ASSERT_FALSE(utils::isValidDecimal(""));
+}
+
+TEST_F(cta_UtilsTest, isValidDecimal_negative_double) {
+  using namespace cta;
+
+  ASSERT_TRUE(utils::isValidDecimal("-1.234"));
+}
+
+TEST_F(cta_UtilsTest, isValidDecimal_not_a_number) {
+  using namespace cta;
+
+  ASSERT_FALSE(utils::isValidDecimal("one"));
+}
+
+TEST_F(cta_UtilsTest, isValidDecimal_two_decimal_points) {
+  using namespace cta;
+
+  ASSERT_FALSE(utils::isValidDecimal("1.2.34"));
+}
+
+TEST_F(cta_UtilsTest, toDouble_double) {
+  using namespace cta;
+
+  ASSERT_EQ((double)1.234, utils::toDouble("1.234"));
+}
+
+TEST_F(cta_UtilsTest, toDouble_negative_double) {
+  using namespace cta;
+
+  ASSERT_EQ((double)-1.234, utils::toDouble("-1.234"));
+}
+
+TEST_F(cta_UtilsTest, toDouble_too_big) {
+  using namespace cta;
+
+  // std::numeric_limits<double>::max=1.79769e+308
+  ASSERT_THROW(utils::toDouble("1.79770e+308"), exception::Exception);
+}
+
+TEST_F(cta_UtilsTest, toDouble_empty_string) {
+  using namespace cta;
+
+  ASSERT_THROW(utils::toDouble(""), exception::Exception);
+}
+
+TEST_F(cta_UtilsTest, toDouble_not_a_number) {
+  using namespace cta;
+
+  ASSERT_THROW(utils::toDouble("one"), exception::Exception);
+}
+
 TEST_F(cta_UtilsTest, adler32_empty_buf) {
   using namespace cta;
 
@@ -683,4 +744,16 @@ TEST_F(cta_UtilsTest, DISABLED_currentTime) {
   std::cout << getCurrentLocalTime() << std::endl;
 }
 
+TEST_F(cta_UtilsTest, searchAndReplace) {
+  using namespace cta::utils;
+
+  std::string str = "one two three four one two three four";
+  const std::string search = "two";
+  const std::string replacement = "replacement";
+
+  searchAndReplace(str, search, replacement);
+
+  ASSERT_EQ("one replacement three four one replacement three four", str);
+}
+
 } // namespace unitTests
diff --git a/common/utils/utils.cpp b/common/utils/utils.cpp
index 5a764b31d1f5cb05df255551d9c7a3bc96883d87..ac4d0221b54919fcc6c2965ce87f42318a194d7c 100644
--- a/common/utils/utils.cpp
+++ b/common/utils/utils.cpp
@@ -626,7 +626,7 @@ uint64_t toUint64(const std::string &str) {
     try {
       return std::stoul(str);
     } catch(std::invalid_argument &) {
-      throw exception::Exception("Invalid string");
+      throw exception::Exception("Invalid uint64");
     } catch(std::out_of_range &) {
       throw exception::Exception("Out of range");
     } catch(std::exception &se) {
@@ -638,6 +638,61 @@ uint64_t toUint64(const std::string &str) {
   }
 }
 
+//------------------------------------------------------------------------------
+// isValidDecimal
+//------------------------------------------------------------------------------
+bool isValidDecimal(const std::string &str) {
+  // An empty string is not a valid decimal
+  if(str.empty()) {
+    return false;
+  }
+
+  uint64_t nbDecimalPoints = 0;
+
+  // For each character in the string
+  for(std::string::const_iterator itor = str.begin(); itor != str.end(); itor++) {
+
+    const bool isFirstChar = itor == str.begin();
+    const bool isMinusChar = '-' == *itor;
+    const bool isANumericalDigit = '0' <= *itor && *itor <= '9';
+    const bool isADecimalPoint = '.' == *itor;
+
+    if(!(isFirstChar && isMinusChar) && !isANumericalDigit && !isADecimalPoint) {
+      return false;
+    }
+
+    if(isADecimalPoint) {
+      nbDecimalPoints++;
+    }
+
+    if(1 < nbDecimalPoints) {
+      return false;
+    }
+  }
+
+  return true;
+}
+
+//------------------------------------------------------------------------------
+// toDouble
+//------------------------------------------------------------------------------
+double toDouble(const std::string &str) {
+  try {
+    try {
+      return std::stod(str);
+    } catch(std::invalid_argument &) {
+      throw exception::Exception("Invalid double");
+    } catch(std::out_of_range &) {
+      throw exception::Exception("Out of range");
+    } catch(std::exception &se) {
+      throw exception::Exception(se.what());
+    }
+  } catch(exception::Exception  &ex) {
+    throw exception::Exception(std::string("Failed to parse ") + str + " as a double: " +
+      ex.getMessage().str());
+  }
+}
+
 //------------------------------------------------------------------------------
 // toUpper
 //------------------------------------------------------------------------------
@@ -799,5 +854,23 @@ std::string extractPathFromXrootdPath(const std::string& path){
   return std::string(urlInfo.File.c_str());
 }
 
+//------------------------------------------------------------------------------
+// searchAndReplace
+//------------------------------------------------------------------------------
+void searchAndReplace(std::string &str, const std::string &search, const std::string replacement) {
+  std::string::size_type pos = 0;
+  while(std::string::npos != (pos = str.find(search, pos))) {
+    str.replace(pos, search.length(), replacement);
+    pos += replacement.length();
+  }
+}
+
+//------------------------------------------------------------------------------
+// segfault
+//------------------------------------------------------------------------------
+void segfault() {
+  *((int *)nullptr) = 0;
+}
+
 } // namespace utils
 } // namespace cta
diff --git a/common/utils/utils.hpp b/common/utils/utils.hpp
index bb6bf0dac4749fe30dd3d3323392212cc3983472..d56e933011cd61dced8dd996b878c369a50cba36 100644
--- a/common/utils/utils.hpp
+++ b/common/utils/utils.hpp
@@ -280,6 +280,21 @@ namespace utils {
    */
   uint64_t toUint64(const std::string &str);
 
+  /**
+   * Checks if the specified string is a valid decimal.
+   *
+   * @param str The string to be checked.
+   * @returns true if the string is a valid decimal, else false.
+   */
+  bool isValidDecimal(const std::string &str);
+
+  /**
+   * Parses the specified string representation of a double.
+   *
+   * @return The parsed double.
+   */
+  double toDouble(const std::string &str);
+
   /**
    * Converts the specified string to uppercase.
    *
@@ -379,6 +394,22 @@ namespace utils {
    */
   std::string extractPathFromXrootdPath(const std::string &path);
 
+  /**
+   * Performs a search and replace operation on the specified string.
+   *
+   * @param str In/out parameter which is the string to be modified.
+   * @param search The search string.
+   * @param replacement The replacement string.
+   */
+  void searchAndReplace(std::string &str, const std::string &search, const std::string replacement);
+  
+  /**
+   * Willful segmentation violation (accessing nullptr) ensuring the process will stop hard.
+   * This is different from self-killing the process as the signal delivery is not immediate.
+   * Here, the CPU will interrupt the process with a memory protection error.
+   */
+  void segfault(void);
+
 } // namespace utils
 
 } // namespace cta
diff --git a/continuousintegration/docker/ctafrontend/cc7/buildtree-stage1-rpms/Dockerfile b/continuousintegration/docker/ctafrontend/cc7/buildtree-stage1-rpms/Dockerfile
index fb8fb133bcb84e5ffcc9defa12246fdcb9005d95..302dd30ac76cf1b563e5bb6c400f9473cf718f68 100644
--- a/continuousintegration/docker/ctafrontend/cc7/buildtree-stage1-rpms/Dockerfile
+++ b/continuousintegration/docker/ctafrontend/cc7/buildtree-stage1-rpms/Dockerfile
@@ -95,6 +95,7 @@ RUN yum-config-manager --enable epel --setopt="epel.priority=4" \
       hiredis \
       jsoncpp \
       libmicrohttpd \
+      jq \
   && \
     yum clean all \
   && \
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 8a35ba63050da8b3ebb9656c79c123c45793caf7..ef96601fc643bd62754bc4f2a4cfeadb7f9566e9 100644
--- a/continuousintegration/docker/ctafrontend/cc7/etc/yum/pluginconf.d/versionlock.list
+++ b/continuousintegration/docker/ctafrontend/cc7/etc/yum/pluginconf.d/versionlock.list
@@ -1,17 +1,17 @@
-0:eos-archive-4.4.45-3.el7.cern.x86_64
-0:eos-cleanup-4.4.45-3.el7.cern.x86_64
-0:eos-client-4.4.45-3.el7.cern.x86_64
-0:eos-debuginfo-4.4.45-3.el7.cern.x86_64
-0:eos-fuse-4.4.45-3.el7.cern.x86_64
-0:eos-fuse-core-4.4.45-3.el7.cern.x86_64
-0:eos-fuse-sysv-4.4.45-3.el7.cern.x86_64
-0:eos-fusex-4.4.45-3.el7.cern.x86_64
-0:eos-fusex-core-4.4.45-3.el7.cern.x86_64
-0:eos-fusex-selinux-4.4.45-3.el7.cern.x86_64
-0:eos-server-4.4.45-3.el7.cern.x86_64
-0:eos-srm-4.4.45-3.el7.cern.x86_64
-0:eos-test-4.4.45-3.el7.cern.x86_64
-0:eos-testkeytab-4.4.45-3.el7.cern.x86_64
+0:eos-archive-4.4.47-1.el7.cern.x86_64
+0:eos-cleanup-4.4.47-1.el7.cern.x86_64
+0:eos-client-4.4.47-1.el7.cern.x86_64
+0:eos-debuginfo-4.4.47-1.el7.cern.x86_64
+0:eos-fuse-4.4.47-1.el7.cern.x86_64
+0:eos-fuse-core-4.4.47-1.el7.cern.x86_64
+0:eos-fuse-sysv-4.4.47-1.el7.cern.x86_64
+0:eos-fusex-4.4.47-1.el7.cern.x86_64
+0:eos-fusex-core-4.4.47-1.el7.cern.x86_64
+0:eos-fusex-selinux-4.4.47-1.el7.cern.x86_64
+0:eos-server-4.4.47-1.el7.cern.x86_64
+0:eos-srm-4.4.47-1.el7.cern.x86_64
+0:eos-test-4.4.47-1.el7.cern.x86_64
+0:eos-testkeytab-4.4.47-1.el7.cern.x86_64
 1:python2-xrootd-4.9.1-1.el7.*
 1:python3-xrootd-4.9.1-1.el7.*
 1:xrootd-4.9.1-1.el7.*
diff --git a/continuousintegration/docker/ctafrontend/cc7/opt/run/bin/client.sh b/continuousintegration/docker/ctafrontend/cc7/opt/run/bin/client.sh
index 436a27a79e7c6275db061250a9923a4d02d82ff8..05325855de7ff37c0c4bac8d7a044f164fee4e23 100755
--- a/continuousintegration/docker/ctafrontend/cc7/opt/run/bin/client.sh
+++ b/continuousintegration/docker/ctafrontend/cc7/opt/run/bin/client.sh
@@ -7,10 +7,7 @@ if [ ! -e /etc/buildtreeRunner ]; then
   yum-config-manager --enable ceph
 
   # Install missing RPMs
-  yum -y install cta-cli cta-debuginfo xrootd-client eos-client
-
-  # Install needed tools for CI testing
-  yum install -y jq
+  yum -y install cta-cli cta-debuginfo xrootd-client eos-client jq
 
   ## Keep this temporary fix that may be needed if going to protobuf3-3.5.1 for CTA
   # Install eos-protobuf3 separately as eos is OK with protobuf3 but cannot use it..
diff --git a/continuousintegration/orchestration/delete_instance.sh b/continuousintegration/orchestration/delete_instance.sh
index 5e0ca804370cc2546db5d39ba76e8cdad9b58c23..95ce1c489b706aa488c62041c1feb255e9baf81d 100755
--- a/continuousintegration/orchestration/delete_instance.sh
+++ b/continuousintegration/orchestration/delete_instance.sh
@@ -71,7 +71,7 @@ if [ $collectlogs == 1 ] ; then
   for podcontainer in "init -c ctainit" "client -c client" "ctacli -c ctacli" "ctaeos -c mgm" "ctafrontend -c ctafrontend" "kdc -c kdc" "tpsrv01 -c taped" "tpsrv01 -c rmcd" "tpsrv02 -c taped" "tpsrv02 -c rmcd"; do
     kubectl --namespace ${instance} logs ${podcontainer} > ${tmpdir}/$(echo ${podcontainer} | sed -e 's/ -c /-/').log
   done
-  kubectl --namespace ${instance} exec ctacli -- tar -C /mnt/logs -zcf - . > ${tmpdir}/varlog.tgz
+  kubectl --namespace ${instance} exec ctacli -- bash -c "XZ_OPT='-0 -T0' tar -C /mnt/logs -Jcf - ." > ${tmpdir}/varlog.tar.xz
 
   if [ ! -z "${CI_PIPELINE_ID}" ]; then
     # we are in the context of a CI run => save artifacts in the directory structure of the build
diff --git a/continuousintegration/orchestration/tests/archive_retrieve.sh b/continuousintegration/orchestration/tests/archive_retrieve.sh
index bfb8e1ab7f05da45452dbb349ea318ce1124ca9d..4bca61163ae358fd2f18a0b24765fad5d2f77962 100755
--- a/continuousintegration/orchestration/tests/archive_retrieve.sh
+++ b/continuousintegration/orchestration/tests/archive_retrieve.sh
@@ -41,9 +41,6 @@ kubectl -n ${NAMESPACE} exec client -- bash /root/simple_client_ar.sh || exit 1
 kubectl -n ${NAMESPACE} cp grep_xrdlog_mgm_for_error.sh ctaeos:/root/grep_xrdlog_mgm_for_error.sh
 kubectl -n ${NAMESPACE} exec ctaeos -- bash /root/grep_xrdlog_mgm_for_error.sh || exit 1
 
-echo
-./simple_repack.sh -n ${NAMESPACE} || exit 1
-
 NB_FILES=10000
 FILE_SIZE_KB=15
 
diff --git a/continuousintegration/orchestration/tests/client_ar.sh b/continuousintegration/orchestration/tests/client_ar.sh
index 5cb4c82bad0a538da7abc79a4f1d7c91b8cc2972..83f1c8618ee9df0cf834e2894b98349f69a60502 100644
--- a/continuousintegration/orchestration/tests/client_ar.sh
+++ b/continuousintegration/orchestration/tests/client_ar.sh
@@ -292,7 +292,7 @@ RETRIEVED=0
 echo "$(date +%s): Waiting for files to be back on disk:"
 SECONDS_PASSED=0
 WAIT_FOR_RETRIEVED_FILE_TIMEOUT=$((40+${NB_FILES}/5))
-while test 0 != ${RETRIEVING}; do
+while test 0 -lt ${RETRIEVING}; do
   echo "$(date +%s): Waiting for files to be retrieved from tape: Seconds passed = ${SECONDS_PASSED}"
   sleep 3
   let SECONDS_PASSED=SECONDS_PASSED+1
diff --git a/continuousintegration/orchestration/tests/repack_systemtest.sh b/continuousintegration/orchestration/tests/repack_systemtest.sh
index 8928d3426cbbb5891c62648b23cb7b6912a88840..306ef4cf0028644134257af006d0e0e0c8b0b58f 100755
--- a/continuousintegration/orchestration/tests/repack_systemtest.sh
+++ b/continuousintegration/orchestration/tests/repack_systemtest.sh
@@ -21,23 +21,12 @@ exit 1
 }
 
 testRepackBufferURL(){
-  echo "Creating the repack buffer URL at root://${EOSINSTANCE}/${REPACK_BUFFER_BASEDIR}"
+  echo "Testing the repack buffer URL at root://${EOSINSTANCE}/${REPACK_BUFFER_BASEDIR}"
   eos root://${EOSINSTANCE} ls -d ${REPACK_BUFFER_BASEDIR} || die "Repack bufferURL directory does not exist"
   echo "Testing the insertion of a test file in the buffer URL"
-  for ((i=0; i<300; i++)); do
-    xrdcp /etc/group ${FULL_REPACK_BUFFER_URL}/testFile && break
-    echo -n "."
-    sleep 1
-  done
-  echo OK
-  failed_xrdcp_test=$i
-  if test $failed_xrdcp_test -eq 0; then
-    echo "[SUCCESS]: Repack buffer URL OK" | tee -a /var/log/CI_tests
-    echo "Removing the test file"
-    eos root://${EOSINSTANCE} rm ${REPACK_BUFFER_BASEDIR}/testFile
-  else
-    echo "[ERROR]: Unable to write a file into the provided repack buffer URL." | tee -a /var/log/CI_tests
-  fi
+  tempFilePath=$(mktemp /tmp/testFile.XXXX)
+  tempFileName=${tempFilePath##*/}
+  xrdcp ${tempFilePath} ${FULL_REPACK_BUFFER_URL}/${tempFileName} || die "Unable to write a file into the repack buffer directory"
   echo "OK"
 }
 
@@ -82,19 +71,17 @@ fi
 
 # Get kerberos credentials for user1
 admin_kinit
-klist -s || die "Cannot get kerberos credentials for user ${USER}"
-
-# Get kerberos credentials for poweruser1
-eospower_kdestroy
-eospower_kinit
+admin_klist > /dev/null 2>&1 || die "Cannot get kerberos credentials for user ${USER}"
 
-echo "Testing the repackBufferURL provided"
 FULL_REPACK_BUFFER_URL=root://${EOSINSTANCE}/${REPACK_BUFFER_BASEDIR}
 testRepackBufferURL
 
 echo "Deleting existing repack request for VID ${VID_TO_REPACK}"
 admin_cta repack rm --vid ${VID_TO_REPACK}
 
+echo "Marking the tape ${VID_TO_REPACK} as full before Repacking it"
+admin_cta tape ch --vid ${VID_TO_REPACK} --full true
+
 echo "State of the tape VID ${VID_TO_REPACK} BEFORE repack"
 admin_cta --json tape ls --vid ${VID_TO_REPACK} | jq .
 
diff --git a/continuousintegration/orchestration/tests/repack_systemtest_wrapper.sh b/continuousintegration/orchestration/tests/repack_systemtest_wrapper.sh
index cbf9adf476fa22399eb234196eeec8a561da1797..fe31c8ce4223115bdbb3523e4775ac1b9acd37c3 100755
--- a/continuousintegration/orchestration/tests/repack_systemtest_wrapper.sh
+++ b/continuousintegration/orchestration/tests/repack_systemtest_wrapper.sh
@@ -30,7 +30,7 @@ fi
 echo "Preparing namespace for the tests"
 ./prepare_tests.sh -n ${NAMESPACE}
 
-NB_FILES=1000
+NB_FILES=1
 FILE_SIZE_KB=15
 
 kubectl -n ${NAMESPACE} cp client_helper.sh client:/root/client_helper.sh
@@ -50,14 +50,46 @@ kubectl -n ${NAMESPACE} exec ctaeos -- eos chmod 1777 ${REPACK_BUFFER_URL}
 source ./repack_helper.sh
 kubectl -n ${NAMESPACE} cp repack_systemtest.sh client:/root/repack_systemtest.sh
 
+echo
+echo "Launching a round trip repack request"
+
+VID_TO_REPACK=$(getFirstVidContainingFiles)
+if [ "$VID_TO_REPACK" != "null" ] 
+then
+echo
+  echo "Launching the repack test on VID ${VID_TO_REPACK}"
+  kubectl -n ${NAMESPACE} exec client -- bash /root/repack_systemtest.sh -v ${VID_TO_REPACK} -b ${REPACK_BUFFER_URL} || exit 1
+else
+  echo "No vid found to repack"
+  exit 1
+fi
+
+echo "Reclaiming tape ${VID_TO_REPACK}"
+kubectl -n ${NAMESPACE} exec ctacli -- cta-admin tape reclaim --vid ${VID_TO_REPACK}
+
+VID_TO_REPACK=$(getFirstVidContainingFiles)
+if [ "$VID_TO_REPACK" != "null" ] 
+then
+echo
+  echo "Launching the repack test on VID ${VID_TO_REPACK}"
+  kubectl -n ${NAMESPACE} exec client -- bash /root/repack_systemtest.sh -v ${VID_TO_REPACK} -b ${REPACK_BUFFER_URL} || exit 1
+else
+  echo "No vid found to repack"
+  exit 1
+fi
+
+echo "Reclaiming tape ${VID_TO_REPACK}"
+kubectl -n ${NAMESPACE} exec ctacli -- cta-admin tape reclaim --vid ${VID_TO_REPACK}
+
+NB_FILES=1152
+kubectl -n ${NAMESPACE} exec client -- bash /root/client_ar.sh -n ${NB_FILES} -s ${FILE_SIZE_KB} -p 100 -d /eos/ctaeos/preprod -v -A || exit 1
+
 VID_TO_REPACK=$(getFirstVidContainingFiles)
 if [ "$VID_TO_REPACK" != "null" ] 
 then
 echo
-  echo "Marking the tape ${VID_TO_REPACK} as full"
-  kubectl -n ${NAMESPACE} exec ctacli -- cta-admin ta ch -v ${VID_TO_REPACK} -f true
   echo "Launching the repack test on VID ${VID_TO_REPACK}"
-  kubectl -n ${NAMESPACE} exec client -- bash /root/repack_systemtest.sh -v ${VID_TO_REPACK} -b ${REPACK_BUFFER_URL}
+  kubectl -n ${NAMESPACE} exec client -- bash /root/repack_systemtest.sh -v ${VID_TO_REPACK} -b ${REPACK_BUFFER_URL} || exit 1
 else
   echo "No vid found to repack"
   exit 1
diff --git a/continuousintegration/orchestration/tests/simple_repack.sh b/continuousintegration/orchestration/tests/simple_repack.sh
index 498170c5d1c367edddb5d63a3c1bae7533d11727..0bf373ae81a7779c9b4ec3bd7f7cef4a245aab45 100755
--- a/continuousintegration/orchestration/tests/simple_repack.sh
+++ b/continuousintegration/orchestration/tests/simple_repack.sh
@@ -27,66 +27,44 @@ if [ ! -z "${error}" ]; then
     exit 1
 fi
 
+echo
+echo "Launching a round trip repack request" 
+kubectl -n ${NAMESPACE} cp repack_systemtest.sh client:/root/repack_systemtest.sh
 source ./repack_helper.sh
 
-echo "Execution of simple_repack.sh"
-
 REPACK_BUFFER_URL=/eos/ctaeos/repack
-vidToRepack1=$(getFirstVidContainingFiles)
-if [ "$vidToRepack1" != "null" ] 
-then
-  echo
-  echo "Creating the repack buffer URL directory (${REPACK_BUFFER_URL})"
-  kubectl -n ${NAMESPACE} exec ctaeos -- eos mkdir ${REPACK_BUFFER_URL}
-  kubectl -n ${NAMESPACE} exec ctaeos -- eos chmod 1777 ${REPACK_BUFFER_URL}
-
-  echo "Marking tape $vidToRepack1 as full before repacking"
-  kubectl -n ${NAMESPACE} exec ctacli -- cta-admin ta ch -v $vidToRepack1 -f true
+echo "Creating the repack buffer URL directory (${REPACK_BUFFER_URL})"
+kubectl -n ${NAMESPACE} exec ctaeos -- eos mkdir ${REPACK_BUFFER_URL}
+kubectl -n ${NAMESPACE} exec ctaeos -- eos chmod 1777 ${REPACK_BUFFER_URL}
 
-  kubectl -n ${NAMESPACE} cp repack_systemtest.sh client:/root/repack_systemtest.sh
-
-  echo
-  echo "Launching the repack test on VID ${vidToRepack1}"
-  kubectl -n ${NAMESPACE} exec client -- bash /root/repack_systemtest.sh -v ${vidToRepack1} -b ${REPACK_BUFFER_URL}
-
-  echo "Reclaiming tape $vidToRepack1"
-  executeReclaim $vidToRepack1
-  echo
-  writeTapeSummary $vidToRepack1
+VID_TO_REPACK=$(getFirstVidContainingFiles)
+if [ "$VID_TO_REPACK" != "null" ] 
+then
+echo
+  echo "Marking the tape ${VID_TO_REPACK} as full"
+  kubectl -n ${NAMESPACE} exec ctacli -- cta-admin tape ch --vid ${VID_TO_REPACK} -f true
+  echo "Launching the repack test on VID ${VID_TO_REPACK}"
+  kubectl -n ${NAMESPACE} exec client -- bash /root/repack_systemtest.sh -v ${VID_TO_REPACK} -b ${REPACK_BUFFER_URL}
 else
   echo "No vid found to repack"
   exit 1
 fi
 
-vidToRepack2=$(getFirstVidContainingFiles)
-if [ "$vidToRepack2" != "null" ] 
-then
-  echo
-  echo "Creating the repack buffer URL directory (${REPACK_BUFFER_URL})"
-  kubectl -n ${NAMESPACE} exec ctaeos -- eos mkdir ${REPACK_BUFFER_URL}
-  kubectl -n ${NAMESPACE} exec ctaeos -- eos chmod 1777 ${REPACK_BUFFER_URL}
-
-  echo "Marking tape $vidToRepack2 as full before repacking"
-  kubectl -n ${NAMESPACE} exec ctacli -- cta-admin ta ch -v $vidToRepack2 -f true
-  kubectl -n ${NAMESPACE} cp repack_systemtest.sh client:/root/repack_systemtest.sh
+echo "Reclaiming tape ${VID_TO_REPACK}"
+kubectl -n ${NAMESPACE} exec ctacli -- cta-admin tape reclaim --vid ${VID_TO_REPACK}
 
-  echo
-  echo "Launching the repack test on VID ${vidToRepack2}"
-  kubectl -n ${NAMESPACE} exec client -- bash /root/repack_systemtest.sh -v ${vidToRepack2} -b ${REPACK_BUFFER_URL}
-
-  echo "Reclaiming tape $vidToRepack2"
-  executeReclaim $vidToRepack2
-  echo
-  writeTapeSummary $vidToRepack1
-  writeTapeSummary $vidToRepack2
+VID_TO_REPACK=$(getFirstVidContainingFiles)
+if [ "$VID_TO_REPACK" != "null" ] 
+then
+echo
+  echo "Marking the tape ${VID_TO_REPACK} as full"
+  kubectl -n ${NAMESPACE} exec ctacli -- cta-admin tape ch --vid ${VID_TO_REPACK} -f true
+  echo "Launching the repack test on VID ${VID_TO_REPACK}"
+  kubectl -n ${NAMESPACE} exec client -- bash /root/repack_systemtest.sh -v ${VID_TO_REPACK} -b ${REPACK_BUFFER_URL}
 else
   echo "No vid found to repack"
   exit 1
 fi
 
-echo
-echo
-echo "Summary of the repack requests"
-kubectl -n ${NAMESPACE} exec ctacli -- cta-admin re ls -h
-
-echo "End of test simple_repack"
+echo "Reclaiming tape ${VID_TO_REPACK}"
+kubectl -n ${NAMESPACE} exec ctacli -- cta-admin tape reclaim --vid ${VID_TO_REPACK}
diff --git a/cta.spec.in b/cta.spec.in
index 8cd97055a5be7da1274acb616f0a22fad10e18ef..67c7ef15d53eceeb4e9f3638729f82d21028619c 100644
--- a/cta.spec.in
+++ b/cta.spec.in
@@ -279,9 +279,11 @@ Unit tests and system tests with virtual tape drives
 %{_libdir}/libctacommonunittests.so*
 %{_libdir}/libctadbconfigcatalogueunittests.so*
 %{_libdir}/libctadbconfigconnunittests.so*
+%{_libdir}/libctadbconfigstmtunittests.so*
 %{_libdir}/libctaexceptionunittests.so*
 %{_libdir}/libctainmemorycatalogueunittests.so*
 %{_libdir}/libctainmemoryconnunittests.so*
+%{_libdir}/libctainmemorystmtunittests.so*
 %{_libdir}/libctaobjectstoreunittests.so*
 %{_libdir}/libctardbmsunittests.so*
 %{_libdir}/libctardbmswrapperunittests.so*
@@ -334,19 +336,6 @@ Scripts and utilities to faciliate working with the CTA catalogue
 %attr(0644,root,root) %doc /usr/share/man/man1/cta-catalogue-schema-drop.1cta.gz
 %attr(0644,root,root) %doc /usr/share/man/man1/cta-database-poll.1cta.gz
 
-%package -n cta-mediachangerutils
-Summary: Utilities to faciliate working with mediachangers
-Group: Application/CTA
-Requires: cta-lib = %{version}-%{release}
-%description -n cta-mediachangerutils
-CERN Tape Archive:
-Utilities to faciliate working with the mediachangers
-%files -n cta-mediachangerutils
-%attr(0755,root,root) %{_bindir}/cta-mediachanger-dismount
-%attr(0755,root,root) %{_bindir}/cta-mediachanger-mount
-%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-rmcd
 Summary: Tools to faciliate working with rmcd and smc in cta
 Group: Application/CTA
diff --git a/mediachanger/CMakeLists.txt b/mediachanger/CMakeLists.txt
index 2f8e3afe0ea7d89c811d7458d7bf9d32298e072d..a0fe0aaacface7bbdea083f1296342d15afecf6c 100644
--- a/mediachanger/CMakeLists.txt
+++ b/mediachanger/CMakeLists.txt
@@ -105,8 +105,6 @@ set_property (TARGET cta-mediachanger-mount APPEND PROPERTY INSTALL_RPATH ${PROT
 target_link_libraries (cta-mediachanger-mount
   ctacommon
   ctamediachanger)
-install (TARGETS cta-mediachanger-mount DESTINATION /usr/bin)
-install (FILES ${CMAKE_CURRENT_SOURCE_DIR}/cta-mediachanger-mount.1cta DESTINATION /usr/share/man/man1)
 
 set (MEDIA_CHANGER_DISMOUNT_SRC_FILES
   DismountCmd.cpp
@@ -121,5 +119,3 @@ set_property (TARGET cta-mediachanger-dismount APPEND PROPERTY INSTALL_RPATH ${P
 target_link_libraries (cta-mediachanger-dismount
   ctacommon
   ctamediachanger)
-install (TARGETS cta-mediachanger-dismount DESTINATION /usr/bin)
-install (FILES ${CMAKE_CURRENT_SOURCE_DIR}/cta-mediachanger-dismount.1cta DESTINATION /usr/share/man/man1)
diff --git a/objectstore/Agent.cpp b/objectstore/Agent.cpp
index cb68dcb0e394af4c6c9f077ed30fc6bb82f10bce..89cbe6154614afa3925aec59a431a8241b071c7d 100644
--- a/objectstore/Agent.cpp
+++ b/objectstore/Agent.cpp
@@ -42,7 +42,7 @@ cta::objectstore::Agent::Agent(const std::string & name, Backend & os):
 void cta::objectstore::Agent::initialize() {
   ObjectOps<serializers::Agent, serializers::Agent_t>::initialize();
   m_payload.set_heartbeat(0);
-  m_payload.set_timeout_us(60*1000*1000);
+  m_payload.set_timeout_us(120*1000*1000);
   m_payload.set_description("");
   m_payload.set_being_garbage_collected(false);
   m_payloadInterpreted = true;
diff --git a/objectstore/AgentHeartbeatThread.cpp b/objectstore/AgentHeartbeatThread.cpp
index f09bc3aead502651906bd9023f288ef98b53e085..358be90625aa4a20635bf6dd5e657d95345eeeb7 100644
--- a/objectstore/AgentHeartbeatThread.cpp
+++ b/objectstore/AgentHeartbeatThread.cpp
@@ -19,6 +19,7 @@
 #include "AgentHeartbeatThread.hpp"
 #include "common/log/LogContext.hpp"
 #include "common/Timer.hpp"
+#include "common/utils/utils.hpp"
 #include <sys/types.h>
 #include <signal.h>
 #include <unistd.h>
@@ -45,13 +46,12 @@ void AgentHeartbeatThread::run() {
       utils::Timer t;
       m_agentReference.bumpHeatbeat(m_backend);
       auto updateTime = t.secs();
-      auto updateTimeLimit = std::chrono::duration<double, std::ratio<1, 1>>(m_heartRate).count();
-      if (updateTime > updateTimeLimit) {
+      if (updateTime > std::chrono::duration_cast<std::chrono::seconds>(m_heartbeatDeadline).count()) {
         log::ScopedParamContainer params(lc);
-        params.add("HeartbeatUpdateTimeLimit", updateTimeLimit)
+        params.add("HeartbeatDeadline", std::chrono::duration_cast<std::chrono::seconds>(m_heartbeatDeadline).count())
               .add("HeartbeatUpdateTime", updateTime);
         lc.log(log::CRIT, "In AgentHeartbeatThread::run(): Could not update heartbeat in time. Exiting (segfault).");
-        ::kill(::getpid(), SIGSEGV);
+        cta::utils::segfault();
         ::exit(EXIT_FAILURE);
       }
     }
@@ -62,7 +62,7 @@ void AgentHeartbeatThread::run() {
     params.add("Message", ex.getMessageValue());
     lc.log(log::CRIT, "In AgentHeartbeatThread::run(): exception while bumping heartbeat. Backtrace follows. Exiting (segfault).");
     lc.logBacktrace(log::ERR, ex.backtrace());
-    ::kill(::getpid(), SIGSEGV);
+    cta::utils::segfault();
     ::exit(EXIT_FAILURE);
   }
 }
diff --git a/objectstore/AgentHeartbeatThread.hpp b/objectstore/AgentHeartbeatThread.hpp
index addbd5e98f8056fdf7ea1fa2b337b358c4b02f88..6c94483f6e6923b0fdaa4a505cd0247c7c0765b1 100644
--- a/objectstore/AgentHeartbeatThread.hpp
+++ b/objectstore/AgentHeartbeatThread.hpp
@@ -64,8 +64,11 @@ private:
   std::promise<void> m_exit;
   
   /// The heartbeat update rate.
-  std::chrono::seconds const m_heartRate = std::chrono::seconds(60);
+  std::chrono::seconds const m_heartRate = std::chrono::seconds(30);
   
+  /// The heartbeat update deadline.
+  std::chrono::seconds const m_heartbeatDeadline = std::chrono::seconds(60);
+
   /// The logging context
   log::Logger & m_logger;
 };
diff --git a/objectstore/AgentReference.cpp b/objectstore/AgentReference.cpp
index d46e65e9180eb81436487485f743b6394677076b..df92d50a0bc249cd05f76fc24522b1de5c0b84bc 100644
--- a/objectstore/AgentReference.cpp
+++ b/objectstore/AgentReference.cpp
@@ -20,6 +20,7 @@
 #include "AgentReference.hpp"
 #include "Agent.hpp"
 #include "common/exception/Errnum.hpp"
+#include "common/utils/utils.hpp"
 
 #include <sstream>
 #include <unistd.h>
@@ -163,7 +164,7 @@ void AgentReference::queueAndExecuteAction(std::shared_ptr<Action> action, objec
         log::ScopedParamContainer params(lc);
         params.add("agentObject", ag.getAddressIfSet());
         lc.log(log::CRIT, "In AgentReference::queueAndExecuteAction(): agent object being garbage collected. Exiting (segfault).");
-        ::kill(::getpid(), SIGSEGV);
+        cta::utils::segfault();
         ::exit(EXIT_FAILURE);
       }
       double agentFetchTime = t.secs(utils::Timer::resetCounter);
diff --git a/objectstore/BackendPopulator.cpp b/objectstore/BackendPopulator.cpp
index ea4dd0eac3b2ef1558a9153aa86fe16b03247420..3a7f71a1af683f77cd2ca404b42be1b19901d246 100644
--- a/objectstore/BackendPopulator.cpp
+++ b/objectstore/BackendPopulator.cpp
@@ -19,6 +19,7 @@
 #include "objectstore/BackendVFS.hpp"
 #include "objectstore/RootEntry.hpp"
 #include "objectstore/BackendPopulator.hpp"
+#include "common/utils/utils.hpp"
 
 namespace cta { namespace objectstore {
 
@@ -77,13 +78,13 @@ BackendPopulator::~BackendPopulator() throw() {
     m_lc.log(log::CRIT, "In BackendPopulator::~BackendPopulator(): error deleting agent (cta::exception::Exception). Backtrace follows.");
     m_lc.logBacktrace(log::ERR, ex.backtrace());
     // We have an exception (we should not), let's core dump.
-    *((int*)nullptr)=0;
+    cta::utils::segfault();
   } catch (std::exception & ex) {
     cta::log::ScopedParamContainer params(m_lc);
     params.add("exceptionWhat", ex.what());
     m_lc.log(log::CRIT, "In BackendPopulator::~BackendPopulator(): error deleting agent (std::exception).");
     // We have an exception (we should not), let's core dump.
-    *((int*)nullptr)=0;    
+    cta::utils::segfault();
   }
 }
 
diff --git a/objectstore/BackendRados.cpp b/objectstore/BackendRados.cpp
index dd4d39fb16e217459296bece36b1c9b28b73f614..2a8abfb75c0f25ec7d3c59e726dc068625c8c0a3 100644
--- a/objectstore/BackendRados.cpp
+++ b/objectstore/BackendRados.cpp
@@ -21,6 +21,7 @@
 #include "common/Timer.hpp"
 #include "common/threading/MutexLocker.hpp"
 #include "common/log/LogContext.hpp"
+#include "common/utils/utils.hpp"
 #include <rados/librados.hpp>
 #include <sys/syscall.h>
 #include <errno.h>
@@ -453,7 +454,7 @@ BackendRados::LockWatcher::~LockWatcher() {
     }, "In BackendRados::LockWatcher::~LockWatcher(): failed m_context.aio_unwatch()");
   } catch (cta::exception::Exception & ex) {
     // If we get an exception in a destructor, we are going to exit anyway, so better halt the process early.
-    *((int *) nullptr) = 0;
+    cta::utils::segfault();
   }
   completion->release();
   rtl.logIfNeeded("In BackendRados::LockWatcher::~LockWatcher(): m_context.aio_unwatch() call", name);
diff --git a/objectstore/Helpers.cpp b/objectstore/Helpers.cpp
index f0b770566cc81be48bc279c586133a3455d558f6..6eff98a143208124434afcc62528a40515e80633 100644
--- a/objectstore/Helpers.cpp
+++ b/objectstore/Helpers.cpp
@@ -669,7 +669,7 @@ void Helpers::registerRepackRequestToIndex(const std::string& vid, const std::st
   // First, try to get the address of of the repack index lockfree.
   try {
     repackIndexAddress = re.getRepackIndexAddress();
-  } catch (RootEntry::NotAllocated &){
+  } catch (cta::exception::Exception &){
     ScopedExclusiveLock rel(re);
     re.fetch();
     repackIndexAddress = re.addOrGetRepackIndexAndCommit(agentReference);
@@ -692,7 +692,7 @@ void Helpers::removeRepackRequestToIndex(const std::string& vid, Backend& backen
   // First, try to get the address of of the repack index lockfree.
   try {
     repackIndexAddress = re.getRepackIndexAddress();
-  } catch (RootEntry::NotAllocated &){
+  } catch (cta::exception::Exception &){
     // No repack index, nothing to do.
     return;
   }
diff --git a/objectstore/RepackRequest.cpp b/objectstore/RepackRequest.cpp
index bfbe311b1b17803aa25d9dc883b5c010234d5d0a..0a0bb02505c8e06d831ad49b49f3379e75fd3668 100644
--- a/objectstore/RepackRequest.cpp
+++ b/objectstore/RepackRequest.cpp
@@ -75,6 +75,7 @@ void RepackRequest::initialize() {
   m_payload.set_failedtoarchivebytes(0);
   m_payload.set_lastexpandedfseq(0);
   m_payload.set_is_expand_finished(false);
+  m_payload.set_is_expand_started(false);
   // This object is good to go (to storage)
   m_payloadInterpreted = true;
 }
@@ -162,6 +163,47 @@ void RepackRequest::setExpandFinished(const bool expandFinished){
   m_payload.set_is_expand_finished(expandFinished);
 }
 
+void RepackRequest::setExpandStarted(const bool expandStarted){
+  checkPayloadWritable();
+  m_payload.set_is_expand_started(expandStarted);
+}
+
+void RepackRequest::setTotalStats(const cta::SchedulerDatabase::RepackRequest::TotalStatsFiles& totalStatsFiles){
+  setTotalFileToRetrieve(totalStatsFiles.totalFilesToRetrieve);
+  setTotalFileToArchive(totalStatsFiles.totalFilesToArchive);
+  setTotalBytesToArchive(totalStatsFiles.totalBytesToArchive);
+  setTotalBytesToRetrieve(totalStatsFiles.totalBytesToRetrieve);
+}
+
+void RepackRequest::setStatus(){
+  checkPayloadWritable();
+  checkPayloadReadable();
+  
+  if(m_payload.is_expand_started()){
+    //The expansion of the Repack Request have started
+    if(m_payload.is_expand_finished()){
+      if( (m_payload.retrievedfiles() + m_payload.failedtoretrievefiles() >= m_payload.totalfilestoretrieve()) && (m_payload.archivedfiles() + m_payload.failedtoarchivefiles() >= m_payload.totalfilestoarchive()) ){
+        //We reached the end
+        if (m_payload.failedtoretrievefiles() || m_payload.failedtoarchivefiles()) {
+          //At least one retrieve or archive has failed
+          setStatus(common::dataStructures::RepackInfo::Status::Failed);
+        } else {
+          //No Failure, we are status Complete
+          setStatus(common::dataStructures::RepackInfo::Status::Complete);
+        }
+        return;
+      }
+    }
+    //Expand is finished or not, if we have retrieved files, we are in Running,
+    //else we are in starting
+    if(m_payload.retrievedfiles()){
+      setStatus(common::dataStructures::RepackInfo::Status::Running);
+    } else {
+      setStatus(common::dataStructures::RepackInfo::Status::Starting);
+    }
+  }
+}
+
 //------------------------------------------------------------------------------
 // RepackRequest::getExpandFinished()
 //------------------------------------------------------------------------------
@@ -276,8 +318,17 @@ void RepackRequest::setTotalFileToArchive(const uint64_t nbFilesToArchive){
 void RepackRequest::setTotalBytesToArchive(const uint64_t nbBytesToArchive) {
   checkPayloadWritable();
   m_payload.set_totalbytestoarchive(nbBytesToArchive);
-}
+    }
 
+cta::SchedulerDatabase::RepackRequest::TotalStatsFiles RepackRequest::getTotalStatsFile() {
+  checkPayloadReadable();
+  cta::SchedulerDatabase::RepackRequest::TotalStatsFiles ret;
+  ret.totalBytesToRetrieve = m_payload.totalbytestoretrieve();
+  ret.totalBytesToArchive = m_payload.totalbytestoarchive();
+  ret.totalFilesToRetrieve = m_payload.totalfilestoretrieve();
+  ret.totalFilesToArchive = m_payload.totalfilestoarchive();
+  return ret;
+}
 
 //------------------------------------------------------------------------------
 // RepackRequest::reportRetriveSuccesses()
@@ -302,6 +353,7 @@ void RepackRequest::reportRetriveSuccesses(SubrequestStatistics::List& retrieveS
     }
   }
   if (didUpdate) {
+    setStatus();
     m_payload.mutable_subrequests()->Clear();
     for (auto & p: pointerMap) p.second.serialize(*m_payload.mutable_subrequests()->Add());
   }
@@ -330,6 +382,7 @@ void RepackRequest::reportRetriveFailures(SubrequestStatistics::List& retrieveFa
     }
   }
   if (didUpdate) {
+    setStatus();
     m_payload.mutable_subrequests()->Clear();
     for (auto & p: pointerMap) p.second.serialize(*m_payload.mutable_subrequests()->Add());
   }
@@ -360,14 +413,7 @@ serializers::RepackRequestStatus RepackRequest::reportArchiveSuccesses(Subreques
     }
   }
   if (didUpdate) {
-    // Check whether we reached the end.
-    if (m_payload.archivedfiles() + m_payload.failedtoarchivefiles() >= m_payload.totalfilestoarchive()) {
-      if (m_payload.failedtoarchivefiles()) {
-        m_payload.set_status(serializers::RepackRequestStatus::RRS_Failed);
-      } else {
-        m_payload.set_status(serializers::RepackRequestStatus::RRS_Complete);
-      }
-    }
+    setStatus();
     m_payload.mutable_subrequests()->Clear();
     for (auto & p: pointerMap) p.second.serialize(*m_payload.mutable_subrequests()->Add());
   }
@@ -399,8 +445,7 @@ serializers::RepackRequestStatus RepackRequest::reportArchiveFailures(Subrequest
   }
   if (didUpdate) {
     // Check whether we reached the end.
-    if (m_payload.archivedfiles() + m_payload.failedtoarchivefiles() >= m_payload.totalfilestoarchive())
-      m_payload.set_status(serializers::RepackRequestStatus::RRS_Failed);
+    setStatus();
     m_payload.mutable_subrequests()->Clear();
     for (auto & p: pointerMap) p.second.serialize(*m_payload.mutable_subrequests()->Add());
   }
diff --git a/objectstore/RepackRequest.hpp b/objectstore/RepackRequest.hpp
index bc8de1d2b69e6f6fb56da5a0fc3443a0c127b51b..29b1d618aed8fc04ec7c88f5341134d9f348585f 100644
--- a/objectstore/RepackRequest.hpp
+++ b/objectstore/RepackRequest.hpp
@@ -23,6 +23,7 @@
 #include "common/dataStructures/RepackInfo.hpp"
 #include "common/log/TimingList.hpp"
 #include "common/Timer.hpp"
+#include "scheduler/SchedulerDatabase.hpp"
 
 namespace cta { namespace objectstore {
 
@@ -44,6 +45,14 @@ public:
   void setBufferURL(const std::string & bufferURL);
   void setExpandFinished(const bool expandFinished);
   bool isExpandFinished();
+  void setExpandStarted(const bool expandStarted);
+  void setTotalStats(const cta::SchedulerDatabase::RepackRequest::TotalStatsFiles& totalStatsFiles);
+  cta::SchedulerDatabase::RepackRequest::TotalStatsFiles getTotalStatsFile();
+  /**
+   * Automatically set the new status of the Repack Request
+   * regarding multiple parameters
+   */
+  void setStatus();
   // Sub request management
   struct SubrequestInfo {
     std::string address;
diff --git a/objectstore/RootEntry.cpp b/objectstore/RootEntry.cpp
index 6f67ce58394dae3bc42c47ea070fae9ebdf0aa69..91869db204155dddaf1ab0f633c9b00954bf14f4 100644
--- a/objectstore/RootEntry.cpp
+++ b/objectstore/RootEntry.cpp
@@ -740,7 +740,7 @@ std::string RootEntry::getRepackIndexAddress() {
       m_payload.repackindexpointer().address().size()) {
     return m_payload.repackindexpointer().address();
   }
-  throw NotAllocated("In RootEntry::getRepackIndexAddress: repack tape register not yet allocated");
+  throw cta::exception::Exception("In RootEntry::getRepackIndexAddress: repack tape register not yet allocated");
 }
 
 std::string RootEntry::addOrGetRepackIndexAndCommit(AgentReference& agentRef) {
@@ -748,7 +748,7 @@ std::string RootEntry::addOrGetRepackIndexAndCommit(AgentReference& agentRef) {
   // Check if the repack tape register exists
   try {
     return getRepackIndexAddress();
-  } catch (NotAllocated &) {
+  } catch (cta::exception::Exception &) {
     // TODO: this insertion method is much simpler than the ones used for other objects.
     // It implies the only dangling pointer situation we can get is the one where
     // the object does not exist.
diff --git a/objectstore/cta.proto b/objectstore/cta.proto
index fa14344739c77ce52e1b445369b9f735877345bc..9b8fefea134df0aab64d37438079363802422000 100644
--- a/objectstore/cta.proto
+++ b/objectstore/cta.proto
@@ -545,6 +545,7 @@ message RepackRequest {
   //is not finished. This boolean is used to indicate wether
   //the expansion of the RepackRequest is done or not
   required bool is_expand_finished = 11561;
+  required bool is_expand_started = 11562;
   repeated RepackSubRequestPointer subrequests = 11570;
 }
 
diff --git a/operations/tape/tape-config-generate b/operations/tape/tape-config-generate
new file mode 100755
index 0000000000000000000000000000000000000000..fcb5ff47998e6fe76b3e73c591a1ccab2e28fe0b
--- /dev/null
+++ b/operations/tape/tape-config-generate
@@ -0,0 +1,193 @@
+#!/usr/bin/perl -w
+#######################################################################
+#
+# This script will generate /etc/cta/TPCONFIG file with the data from
+# TOMS (Tape Operations Management System) URL:
+#
+# https://apex.cern.ch/pls/htmldb_castorns/f?p=toms_prod:250:163672298908022::NO::P250_TAPESERVER:HOSTNAME
+#
+# Vladimir Bahyl - 05/2019
+#
+#######################################################################
+
+use strict;
+use XML::DOM;
+use Sys::Hostname;
+use LWP::UserAgent;
+use LC::Check qw(file);
+
+#use Data::Dumper;
+
+my $today = localtime;
+
+my %TPCONFIG = ();
+my $hostname = '';
+
+my $tpconfigfile = '/etc/castor/TPCONFIG';
+my $tpconfig = "#######################################################################
+#
+# CTA Tape Server Configuration file
+#
+# This tape server is not configured.
+#
+#######################################################################
+#
+# Generated on $today by $0
+";
+
+my $changes = 0;
+
+($hostname = hostname()) =~ s/\.cern\.ch$//io;
+
+my $configUrl = 'https://apex.cern.ch/pls/htmldb_castorns/f?p=toms_prod:250:163672298908022::NO::P250_TAPESERVER:HOSTNAME';
+die ("$0: missing configuration URL") unless ($configUrl);
+$configUrl =~ s/HOSTNAME/$hostname/o;
+
+#
+# Fetch the data
+#
+print("$0: Fetching the data over HTTP from the Oracle APEX database ... please be patient ...\n");
+%TPCONFIG = &GetData($configUrl);
+
+#
+# Prepare the TPCONFIG file
+#
+my $i = 0;
+while (%TPCONFIG and defined($TPCONFIG{$i}{'tapeserver'}) and (lc($TPCONFIG{$i}{'tapeserver'}) eq lc($hostname))) {
+  $tpconfig = "#######################################################################
+#
+# CTA Tape Server Configuration file
+#
+# unit      device    system                control
+# name      group     device                method
+
+" if ($i == 0);
+
+  $tpconfig .= "$TPCONFIG{$i}{'tapedrive'}    $TPCONFIG{$i}{'devicegroup'}    $TPCONFIG{$i}{'unixdevice'}    $TPCONFIG{$i}{'controlmethod'}
+
+# Tape Drive Comment: $TPCONFIG{$i}{'tapedrivecomment'}
+# Tape Service Comment: $TPCONFIG{$i}{'tapeservicecomment'}
+# Modified by: $TPCONFIG{$i}{'modifuser'}
+# Modify date: $TPCONFIG{$i}{'modifdate'}
+
+";
+  $i++;
+}
+
+$tpconfig .= "#
+#######################################################################
+#
+# Generated on $today by $0
+" if (%TPCONFIG and (lc($TPCONFIG{0}{'tapeserver'}) eq lc($hostname)));
+
+# Change the TPCONFIG location if comment mentions CTA
+$tpconfigfile = '/etc/cta/TPCONFIG' if (%TPCONFIG and (defined $TPCONFIG{0}{'tapeservicecomment'}) and ($TPCONFIG{0}{'tapeservicecomment'} =~ /CTA/oi));
+
+#
+# Configure TPCONFIG and SSI files
+#
+$changes += &UpdateFile($tpconfigfile, $tpconfig);
+
+LC::Check::link('/etc/TPCONFIG', $tpconfigfile,
+  backup  => '.old',
+  nocheck => 1,
+  force   => 1
+);
+
+##########################################################################
+sub GetData {
+##########################################################################
+  my ($url) = @_;
+
+  my %TPCONFIG = ();
+
+  my $xmlParser = new XML::DOM::Parser;
+
+  # Download the XML formated configuration data
+  # Use cookies because of APEX (otherwise, nothing will be downloaded; redirection will not work)
+  my $UserAgent = LWP::UserAgent->new;
+  $UserAgent->cookie_jar({ file => undef });
+  my $xml = $UserAgent->get($url);
+
+  if (defined ($xml->content)) {
+    if ($xml->content =~/TAPESERVER/oi) {
+      my $xmlDoc = $xmlParser->parse($xml->content);
+
+      # pcitpdp39 ~ > lynx -source "http://oraweb.cern.ch/pls/cdbsqldev/web.show_tpconfig?p_tapeserver=tpsrv027&p_output=xml"
+      # <?xml version = '1.0'?>
+      # <TPCONFIGSEARCHLIST> <TAPESERVER NAME="tpsrv027" TAPEDRIVE="994B53A6" DEVICEGROUP="994BR5" UNIXDEVICE="/dev/nst0" DENSITY="200G" COMPRESSION="Y" INITSTATUS="DOWN" CONTROLMETHOD="acs0,3,10,6" MODEL="9940" ROBOTHOST="sunstk62" /> </TPCONFIGSEARCHLIST>
+
+      for my $i (0 .. ($xmlDoc->getElementsByTagName("TAPESERVER")->getLength())-1) {
+        $TPCONFIG{$i}{'tapeserver'}         = $xmlDoc->getElementsByTagName("TAPESERVER")->item($i)->getAttribute("NAME");
+        $TPCONFIG{$i}{'tapedrive'}          = $xmlDoc->getElementsByTagName("TAPESERVER")->item($i)->getAttribute("TAPEDRIVE");
+        $TPCONFIG{$i}{'devicegroup'}        = $xmlDoc->getElementsByTagName("TAPESERVER")->item($i)->getAttribute("DEVICEGROUP");
+        $TPCONFIG{$i}{'unixdevice'}         = $xmlDoc->getElementsByTagName("TAPESERVER")->item($i)->getAttribute("UNIXDEVICE");
+        $TPCONFIG{$i}{'initstatus'}         = lc($xmlDoc->getElementsByTagName("TAPESERVER")->item($i)->getAttribute("INITSTATUS"));
+        $TPCONFIG{$i}{'controlmethod'}      = $xmlDoc->getElementsByTagName("TAPESERVER")->item($i)->getAttribute("CONTROLMETHOD");
+        $TPCONFIG{$i}{'modifdate'}          = $xmlDoc->getElementsByTagName("TAPESERVER")->item($i)->getAttribute("MODIFDATE");
+        $TPCONFIG{$i}{'modifuser'}          = $xmlDoc->getElementsByTagName("TAPESERVER")->item($i)->getAttribute("MODIFUSER");
+        $TPCONFIG{$i}{'tapedrivecomment'}   = $xmlDoc->getElementsByTagName("TAPESERVER")->item($i)->getAttribute("TAPEDRIVECOMMENT");
+        $TPCONFIG{$i}{'tapeservicecomment'} = $xmlDoc->getElementsByTagName("TAPESERVER")->item($i)->getAttribute("TAPESERVICECOMMENT");
+
+        warn("$0: database entry nr. ".($i+1)." missing tape server hostname\n")    unless ($TPCONFIG{$i}{'tapeserver'});
+        warn("$0: database entry nr. ".($i+1)." missing tape drive name\n")         unless ($TPCONFIG{$i}{'tapedrive'});
+        warn("$0: database entry nr. ".($i+1)." missing device group name\n")       unless ($TPCONFIG{$i}{'devicegroup'});
+        warn("$0: database entry nr. ".($i+1)." missing unix device\n")             unless ($TPCONFIG{$i}{'unixdevice'});
+        warn("$0: database entry nr. ".($i+1)." missing init status\n")             unless ($TPCONFIG{$i}{'initstatus'});
+        warn("$0: database entry nr. ".($i+1)." missing control method\n")          unless ($TPCONFIG{$i}{'controlmethod'});
+        warn("$0: database entry nr. ".($i+1)." missing the modification date\n")   unless ($TPCONFIG{$i}{'modifdate'});
+        warn("$0: database entry nr. ".($i+1)." missing user name\n")               unless ($TPCONFIG{$i}{'modifuser'});
+        print("$0: database entry nr. ".($i+1)." no tape service comment\n")        unless ($TPCONFIG{$i}{'tapeservicecomment'});
+        print("$0: database entry nr. ".($i+1)." no tape drive comment\n")          unless ($TPCONFIG{$i}{'tapedrivecomment'});
+      }
+
+      $xmlDoc->dispose;
+    } else {
+      warn("$0: URL $url is not returning any usable data for $hostname. This tape server will not be configured. Please check whether there is a tape drive assigned to this tape server.\n");
+    }
+  } else {
+    warn("$0: URL $url doesn't seem to work. There could be a problem with the Web server or the Oracle APEX database server.\n");
+  }
+
+  return %TPCONFIG;
+}
+
+##########################################################################
+sub UpdateFile {
+##########################################################################
+  my ($filename, $newcontent) = @_;
+
+  my $changes = 0;
+
+  if ((-f $filename) and (-r $filename) and (-s $filename)) {
+      # Check the content of the file and correct it if there are some differences
+      $changes += LC::Check::file($filename,
+      source => $filename,
+      owner  => 0,
+      group  => 0,
+      mode   => 0644,
+      backup => '.old',
+      code   => sub {
+        my($oldcontent) = @_;
+        return() unless $oldcontent;
+
+        (my $oldfile = $oldcontent) =~ s/^#.*$//gim; # remove lines with comments
+        $oldfile =~ s/^\s*$//gim;                    # remove empty lines
+
+        (my $newfile = $newcontent) =~ s/^#.*$//gim; # remove lines with comments
+        $newfile =~ s/^\s*$//gim;                    # remove empty lines
+
+        $oldcontent = $newcontent unless ($oldfile eq $newfile);
+
+        return($oldcontent);
+      }
+    );
+  } else {
+    # The file is missing, create a new one
+    $changes += LC::File::file_contents($filename, $newcontent);
+    print "$0: created new $filename\n";
+  }
+  die ("$0: error modifying $filename\n") unless (defined($changes));
+
+  return $changes;
+}
diff --git a/operations/tape/tape-devices-namer b/operations/tape/tape-devices-namer
new file mode 100755
index 0000000000000000000000000000000000000000..708bea830bd59e1d3f8d4002363092e72fb6d892
--- /dev/null
+++ b/operations/tape/tape-devices-namer
@@ -0,0 +1,227 @@
+#!/usr/bin/python
+
+"""
+This script creates links to tape and medium changer devices.
+The association between tape and smc device is made based on
+the serial numbers stored in the TOMS DB.
+"""
+
+import re
+import os
+import sys
+import socket 
+import pprint
+import urllib2
+import optparse
+import cookielib
+import subprocess 
+pp = pprint.PrettyPrinter(width=200)
+
+#------------------------------------------------------------
+def mklink(dev, sn, drivename, type):
+    if not options.noaction and drivename is not None:
+        link = '/dev/' + type + '_' + drivename
+        subprocess.Popen(['/bin/ln', '-f',  '-s', dev, link]).wait()
+        print 'Created link', link
+    else:
+        print 'Cannot create link to ' + dev
+        print 'Drivename for serial number ' + sn + ' not found'
+
+#------------------------------------------------------------
+def fix_mismatch(mm_tape_dev, toms_drives, hostname):
+    #this fucntions assumes that there is only one mismatch,
+    #i.e. only one tape device with S/N not found in TOMS
+    #and only one drives in TOSM with S/N not found in the server.
+    l = []
+    cj = cookielib.CookieJar()
+    opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cj))
+    for d in toms_drives:
+        if d['match'] == 0:
+            #assigning drivename to the mismatched tape device 
+            mm_tape_dev['drivename'] = d['drivename']
+            #fixing the S/N in TOMS
+            tomsurl = 'http://castortapeweb.cern.ch/cgi-bin/serial-nr-update.cgi?tapedrive=' + d['drivename'] + '&tapeserver=' + hostname + '&serialnumber=' + mm_tape_dev['sn']
+            if options.debug: print 'Opening', tomsurl
+            try:
+                urlfh = opener.open(tomsurl)
+            except:
+                print 'Cannot open ' + tomsurl
+                
+            
+#------------------------------------------------------------
+#main
+#------------------------------------------------------------
+
+# options ---------------------------------------------------
+usage = "usage: %prog [options]"
+parser = optparse.OptionParser(usage)
+parser.add_option("-d", "--debug", action="store_true", dest="debug", help="print debug messages")
+parser.add_option("--noaction", action="store_true", dest="noaction", help="do nothing")
+(options, args) = parser.parse_args()
+
+tape_devices = []
+smc_devices = []
+
+# find tape and smc devices
+if options.debug: print 'Searching tape devices'
+try:
+    p = subprocess.Popen(['/usr/bin/lsscsi', '-g'], stdout=subprocess.PIPE)
+    p.wait()
+except:
+    print 'Cannot run lsscsi. Exit.'
+    sys.exit(0)
+    
+for line in p.stdout:
+    fields = line.split() 
+    scsi_address = fields[0][1:-1]
+    type = fields[1]
+    scsi_generic = fields.pop()
+    scsi_tape = fields.pop()
+    if type == 'tape':
+        tape_devices.append({'scsi_address' : scsi_address, 'scsi_generic' : scsi_generic, 'scsi_tape' : scsi_tape, 'sn' : None, 'drivename' : None})
+    if type == 'mediumx':
+        smc_devices.append({'scsi_address' : scsi_address, 'scsi_generic' : scsi_generic, 'scsi_tape' : scsi_tape, 'sn' : None, 'drivename' : None})
+
+ntpdev=len(tape_devices)
+
+if options.debug:
+    print 'tape_devices:'
+    pp.pprint(tape_devices)
+    print 'smc_devices:'
+    pp.pprint(smc_devices)
+
+# associate tape and smc devices
+if options.debug: print 'Coupling tape and smc devices (if any)'
+pairs = []
+for tapedev in tape_devices:
+    for smcdev in smc_devices:
+        if tapedev['scsi_address'][:-2] == smcdev['scsi_address'][:-2]:
+            pairs.append([tapedev, smcdev])
+if options.debug:
+    print 'pairs:'
+    pp.pprint(pairs)
+
+if len(tape_devices)>len(smc_devices) and len(smc_devices)>0:
+    print 'Number of control paths lower that number of drives'
+    sys.exit(0)
+
+
+# find the serial number of the tape device
+# sg_inq will not work if the /dev/sgX device is not reachable
+# sg_inq will not work if the /dev/nstY device is being used
+# run sg_inq against the nst dev so that if it is already being used we exit
+if options.debug: print 'Reading serial numbers from tape devices'
+
+for tapedev in tape_devices:
+    tapedn = '/dev/nst'+tapedev['scsi_tape'][-1]
+    p = subprocess.Popen(['/usr/bin/sg_inq', tapedn], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+    if p.wait() != 0:
+        print 'Cannot run sg_inq on ' +  tapedn + '. Exit'
+        sys.exit(0)
+    else:
+        for line in p.stdout:
+            #reg = re.search('(?<=Unit serial number: )(\d+)', line)
+            if re.search('Unit serial number', line):
+                l = line.split(':')
+                tapedev['sn'] = l[1][1:-1]
+
+    if tapedev['sn'] is None:
+        print 'Could not extract the serial number from the output of sg_inq ' + tapedn
+        sys.exit(0)
+                
+if options.debug:
+    print 'tape_devices:'
+    pp.pprint(tape_devices)
+
+
+# search the drive names in toms by serial number
+toms_drives = []
+if options.debug: print 'Looking into TOMS for drive names'
+hostname = socket.gethostname().split('.')[0]
+tomsurl =  'https://apex.cern.ch/pls/htmldb_castorns/f?p=toms_prod:250:::NO::P250_TAPESERVER:' + hostname
+if options.debug: print 'Opening', tomsurl
+
+cj = cookielib.CookieJar()
+opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cj))
+
+try:
+    urlfh = opener.open(tomsurl)
+except:
+    print 'Cannot open ' + tomsurl
+    sys.exit(0)
+
+for line in urlfh:
+
+    if options.debug: print line
+
+    if not re.search('TAPESERVER', line): continue
+
+    drivename, serialnumber = '', ''
+
+    l = line.split()
+    for item in l:
+        g = item.split('=')
+        if g[0] == 'CURRENTSERIALNR': serialnumber =  g[1][1:-1]
+        if g[0] == 'TAPEDRIVE': drivename =  g[1][1:-1]
+
+    if drivename == '':
+        print 'drive name for host ' + hostname + ' not found in TOMS'
+        sys.exit(0)
+
+    if serialnumber  == '':
+        print 'Serial number for drive', drivename, 'not found in TOMS'
+        #here we don't exit, in case of a signle mismatch we update the s/n
+
+    toms_drives.append({'drivename' : drivename, 'sn': serialnumber, 'match' : 0})
+        
+    for tapedev in tape_devices:
+        if tapedev['sn'] == serialnumber:
+            tapedev['drivename'] = drivename
+            for d in toms_drives:
+                if d['drivename'] == drivename: d['match'] = 1
+
+if options.debug:
+    print 'tape_devices:'
+    pp.pprint(tape_devices)
+    print 'toms_drives:'
+    pp.pprint(toms_drives)
+
+
+#Check how many S/N are missing.
+#1. If there is only one assume that the drive has been replaced and update the S/N in TOMS.
+#2. If there are more than one the script does nothing (new or changed drives/devices
+#   will not be configured (link not created).
+
+devs_mm_sn = 0
+mm_tape_dev = None
+for t in tape_devices:
+    if t['drivename'] is None:
+        devs_mm_sn += 1
+        mm_tape_dev = t
+
+if devs_mm_sn == 1:
+    print 'One S/N mismatch. Going to fix S/N in TOMS'
+    fix_mismatch(mm_tape_dev, toms_drives, hostname)
+elif devs_mm_sn == 0:
+    if options.debug: print 'No S/N mismatches'
+else:
+    if options.debug: print 'Too many S/N mismatches'
+    
+
+# created links
+if pairs == []:
+    # this is a SUN tape server
+    for tapedev in tape_devices:
+        tapedn = '/dev/nst'+tapedev['scsi_tape'][-1]
+        mklink(tapedn, tapedev['sn'], tapedev['drivename'], 'tape')
+else:
+    #this is a IBM tape server
+    for pair in pairs:
+        tapedev = pair[0]
+        tapedn = '/dev/nst'+tapedev['scsi_tape'][-1]
+        mklink(tapedn, tapedev['sn'], tapedev['drivename'], 'tape')
+        smcdev = pair[1]
+        mklink(smcdev['scsi_generic'], tapedev['sn'], tapedev['drivename'], 'smc')
+
+
+
diff --git a/rdbms/CMakeLists.txt b/rdbms/CMakeLists.txt
index 8ff00d676c4fefcf472fb174c61b633ff7725c20..c6e926561262358a0dc6080292cd491f74d97f8e 100644
--- a/rdbms/CMakeLists.txt
+++ b/rdbms/CMakeLists.txt
@@ -43,7 +43,6 @@ install (TARGETS ctardbms DESTINATION usr/${CMAKE_INSTALL_LIBDIR})
 
 set(RDBMS_UNIT_TESTS_LIB_SRC_FILES
   ConnPoolTest.cpp
-  ConnTest.cpp
   LoginTest.cpp
   RdbmsTest.cpp
   StmtPoolTest.cpp)
@@ -72,6 +71,20 @@ target_link_libraries (ctainmemoryconnunittests
 
 install (TARGETS ctainmemoryconnunittests DESTINATION usr/${CMAKE_INSTALL_LIBDIR})
 
+set(IN_MEMORY_STMT_UNIT_TESTS_LIB_SRC_FILES
+  StmtTest.cpp
+  InMemoryVersionOfStmtTest.cpp)
+
+add_library (ctainmemorystmtunittests SHARED
+  ${IN_MEMORY_STMT_UNIT_TESTS_LIB_SRC_FILES})
+set_property(TARGET ctainmemorystmtunittests PROPERTY SOVERSION "${CTA_SOVERSION}")
+set_property(TARGET ctainmemorystmtunittests PROPERTY   VERSION "${CTA_LIBVERSION}")
+
+target_link_libraries (ctainmemorystmtunittests
+  ctardbms)
+
+install (TARGETS ctainmemorystmtunittests DESTINATION usr/${CMAKE_INSTALL_LIBDIR})
+
 set (DBCONFIG_CONN_UNIT_TESTS_LIB_SRC_FILES
   ConnTest.cpp
   DbConfigVersionOfConnTest.cpp)
@@ -85,3 +98,17 @@ target_link_libraries (ctadbconfigconnunittests
   ctardbms)
 
 install (TARGETS ctadbconfigconnunittests DESTINATION usr/${CMAKE_INSTALL_LIBDIR})
+
+set (DBCONFIG_STMT_UNIT_TESTS_LIB_SRC_FILES
+  StmtTest.cpp
+  DbConfigVersionOfStmtTest.cpp)
+
+add_library (ctadbconfigstmtunittests SHARED
+  ${DBCONFIG_STMT_UNIT_TESTS_LIB_SRC_FILES})
+set_property(TARGET ctadbconfigstmtunittests PROPERTY SOVERSION "${CTA_SOVERSION}")
+set_property(TARGET ctadbconfigstmtunittests PROPERTY   VERSION "${CTA_LIBVERSION}")
+
+target_link_libraries (ctadbconfigstmtunittests
+  ctardbms)
+
+install (TARGETS ctadbconfigstmtunittests DESTINATION usr/${CMAKE_INSTALL_LIBDIR})
diff --git a/rdbms/DbConfigVersionOfStmtTest.cpp b/rdbms/DbConfigVersionOfStmtTest.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..f274f726d11a9796ccbb72e650b6230f628ffc36
--- /dev/null
+++ b/rdbms/DbConfigVersionOfStmtTest.cpp
@@ -0,0 +1,56 @@
+/*
+ * 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 "rdbms/StmtTest.hpp"
+#include "tests/RdbmsUnitTestsCmdLineArgs.hpp"
+
+namespace {
+
+/**
+ * Creates Login objects from a database configuration file passed on the
+ * command-line to the unit-tests program.
+ */
+class DbConfigFileVersionOfStmtTestLoginFactory: public cta::rdbms::LoginFactory {
+public:
+
+  /**
+   * Destructor.
+   */
+  virtual ~DbConfigFileVersionOfStmtTestLoginFactory() {
+  }
+
+  /**
+   * Returns a newly created Login object.
+   *
+   * @return A newly created Login object.
+   */
+  virtual cta::rdbms::Login create() {
+    return cta::rdbms::Login::parseFile(g_cmdLineArgs.dbConfigPath);
+  }
+}; // class OracleLoginFactory
+
+DbConfigFileVersionOfStmtTestLoginFactory g_dbConfigFileVersionOfStmtTestLoginFactory;
+
+} // anonymous namespace
+
+namespace unitTests {
+
+INSTANTIATE_TEST_CASE_P(DbConfigFile, cta_rdbms_StmtTest,
+  ::testing::Values(dynamic_cast<cta::rdbms::LoginFactory*>(&g_dbConfigFileVersionOfStmtTestLoginFactory)));
+
+} // namespace unitTests
diff --git a/rdbms/InMemoryVersionOfStmtTest.cpp b/rdbms/InMemoryVersionOfStmtTest.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..46f119449e9c21beb6bbc21e3b9e2f46d45b5791
--- /dev/null
+++ b/rdbms/InMemoryVersionOfStmtTest.cpp
@@ -0,0 +1,54 @@
+/*
+ * 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 "rdbms/StmtTest.hpp"
+
+namespace unitTests {
+
+namespace {
+
+/**
+ * Creates Login objects for in-memory catalogue databases.
+ */
+class RdbmsInMemoryLoginFactory: public cta::rdbms::LoginFactory {
+public:
+
+  /**
+   * Destructor.
+   */
+  virtual ~RdbmsInMemoryLoginFactory() {
+  }
+
+  /**
+   * Returns a newly created Login object.
+   *
+   * @return A newly created Login object.
+   */
+  virtual cta::rdbms::Login create() {
+    return cta::rdbms::Login(cta::rdbms::Login::DBTYPE_IN_MEMORY, "", "", "", "", 0);
+  }
+}; // class RdbmsInMemoryLoginFactory
+
+RdbmsInMemoryLoginFactory g_inMemoryLoginFactory;
+
+} // anonymous namespace
+
+INSTANTIATE_TEST_CASE_P(InMemory, cta_rdbms_StmtTest,
+  ::testing::Values(dynamic_cast<cta::rdbms::LoginFactory*>(&g_inMemoryLoginFactory)));
+
+} // namespace unitTests
diff --git a/rdbms/Rset.cpp b/rdbms/Rset.cpp
index 065afe071ad04a65ac5b393d8f2aa1b8e373e5e5..f811cb387357b10371aed2aac73cb8b8163d51f9 100644
--- a/rdbms/Rset.cpp
+++ b/rdbms/Rset.cpp
@@ -192,5 +192,36 @@ optional<uint64_t> Rset::columnOptionalUint64(const std::string &colName) const
   return m_impl->columnOptionalUint64(colName);
 }
 
+//------------------------------------------------------------------------------
+// columnDouble
+//------------------------------------------------------------------------------
+double Rset::columnDouble(const std::string &colName) const {
+  try {
+    if(nullptr == m_impl) {
+      throw exception::Exception("This result set is invalid");
+    }
+
+    const optional<double> col = columnOptionalDouble(colName);
+    if(col) {
+      return col.value();
+    } else {
+      throw NullDbValue(std::string("Database column ") + colName + " contains a null value");
+    }
+  } catch(exception::Exception &ex) {
+    throw exception::Exception(std::string(__FUNCTION__) + " failed: " + ex.getMessage().str());
+  }
+}
+
+//------------------------------------------------------------------------------
+// columnOptionalDouble
+//------------------------------------------------------------------------------
+optional<double> Rset::columnOptionalDouble(const std::string &colName) const {
+  if(nullptr == m_impl) {
+    throw exception::Exception(std::string(__FUNCTION__) + " failed: "
+      "This result set is invalid");
+  }
+  return m_impl->columnOptionalDouble(colName);
+}
+
 } // namespace rdbms
 } // namespace cta
diff --git a/rdbms/Rset.hpp b/rdbms/Rset.hpp
index 12818d2747f22cb2ddda43321046c081d0ef096c..cbf17fd856d4fee550a1e1b335f648170beb1707 100644
--- a/rdbms/Rset.hpp
+++ b/rdbms/Rset.hpp
@@ -166,6 +166,27 @@ public:
    */
   optional<bool> columnOptionalBool(const std::string &colName) const;
 
+  /**
+   * Returns the value of the specified column as a double.
+   *
+   * This method will throw an exception if the value of the specified column
+   * is nullptr.
+   *
+   * @param colName The name of the column.
+   * @return The value of the specified column.
+   */
+  double columnDouble(const std::string &colName) const;
+
+  /**
+   * Returns the value of the specified column as a double.
+   *
+   * 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<double> columnOptionalDouble(const std::string &colName) const;
+
 private:
 
   /**
diff --git a/rdbms/Stmt.cpp b/rdbms/Stmt.cpp
index aa99fe1c5d247a1ceddc69cb46720fe15cade972..0069bbf3b0343c03a1ce3e34335ca0db818031c0 100644
--- a/rdbms/Stmt.cpp
+++ b/rdbms/Stmt.cpp
@@ -128,6 +128,28 @@ void Stmt::bindOptionalUint64(const std::string &paramName, const optional<uint6
   }
 }
 
+//-----------------------------------------------------------------------------
+// bindDouble
+//-----------------------------------------------------------------------------
+void Stmt::bindDouble(const std::string &paramName, const double paramValue) {
+  if(nullptr != m_stmt) {
+    return m_stmt->bindDouble(paramName, paramValue);
+  } else {
+    throw exception::Exception(std::string(__FUNCTION__) + " failed: Stmt does not contain a cached statement");
+  }
+}
+
+//-----------------------------------------------------------------------------
+// bindOptionalDouble
+//-----------------------------------------------------------------------------
+void Stmt::bindOptionalDouble(const std::string &paramName, const optional<double> &paramValue) {
+  if(nullptr != m_stmt) {
+    return m_stmt->bindOptionalDouble(paramName, paramValue);
+  } else {
+    throw exception::Exception(std::string(__FUNCTION__) + " failed: Stmt does not contain a cached statement");
+  }
+}
+
 //-----------------------------------------------------------------------------
 // bindBool
 //-----------------------------------------------------------------------------
diff --git a/rdbms/Stmt.hpp b/rdbms/Stmt.hpp
index cc4f406781e32a0f5156f0e058ee9c10c3f00855..5a3e7a6076b9192fbc17d68967437500723a816b 100644
--- a/rdbms/Stmt.hpp
+++ b/rdbms/Stmt.hpp
@@ -119,6 +119,22 @@ public:
    */
   void bindOptionalUint64(const std::string &paramName, const optional<uint64_t> &paramValue);
 
+  /**
+   * Binds an SQL parameter.
+   *
+   * @param paramName The name of the parameter.
+   * @param paramValue The value to be bound.
+   */
+  void bindDouble(const std::string &paramName, const double paramValue);
+
+  /**
+   * Binds an SQL parameter.
+   *
+   * @param paramName The name of the parameter.
+   * @param paramValue The value to be bound.
+   */
+  void bindOptionalDouble(const std::string &paramName, const optional<double> &paramValue);
+
   /**
    * Binds an SQL parameter.
    *
diff --git a/rdbms/StmtTest.cpp b/rdbms/StmtTest.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..0a09095fdfe2f42b17dd1da6f85bb9d823362ace
--- /dev/null
+++ b/rdbms/StmtTest.cpp
@@ -0,0 +1,390 @@
+/*
+ * 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 "common/make_unique.hpp"
+#include "common/utils/utils.hpp"
+#include "rdbms/ConnPool.hpp"
+#include "rdbms/StmtTest.hpp"
+
+#include <gtest/gtest.h>
+
+namespace unitTests {
+
+//------------------------------------------------------------------------------
+// Setup
+//------------------------------------------------------------------------------
+void cta_rdbms_StmtTest::SetUp() {
+  using namespace cta::rdbms;
+
+  if(!m_connPool) {
+    m_login = GetParam()->create();
+    const uint64_t maxNbConns = 1;
+    m_connPool = cta::make_unique<ConnPool>(m_login, maxNbConns);
+  }
+
+  m_conn = m_connPool->getConn();
+  ASSERT_EQ(AutocommitMode::AUTOCOMMIT_ON, m_conn.getAutocommitMode());
+
+  try {
+    m_conn.executeNonQuery("DROP TABLE STMT_TEST");
+  } catch(...) {
+    // Do nothing
+  }
+
+  const std::string createTableSql = getCreateStmtTestTableSql();
+  m_conn.executeNonQuery(createTableSql);
+}
+
+//------------------------------------------------------------------------------
+// getCreateStmtTestTableSql
+//------------------------------------------------------------------------------
+std::string cta_rdbms_StmtTest::getCreateStmtTestTableSql() {
+  using namespace cta;
+  using namespace cta::rdbms;
+
+  try {
+    std::string sql =
+      "CREATE TABLE STMT_TEST("
+        "DOUBLE_COL FLOAT,"
+        "UINT64_COL NUMERIC(20, 0),"
+        "STRING_COL VARCHAR(100),"
+        "BOOL_COL CHAR(1)"
+      ")";
+
+    switch(m_login.dbType) {
+    case Login::DBTYPE_IN_MEMORY:
+      break;
+    case Login::DBTYPE_ORACLE:
+      utils::searchAndReplace(sql, "VARCHAR", "VARCHAR2");
+      break;
+    case Login::DBTYPE_SQLITE:
+      break;
+    case Login::DBTYPE_MYSQL:
+      break;
+    case Login::DBTYPE_POSTGRESQL:
+      break;
+    case Login::DBTYPE_NONE:
+      {
+        throw exception::Exception("Cannot create SQL for database type DBTYPE_NONE");
+      }
+    default:
+      {
+        std::ostringstream msg;
+        msg << "Unknown database type: intVal=" << m_login.dbType;
+        throw exception::Exception(msg.str());
+      }
+    }
+
+    return sql;
+  } catch(exception::Exception &ex) {
+    std::ostringstream msg;
+    msg << __FUNCTION__ << " failed: " << ex.getMessage().str();
+    ex.getMessage().str(msg.str());
+    throw ex;
+  }
+}
+
+//------------------------------------------------------------------------------
+// TearDown
+//------------------------------------------------------------------------------
+void cta_rdbms_StmtTest::TearDown() {
+  using namespace cta::rdbms;
+  try {
+    m_conn.executeNonQuery("DROP TABLE STMT_TEST");
+  } catch(...) {
+    // Do nothing
+  }
+}
+
+TEST_P(cta_rdbms_StmtTest, insert_with_bindDouble) {
+  using namespace cta::rdbms;
+
+  const double insertValue = 1.234;
+
+  // Insert a row into the test table
+  {
+    const char *const sql =
+      "INSERT INTO STMT_TEST("
+        "DOUBLE_COL) "
+      "VALUES("
+        ":DOUBLE_COL)";
+    auto stmt = m_conn.createStmt(sql);
+    stmt.bindDouble(":DOUBLE_COL", insertValue);
+    stmt.executeNonQuery();
+  }
+
+  // Select the row back from the table
+  {
+    const char *const sql =
+      "SELECT "
+        "DOUBLE_COL AS DOUBLE_COL "
+      "FROM "
+        "STMT_TEST";
+    auto stmt = m_conn.createStmt(sql);
+    auto rset = stmt.executeQuery();
+    ASSERT_TRUE(rset.next());
+
+    const auto selectValue = rset.columnOptionalDouble("DOUBLE_COL");
+
+    ASSERT_TRUE((bool)selectValue);
+
+    const double diff = insertValue - selectValue.value();
+    ASSERT_TRUE(0.000001 > diff);
+
+    ASSERT_FALSE(rset.next());
+  }
+}
+
+TEST_P(cta_rdbms_StmtTest, insert_with_bindUint64) {
+  using namespace cta::rdbms;
+
+  const uint64_t insertValue = 1234;
+
+  // Insert a row into the test table
+  {
+    const char *const sql =
+      "INSERT INTO STMT_TEST("
+        "UINT64_COL) "
+      "VALUES("
+        ":UINT64_COL)";
+    auto stmt = m_conn.createStmt(sql);
+    stmt.bindDouble(":UINT64_COL", insertValue);
+    stmt.executeNonQuery();
+  }
+
+  // Select the row back from the table
+  {
+    const char *const sql =
+      "SELECT "
+        "UINT64_COL AS UINT64_COL "
+      "FROM "
+        "STMT_TEST";
+    auto stmt = m_conn.createStmt(sql);
+    auto rset = stmt.executeQuery();
+    ASSERT_TRUE(rset.next());
+
+    const auto selectValue = rset.columnOptionalDouble("UINT64_COL");
+
+    ASSERT_TRUE((bool)selectValue);
+
+    ASSERT_EQ(insertValue,selectValue.value());
+
+    ASSERT_FALSE(rset.next());
+  }
+}
+
+TEST_P(cta_rdbms_StmtTest, insert_with_bindUint64_2_pow_54_minus_2) {
+  using namespace cta::rdbms;
+
+  // The MySql support in CTA cannot store an unsigned integer greater than
+  // 2^54-2
+  const uint64_t insertValue = 18014398509481982;
+
+  // Insert a row into the test table
+  {
+    const char *const sql =
+      "INSERT INTO STMT_TEST("
+        "UINT64_COL) "
+      "VALUES("
+        ":UINT64_COL)";
+    auto stmt = m_conn.createStmt(sql);
+    stmt.bindUint64(":UINT64_COL", insertValue);
+    stmt.executeNonQuery();
+  }
+
+  // Select the row back from the table
+  {
+    const char *const sql =
+      "SELECT "
+        "UINT64_COL AS UINT64_COL "
+      "FROM "
+        "STMT_TEST";
+    auto stmt = m_conn.createStmt(sql);
+    auto rset = stmt.executeQuery();
+    ASSERT_TRUE(rset.next());
+
+    const auto selectValue = rset.columnOptionalUint64("UINT64_COL");
+
+    ASSERT_TRUE((bool)selectValue);
+
+    ASSERT_EQ(insertValue,selectValue.value());
+
+    ASSERT_FALSE(rset.next());
+  }
+}
+
+TEST_P(cta_rdbms_StmtTest, insert_with_bindUint64_2_pow_64_minus_1_not_mysql) {
+  using namespace cta::rdbms;
+
+  if(m_login.dbType == Login::DBTYPE_MYSQL) {
+    return;
+  }
+
+  // The MySql support in CTA cannot store an unsigned integer greater than
+  // 2^54-2
+  const uint64_t insertValue = 18446744073709551615U;
+
+  // Insert a row into the test table
+  {
+    const char *const sql =
+      "INSERT INTO STMT_TEST("
+        "UINT64_COL) "
+      "VALUES("
+        ":UINT64_COL)";
+    auto stmt = m_conn.createStmt(sql);
+    stmt.bindUint64(":UINT64_COL", insertValue);
+    stmt.executeNonQuery();
+  }
+
+  // Select the row back from the table
+  {
+    const char *const sql =
+      "SELECT "
+        "UINT64_COL AS UINT64_COL "
+      "FROM "
+        "STMT_TEST";
+    auto stmt = m_conn.createStmt(sql);
+    auto rset = stmt.executeQuery();
+    ASSERT_TRUE(rset.next());
+
+    const auto selectValue = rset.columnOptionalUint64("UINT64_COL");
+
+    ASSERT_TRUE((bool)selectValue);
+
+    ASSERT_EQ(insertValue,selectValue.value());
+
+    ASSERT_FALSE(rset.next());
+  }
+}
+
+TEST_P(cta_rdbms_StmtTest, insert_with_bindString) {
+  using namespace cta::rdbms;
+
+  const std::string insertValue = "value";
+
+  // Insert a row into the test table
+  {
+    const char *const sql =
+      "INSERT INTO STMT_TEST("
+        "STRING_COL) "
+      "VALUES("
+        ":STRING_COL)";
+    auto stmt = m_conn.createStmt(sql);
+    stmt.bindString(":STRING_COL", insertValue);
+    stmt.executeNonQuery();
+  }
+
+  // Select the row back from the table
+  {
+    const char *const sql =
+      "SELECT "
+        "STRING_COL AS STRING_COL "
+      "FROM "
+        "STMT_TEST";
+    auto stmt = m_conn.createStmt(sql);
+    auto rset = stmt.executeQuery();
+    ASSERT_TRUE(rset.next());
+
+    const auto selectValue = rset.columnOptionalString("STRING_COL");
+
+    ASSERT_TRUE((bool)selectValue);
+
+    ASSERT_EQ(insertValue,selectValue.value());
+
+    ASSERT_FALSE(rset.next());
+  }
+}
+
+TEST_P(cta_rdbms_StmtTest, insert_with_bindBool_true) {
+  using namespace cta::rdbms;
+
+  const bool insertValue = true;
+
+  // Insert a row into the test table
+  {
+    const char *const sql =
+      "INSERT INTO STMT_TEST("
+        "BOOL_COL) "
+      "VALUES("
+        ":BOOL_COL)";
+    auto stmt = m_conn.createStmt(sql);
+    stmt.bindBool(":BOOL_COL", insertValue);
+    stmt.executeNonQuery();
+  }
+
+  // Select the row back from the table
+  {
+    const char *const sql =
+      "SELECT "
+        "BOOL_COL AS BOOL_COL "
+      "FROM "
+        "STMT_TEST";
+    auto stmt = m_conn.createStmt(sql);
+    auto rset = stmt.executeQuery();
+    ASSERT_TRUE(rset.next());
+
+    const auto selectValue = rset.columnOptionalBool("BOOL_COL");
+
+    ASSERT_TRUE((bool)selectValue);
+
+    ASSERT_EQ(insertValue,selectValue.value());
+
+    ASSERT_FALSE(rset.next());
+  }
+}
+
+TEST_P(cta_rdbms_StmtTest, insert_with_bindBool_false) {
+  using namespace cta::rdbms;
+
+  const bool insertValue = false;
+
+  // Insert a row into the test table
+  {
+    const char *const sql =
+      "INSERT INTO STMT_TEST("
+        "BOOL_COL) "
+      "VALUES("
+        ":BOOL_COL)";
+    auto stmt = m_conn.createStmt(sql);
+    stmt.bindBool(":BOOL_COL", insertValue);
+    stmt.executeNonQuery();
+  }
+
+  // Select the row back from the table
+  {
+    const char *const sql =
+      "SELECT "
+        "BOOL_COL AS BOOL_COL "
+      "FROM "
+        "STMT_TEST";
+    auto stmt = m_conn.createStmt(sql);
+    auto rset = stmt.executeQuery();
+    ASSERT_TRUE(rset.next());
+
+    const auto selectValue = rset.columnOptionalBool("BOOL_COL");
+
+    ASSERT_TRUE((bool)selectValue);
+
+    ASSERT_EQ(insertValue,selectValue.value());
+
+    ASSERT_FALSE(rset.next());
+  }
+}
+
+} // namespace unitTests
diff --git a/rdbms/StmtTest.hpp b/rdbms/StmtTest.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..46dba5489fc34e4ea26d086c97f21742fa8e467b
--- /dev/null
+++ b/rdbms/StmtTest.hpp
@@ -0,0 +1,61 @@
+/*
+ * 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 "rdbms/LoginFactory.hpp"
+#include "rdbms/Conn.hpp"
+
+#include <gtest/gtest.h>
+#include <memory>
+
+namespace unitTests {
+
+class cta_rdbms_StmtTest : public ::testing::TestWithParam<cta::rdbms::LoginFactory*> {
+protected:
+  /**
+   * The database login.
+   */
+  cta::rdbms::Login m_login;
+
+  /**
+   * The database connection pool.
+   */
+  std::unique_ptr<cta::rdbms::ConnPool> m_connPool;
+
+  /**
+   * The database connection.
+   */
+  cta::rdbms::Conn m_conn;
+
+  virtual void SetUp();
+
+  /**
+   * Returns the SQL to create the STMT_TEST table taking into account any
+   * differences between the various types of database backend.
+   *
+   * @return The SQL to create the STMT_TEST table taking into account any
+   * differences between the various types of database backend.
+   */
+  std::string getCreateStmtTestTableSql();
+
+  virtual void TearDown();
+
+}; // cta_rdbms_StmtTest
+
+} // namespace unitTests
diff --git a/rdbms/wrapper/Mysql.hpp b/rdbms/wrapper/Mysql.hpp
index 327dbba8d1b359bc8a95f36d4592f04cd9778b9d..e47b0606881a49fd0042a4da6cca6168aaa6c721 100644
--- a/rdbms/wrapper/Mysql.hpp
+++ b/rdbms/wrapper/Mysql.hpp
@@ -99,6 +99,7 @@ class Mysql {
     enum buffer_types {
       placeholder_uint64,
       placeholder_string,
+      placeholder_double,
     };
 
     virtual std::string show() = 0;
@@ -113,6 +114,7 @@ class Mysql {
     // following is to access data
     virtual uint64_t get_uint64() = 0;
     virtual std::string get_string() = 0;
+    virtual double get_double() = 0;
     // helper
     virtual bool reset() = 0;
   };
@@ -155,6 +157,10 @@ class Mysql {
       return std::to_string(val);
     }
 
+    double get_double() {
+      return val;
+    }
+
     bool reset() {
       return false;
     }
@@ -210,6 +216,12 @@ class Mysql {
       return std::string(val, val+*get_length());
     }
 
+    // note: allow users try to convert from string to int,
+    //       but users need to catch the exception.
+    double get_double() {
+      return std::stod(val);
+    }
+
     bool reset() {
       memset(val, 0, buf_sz);
       
@@ -218,6 +230,54 @@ class Mysql {
 
   };
 
+  struct Placeholder_Double: Placeholder {
+    double val;
+
+    Placeholder_Double()
+      : Placeholder(), val(0) {
+
+    }
+
+    std::string show() override {
+      std::stringstream ss;
+      ss << "['" << idx << "' '" << is_null << "' '" << length << "' '" << val << "' '" << get_buffer_length() << "']";
+      return ss.str();
+    }
+
+    buffer_types get_buffer_type() override {
+      return placeholder_double;
+    }
+
+    void* get_buffer() override {
+      return &val;
+    }
+
+    unsigned long get_buffer_length() override {
+      return sizeof(double);
+    }
+
+    bool get_is_unsigned() override {
+      return true;
+    }
+
+    uint64_t get_uint64() override {
+      return val;
+    }
+
+    std::string get_string() override {
+      return std::to_string(val);
+    }
+
+    double get_double() override {
+      return val;
+    }
+
+    bool reset() {
+      return false;
+    }
+
+  };
+
   struct FieldsInfo {
     FieldsInfo(MYSQL_RES* result_metadata);
 
diff --git a/rdbms/wrapper/MysqlRset.cpp b/rdbms/wrapper/MysqlRset.cpp
index a302ceb853ef5325211f1b592a887bd9d57c197a..66a3f649e96d92fff386d2b610a623cc20d22b64 100644
--- a/rdbms/wrapper/MysqlRset.cpp
+++ b/rdbms/wrapper/MysqlRset.cpp
@@ -134,6 +134,25 @@ optional<uint64_t> MysqlRset::columnOptionalUint64(const std::string &colName) c
   return optional<uint64_t>(holder->get_uint64());
 }
 
+//------------------------------------------------------------------------------
+// columnOptionalDouble
+//------------------------------------------------------------------------------
+optional<double> MysqlRset::columnOptionalDouble(const std::string &colName) const {
+  if (not m_fields.exists(colName)) {
+    throw exception::Exception(std::string(__FUNCTION__) + " column does not exist: " + colName);
+    return nullopt;
+  }
+
+  Mysql::Placeholder* holder = m_stmt.columnHolder(colName); // m_holders[idx];
+
+  // the value can be null
+  if (holder->get_is_null() and *holder->get_is_null()) {
+    return nullopt;
+  }
+
+  return optional<double>(holder->get_double());
+}
+
 } // namespace wrapper
 } // namespace rdbms
 } // namespace cta
diff --git a/rdbms/wrapper/MysqlRset.hpp b/rdbms/wrapper/MysqlRset.hpp
index 27a77879da5d7341756f1afb995ab4874b9558ce..ff263a397c9d59fde25476e5f8bcf778752a532c 100644
--- a/rdbms/wrapper/MysqlRset.hpp
+++ b/rdbms/wrapper/MysqlRset.hpp
@@ -96,6 +96,16 @@ public:
    */
   optional<uint64_t> columnOptionalUint64(const std::string &colName) const override;
 
+  /**
+   * Returns the value of the specified column as a double.
+   *
+   * 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<double> columnOptionalDouble(const std::string &colName) const override;
+
 private:
 
   /**
diff --git a/rdbms/wrapper/MysqlStmt.cpp b/rdbms/wrapper/MysqlStmt.cpp
index 8a3811424425462242980a20ce1c82cd0610b6b6..6d22de3bc87deb981ca45705b33976fb2fb0c0a0 100644
--- a/rdbms/wrapper/MysqlStmt.cpp
+++ b/rdbms/wrapper/MysqlStmt.cpp
@@ -189,14 +189,59 @@ void MysqlStmt::bindOptionalUint64(const std::string &paramName, const optional<
     const unsigned int paramIdx = getParamIdx(paramName); // starts from 1.
     const unsigned int idx = paramIdx - 1;
 
-    Mysql::Placeholder_Uint64* holder = dynamic_cast<Mysql::Placeholder_Uint64*>(m_placeholder[idx]);
+    Mysql::Placeholder_Double* holder = dynamic_cast<Mysql::Placeholder_Double*>(m_placeholder[idx]);
     // if already exists, try to reuse
     if (!holder and m_placeholder[idx]) {
       throw exception::Exception(std::string(__FUNCTION__) + " can't cast from Placeholder to Placeholder_Uint64. " );
     }
 
     if (!holder) {
-      holder = new Mysql::Placeholder_Uint64();
+      holder = new Mysql::Placeholder_Double();
+      holder->idx = idx;
+      holder->length = sizeof(uint64_t);
+    }
+
+    if (paramValue) {
+      holder->val = paramValue.value();
+    } else {
+      holder->is_null = true;
+    }
+    // delete m_placeholder[idx]; // remove the previous placeholder
+
+    m_placeholder[idx] = holder;
+  } catch(exception::Exception &ex) {
+    throw exception::Exception(std::string(__FUNCTION__) + " failed for SQL statement " +
+      getSqlForException() + ": " + ex.getMessage().str());
+  }
+}
+
+//------------------------------------------------------------------------------
+// bindDouble
+//------------------------------------------------------------------------------
+void MysqlStmt::bindDouble(const std::string &paramName, const double paramValue) {
+  try {
+    bindOptionalDouble(paramName, paramValue);
+  } catch(exception::Exception &ex) {
+    throw exception::Exception(std::string(__FUNCTION__) + " failed: " + ex.getMessage().str());
+  }
+}
+
+//------------------------------------------------------------------------------
+// bindOptionalDouble
+//------------------------------------------------------------------------------
+void MysqlStmt::bindOptionalDouble(const std::string &paramName, const optional<double> &paramValue) {
+  try {
+    const unsigned int paramIdx = getParamIdx(paramName); // starts from 1.
+    const unsigned int idx = paramIdx - 1;
+
+    Mysql::Placeholder_Double* holder = dynamic_cast<Mysql::Placeholder_Double*>(m_placeholder[idx]);
+    // if already exists, try to reuse
+    if (!holder and m_placeholder[idx]) {
+      throw exception::Exception(std::string(__FUNCTION__) + " can't cast from Placeholder to Placeholder_Double. " );
+    }
+
+    if (!holder) {
+      holder = new Mysql::Placeholder_Double();
       holder->idx = idx;
       holder->length = sizeof(uint64_t);
     }
@@ -393,6 +438,9 @@ bool MysqlStmt::do_bind() {
     case Mysql::Placeholder::placeholder_string:
       bind[idx].buffer_type = MYSQL_TYPE_STRING;
       break;
+    case Mysql::Placeholder::placeholder_double:
+      bind[idx].buffer_type = MYSQL_TYPE_DOUBLE;
+      break;
     default:
       throw exception::Exception(std::string(__FUNCTION__) + " Unknown buffer type in placeholder " + std::to_string(holder->get_buffer_type()));
       break;
@@ -473,6 +521,14 @@ bool MysqlStmt::do_bind_results() {
         bind[i].buffer_type = MYSQL_TYPE_STRING;
       }
       break;
+    case MYSQL_TYPE_FLOAT:
+    case MYSQL_TYPE_DOUBLE:
+      {
+        Mysql::Placeholder_Double* holder_ = new Mysql::Placeholder_Double();
+        holder = holder_;
+        bind[i].buffer_type = MYSQL_TYPE_DOUBLE;
+      }
+      break;
     default:
       throw exception::Exception(std::string(__FUNCTION__) + " unsupport buffer type: " + std::to_string(buffer_type));
       break;
diff --git a/rdbms/wrapper/MysqlStmt.hpp b/rdbms/wrapper/MysqlStmt.hpp
index 96bca5374b42d6f5bf1c7472e0170acb16f7e7d1..5f36b0f19c8637d24cb9825ff81d12f02c6d50df 100644
--- a/rdbms/wrapper/MysqlStmt.hpp
+++ b/rdbms/wrapper/MysqlStmt.hpp
@@ -100,6 +100,22 @@ public:
    */
   void bindOptionalUint64(const std::string &paramName, const optional<uint64_t> &paramValue) override;
 
+  /**
+   * Binds an SQL parameter.
+   *
+   * @param paramName The name of the parameter.
+   * @param paramValue The value to be bound.
+   */
+  void bindDouble(const std::string &paramName, const double paramValue) override;
+
+  /**
+   * Binds an SQL parameter.
+   *
+   * @param paramName The name of the parameter.
+   * @param paramValue The value to be bound.
+   */
+  void bindOptionalDouble(const std::string &paramName, const optional<double> &paramValue) override;
+
   /** 
    * Binds an SQL parameter of type string.
    *
diff --git a/rdbms/wrapper/OcciRset.cpp b/rdbms/wrapper/OcciRset.cpp
index 43553fdd9aea7372e9b9a1cd224d31c5b6cb94b9..e1e16e158c5f858e8d73a5ed05c6ce425bd18ef8 100644
--- a/rdbms/wrapper/OcciRset.cpp
+++ b/rdbms/wrapper/OcciRset.cpp
@@ -172,6 +172,28 @@ optional<uint64_t> OcciRset::columnOptionalUint64(const std::string &colName) co
   }
 }
 
+//------------------------------------------------------------------------------
+// columnOptionalDouble
+//------------------------------------------------------------------------------
+optional<double> OcciRset::columnOptionalDouble(const std::string &colName) const {
+  try {
+    threading::Mutex locker(m_mutex);
+
+    const int colIdx = m_colNameToIdx.getIdx(colName);
+    if(m_rset->isNull(colIdx)) {
+      return nullopt;
+    } else {
+      return m_rset->getDouble(colIdx);
+    }
+  } catch(exception::Exception &ne) {
+    throw exception::Exception(std::string(__FUNCTION__) + " failed for SQL statement " + m_stmt.getSql() + ": " +
+      ne.getMessage().str());
+  } catch(std::exception &se) {
+    throw exception::Exception(std::string(__FUNCTION__) + " failed for SQL statement " + m_stmt.getSql() + ": " +
+      se.what());
+  }
+}
+
 } // namespace wrapper
 } // namespace rdbms
 } // namespace cta
diff --git a/rdbms/wrapper/OcciRset.hpp b/rdbms/wrapper/OcciRset.hpp
index 4750b9cee2d9a915ecd9cd4a1f25336eedcb56a1..27fc061f8c0a90a48018361343b9c05f64eeae5c 100644
--- a/rdbms/wrapper/OcciRset.hpp
+++ b/rdbms/wrapper/OcciRset.hpp
@@ -100,6 +100,16 @@ public:
    */
   optional<uint64_t> columnOptionalUint64(const std::string &colName) const override;
 
+  /**
+   * Returns the value of the specified column as a double.
+   *
+   * 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<double> columnOptionalDouble(const std::string &colName) const override;
+
 private:
 
   /**
diff --git a/rdbms/wrapper/OcciStmt.cpp b/rdbms/wrapper/OcciStmt.cpp
index 4cb0d3b2d6a48bca3156e231e859fb021140f01a..ced47e61d31e3a53de3bb3f05be326622e22e135 100644
--- a/rdbms/wrapper/OcciStmt.cpp
+++ b/rdbms/wrapper/OcciStmt.cpp
@@ -115,6 +115,38 @@ void OcciStmt::bindOptionalUint64(const std::string &paramName, const optional<u
   }
 }
 
+//------------------------------------------------------------------------------
+// bindDouble
+//------------------------------------------------------------------------------
+void OcciStmt::bindDouble(const std::string &paramName, const double paramValue) {
+  try {
+    bindOptionalDouble(paramName, paramValue);
+  } catch(exception::Exception &ex) {
+    throw exception::Exception(std::string(__FUNCTION__) + " failed: " + ex.getMessage().str());
+  }
+}
+
+//------------------------------------------------------------------------------
+// bindOptionalDouble
+//------------------------------------------------------------------------------
+void OcciStmt::bindOptionalDouble(const std::string &paramName, const optional<double> &paramValue) {
+  try {
+    const unsigned paramIdx = getParamIdx(paramName);
+    if(paramValue) {
+      // Bind integer as a string in order to support 64-bit integers
+      m_stmt->setDouble(paramIdx, paramValue.value());
+    } else {
+      m_stmt->setNull(paramIdx, oracle::occi::OCCIDOUBLE);
+    }
+  } catch(exception::Exception &ex) {
+    throw exception::Exception(std::string(__FUNCTION__) + " failed for SQL statement " +
+      getSqlForException() + ": " + ex.getMessage().str());
+  } catch(std::exception &se) {
+    throw exception::Exception(std::string(__FUNCTION__) + " failed for SQL statement " +
+      getSqlForException() + ": " + se.what());
+  }
+}
+
 //------------------------------------------------------------------------------
 // bind
 //------------------------------------------------------------------------------
diff --git a/rdbms/wrapper/OcciStmt.hpp b/rdbms/wrapper/OcciStmt.hpp
index b95a715542df24bd1fe655439fa60534dcebd124..6db7e1b80ab028ab14cef37271636c4595643ef7 100644
--- a/rdbms/wrapper/OcciStmt.hpp
+++ b/rdbms/wrapper/OcciStmt.hpp
@@ -97,6 +97,22 @@ public:
    */
   void bindOptionalUint64(const std::string &paramName, const optional<uint64_t> &paramValue) override;
 
+  /**
+   * Binds an SQL parameter.
+   *
+   * @param paramName The name of the parameter.
+   * @param paramValue The value to be bound.
+   */
+  void bindDouble(const std::string &paramName, const double paramValue) override;
+
+  /**
+   * Binds an SQL parameter.
+   *
+   * @param paramName The name of the parameter.
+   * @param paramValue The value to be bound.
+   */
+  void bindOptionalDouble(const std::string &paramName, const optional<double> &paramValue) override;
+
   /** 
    * Binds an SQL parameter of type string.
    *
diff --git a/rdbms/wrapper/PostgresRset.cpp b/rdbms/wrapper/PostgresRset.cpp
index 3ba8ab0de5ff793ac34709f0ab75231de8407a49..8ade84da2175cf0c3d74b9080fbaaaa04b32db90 100644
--- a/rdbms/wrapper/PostgresRset.cpp
+++ b/rdbms/wrapper/PostgresRset.cpp
@@ -124,6 +124,34 @@ optional<uint64_t> PostgresRset::columnOptionalUint64(const std::string &colName
   return utils::toUint64(stringValue);
 }
 
+//------------------------------------------------------------------------------
+// columnOptionalDouble
+//------------------------------------------------------------------------------
+optional<double> PostgresRset::columnOptionalDouble(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::isValidDecimal(stringValue)) {
+    throw exception::Exception(std::string("Column ") + colName + " contains the value " + stringValue +
+      " which is not a valid decimal");
+  }
+
+  return utils::toDouble(stringValue);
+}
+
 //------------------------------------------------------------------------------
 // getSql
 //------------------------------------------------------------------------------
diff --git a/rdbms/wrapper/PostgresRset.hpp b/rdbms/wrapper/PostgresRset.hpp
index 1abc4fa9c2cae01731905c59d066e82c5d253a7e..4936da35e9a70fde804492c86b0903b5a585dbc1 100644
--- a/rdbms/wrapper/PostgresRset.hpp
+++ b/rdbms/wrapper/PostgresRset.hpp
@@ -80,6 +80,16 @@ public:
    */
   optional<uint64_t> columnOptionalUint64(const std::string &colName) const override;
 
+  /**
+   * Returns the value of the specified column as a double.
+   *
+   * 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<double> columnOptionalDouble(const std::string &colName) const override;
+
   /**
    * Returns the SQL statement.
    *
diff --git a/rdbms/wrapper/PostgresStmt.cpp b/rdbms/wrapper/PostgresStmt.cpp
index 2c3882516a1451702d089e889aa8d1b94b5ff4ca..d00e43f99802cf5aca845e038bc2189028486198 100644
--- a/rdbms/wrapper/PostgresStmt.cpp
+++ b/rdbms/wrapper/PostgresStmt.cpp
@@ -152,6 +152,45 @@ void PostgresStmt::bindUint64(const std::string &paramName, const uint64_t param
   }
 }
 
+//------------------------------------------------------------------------------
+// bindDouble
+//------------------------------------------------------------------------------
+void PostgresStmt::bindDouble(const std::string &paramName, const double paramValue) {
+  try {
+    bindOptionalDouble(paramName, paramValue);
+  } catch(exception::Exception &ex) {
+    throw exception::Exception(std::string(__FUNCTION__) + " failed: " + ex.getMessage().str());
+  }
+}
+
+//------------------------------------------------------------------------------
+// bindOptionalDouble
+//------------------------------------------------------------------------------
+void PostgresStmt::bindOptionalDouble(const std::string &paramName, const optional<double> &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());
+  }
+}
+
 //------------------------------------------------------------------------------
 // clear
 //------------------------------------------------------------------------------
diff --git a/rdbms/wrapper/PostgresStmt.hpp b/rdbms/wrapper/PostgresStmt.hpp
index e0e91648a471753e6985f11cf63875ef15ce0286..396b09c75799ae14e5d2349ec024d262d0907e70 100644
--- a/rdbms/wrapper/PostgresStmt.hpp
+++ b/rdbms/wrapper/PostgresStmt.hpp
@@ -103,6 +103,22 @@ public:
    */
   void bindUint64(const std::string &paramName, const uint64_t paramValue) override;
 
+  /**
+   * Binds an SQL parameter.
+   *
+   * @param paramName The name of the parameter.
+   * @param paramValue The value to be bound.
+   */
+  void bindDouble(const std::string &paramName, const double paramValue) override;
+
+  /**
+   * Binds an SQL parameter.
+   *
+   * @param paramName The name of the parameter.
+   * @param paramValue The value to be bound.
+   */
+  void bindOptionalDouble(const std::string &paramName, const optional<double> &paramValue) override;
+
   /**
    * Clears the prepared statement so that it is ready to be reused.
    */
diff --git a/rdbms/wrapper/RsetWrapper.hpp b/rdbms/wrapper/RsetWrapper.hpp
index 88a210a59c6ce5e587db80933e24e9dfa3670e14..aceff03b11e04242f7d86695273f877659761eeb 100644
--- a/rdbms/wrapper/RsetWrapper.hpp
+++ b/rdbms/wrapper/RsetWrapper.hpp
@@ -82,6 +82,16 @@ public:
    */
   virtual optional<uint64_t> columnOptionalUint64(const std::string &colName) const = 0;
 
+  /**
+   * Returns the value of the specified column as a double.
+   *
+   * 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.
+   */
+  virtual optional<double> columnOptionalDouble(const std::string &colName) const = 0;
+
 }; // class RsetWrapper
 
 } // namespace wrapper
diff --git a/rdbms/wrapper/SqliteRset.cpp b/rdbms/wrapper/SqliteRset.cpp
index fa5870c957bea2ea35ee62ae32d06c7744d581fc..9aea8f932faa8f497e81f03c1812fd35d2784301 100644
--- a/rdbms/wrapper/SqliteRset.cpp
+++ b/rdbms/wrapper/SqliteRset.cpp
@@ -254,6 +254,22 @@ optional<uint64_t> SqliteRset::columnOptionalUint64(const std::string &colName)
   }
 }
 
+//------------------------------------------------------------------------------
+// columnOptionalDouble
+//------------------------------------------------------------------------------
+optional<double> SqliteRset::columnOptionalDouble(const std::string &colName) const {
+  try {
+    const ColumnNameToIdxAndType::IdxAndType idxAndType = m_colNameToIdxAndType.getIdxAndType(colName);
+    if(SQLITE_NULL == idxAndType.colType) {
+      return nullopt;
+    } else {
+      return optional<double>(sqlite3_column_double(m_stmt.get(), idxAndType.colIdx));
+    }
+  } 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/SqliteRset.hpp b/rdbms/wrapper/SqliteRset.hpp
index d9e7cdeabe10021601aae59d29c659dd42d224ff..bc9262d53594eec9ef8fd493665ab75917483281 100644
--- a/rdbms/wrapper/SqliteRset.hpp
+++ b/rdbms/wrapper/SqliteRset.hpp
@@ -95,6 +95,16 @@ public:
    */
   optional<uint64_t> columnOptionalUint64(const std::string &colName) const override;
 
+  /**
+   * Returns the value of the specified column as a double.
+   *
+   * 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<double> columnOptionalDouble(const std::string &colName) const override;
+
 private:
 
   /**
diff --git a/rdbms/wrapper/SqliteStmt.cpp b/rdbms/wrapper/SqliteStmt.cpp
index 059b60aed4947c4afd603cffd8553479dcb567cc..7f09732a3751552a7394feb53e6547312fe08d04 100644
--- a/rdbms/wrapper/SqliteStmt.cpp
+++ b/rdbms/wrapper/SqliteStmt.cpp
@@ -171,9 +171,39 @@ void SqliteStmt::bindOptionalUint64(const std::string &paramName, const optional
       bindRc = sqlite3_bind_null(m_stmt, paramIdx);
     }
     if(SQLITE_OK != bindRc) {
-      exception::Exception ex;
-      ex.getMessage() << "sqlite3_bind_int64() failed: " << Sqlite::rcToStr(bindRc);
-      throw ex;
+      throw exception::Exception(Sqlite::rcToStr(bindRc));
+    }
+  } catch(exception::Exception &ex) {
+    throw exception::Exception(std::string(__FUNCTION__) + " failed for SQL statement " +
+      getSqlForException() + ": " + ex.getMessage().str());
+  }
+}
+
+//------------------------------------------------------------------------------
+// bindDouble
+//------------------------------------------------------------------------------
+void SqliteStmt::bindDouble(const std::string &paramName, const double paramValue) {
+  try {
+    bindOptionalDouble(paramName, paramValue);
+  } catch(exception::Exception &ex) {
+    throw exception::Exception(std::string(__FUNCTION__) + " failed: " + ex.getMessage().str());
+  }
+}
+
+//------------------------------------------------------------------------------
+// bindOptionalDouble
+//------------------------------------------------------------------------------
+void SqliteStmt::bindOptionalDouble(const std::string &paramName, const optional<double> &paramValue) {
+  try {
+    const unsigned int paramIdx = getParamIdx(paramName);
+    int bindRc = 0;
+    if(paramValue) {
+      bindRc = sqlite3_bind_double(m_stmt, paramIdx, paramValue.value());
+    } else {
+      bindRc = sqlite3_bind_null(m_stmt, paramIdx);
+    }
+    if(SQLITE_OK != bindRc) {
+      throw exception::Exception(Sqlite::rcToStr(bindRc));
     }
   } catch(exception::Exception &ex) {
     throw exception::Exception(std::string(__FUNCTION__) + " failed for SQL statement " +
@@ -209,10 +239,7 @@ void SqliteStmt::bindOptionalString(const std::string &paramName, const optional
       bindRc = sqlite3_bind_null(m_stmt, paramIdx);
     }
     if(SQLITE_OK != bindRc) {
-      exception::Exception ex;
-
-      ex.getMessage() << "sqlite3_bind_text() failed: " << Sqlite::rcToStr(bindRc);
-      throw ex;
+      throw exception::Exception(Sqlite::rcToStr(bindRc));
     }
   } catch(exception::Exception &ex) {
     throw exception::Exception(std::string(__FUNCTION__) + " failed for SQL statement " +
diff --git a/rdbms/wrapper/SqliteStmt.hpp b/rdbms/wrapper/SqliteStmt.hpp
index 0bb632fa6d3e9ca0b811c5fa9d13c751ed9d3524..54f104b845fc2f49f229a2d35a3a55455f7f8cdf 100644
--- a/rdbms/wrapper/SqliteStmt.hpp
+++ b/rdbms/wrapper/SqliteStmt.hpp
@@ -91,6 +91,22 @@ public:
    */
   void bindOptionalUint64(const std::string &paramName, const optional<uint64_t> &paramValue) override;
 
+  /**
+   * Binds an SQL parameter.
+   *
+   * @param paramName The name of the parameter.
+   * @param paramValue The value to be bound.
+   */
+  void bindDouble(const std::string &paramName, const double paramValue) override;
+
+  /**
+   * Binds an SQL parameter.
+   *
+   * @param paramName The name of the parameter.
+   * @param paramValue The value to be bound.
+   */
+  void bindOptionalDouble(const std::string &paramName, const optional<double> &paramValue) override;
+
   /** 
    * Binds an SQL parameter of type string.
    *
diff --git a/rdbms/wrapper/StmtWrapper.hpp b/rdbms/wrapper/StmtWrapper.hpp
index f3472a74f0d066431342950fc4d1b112f9021513..e14221e1e96271c53bdae88a3c502988d46444f1 100644
--- a/rdbms/wrapper/StmtWrapper.hpp
+++ b/rdbms/wrapper/StmtWrapper.hpp
@@ -111,6 +111,22 @@ public:
    */
   virtual void bindOptionalUint64(const std::string &paramName, const optional<uint64_t> &paramValue) = 0;
 
+  /**
+   * Binds an SQL parameter.
+   *
+   * @param paramName The name of the parameter.
+   * @param paramValue The value to be bound.
+   */
+  virtual void bindDouble(const std::string &paramName, const double paramValue) = 0;
+
+  /**
+   * Binds an SQL parameter.
+   *
+   * @param paramName The name of the parameter.
+   * @param paramValue The value to be bound.
+   */
+  virtual void bindOptionalDouble(const std::string &paramName, const optional<double> &paramValue) = 0;
+
   /**
    * Binds an SQL parameter.
    *
diff --git a/scheduler/OStoreDB/OStoreDB.cpp b/scheduler/OStoreDB/OStoreDB.cpp
index f61b74c340c16b191988dd6d348ee6e33fb8d1d2..825b7a67c217feed73c74ad011c0863d33a233f4 100644
--- a/scheduler/OStoreDB/OStoreDB.cpp
+++ b/scheduler/OStoreDB/OStoreDB.cpp
@@ -1377,7 +1377,7 @@ std::list<common::dataStructures::RepackInfo> OStoreDB::getRepackInfo() {
   // First, try to get the address of of the repack index lockfree.
   try {
     ri.setAddress(re.getRepackIndexAddress());
-  } catch (RootEntry::NotAllocated &) {
+  } catch (cta::exception::Exception &) {
     return ret;
   }
   ri.fetchNoLock();
@@ -1402,7 +1402,7 @@ common::dataStructures::RepackInfo OStoreDB::getRepackInfo(const std::string& vi
   // First, try to get the address of of the repack index lockfree.
   try {
     ri.setAddress(re.getRepackIndexAddress());
-  } catch (RootEntry::NotAllocated &) {
+  } catch (cta::exception::Exception &) {
     throw NoSuchRepackRequest("In OStoreDB::getRepackInfo(): No repack request for this VID (index not present).");
   }
   ri.fetchNoLock();
@@ -1479,7 +1479,7 @@ void OStoreDB::populateRepackRequestsStatistics(RootEntry & re, SchedulerDatabas
   objectstore::RepackIndex ri(m_objectStore);
   try {
     ri.setAddress(re.getRepackIndexAddress());
-  } catch (RootEntry::NotAllocated &) {
+  } catch (cta::exception::Exception &) {
     return;
   }
   ri.fetchNoLock();
@@ -1491,7 +1491,7 @@ void OStoreDB::populateRepackRequestsStatistics(RootEntry & re, SchedulerDatabas
   }
   // Ensure existence of stats for important statuses
   typedef common::dataStructures::RepackInfo::Status Status; 
-  for (auto s: {Status::Pending, Status::ToExpand, Status::Starting}) {
+  for (auto s: {Status::Pending, Status::ToExpand, Status::Starting, Status::Running}) {
     stats[s] = 0;
   }
   auto fet = fetchers.begin();
@@ -1793,7 +1793,6 @@ void OStoreDB::RepackRetrieveSuccessesReportBatch::report(log::LogContext& lc) {
     objectstore::ScopedExclusiveLock rrl(m_repackRequest);
     timingList.insertAndReset("successStatsLockTime", t);
     m_repackRequest.fetch();
-    m_repackRequest.setStatus(common::dataStructures::RepackInfo::Status::Running);
     timingList.insertAndReset("successStatsFetchTime", t);
     m_repackRequest.reportRetriveSuccesses(ssl);
     timingList.insertAndReset("successStatsUpdateTime", t);
@@ -2077,13 +2076,16 @@ void OStoreDB::RepackRequest::setLastExpandedFSeq(uint64_t fseq){
 //------------------------------------------------------------------------------
 // OStoreDB::RepackRequest::addSubrequests()
 //------------------------------------------------------------------------------
-void OStoreDB::RepackRequest::addSubrequests(std::list<Subrequest>& repackSubrequests, cta::common::dataStructures::ArchiveRoute::FullMap& archiveRoutesMap, uint64_t maxFSeqLowBound, log::LogContext& lc) {
+void OStoreDB::RepackRequest::addSubrequestsAndUpdateStats(std::list<Subrequest>& repackSubrequests, cta::common::dataStructures::ArchiveRoute::FullMap& archiveRoutesMap, uint64_t maxFSeqLowBound, const uint64_t maxAddedFSeq, const cta::SchedulerDatabase::RepackRequest::TotalStatsFiles &totalStatsFiles, log::LogContext& lc) {
   // We need to prepare retrieve requests names and reference them, create them, enqueue them.
   objectstore::ScopedExclusiveLock rrl (m_repackRequest);
   m_repackRequest.fetch();
   std::set<uint64_t> fSeqs;
   for (auto rsr: repackSubrequests) fSeqs.insert(rsr.fSeq);
   auto subrequestsNames = m_repackRequest.getOrPrepareSubrequestInfo(fSeqs, *m_oStoreDB.m_agentReference);
+  m_repackRequest.setTotalStats(totalStatsFiles);
+  uint64_t fSeq = std::max(maxFSeqLowBound+1, maxAddedFSeq + 1);
+  m_repackRequest.setLastExpandedFSeq(fSeq);
   // We make sure the references to subrequests exist persistently before creating them.
   m_repackRequest.commit();
   // We keep holding the repack request lock: we need to ensure de deleted boolean of each subrequest does
@@ -2294,32 +2296,9 @@ void OStoreDB::RepackRequest::expandDone() {
   // We are now done with the repack request. We can set its status.
   ScopedExclusiveLock rrl(m_repackRequest);
   m_repackRequest.fetch();
-  // After expansion, 2 statuses are possible: starting (nothing reported as done) or running (anything reported as done).
-  // We can find that out from the statistics...
-  typedef objectstore::RepackRequest::StatsType StatsType;
-  bool running=false;
-  auto stats=m_repackRequest.getStats();
-  for (auto t: {StatsType::ArchiveFailure, StatsType::ArchiveSuccess, StatsType::RetrieveSuccess, StatsType::RetrieveFailure}) {
-    if (stats.at(t).files) {
-      running=true;
-      break;
-    }
-  }
-  if(stats.at(StatsType::RetrieveTotal).files == m_repackRequest.getInfo().totalFilesToRetrieve){
-    m_repackRequest.setExpandFinished(true);
-  }
-  typedef common::dataStructures::RepackInfo::Status Status;
-  m_repackRequest.setStatus(running? Status::Running: Status::Starting);
-  m_repackRequest.commit();
-}
 
-void OStoreDB::RepackRequest::setTotalStats(const TotalStatsFiles& stats){
-  ScopedExclusiveLock rrl(m_repackRequest);
-  m_repackRequest.fetch();
-  m_repackRequest.setTotalFileToArchive(stats.totalFilesToArchive);
-  m_repackRequest.setTotalBytesToArchive(stats.totalBytesToArchive);
-  m_repackRequest.setTotalFileToRetrieve(stats.totalFilesToRetrieve);
-  m_repackRequest.setTotalBytesToRetrieve(stats.totalBytesToRetrieve);
+  m_repackRequest.setExpandFinished(true);
+  m_repackRequest.setStatus();
   m_repackRequest.commit();
 }
 
@@ -2333,6 +2312,36 @@ void OStoreDB::RepackRequest::fail() {
   m_repackRequest.commit();
 }
 
+void OStoreDB::RepackRequest::requeueInToExpandQueue(log::LogContext& lc){
+  ScopedExclusiveLock rrl(m_repackRequest);
+  m_repackRequest.fetch();
+  std::string previousOwner = m_repackRequest.getOwner();
+  m_repackRequest.setStatus();
+  m_repackRequest.commit();
+  rrl.release();
+  std::unique_ptr<cta::objectstore::RepackRequest> rr(new cta::objectstore::RepackRequest(m_repackRequest.getAddressIfSet(),m_oStoreDB.m_objectStore));
+  typedef objectstore::ContainerAlgorithms<RepackQueue, RepackQueueToExpand> RQTEAlgo;
+  RQTEAlgo rqteAlgo(m_oStoreDB.m_objectStore, *m_oStoreDB.m_agentReference);
+  RQTEAlgo::InsertedElement::list insertedElements;
+  insertedElements.push_back(RQTEAlgo::InsertedElement());
+  insertedElements.back().repackRequest = std::move(rr);
+  rqteAlgo.referenceAndSwitchOwnership(nullopt, previousOwner, insertedElements, lc);
+}
+
+void OStoreDB::RepackRequest::setExpandStartedAndChangeStatus(){
+  ScopedExclusiveLock rrl(m_repackRequest);
+  m_repackRequest.fetch();
+  m_repackRequest.setExpandStarted(true);
+  m_repackRequest.setStatus();
+  m_repackRequest.commit();
+}
+
+void OStoreDB::RepackRequest::fillLastExpandedFSeqAndTotalStatsFile(uint64_t& fSeq, TotalStatsFiles& totalStatsFiles) {
+  ScopedExclusiveLock rrl(m_repackRequest);
+  m_repackRequest.fetch();
+  fSeq = m_repackRequest.getLastExpandedFSeq();
+  totalStatsFiles = m_repackRequest.getTotalStatsFile();
+}
 
 //------------------------------------------------------------------------------
 // OStoreDB::cancelRepack()
@@ -2345,7 +2354,7 @@ void OStoreDB::cancelRepack(const std::string& vid, log::LogContext & lc) {
   // First, try to get the address of of the repack index lockfree.
   try {
     ri.setAddress(re.getRepackIndexAddress());
-  } catch (RootEntry::NotAllocated &) {
+  } catch (cta::exception::Exception &) {
     throw NoSuchRepackRequest("In OStoreDB::cancelRepack(): No repack request for this VID (index not present).");
   }
   ri.fetchNoLock();
diff --git a/scheduler/OStoreDB/OStoreDB.hpp b/scheduler/OStoreDB/OStoreDB.hpp
index 830a3ac1f8fca8a9820eb326493c117ef4a945d1..a5daab47a625e58bf97a5e412ea38a1073e1d1c4 100644
--- a/scheduler/OStoreDB/OStoreDB.hpp
+++ b/scheduler/OStoreDB/OStoreDB.hpp
@@ -342,13 +342,15 @@ public:
   public:
     RepackRequest(const std::string &jobAddress, OStoreDB &oStoreDB) :
     m_oStoreDB(oStoreDB), m_repackRequest(jobAddress, m_oStoreDB.m_objectStore){}
-    void addSubrequests(std::list<Subrequest>& repackSubrequests, cta::common::dataStructures::ArchiveRoute::FullMap& archiveRoutesMap,
-      uint64_t maxFSeqLowBound, log::LogContext& lc) override;
+    void addSubrequestsAndUpdateStats(std::list<Subrequest>& repackSubrequests, cta::common::dataStructures::ArchiveRoute::FullMap& archiveRoutesMap,
+      uint64_t maxFSeqLowBound, const uint64_t maxAddedFSeq, const TotalStatsFiles &totalStatsFiles,  log::LogContext& lc) override;
     void expandDone() override;
     void fail() override;
+    void requeueInToExpandQueue(log::LogContext& lc) override;
+    void setExpandStartedAndChangeStatus() override;
+    void fillLastExpandedFSeqAndTotalStatsFile(uint64_t& fSeq, TotalStatsFiles& totalStatsFiles) override;
     uint64_t getLastExpandedFSeq() override;
     void setLastExpandedFSeq(uint64_t fseq) override;
-    void setTotalStats(const TotalStatsFiles& stats) override;
 
   private:
     OStoreDB & m_oStoreDB;
diff --git a/scheduler/RepackRequestManager.cpp b/scheduler/RepackRequestManager.cpp
index 41d511b5c495a8b7df7c08ef4a7ed6b84a2b68bc..cf5fbf7b6adc9ef497334c9eafbe8a5384c3a218 100644
--- a/scheduler/RepackRequestManager.cpp
+++ b/scheduler/RepackRequestManager.cpp
@@ -37,13 +37,8 @@ void RepackRequestManager::runOnePass(log::LogContext& lc) {
     std::unique_ptr<cta::RepackRequest> repackRequest = m_scheduler.getNextRepackRequestToExpand();
     if(repackRequest != nullptr){
       //We have a RepackRequest that has the status ToExpand, expand it
-      timingList.insertAndReset("expandRepackRequestTime", t);
       try{
         m_scheduler.expandRepackRequest(repackRequest,timingList,t,lc);
-        log::ScopedParamContainer params(lc);
-        params.add("tapeVid",repackRequest->getRepackInfo().vid);
-        timingList.addToLog(params);
-        lc.log(log::INFO, "In RepackRequestManager::runOnePass(): Repack Request expanded");
       } catch(const cta::exception::Exception &e){
         lc.log(log::ERR,e.what());
         repackRequest->fail();
diff --git a/scheduler/Scheduler.cpp b/scheduler/Scheduler.cpp
index 29f7526c805257924ae0e596e6bfef8e1674f193..6d6670763e1886d6395321c1db83e82839020916 100644
--- a/scheduler/Scheduler.cpp
+++ b/scheduler/Scheduler.cpp
@@ -317,6 +317,22 @@ void Scheduler::queueLabel(const common::dataStructures::SecurityIdentity &cliId
   throw exception::Exception(std::string("Not implemented: ") + __PRETTY_FUNCTION__);
 }
 
+void Scheduler::checkTapeFullBeforeRepack(std::string vid){
+  std::set<std::string> vidToRepack;
+  vidToRepack.insert(vid);
+  try{
+    auto vidToTapesMap = m_catalogue.getTapesByVid(vidToRepack); //throws an exception if the vid is not found on the database
+    cta::common::dataStructures::Tape tapeToCheck = vidToTapesMap.at(vid);
+    if(!tapeToCheck.full){
+      throw exception::UserError("You must set the tape as full before repacking it.");
+    }
+  } catch(const exception::UserError& userEx){
+    throw userEx;
+  } catch(const cta::exception::Exception & ex){
+    throw exception::UserError("The VID provided for repacking does not exist");
+  }
+}
+
 //------------------------------------------------------------------------------
 // repack
 //------------------------------------------------------------------------------
@@ -326,6 +342,7 @@ void Scheduler::queueRepack(const common::dataStructures::SecurityIdentity &cliI
   if (vid.empty()) throw exception::UserError("Empty VID name.");
   if (bufferURL.empty()) throw exception::UserError("Empty buffer URL.");
   utils::Timer t;
+  checkTapeFullBeforeRepack(vid);
   m_db.queueRepack(vid, bufferURL, repackType, lc);
   log::TimingList tl;
   tl.insertAndReset("schedulerDbTime", t);
@@ -411,13 +428,26 @@ std::unique_ptr<RepackRequest> Scheduler::getNextRepackRequestToExpand() {
     return nullptr;
 }
 
+//------------------------------------------------------------------------------
+// setRepackRequestExpansionTimeLimit
+//------------------------------------------------------------------------------
+void Scheduler::setRepackRequestExpansionTimeLimit(const double& time) {
+  m_repackRequestExpansionTimeLimit = time;
+}
+
+//------------------------------------------------------------------------------
+// getRepackRequestExpansionTimeLimit
+//------------------------------------------------------------------------------
+double Scheduler::getRepackRequestExpansionTimeLimit() const {
+  return m_repackRequestExpansionTimeLimit;
+}
+
 //------------------------------------------------------------------------------
 // expandRepackRequest
 //------------------------------------------------------------------------------
-void Scheduler::expandRepackRequest(std::unique_ptr<RepackRequest>& repackRequest, log::TimingList&, utils::Timer&, log::LogContext& lc) {
+void Scheduler::expandRepackRequest(std::unique_ptr<RepackRequest>& repackRequest, log::TimingList& timingList, utils::Timer& t, log::LogContext& lc) {
   std::list<common::dataStructures::ArchiveFile> files;
   auto repackInfo = repackRequest->getRepackInfo();
-  cta::SchedulerDatabase::RepackRequest::TotalStatsFiles totalStatsFile;
   
   typedef cta::common::dataStructures::RepackInfo::Type RepackType;
   if (repackInfo.type != RepackType::MoveOnly) {
@@ -430,6 +460,7 @@ void Scheduler::expandRepackRequest(std::unique_ptr<RepackRequest>& repackReques
   //We need to get the ArchiveRoutes to allow the retrieval of the tapePool in which the
   //tape where the file is is located
   std::list<common::dataStructures::ArchiveRoute> routes = m_catalogue.getArchiveRoutes();
+  timingList.insertAndReset("catalogueGetArchiveRoutesTime",t);
   //To identify the routes, we need to have both the dist instance name and the storage class name
   //thus, the key of the map is a pair of string
   cta::common::dataStructures::ArchiveRoute::FullMap archiveRoutesMap;
@@ -437,8 +468,12 @@ void Scheduler::expandRepackRequest(std::unique_ptr<RepackRequest>& repackReques
     //insert the route into the map to allow a quick retrieval
     archiveRoutesMap[std::make_pair(route.diskInstanceName,route.storageClassName)][route.copyNb] = route;
   }
-  uint64_t fSeq = repackRequest->m_dbReq->getLastExpandedFSeq() + 1;
+  uint64_t fSeq;
+  cta::SchedulerDatabase::RepackRequest::TotalStatsFiles totalStatsFile;
+  repackRequest->m_dbReq->fillLastExpandedFSeqAndTotalStatsFile(fSeq,totalStatsFile);
+  timingList.insertAndReset("fillTotalStatsFileBeforeExpandTime",t);
   cta::catalogue::ArchiveFileItor archiveFilesForCatalogue = m_catalogue.getArchiveFilesForRepackItor(repackInfo.vid, fSeq);
+  timingList.insertAndReset("catalogueGetArchiveFilesForRepackItorTime",t);
   std::stringstream dirBufferURL;
   dirBufferURL << repackInfo.repackBufferBaseURL << "/" << repackInfo.vid << "/";
   cta::disk::DirectoryFactory dirFactory;
@@ -450,11 +485,14 @@ void Scheduler::expandRepackRequest(std::unique_ptr<RepackRequest>& repackReques
   } else {
     dir->mkdir();
   }
-  while(archiveFilesForCatalogue.hasMore()) {
+  double elapsedTime = 0;
+  bool stopExpansion = false;
+  while(archiveFilesForCatalogue.hasMore() && !stopExpansion) {
     size_t filesCount = 0;
     uint64_t maxAddedFSeq = 0;
     std::list<SchedulerDatabase::RepackRequest::Subrequest> retrieveSubrequests;
-    while(filesCount < c_defaultMaxNbFilesForRepack && archiveFilesForCatalogue.hasMore())
+    repackRequest->m_dbReq->setExpandStartedAndChangeStatus();
+    while(filesCount < c_defaultMaxNbFilesForRepack && !stopExpansion && archiveFilesForCatalogue.hasMore())
     {
       filesCount++;
       fSeq++;
@@ -487,8 +525,8 @@ void Scheduler::expandRepackRequest(std::unique_ptr<RepackRequest>& repackReques
         cta::disk::DiskFileFactory fileFactory("",0,radosStriperPool);
         cta::disk::ReadFile *fileReader = fileFactory.createReadFile(dirBufferURL.str() + fileName.str());
         if(fileReader->size() == archiveFile.fileSize){
-          createArchiveSubrequest = true;
-          retrieveSubrequests.pop_back();
+          /*createArchiveSubrequest = true;
+          retrieveSubrequests.pop_back();*/
           //TODO : We don't want to retrieve the file again, create archive subrequest
         }
       }
@@ -516,17 +554,27 @@ void Scheduler::expandRepackRequest(std::unique_ptr<RepackRequest>& repackReques
           retrieveSubRequest.fileBufferURL = dirBufferURL.str() + fileName.str();
         }
       }
+      stopExpansion = (elapsedTime >= m_repackRequestExpansionTimeLimit);
     }
     // Note: the highest fSeq will be recorded internally in the following call.
     // We know that the fSeq processed on the tape are >= initial fSeq + filesCount - 1 (or fSeq - 1 as we counted). 
     // We pass this information to the db for recording in the repack request. This will allow restarting from the right
     // value in case of crash.
-    repackRequest->m_dbReq->setTotalStats(totalStatsFile);
-    repackRequest->m_dbReq->addSubrequests(retrieveSubrequests, archiveRoutesMap, fSeq - 1, lc);
-    fSeq = std::max(fSeq, maxAddedFSeq + 1);
-    repackRequest->m_dbReq->setLastExpandedFSeq(fSeq);
+    repackRequest->m_dbReq->addSubrequestsAndUpdateStats(retrieveSubrequests, archiveRoutesMap, fSeq - 1, maxAddedFSeq, totalStatsFile, lc);
+    timingList.insertAndReset("addSubrequestsAndUpdateStatsTime",t);
+  }
+  log::ScopedParamContainer params(lc);
+  params.add("tapeVid",repackInfo.vid);
+  timingList.addToLog(params);
+  if(archiveFilesForCatalogue.hasMore()){
+    if(stopExpansion){
+      repackRequest->m_dbReq->requeueInToExpandQueue(lc);
+      lc.log(log::INFO,"Expansion time reached, Repack Request requeued in ToExpand queue.");
+    }
+  } else {
+    repackRequest->m_dbReq->expandDone();
+    lc.log(log::INFO,"In Scheduler::expandRepackRequest(), repack request expanded");
   }
-  repackRequest->m_dbReq->expandDone();
 }
 
 //------------------------------------------------------------------------------
diff --git a/scheduler/Scheduler.hpp b/scheduler/Scheduler.hpp
index 5448685c72604d977427db786523ac86053b9266..d0e2aa2985b6bd7078d081d91a10966abd082262 100644
--- a/scheduler/Scheduler.hpp
+++ b/scheduler/Scheduler.hpp
@@ -265,6 +265,12 @@ public:
   /*============== Actual mount scheduling and queue status reporting ========*/
 private:
   const size_t c_defaultMaxNbFilesForRepack = 500;
+  /**
+   * This time is used to limitate the time an expansion of a RepackRequest will take
+   * If the RepackRequest has not finished its expansion before this time limit,
+   * it will be requeued in the RepackQueueToExpand queue.
+   */
+  double m_repackRequestExpansionTimeLimit = 30;
   
   typedef std::pair<std::string, common::dataStructures::MountType> tpType;
   /**
@@ -276,6 +282,13 @@ private:
     std::map<tpType, uint32_t> & existingMountsSummary, std::set<std::string> & tapesInUse, std::list<catalogue::TapeForWriting> & tapeList,
     double & getTapeInfoTime, double & candidateSortingTime, double & getTapeForWriteTime, log::LogContext & lc);
   
+  /**
+   * Checks wether the tape is full before repacking
+   * @param vid the vid of the tape to check
+   * @throws a UserError exception if the vid does not exist or if
+   * the tape is not full
+   */
+  void checkTapeFullBeforeRepack(std::string vid);
   
 public:
   /**
@@ -372,6 +385,10 @@ public:
 
   /*======================== Administrator management ========================*/
   void authorizeAdmin(const cta::common::dataStructures::SecurityIdentity &cliIdentity, log::LogContext & lc);
+  
+  void setRepackRequestExpansionTimeLimit(const double &time);
+  
+  double getRepackRequestExpansionTimeLimit() const;
 
 private:
 
diff --git a/scheduler/SchedulerDatabase.hpp b/scheduler/SchedulerDatabase.hpp
index 67508481059853932ecc639994fed5f9cb44b3fb..ee1de1f9ba1c223e66c5a0995f4c47411d70b087 100644
--- a/scheduler/SchedulerDatabase.hpp
+++ b/scheduler/SchedulerDatabase.hpp
@@ -450,11 +450,13 @@ public:
       //TODO : userprovidedfiles and userprovidedbytes
     };
     
-    virtual void addSubrequests(std::list<Subrequest>& repackSubrequests, 
-      cta::common::dataStructures::ArchiveRoute::FullMap & archiveRoutesMap, uint64_t maxFSeqLowBound, log::LogContext & lc) = 0;
-    virtual void setTotalStats(const TotalStatsFiles& stats) = 0;
+    virtual void addSubrequestsAndUpdateStats(std::list<Subrequest>& repackSubrequests, 
+      cta::common::dataStructures::ArchiveRoute::FullMap & archiveRoutesMap, uint64_t maxFSeqLowBound, const uint64_t maxAddedFSeq, const TotalStatsFiles &totalStatsFiles, log::LogContext & lc) = 0;
     virtual void expandDone() = 0;
     virtual void fail() = 0;
+    virtual void requeueInToExpandQueue(log::LogContext &lc) = 0;
+    virtual void setExpandStartedAndChangeStatus() = 0;
+    virtual void fillLastExpandedFSeqAndTotalStatsFile(uint64_t &fSeq, TotalStatsFiles &totalStatsFiles) = 0;
     virtual ~RepackRequest() {}
   };
   
diff --git a/scheduler/SchedulerTest.cpp b/scheduler/SchedulerTest.cpp
index e19034f0fabfb562cece3346815ec6f00858a26e..3067e541ae811a8175c9a2cd399127a319de6f68 100644
--- a/scheduler/SchedulerTest.cpp
+++ b/scheduler/SchedulerTest.cpp
@@ -53,6 +53,7 @@
 #include <gtest/gtest.h>
 #include <memory>
 #include <utility>
+#include <bits/unique_ptr.h>
 
 namespace unitTests {
 
@@ -214,7 +215,9 @@ public:
     const std::string tapePoolComment = "Tape-pool comment";
     const std::string vo = "vo";
     const bool tapePoolEncryption = false;
-    catalogue.createTapePool(s_adminOnAdminHost, s_tapePoolName, vo, nbPartialTapes, tapePoolEncryption, tapePoolComment);
+    const cta::optional<std::string> tapePoolSupply("value for the supply pool mechanism");
+    catalogue.createTapePool(s_adminOnAdminHost, s_tapePoolName, vo, nbPartialTapes, tapePoolEncryption, tapePoolSupply,
+      tapePoolComment);
     const uint32_t copyNb = 1;
     const std::string archiveRouteComment = "Archive-route comment";
     catalogue.createArchiveRoute(s_adminOnAdminHost, s_diskInstance, s_storageClassName, copyNb, s_tapePoolName,
@@ -432,8 +435,9 @@ TEST_P(SchedulerTest, archive_report_and_retrieve_new_file) {
 
   // Create the environment for the migration to happen (library + tape) 
   const std::string libraryComment = "Library comment";
+  const bool libraryIsDisabled = false;
   catalogue.createLogicalLibrary(s_adminOnAdminHost, s_libraryName,
-    libraryComment);
+    libraryIsDisabled, libraryComment);
   {
     auto libraries = catalogue.getLogicalLibraries();
     ASSERT_EQ(1, libraries.size());
@@ -631,8 +635,9 @@ TEST_P(SchedulerTest, archive_and_retrieve_failure) {
 
   // Create the environment for the migration to happen (library + tape) 
   const std::string libraryComment = "Library comment";
+  const bool libraryIsDisabled = false;
   catalogue.createLogicalLibrary(s_adminOnAdminHost, s_libraryName,
-    libraryComment);
+    libraryIsDisabled, libraryComment);
   {
     auto libraries = catalogue.getLogicalLibraries();
     ASSERT_EQ(1, libraries.size());
@@ -881,8 +886,9 @@ TEST_P(SchedulerTest, archive_and_retrieve_report_failure) {
 
   // Create the environment for the migration to happen (library + tape) 
   const std::string libraryComment = "Library comment";
+  const bool libraryIsDisabled = false;
   catalogue.createLogicalLibrary(s_adminOnAdminHost, s_libraryName,
-    libraryComment);
+    libraryIsDisabled, libraryComment);
   {
     auto libraries = catalogue.getLogicalLibraries();
     ASSERT_EQ(1, libraries.size());
@@ -1125,8 +1131,9 @@ TEST_P(SchedulerTest, retry_archive_until_max_reached) {
   
   // Create the environment for the migration to happen (library + tape) 
     const std::string libraryComment = "Library comment";
+  const bool libraryIsDisabled = false;
   catalogue.createLogicalLibrary(s_adminOnAdminHost, s_libraryName,
-    libraryComment);
+    libraryIsDisabled, libraryComment);
   {
     auto libraries = catalogue.getLogicalLibraries();
     ASSERT_EQ(1, libraries.size());
@@ -1247,16 +1254,35 @@ TEST_P(SchedulerTest, repack) {
   setupDefaultCatalogue();
   
   Scheduler &scheduler = getScheduler();
-  
+  cta::catalogue::Catalogue& catalogue = getCatalogue();
+    
   log::DummyLogger dl("", "");
   log::LogContext lc(dl);
   
   typedef cta::common::dataStructures::RepackInfo RepackInfo;
   typedef cta::common::dataStructures::RepackInfo::Status Status;
   
-  // Create and then cancel repack
+   // Create the environment for the migration to happen (library + tape) 
+  const std::string libraryComment = "Library comment";
+  const bool libraryIsDisabled = false;
+  catalogue.createLogicalLibrary(s_adminOnAdminHost, s_libraryName,
+    libraryIsDisabled, libraryComment);
+  
   common::dataStructures::SecurityIdentity cliId;
+  cliId.host = "host";
+  cliId.username = s_userName;
   std::string tape1 = "Tape";
+  
+  catalogue.createTape(cliId,tape1,"mediaType","vendor",s_libraryName,s_tapePoolName,500,false,false,"Comment");
+  
+  //The queueing of a repack request should fail if the tape to repack is not full
+  ASSERT_THROW(scheduler.queueRepack(cliId, tape1, "file://"+tempDirectory.path(), common::dataStructures::RepackInfo::Type::MoveOnly, lc),cta::exception::UserError);
+  //The queueing of a repack request in a vid that does not exist should throw an exception
+  ASSERT_THROW(scheduler.queueRepack(cliId, "NOT_EXIST", "file://"+tempDirectory.path(), common::dataStructures::RepackInfo::Type::MoveOnly, lc),cta::exception::UserError);
+  
+  catalogue.setTapeFull(cliId,tape1,true);
+  
+  // Create and then cancel repack
   scheduler.queueRepack(cliId, tape1, "file://"+tempDirectory.path(), common::dataStructures::RepackInfo::Type::MoveOnly, lc);
   {
     auto repacks = scheduler.getRepacks();
@@ -1267,12 +1293,14 @@ TEST_P(SchedulerTest, repack) {
   scheduler.cancelRepack(cliId, tape1, lc);
   ASSERT_EQ(0, scheduler.getRepacks().size());
   // Recreate a repack and get it moved to ToExpand
-  scheduler.queueRepack(cliId, "Tape2", "file://"+tempDirectory.path(), common::dataStructures::RepackInfo::Type::MoveOnly, lc);
+  std::string tape2 = "Tape2";
+  catalogue.createTape(cliId,tape2,"mediaType","vendor",s_libraryName,s_tapePoolName,500,false,true,"Comment");
+  scheduler.queueRepack(cliId, tape2, "file://"+tempDirectory.path(), common::dataStructures::RepackInfo::Type::MoveOnly, lc);
   {
     auto repacks = scheduler.getRepacks();
     ASSERT_EQ(1, repacks.size());
     auto repack = scheduler.getRepack(repacks.front().vid);
-    ASSERT_EQ("Tape2", repack.vid);
+    ASSERT_EQ(tape2, repack.vid);
   }
   scheduler.promoteRepackRequestsToToExpand(lc);
   {
@@ -1289,16 +1317,30 @@ TEST_P(SchedulerTest, getNextRepackRequestToExpand) {
   setupDefaultCatalogue();
   
   Scheduler &scheduler = getScheduler();
+  catalogue::Catalogue& catalogue = getCatalogue();
   
   log::DummyLogger dl("", "");
   log::LogContext lc(dl);
   
-  // Create a repack request
+  // Create the environment for the migration to happen (library + tape) 
+  const std::string libraryComment = "Library comment";
+  const bool libraryIsDisabled = false;
+  catalogue.createLogicalLibrary(s_adminOnAdminHost, s_libraryName,
+    libraryIsDisabled, libraryComment);
+  
   common::dataStructures::SecurityIdentity cliId;
+  cliId.host = "host";
+  cliId.username = s_userName;
   std::string tape1 = "Tape";
+  catalogue.createTape(cliId,tape1,"mediaType","vendor",s_libraryName,s_tapePoolName,500,false,true,"Comment");
+  
+  //Queue the first repack request
   scheduler.queueRepack(cliId, tape1, "file://"+tempDirectory.path(), common::dataStructures::RepackInfo::Type::MoveOnly, lc);
   
   std::string tape2 = "Tape2";
+  catalogue.createTape(cliId,tape2,"mediaType","vendor",s_libraryName,s_tapePoolName,500,false,true,"Comment");
+  
+  //Queue the second repack request
   scheduler.queueRepack(cliId,tape2,"file://"+tempDirectory.path(),common::dataStructures::RepackInfo::Type::AddCopiesOnly,lc);
   
   //Test the repack request queued has status Pending
@@ -1354,7 +1396,7 @@ TEST_P(SchedulerTest, expandRepackRequest) {
   
   const uint64_t capacityInBytes = (uint64_t)10 * 1000 * 1000 * 1000 * 1000;
   const bool disabledValue = false;
-  const bool fullValue = false;
+  const bool fullValue = true;
   const std::string comment = "Create tape";
   cta::common::dataStructures::SecurityIdentity admin;
   admin.username = "admin_user_name";
@@ -1363,7 +1405,8 @@ TEST_P(SchedulerTest, expandRepackRequest) {
   const std::string diskFileGroup = "public_disk_group";
   
   //Create a logical library in the catalogue
-  catalogue.createLogicalLibrary(admin, s_libraryName, "Create logical library");
+  const bool libraryIsDisabled = false;
+  catalogue.createLogicalLibrary(admin, s_libraryName, libraryIsDisabled, "Create logical library");
   
   uint64_t nbTapesToRepack = 10;
   uint64_t nbTapesForTest = 2; //corresponds to the targetAvailableRequests variable in the Scheduler::promoteRepackRequestsToToExpand() method
@@ -1510,23 +1553,23 @@ TEST_P(SchedulerTest, expandRepackRequest) {
         executedJobs.push_back(std::move(retrieveJob));
       }
       //Now, report the retrieve jobs to be completed
-        castor::tape::tapeserver::daemon::RecallReportPacker rrp(retrieveMount.get(),lc);
+      castor::tape::tapeserver::daemon::RecallReportPacker rrp(retrieveMount.get(),lc);
 
-        rrp.startThreads();
-        for(auto it = executedJobs.begin(); it != executedJobs.end(); ++it)
-        {
-          rrp.reportCompletedJob(std::move(*it));
-        }
-        rrp.setDiskDone();
-        rrp.setTapeDone();
+      rrp.startThreads();
+      for(auto it = executedJobs.begin(); it != executedJobs.end(); ++it)
+      {
+        rrp.reportCompletedJob(std::move(*it));
+      }
+      rrp.setDiskDone();
+      rrp.setTapeDone();
 
-        rrp.reportDriveStatus(cta::common::dataStructures::DriveStatus::Unmounting);
+      rrp.reportDriveStatus(cta::common::dataStructures::DriveStatus::Unmounting);
 
-        rrp.reportEndOfSession();
-        rrp.waitThread();
+      rrp.reportEndOfSession();
+      rrp.waitThread();
 
-        ASSERT_EQ(rrp.allThreadsDone(),true);
-      }
+      ASSERT_EQ(rrp.allThreadsDone(),true);
+    }
     
     uint64_t archiveFileId = 1;
     for(uint64_t i = 1; i<= nbTapesForTest ;++i)
@@ -1689,7 +1732,7 @@ TEST_P(SchedulerTest, expandRepackRequestRetrieveFailed) {
   
   const uint64_t capacityInBytes = (uint64_t)10 * 1000 * 1000 * 1000 * 1000;
   const bool disabledValue = false;
-  const bool fullValue = false;
+  const bool fullValue = true;
   const std::string comment = "Create tape";
   cta::common::dataStructures::SecurityIdentity admin;
   admin.username = "admin_user_name";
@@ -1698,7 +1741,8 @@ TEST_P(SchedulerTest, expandRepackRequestRetrieveFailed) {
   const std::string diskFileGroup = "public_disk_group";
   
   //Create a logical library in the catalogue
-  catalogue.createLogicalLibrary(admin, s_libraryName, "Create logical library");
+  const bool libraryIsDisabled = false;
+  catalogue.createLogicalLibrary(admin, s_libraryName, libraryIsDisabled, "Create logical library");
   
   std::ostringstream ossVid;
   ossVid << s_vid << "_" << 1;
@@ -1928,7 +1972,7 @@ TEST_P(SchedulerTest, expandRepackRequestArchiveSuccess) {
   
   const uint64_t capacityInBytes = (uint64_t)10 * 1000 * 1000 * 1000 * 1000;
   const bool disabledValue = false;
-  const bool fullValue = false;
+  const bool fullValue = true;
   const std::string comment = "Create tape";
   cta::common::dataStructures::SecurityIdentity admin;
   admin.username = "admin_user_name";
@@ -1937,13 +1981,18 @@ TEST_P(SchedulerTest, expandRepackRequestArchiveSuccess) {
   const std::string diskFileGroup = "public_disk_group";
   
   //Create a logical library in the catalogue
-  catalogue.createLogicalLibrary(admin, s_libraryName, "Create logical library");
+  const bool libraryIsDisabled = false;
+  catalogue.createLogicalLibrary(admin, s_libraryName, libraryIsDisabled, "Create logical library");
   
   std::ostringstream ossVid;
   ossVid << s_vid << "_" << 1;
   std::string vid = ossVid.str();
   catalogue.createTape(s_adminOnAdminHost,vid, s_mediaType, s_vendor, s_libraryName, s_tapePoolName, capacityInBytes,
     disabledValue, fullValue, comment);
+  //Create a repack destination tape
+  std::string vidDestination = "vidDestination";
+  catalogue.createTape(s_adminOnAdminHost,vidDestination, s_mediaType, s_vendor, s_libraryName, s_tapePoolName, capacityInBytes,
+    disabledValue, false, comment);
   
   //Create a storage class in the catalogue
   common::dataStructures::StorageClass storageClass;
@@ -2174,7 +2223,7 @@ TEST_P(SchedulerTest, expandRepackRequestArchiveFailed) {
   
   const uint64_t capacityInBytes = (uint64_t)10 * 1000 * 1000 * 1000 * 1000;
   const bool disabledValue = false;
-  const bool fullValue = false;
+  const bool fullValue = true;
   const std::string comment = "Create tape";
   cta::common::dataStructures::SecurityIdentity admin;
   admin.username = "admin_user_name";
@@ -2183,13 +2232,19 @@ TEST_P(SchedulerTest, expandRepackRequestArchiveFailed) {
   const std::string diskFileGroup = "public_disk_group";
   
   //Create a logical library in the catalogue
-  catalogue.createLogicalLibrary(admin, s_libraryName, "Create logical library");
+  const bool libraryIsDisabled = false;
+  catalogue.createLogicalLibrary(admin, s_libraryName, libraryIsDisabled, "Create logical library");
   
   std::ostringstream ossVid;
   ossVid << s_vid << "_" << 1;
   std::string vid = ossVid.str();
   catalogue.createTape(s_adminOnAdminHost,vid, s_mediaType, s_vendor, s_libraryName, s_tapePoolName, capacityInBytes,
     disabledValue, fullValue, comment);
+
+  //Create a repack destination tape
+  std::string vidDestinationRepack = "vidDestinationRepack";
+  catalogue.createTape(s_adminOnAdminHost,vidDestinationRepack, s_mediaType, s_vendor, s_libraryName, s_tapePoolName, capacityInBytes,
+   disabledValue, false, comment);
   
   //Create a storage class in the catalogue
   common::dataStructures::StorageClass storageClass;
@@ -2446,6 +2501,127 @@ TEST_P(SchedulerTest, expandRepackRequestArchiveFailed) {
   }
 }
 
+TEST_P(SchedulerTest, expandRepackRequestExpansionTimeLimitReached) {
+  using namespace cta;
+  using namespace cta::objectstore;
+  unitTests::TempDirectory tempDirectory;
+  auto &catalogue = getCatalogue();
+  auto &scheduler = getScheduler();
+  //Set the expansion time limit to 0
+  scheduler.setRepackRequestExpansionTimeLimit(0.0);
+  auto &schedulerDB = getSchedulerDB();
+  cta::objectstore::Backend& backend = schedulerDB.getBackend();
+  setupDefaultCatalogue();
+#ifdef STDOUT_LOGGING
+  log::StdoutLogger dl("dummy", "unitTest");
+#else
+  log::DummyLogger dl("", "");
+#endif
+  log::LogContext lc(dl);
+  
+  //Create an agent to represent this test process
+  cta::objectstore::AgentReference agentReference("expandRepackRequestTest", dl);
+  cta::objectstore::Agent agent(agentReference.getAgentAddress(), backend);
+  agent.initialize();
+  agent.setTimeout_us(0);
+  agent.insertAndRegisterSelf(lc);
+  
+  const uint64_t capacityInBytes = (uint64_t)10 * 1000 * 1000 * 1000 * 1000;
+  const bool disabledValue = false;
+  const bool fullValue = true;
+  const std::string comment = "Create tape";
+  cta::common::dataStructures::SecurityIdentity admin;
+  admin.username = "admin_user_name";
+  admin.host = "admin_host";
+  const std::string diskFileUser = "public_disk_user";
+  const std::string diskFileGroup = "public_disk_group";
+  
+  //Create a logical library in the catalogue
+  const bool logicalLibraryIsDisabled = false;
+  catalogue.createLogicalLibrary(admin, s_libraryName, logicalLibraryIsDisabled, "Create logical library");
+  
+  std::ostringstream ossVid;
+  ossVid << s_vid << "_" << 1;
+  std::string vid = ossVid.str();
+  catalogue.createTape(s_adminOnAdminHost,vid, s_mediaType, s_vendor, s_libraryName, s_tapePoolName, capacityInBytes,
+    disabledValue, fullValue, comment);
+  
+  //Create a storage class in the catalogue
+  common::dataStructures::StorageClass storageClass;
+  storageClass.diskInstance = s_diskInstance;
+  storageClass.name = s_storageClassName;
+  storageClass.nbCopies = 2;
+  storageClass.comment = "Create storage class";
+
+  const std::string checksumType = "checksum_type";
+  const std::string checksumValue = "checksum_value";
+  const std::string tapeDrive = "tape_drive";
+  const uint64_t nbArchiveFilesPerTape = 10;
+  const uint64_t archiveFileSize = 2 * 1000 * 1000 * 1000;
+  const uint64_t compressedFileSize = archiveFileSize;
+  
+  //Simulate the writing of 10 files in 1 tape in the catalogue
+  std::set<catalogue::TapeItemWrittenPointer> tapeFilesWrittenCopy1;
+  {
+    uint64_t archiveFileId = 1;
+    std::string currentVid = vid;
+    for(uint64_t j = 1; j <= nbArchiveFilesPerTape; ++j) {
+      std::ostringstream diskFileId;
+      diskFileId << (12345677 + archiveFileId);
+      std::ostringstream diskFilePath;
+      diskFilePath << "/public_dir/public_file_"<<1<<"_"<< j;
+      auto fileWrittenUP=cta::make_unique<cta::catalogue::TapeFileWritten>();
+      auto & fileWritten = *fileWrittenUP;
+      fileWritten.archiveFileId = archiveFileId++;
+      fileWritten.diskInstance = storageClass.diskInstance;
+      fileWritten.diskFileId = diskFileId.str();
+      fileWritten.diskFilePath = diskFilePath.str();
+      fileWritten.diskFileUser = diskFileUser;
+      fileWritten.diskFileGroup = diskFileGroup;
+      fileWritten.size = archiveFileSize;
+      fileWritten.checksumType = checksumType;
+      fileWritten.checksumValue = checksumValue;
+      fileWritten.storageClassName = s_storageClassName;
+      fileWritten.vid = currentVid;
+      fileWritten.fSeq = j;
+      fileWritten.blockId = j * 100;
+      fileWritten.compressedSize = compressedFileSize;
+      fileWritten.copyNb = 1;
+      fileWritten.tapeDrive = tapeDrive;
+      tapeFilesWrittenCopy1.emplace(fileWrittenUP.release());
+    }
+    //update the DB tape
+    catalogue.filesWrittenToTape(tapeFilesWrittenCopy1);
+    tapeFilesWrittenCopy1.clear();
+  }
+  //Test the expanding requeue the Repack after the creation of 
+  //one retrieve request
+  scheduler.waitSchedulerDbSubthreadsComplete();
+  {
+    scheduler.queueRepack(admin,vid,"file://"+tempDirectory.path(),common::dataStructures::RepackInfo::Type::MoveOnly,lc);
+    scheduler.waitSchedulerDbSubthreadsComplete();
+
+    log::TimingList tl;
+    utils::Timer t;
+
+    scheduler.promoteRepackRequestsToToExpand(lc);
+    scheduler.waitSchedulerDbSubthreadsComplete();
+
+    auto repackRequestToExpand = scheduler.getNextRepackRequestToExpand();
+    scheduler.expandRepackRequest(repackRequestToExpand,tl,t,lc);
+    scheduler.waitSchedulerDbSubthreadsComplete();
+    
+    ASSERT_EQ(vid,repackRequestToExpand->getRepackInfo().vid);
+    //Because the timer is set to 0, the Repack Request should
+    //have been requeued in the ToExpand queue.
+    //We check that by the getNextRepackRequestToExpand method
+    repackRequestToExpand = scheduler.getNextRepackRequestToExpand();
+    ASSERT_NE(nullptr,repackRequestToExpand);
+    ASSERT_EQ(vid,repackRequestToExpand->getRepackInfo().vid);
+    
+  }
+}
+
 #undef TEST_MOCK_DB
 #ifdef TEST_MOCK_DB
 static cta::MockSchedulerDatabaseFactory mockDbFactory;
diff --git a/tapeserver/castor/tape/tapeserver/daemon/DataTransferSessionTest.cpp b/tapeserver/castor/tape/tapeserver/daemon/DataTransferSessionTest.cpp
index ac371d79d09981b1b9e3720cede9ffbddd26f0fa..4bd976026c1b9892e871d48d0d9544448af9392c 100644
--- a/tapeserver/castor/tape/tapeserver/daemon/DataTransferSessionTest.cpp
+++ b/tapeserver/castor/tape/tapeserver/daemon/DataTransferSessionTest.cpp
@@ -295,8 +295,9 @@ public:
     const std::string tapePoolComment = "Tape-pool comment";
     const std::string vo = "vo";
     const bool tapePoolEncryption = false;
+    const cta::optional<std::string> tapePoolSupply("value for the supply pool mechanism");
     ASSERT_NO_THROW(catalogue.createTapePool(s_adminOnAdminHost, s_tapePoolName, vo, nbPartialTapes, tapePoolEncryption,
-      tapePoolComment));
+      tapePoolSupply, tapePoolComment));
     const uint32_t copyNb = 1;
     const std::string archiveRouteComment = "Archive-route comment";
     catalogue.createArchiveRoute(s_adminOnAdminHost, s_diskInstance, s_storageClassName, copyNb, s_tapePoolName,
@@ -373,8 +374,9 @@ TEST_P(DataTransferSessionTest, DataTransferSessionGooddayRecall) {
   
   // 5) Create the environment for the migration to happen (library + tape) 
     const std::string libraryComment = "Library comment";
+  const bool libraryIsDisabled = false;
   catalogue.createLogicalLibrary(s_adminOnAdminHost, s_libraryName,
-    libraryComment);
+    libraryIsDisabled, libraryComment);
   {
     auto libraries = catalogue.getLogicalLibraries();
     ASSERT_EQ(1, libraries.size());
@@ -553,8 +555,9 @@ TEST_P(DataTransferSessionTest, DataTransferSessionWrongRecall) {
   
   // 5) Create the environment for the migration to happen (library + tape) 
     const std::string libraryComment = "Library comment";
+  const bool libraryIsDisabled = false;
   catalogue.createLogicalLibrary(s_adminOnAdminHost, s_libraryName,
-    libraryComment);
+    libraryIsDisabled, libraryComment);
   {
     auto libraries = catalogue.getLogicalLibraries();
     ASSERT_EQ(1, libraries.size());
@@ -747,8 +750,9 @@ TEST_P(DataTransferSessionTest, DataTransferSessionRAORecall) {
   
   // 5) Create the environment for the migration to happen (library + tape) 
     const std::string libraryComment = "Library comment";
+  const bool libraryIsDisabled = false;
   catalogue.createLogicalLibrary(s_adminOnAdminHost, s_libraryName,
-    libraryComment);
+    libraryIsDisabled, libraryComment);
   {
     auto libraries = catalogue.getLogicalLibraries();
     ASSERT_EQ(1, libraries.size());
@@ -964,8 +968,9 @@ TEST_P(DataTransferSessionTest, DataTransferSessionNoSuchDrive) {
   
   // 5) Create the environment for the migration to happen (library + tape) 
     const std::string libraryComment = "Library comment";
+  const bool libraryIsDisabled = false;
   catalogue.createLogicalLibrary(s_adminOnAdminHost, s_libraryName,
-    libraryComment);
+    libraryIsDisabled, libraryComment);
   {
     auto libraries = catalogue.getLogicalLibraries();
     ASSERT_EQ(1, libraries.size());
@@ -1111,8 +1116,9 @@ TEST_P(DataTransferSessionTest, DataTransferSessionFailtoMount) {
   
   // 5) Create the environment for the migration to happen (library + tape) 
     const std::string libraryComment = "Library comment";
+  const bool libraryIsDisabled = false;
   catalogue.createLogicalLibrary(s_adminOnAdminHost, s_libraryName,
-    libraryComment);
+    libraryIsDisabled, libraryComment);
   {
     auto libraries = catalogue.getLogicalLibraries();
     ASSERT_EQ(1, libraries.size());
@@ -1268,8 +1274,9 @@ TEST_P(DataTransferSessionTest, DataTransferSessionGooddayMigration) {
   
   // 5) Create the environment for the migration to happen (library + tape) 
     const std::string libraryComment = "Library comment";
+  const bool libraryIsDisabled = false;
   catalogue.createLogicalLibrary(s_adminOnAdminHost, s_libraryName,
-    libraryComment);
+    libraryIsDisabled, libraryComment);
   {
     auto libraries = catalogue.getLogicalLibraries();
     ASSERT_EQ(1, libraries.size());
@@ -1410,8 +1417,9 @@ TEST_P(DataTransferSessionTest, DataTransferSessionMissingFilesMigration) {
   
   // 5) Create the environment for the migration to happen (library + tape) 
     const std::string libraryComment = "Library comment";
+  const bool libraryIsDisabled = false;
   catalogue.createLogicalLibrary(s_adminOnAdminHost, s_libraryName,
-    libraryComment);
+    libraryIsDisabled, libraryComment);
   {
     auto libraries = catalogue.getLogicalLibraries();
     ASSERT_EQ(1, libraries.size());
@@ -1568,8 +1576,9 @@ TEST_P(DataTransferSessionTest, DataTransferSessionTapeFullMigration) {
   
   // 5) Create the environment for the migration to happen (library + tape) 
     const std::string libraryComment = "Library comment";
+  const bool libraryIsDisabled = false;
   catalogue.createLogicalLibrary(s_adminOnAdminHost, s_libraryName,
-    libraryComment);
+    libraryIsDisabled, libraryComment);
   {
     auto libraries = catalogue.getLogicalLibraries();
     ASSERT_EQ(1, libraries.size());
@@ -1724,8 +1733,9 @@ TEST_P(DataTransferSessionTest, DataTransferSessionTapeFullOnFlushMigration) {
   
   // 5) Create the environment for the migration to happen (library + tape) 
     const std::string libraryComment = "Library comment";
+  const bool libraryIsDisabled = false;
   catalogue.createLogicalLibrary(s_adminOnAdminHost, s_libraryName,
-    libraryComment);
+    libraryIsDisabled, libraryComment);
   {
     auto libraries = catalogue.getLogicalLibraries();
     ASSERT_EQ(1, libraries.size());
@@ -1878,8 +1888,9 @@ TEST_P(DataTransferSessionTest, WriteDataInTapeWithNonSupersededFilesOnIt) {
   
   // 5) Create the environment for the migration to happen (library + tape) 
     const std::string libraryComment = "Library comment";
+  const bool libraryIsDisabled = false;
   catalogue.createLogicalLibrary(s_adminOnAdminHost, s_libraryName,
-    libraryComment);
+    libraryIsDisabled, libraryComment);
   {
     auto libraries = catalogue.getLogicalLibraries();
     ASSERT_EQ(1, libraries.size());
diff --git a/tapeserver/castor/tape/tapeserver/daemon/MigrationReportPackerTest.cpp b/tapeserver/castor/tape/tapeserver/daemon/MigrationReportPackerTest.cpp
index 297d99caa0a5a6eb7ef515d912f2b69f2890a921..9b7f5028611ccf401b645bd07c184a63d9b348f9 100644
--- a/tapeserver/castor/tape/tapeserver/daemon/MigrationReportPackerTest.cpp
+++ b/tapeserver/castor/tape/tapeserver/daemon/MigrationReportPackerTest.cpp
@@ -116,16 +116,18 @@ namespace unitTests {
     const std::string mediaType = "media_type";
     const std::string vendor = "vendor";
     const std::string logicalLibraryName = "logical_library_name";
+    const bool logicalLibraryIsDisabled = false;
     const std::string tapePoolName = "tape_pool_name";
     const std::string vo = "vo";
+    const cta::optional<std::string> supply("value for the supply pool mechanism");
     const uint64_t capacityInBytes = (uint64_t)10 * 1000 * 1000 * 1000 * 1000;
     const bool disabledValue = true;
     const bool fullValue = false;
     const std::string createTapeComment = "Create tape";
     cta::common::dataStructures::SecurityIdentity admin = cta::common::dataStructures::SecurityIdentity("admin","localhost");
 
-    m_catalogue->createLogicalLibrary(admin, logicalLibraryName, "Create logical library");
-    m_catalogue->createTapePool(admin, tapePoolName, vo, 2, true, "Create tape pool");
+    m_catalogue->createLogicalLibrary(admin, logicalLibraryName, logicalLibraryIsDisabled, "Create logical library");
+    m_catalogue->createTapePool(admin, tapePoolName, vo, 2, true, supply, "Create tape pool");
     m_catalogue->createTape(admin, vid1, mediaType, vendor, logicalLibraryName, tapePoolName, capacityInBytes,
       disabledValue, fullValue, createTapeComment);
 
@@ -262,16 +264,20 @@ namespace unitTests {
     const std::string mediaType = "media_type";
     const std::string vendor = "vendor";
     const std::string logicalLibraryName = "logical_library_name";
+    const bool logicalLibraryIsDisabled = false;
     const std::string tapePoolName = "tape_pool_name";
     const std::string vo = "vo";
+    const uint64_t nbPartialTapes = 2;
+    const bool isEncrypted = true;
+    const cta::optional<std::string> supply("value for the supply pool mechanism");
     const uint64_t capacityInBytes = (uint64_t)10 * 1000 * 1000 * 1000 * 1000;
     const bool disabledValue = true;
     const bool fullValue = false;
     const std::string createTapeComment = "Create tape";
     cta::common::dataStructures::SecurityIdentity admin = cta::common::dataStructures::SecurityIdentity("admin","localhost");
 
-    m_catalogue->createLogicalLibrary(admin, logicalLibraryName, "Create logical library");
-    m_catalogue->createTapePool(admin, tapePoolName, vo, 2, true, "Create tape pool");
+    m_catalogue->createLogicalLibrary(admin, logicalLibraryName, logicalLibraryIsDisabled, "Create logical library");
+    m_catalogue->createTapePool(admin, tapePoolName, vo, nbPartialTapes, isEncrypted, supply, "Create tape pool");
     m_catalogue->createTape(admin, vid1, mediaType, vendor, logicalLibraryName, tapePoolName, capacityInBytes,
       disabledValue, fullValue, createTapeComment);
 
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index 620fd8287a120dfe797ad2fb32f477c2fb9f1094..75f5e3f9504cf8177e0c54e3616ee2d891ad84bc 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -32,6 +32,7 @@ target_link_libraries(cta-unitTests
   ctamediachangerunittests
   ctainmemorycatalogueunittests
   ctainmemoryconnunittests
+  ctainmemorystmtunittests
   ctaobjectstore
   ctaobjectstoreunittests
   ctardbmswrapperunittests
@@ -58,6 +59,8 @@ add_executable(cta-rdbmsUnitTests
 target_link_libraries(cta-rdbmsUnitTests
   ctadbconfigcatalogueunittests
   ctadbconfigconnunittests
+  ctadbconfigstmtunittests
+  ctardbmsunittests
   gtest
   pthread)
 
diff --git a/xroot_plugins/XrdCtaTapePoolLs.hpp b/xroot_plugins/XrdCtaTapePoolLs.hpp
index de855f0494fc6fa6802cfb1ffb99bd1f89386ffa..595d9ae96d9108d315c0be1ac6cf23e6c734f51f 100644
--- a/xroot_plugins/XrdCtaTapePoolLs.hpp
+++ b/xroot_plugins/XrdCtaTapePoolLs.hpp
@@ -91,6 +91,7 @@ public:
         tp_item->set_capacity_bytes(tp.capacityBytes);
         tp_item->set_data_bytes(tp.dataBytes);
         tp_item->set_encrypt(tp.encryption);
+        tp_item->set_supply(tp.supply ? tp.supply.value() : "");
         tp_item->mutable_created()->set_username(tp.creationLog.username);
         tp_item->mutable_created()->set_host(tp.creationLog.host);
         tp_item->mutable_created()->set_time(tp.creationLog.time);
diff --git a/xroot_plugins/XrdSsiCtaRequestMessage.cpp b/xroot_plugins/XrdSsiCtaRequestMessage.cpp
index 7a57bd5124c956d7cb3b80a9099a9b9ca5dabbd4..4d4acb1e6dcc1656d6923b2f0e07e05d3fc2f767 100644
--- a/xroot_plugins/XrdSsiCtaRequestMessage.cpp
+++ b/xroot_plugins/XrdSsiCtaRequestMessage.cpp
@@ -1177,10 +1177,11 @@ void RequestMessage::processLogicalLibrary_Add(const cta::admin::AdminCmd &admin
 {
    using namespace cta::admin;
 
-   auto &name    = getRequired(OptionString::LOGICAL_LIBRARY);
-   auto &comment = getRequired(OptionString::COMMENT);
+   auto &name      = getRequired(OptionString::LOGICAL_LIBRARY);
+   auto isDisabled = getOptional(OptionBoolean::DISABLED);
+   auto &comment   = getRequired(OptionString::COMMENT);
 
-   m_catalogue.createLogicalLibrary(m_cliIdentity, name, comment);
+   m_catalogue.createLogicalLibrary(m_cliIdentity, name, isDisabled ? isDisabled.value() : false, comment);
 
    response.set_type(cta::xrd::Response::RSP_SUCCESS);
 }
@@ -1191,10 +1192,16 @@ void RequestMessage::processLogicalLibrary_Ch(const cta::admin::AdminCmd &adminc
 {
    using namespace cta::admin;
 
-   auto &name    = getRequired(OptionString::LOGICAL_LIBRARY);
-   auto &comment = getRequired(OptionString::COMMENT);
+   auto &name     = getRequired(OptionString::LOGICAL_LIBRARY);
+   auto  disabled = getOptional(OptionBoolean::DISABLED);
+   auto  comment  = getOptional(OptionString::COMMENT);
 
-   m_catalogue.modifyLogicalLibraryComment(m_cliIdentity, name, comment);
+   if(disabled) {
+      m_catalogue.setLogicalLibraryDisabled(m_cliIdentity, name, disabled.value());
+   }
+   if(comment) {
+      m_catalogue.modifyLogicalLibraryComment(m_cliIdentity, name, comment.value());
+   }
 
    response.set_type(cta::xrd::Response::RSP_SUCCESS);
 }
@@ -1226,12 +1233,13 @@ void RequestMessage::processLogicalLibrary_Ls(const cta::admin::AdminCmd &adminc
    {
       std::vector<std::vector<std::string>> responseTable;
       std::vector<std::string> header = {
-         "name","c.user","c.host","c.time","m.user","m.host","m.time","comment"
+         "name","disabled","c.user","c.host","c.time","m.user","m.host","m.time","comment"
       };
       if(has_flag(OptionBoolean::SHOW_HEADER)) responseTable.push_back(header);    
       for(auto it = list.cbegin(); it != list.cend(); it++) {
          std::vector<std::string> currentRow;
          currentRow.push_back(it->name);
+         currentRow.push_back(std::to_string(it->isDisabled));
          addLogInfoToResponseRow(currentRow, it->creationLog, it->lastModificationLog);
          currentRow.push_back(it->comment);
          responseTable.push_back(currentRow);
@@ -2012,8 +2020,9 @@ void RequestMessage::processTapePool_Add(const cta::admin::AdminCmd &admincmd, c
    auto &ptn       = getRequired(OptionUInt64::PARTIAL_TAPES_NUMBER);
    auto &comment   = getRequired(OptionString::COMMENT);
    auto &encrypted = getRequired(OptionBoolean::ENCRYPTED);
+   auto  supply    = getOptional(OptionString::SUPPLY);
 
-   m_catalogue.createTapePool(m_cliIdentity, name, vo, ptn, encrypted, comment);
+   m_catalogue.createTapePool(m_cliIdentity, name, vo, ptn, encrypted, supply, comment);
 
    response.set_type(cta::xrd::Response::RSP_SUCCESS);
 }
@@ -2029,6 +2038,7 @@ void RequestMessage::processTapePool_Ch(const cta::admin::AdminCmd &admincmd, ct
    auto  ptn       = getOptional(OptionUInt64::PARTIAL_TAPES_NUMBER);
    auto  comment   = getOptional(OptionString::COMMENT);
    auto  encrypted = getOptional(OptionBoolean::ENCRYPTED);
+   auto  supply    = getOptional(OptionString::SUPPLY);
 
    if(comment) {
       m_catalogue.modifyTapePoolComment(m_cliIdentity, name, comment.value());
@@ -2042,6 +2052,9 @@ void RequestMessage::processTapePool_Ch(const cta::admin::AdminCmd &admincmd, ct
    if(encrypted) {
       m_catalogue.setTapePoolEncryption(m_cliIdentity, name, encrypted.value());
    }
+   if(supply) {
+      m_catalogue.modifyTapePoolSupply(m_cliIdentity, name, supply.value());
+   }
 
    response.set_type(cta::xrd::Response::RSP_SUCCESS);
 }