diff --git a/middletier/CMakeLists.txt b/middletier/CMakeLists.txt
index 312d5de042b67a1088fe5798d3c2ae1915673aa8..8c50f34d7930d3a03204e9d597dfc90bb7cfafdc 100644
--- a/middletier/CMakeLists.txt
+++ b/middletier/CMakeLists.txt
@@ -20,6 +20,7 @@ set (MIDDLE_TIER_LIB_SRC_FILES
   cta/DirectoryEntry.cpp
   cta/DirectoryIterator.cpp
   cta/DiskException.cpp
+  cta/DriveQuota.cpp
   cta/EosRemoteStorage.cpp
   cta/Exception.cpp
   cta/FileAttribute.cpp
@@ -32,6 +33,7 @@ set (MIDDLE_TIER_LIB_SRC_FILES
   cta/MiddleTierAdmin.cpp
   cta/MiddleTierUser.cpp
   cta/Mount.cpp
+  cta/MountCriteria.cpp
   cta/RemoteStorage.cpp
   cta/RetrievalFileTransfer.cpp
   cta/RetrievalJob.cpp
@@ -52,6 +54,7 @@ set (MIDDLE_TIER_LIB_SRC_FILES
   cta/TapeFileLocation.cpp
   cta/TapePool.cpp
   cta/UserIdentity.cpp
+  cta/UserGroup.cpp
   cta/UserRequest.cpp
   cta/Utils.cpp
   cta/Vfs.cpp
diff --git a/middletier/cta/ArchivalRoute.hpp b/middletier/cta/ArchivalRoute.hpp
index b15205069b01399583f12108a81666b905197fdf..06e147b9065d5ba07b4f2c4a3e040dc18786d8aa 100644
--- a/middletier/cta/ArchivalRoute.hpp
+++ b/middletier/cta/ArchivalRoute.hpp
@@ -32,10 +32,12 @@ public:
    * source disk files.
    * @param copyNb The tape copy number.  Copy numbers start from 1.
    * @param tapePoolName The name of the destination tape pool.
-   * @param creator The identity of the user that created the storage class.
-   * @param comment Comment describing the storage class.
-   * @param creationTime The absolute time at which the configuration item was
-   * created.
+   * @param creator The identity of the user that created this configuration
+   * item.
+   * @param comment Comment describing this configuration item.
+   * @param creationTime Optionally the absolute time at which this
+   * configuration item was created.  If no value is given then the current
+   * time is used.
    */
   ArchivalRoute(
     const std::string &storageClassName,
diff --git a/middletier/cta/ConfigurationItem.hpp b/middletier/cta/ConfigurationItem.hpp
index 5fb2408164cd584bc96d628554c833b9e608c843..566e149c6961bfa709f0f66b1952c389f1fe753a 100644
--- a/middletier/cta/ConfigurationItem.hpp
+++ b/middletier/cta/ConfigurationItem.hpp
@@ -26,11 +26,11 @@ public:
   /**
    * Constructor.
    *
-   * @param creator The identity of the user that created the configuration
+   * @param creator The identity of the user that created this configuration
    * item.
-   * @param comment The comment made by the creator of the configuration
-   * request.
-   * @param creationTime Optionally the absolute time at which the
+   * @param comment The comment made by the creator of this configuration
+   * item.
+   * @param creationTime Optionally the absolute time at which this
    * configuration item was created.  If no value is given then the current
    * time is used.
    */
@@ -38,40 +38,40 @@ public:
     const time_t creationTime = time(NULL));
 
   /**
-   * Returns the identity of the user that created the configuration item.
+   * Returns the identity of the user that created this configuration item.
    *
-   * @return The identity of the user that created the configuration item.
+   * @return The identity of the user that created this configuration item.
    */
   const UserIdentity &getCreator() const throw();
 
   /**
-   * Returns the comment made by the creator of the configuration request.
+   * Returns the comment made by the creator of this configuration request.
    *
-   * @return The comment made by the creator of the configuration request.
+   * @return The comment made by the creator of this configuration request.
    */
   const std::string &getComment() const throw();
 
   /**
-   * Returns the absolute time at which the configuration item was created.
+   * Returns the absolute time at which this configuration item was created.
    *
-   * @return The absolute time at which the configuration item was created.
+   * @return The absolute time at which this configuration item was created.
    */
   time_t getCreationTime() const throw();
 
 private:
 
   /**
-   * The identity of the user that created the configuration item.
+   * The identity of the user that created this configuration item.
    */
   UserIdentity m_creator;
 
   /**
-   * The comment made by the creator of the configuration request.
+   * The comment made by the creator of this configuration request.
    */
   std::string m_comment;
 
   /**
-   * The absolute time at which the configuration item was created.
+   * The absolute time at which this configuration item was created.
    */
   time_t m_creationTime;
 
diff --git a/middletier/cta/DriveQuota.cpp b/middletier/cta/DriveQuota.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..dde8cbb03d54a061e733771cddf7a17accd787a5
--- /dev/null
+++ b/middletier/cta/DriveQuota.cpp
@@ -0,0 +1,31 @@
+#include "cta/DriveQuota.hpp"
+
+//------------------------------------------------------------------------------
+// constructor
+//------------------------------------------------------------------------------
+cta::DriveQuota::DriveQuota():
+  m_minDrives(0),
+  m_maxDrives(0) {
+}
+
+//------------------------------------------------------------------------------
+// constructor
+//------------------------------------------------------------------------------
+cta::DriveQuota::DriveQuota(const uint32_t minDrives, const uint32_t maxDrives):
+  m_minDrives(minDrives),
+  m_maxDrives(maxDrives) {
+}
+
+//------------------------------------------------------------------------------
+// getMinDrives
+//------------------------------------------------------------------------------
+uint32_t cta::DriveQuota::getMinDrives() const throw() {
+  return m_minDrives;
+}
+
+//------------------------------------------------------------------------------
+// getMaxDrives
+//------------------------------------------------------------------------------
+uint32_t cta::DriveQuota::getMaxDrives() const throw() {
+  return m_maxDrives;
+}
diff --git a/middletier/cta/DriveQuota.hpp b/middletier/cta/DriveQuota.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..b59cc5ee65440dbd0407df0627ec3a4d62b41633
--- /dev/null
+++ b/middletier/cta/DriveQuota.hpp
@@ -0,0 +1,54 @@
+#pragma once
+
+#include <stdint.h>
+
+namespace cta {
+
+/**
+ * Class representing a tape-drive quota.
+ */
+class DriveQuota {
+public:
+
+  /**
+   * Constructor.
+   */
+  DriveQuota();
+
+  /**
+   * Constructor.
+   *
+   * @param minDrives The minimum number of drives that should be provided.
+   * @param maxDrives The maximum number of drives that should be provided.
+   */
+  DriveQuota(const uint32_t minDrives, const uint32_t maxDrives);
+
+  /**
+   * Returns the minimum number of drives that should be provided.
+   *
+   * @return The minimum number of drives that should be provided.
+   */
+  uint32_t getMinDrives() const throw();
+
+  /**
+   * Returns the maximum number of drives that should be provided.
+   *
+   * @return The maximum number of drives that should be provided.
+   */
+  uint32_t getMaxDrives() const throw();
+
+private:
+
+  /**
+   * The minimum number of drives that should be provided.
+   */
+  uint32_t m_minDrives;
+
+  /**
+   * The maximum number of drives that should be provided.
+   */
+  uint32_t m_maxDrives;
+
+}; // class DriveQuota
+
+} // namespace cta
diff --git a/middletier/cta/LogicalLibrary.hpp b/middletier/cta/LogicalLibrary.hpp
index 50c74b0e8d10783e5816e5b65c21ad6c5af75b52..79864aafd6ccb0959132c8b65faa5798f7debc35 100644
--- a/middletier/cta/LogicalLibrary.hpp
+++ b/middletier/cta/LogicalLibrary.hpp
@@ -27,9 +27,10 @@ public:
    * Constructor.
    *
    * @param name The name of the logical library.
-   * @param creator The identity of the user that created the logical library.
-   * @param comment The comment describing the logical library.
-   * @param creationTime Optionally the absolute time at which the
+   * @param creator The identity of the user that created this configuration
+   * item.
+   * @param comment The comment describing this configuration item.
+   * @param creationTime Optionally the absolute time at which this
    * configuration item was created.  If no value is given then the current
    * time is used.
    */
diff --git a/middletier/cta/MountCriteria.cpp b/middletier/cta/MountCriteria.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..46014ba3cfaf9a46e501974e2441ded86f665f41
--- /dev/null
+++ b/middletier/cta/MountCriteria.cpp
@@ -0,0 +1,41 @@
+#include "cta/MountCriteria.hpp"
+
+//------------------------------------------------------------------------------
+// constructor
+//------------------------------------------------------------------------------
+cta::MountCriteria::MountCriteria():
+  m_nbBytes(0),
+  m_nbFiles(0),
+  m_ageInSecs(0) {
+}
+
+//------------------------------------------------------------------------------
+// constructor
+//------------------------------------------------------------------------------
+cta::MountCriteria::MountCriteria(const uint64_t nbBytes, const uint64_t nbFiles,
+  const uint64_t ageInSecs):
+  m_nbBytes(nbBytes),
+  m_nbFiles(nbFiles),
+  m_ageInSecs(ageInSecs) {
+}
+
+//------------------------------------------------------------------------------
+// getNbBytes
+//------------------------------------------------------------------------------
+uint64_t cta::MountCriteria::getNbBytes() const throw() {
+  return m_nbBytes;
+}
+
+//------------------------------------------------------------------------------
+// getNbFiles
+//------------------------------------------------------------------------------
+uint64_t cta::MountCriteria::getNbFiles() const throw() {
+  return m_nbFiles;
+}
+
+//------------------------------------------------------------------------------
+// getAgeInSecs
+//------------------------------------------------------------------------------
+uint64_t cta::MountCriteria::getAgeInSecs() const throw() {
+  return m_ageInSecs;
+}
diff --git a/middletier/cta/MountCriteria.hpp b/middletier/cta/MountCriteria.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..8968ce3dab593355ead9527f3c8cc7c90879515f
--- /dev/null
+++ b/middletier/cta/MountCriteria.hpp
@@ -0,0 +1,73 @@
+#pragma once
+
+#include <stdint.h>
+
+namespace cta {
+
+/**
+ * Class representing the criteria be met in order to justify mounting a tape.
+ */
+class MountCriteria {
+public:
+
+  /**
+   * Constructor.
+   */
+  MountCriteria();
+
+  /**
+   * Constructor.
+   *
+   * @param nbBytes The minimum number of queued bytes required to justify a
+   * mount.
+   * @param nbFiles The minimum number of queued files required to justify a
+   * mount.
+   * @param ageInSecs The minimum age in seconds of queued data required to
+   * justify a mount.
+   */
+  MountCriteria(const uint64_t nbBytes, const uint64_t nbFiles,
+    const uint64_t ageInSecs);
+
+  /**
+   * Returns the minimum number of queued bytes required to justify a mount.
+   *
+   * @return The minimum number of queued bytes required to justify a mount.
+   */
+  uint64_t getNbBytes() const throw();
+
+  /**
+   * Returns the minimum number of queued files required to justify a mount.
+   *
+   * @return The minimum number of queued files required to justify a mount.
+   */
+  uint64_t getNbFiles() const throw();
+
+  /**
+   * Returns the minimum age in seconds of queued data required to justify a
+   * mount.
+   *
+   * @return The minimum age in seconds of queued data required to justify a
+   * mount.
+   */
+  uint64_t getAgeInSecs() const throw();
+
+private:
+
+  /**
+   * The minimum number of queued bytes required to justify a mount.
+   */
+  uint64_t m_nbBytes;
+
+  /**
+   * The minimum number of queued files required to justify a mount.
+   */
+  uint64_t m_nbFiles;
+
+  /**
+   * The minimum age in seconds of queued data required to justify a mount.
+   */
+  uint64_t m_ageInSecs;
+
+}; // class MountCriteria
+
+} // namespace cta
diff --git a/middletier/cta/StorageClass.hpp b/middletier/cta/StorageClass.hpp
index 6d34b8bf0dc3f4317551615efb14049bcd44a2c9..0995fd536a7abcba13b5a049ef0906258820cf00 100644
--- a/middletier/cta/StorageClass.hpp
+++ b/middletier/cta/StorageClass.hpp
@@ -29,9 +29,10 @@ public:
    * @param name The name of the storage class.
    * @param nbCopies The number of copies a file associated with this storage
    * class should have on tape.
-   * @param creator The identity of the user that created the storage class.
-   * @param comment The comment describing the storage class.
-   * @param creationTime Optionally the absolute time at which the
+   * @param creator The identity of the user that created this configuration
+   * item.
+   * @param comment The comment describing this configuration item.
+   * @param creationTime Optionally the absolute time at which this
    * configuration item was created.  If no value is given then the current
    * time is used.
    */
diff --git a/middletier/cta/Tape.hpp b/middletier/cta/Tape.hpp
index 1fd5a2af0c9c951d3bd8a145be1f713b6d4bbf13..1af068da1b99d5cb6e7b4e32cb9b611896f64bb4 100644
--- a/middletier/cta/Tape.hpp
+++ b/middletier/cta/Tape.hpp
@@ -32,9 +32,10 @@ public:
    * belongs.
    * @param tapePoolName The name of the tape pool to which the tape belongs.
    * @param capacityInBytes The capacity of the tape.
-   * @param creator The identity of the user that created the tape.
-   * @param comment The comment describing the tape.
-   * @param creationTime Optionally the absolute time at which the
+   * @param creator The identity of the user that created this configuration
+   * item.
+   * @param comment The comment describing this configuration item.
+   * @param creationTime Optionally the absolute time at which this
    * configuration item was created.  If no value is given then the current
    * time is used.
    */
diff --git a/middletier/cta/TapePool.hpp b/middletier/cta/TapePool.hpp
index 43a351c03b91b94564edccf9b90b6d7933372ae4..ee0682f7679b08d8a3b3939b2d0482b643048620 100644
--- a/middletier/cta/TapePool.hpp
+++ b/middletier/cta/TapePool.hpp
@@ -28,9 +28,10 @@ public:
    * @param name The name of the tape pool.
    * @param nbPartialTapes The maximum number of tapes that can be partially
    * full at any moment in time.
-   * @param creator The identity of the user that created the tape pool.
-   * @param comment The comment describing the tape pool.
-   * @param creationTime Optionally the absolute time at which the
+   * @param creator The identity of the user that created this configuration
+   * item.
+   * @param comment The comment describing this configuration item.
+   * @param creationTime Optionally the absolute time at which this
    * configuration item was created.  If no value is given then the current
    * time is used.
    */
diff --git a/middletier/cta/UserGroup.cpp b/middletier/cta/UserGroup.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..9ac0bf1787eb4717ef3c257769d652f15d62562e
--- /dev/null
+++ b/middletier/cta/UserGroup.cpp
@@ -0,0 +1,70 @@
+#include "cta/UserGroup.hpp"
+
+//------------------------------------------------------------------------------
+// constructor
+//------------------------------------------------------------------------------
+cta::UserGroup::UserGroup() {
+}
+
+//------------------------------------------------------------------------------
+// destructor
+//------------------------------------------------------------------------------
+cta::UserGroup::~UserGroup() throw() {
+}
+
+//------------------------------------------------------------------------------
+// constructor
+//------------------------------------------------------------------------------
+cta::UserGroup::UserGroup(
+  const std::string &name,
+  const DriveQuota &archivalDriveQuota,
+  const DriveQuota &retrievalDriveQuota,
+  const MountCriteria &archivalMountCriteria,
+  const MountCriteria &retrievalMountCriteria,
+  const UserIdentity &creator,
+  const std::string &comment,
+  const time_t creationTime):
+  ConfigurationItem(creator, comment, creationTime),
+  m_name(name),
+  m_archivalDriveQuota(archivalDriveQuota),
+  m_retrievalDriveQuota(retrievalDriveQuota),
+  m_archivalMountCriteria(archivalMountCriteria),
+  m_retrievalMountCriteria(retrievalMountCriteria) {
+}
+
+//------------------------------------------------------------------------------
+// getName
+//------------------------------------------------------------------------------
+const std::string &cta::UserGroup::getName() const throw() {
+  return m_name;
+}
+
+//------------------------------------------------------------------------------
+// getArchivalQuota
+//------------------------------------------------------------------------------
+const cta::DriveQuota &cta::UserGroup::getArchivalDriveQuota() const throw() {
+  return m_archivalDriveQuota;
+}
+
+//------------------------------------------------------------------------------
+// getRetrievalQuota
+//------------------------------------------------------------------------------
+const cta::DriveQuota &cta::UserGroup::getRetrievalDriveQuota() const throw() {
+  return m_retrievalDriveQuota;
+}
+
+//------------------------------------------------------------------------------
+// getArchivalMountCriteria
+//------------------------------------------------------------------------------
+const cta::MountCriteria &cta::UserGroup::getArchivalMountCriteria() const
+  throw() {
+  return m_archivalMountCriteria;
+}
+
+//------------------------------------------------------------------------------
+// getRetrievalMountCriteria
+//------------------------------------------------------------------------------
+const cta::MountCriteria &cta::UserGroup::getRetrievalMountCriteria() const
+  throw() {
+  return m_retrievalMountCriteria;
+}
diff --git a/middletier/cta/UserGroup.hpp b/middletier/cta/UserGroup.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..1e511ce11e6588afc1e543506c7b5439eacee26b
--- /dev/null
+++ b/middletier/cta/UserGroup.hpp
@@ -0,0 +1,128 @@
+#pragma once
+
+#include "cta/ConfigurationItem.hpp"
+#include "cta/DriveQuota.hpp"
+#include "cta/MountCriteria.hpp"
+
+#include <stdint.h>
+#include <string>
+#include <time.h>
+
+namespace cta {
+
+/**
+ * Class representing a user group.
+ */
+class UserGroup: public ConfigurationItem {
+public:
+
+  /**
+   * Constructor.
+   */
+  UserGroup();
+
+  /**
+   * Destructor.
+   */
+  ~UserGroup() throw();
+
+  /**
+   * Constructor.
+   *
+   * @param name The name of the user group.
+   * @param archivalDriveQuota The tape drive quota for the user group when
+   * mounting tapes for file archival.
+   * @param retrievalDriveQuota The tape drive quota for the user group when
+   * mounting tapes for file retrieval.
+   * @param archivalMountCriteria The criteria of the user group to be met in
+   * order to justify mounting a tape for file archival.
+   * @param retrievalMountCriteria The criteria of the user group to be met in
+   * order to justify mounting a tape for file retrieval.
+   * @param creator The identity of the user that created this configuration
+   * item.
+   * @param comment The comment describing this configuration item.
+   * @param creationTime Optionally the absolute time at which this
+   * configuration item was created.  If no value is given then the current
+   * time is used.
+   */
+  UserGroup(
+    const std::string &name,
+    const DriveQuota &archivalDriveQuota,
+    const DriveQuota &retrievalDriveQuota,
+    const MountCriteria &archivalMountCriteria,
+    const MountCriteria &retrievalMountCriteria,
+    const UserIdentity &creator,
+    const std::string &comment,
+    const time_t creationTime = time(NULL));
+
+  /**
+   * Returns the name of the user group.
+   *
+   * @return The name of the user group.
+   */
+  const std::string &getName() const throw();
+
+  /**
+   * Returns the tape drive quota for the user group when mounting tapes for
+   * file archival.
+   *
+   * @return The tape drive quota for the user group when mounting tapes for
+   * file archival.
+   */
+  const DriveQuota &getArchivalDriveQuota() const throw();
+
+  /**
+   * Returns the tape drive quota for the user group when mounting tapes for
+   * file retrieval.
+   *
+   * @return The tape drive quota for the user group when mounting tapes for
+   * file retrieval.
+   */
+  const DriveQuota &getRetrievalDriveQuota() const throw();
+
+  /**
+   * Returns the criteria of the user group to be met in order to justify
+   * mounting a tape for file archival.
+   */
+  const MountCriteria &getArchivalMountCriteria() const throw();
+
+  /**
+   * Returns the criteria of the user group to be met in order to justify
+   * mounting a tape for file retrieval.
+   */
+  const MountCriteria &getRetrievalMountCriteria() const throw();
+
+private:
+
+  /**
+   * The name of the user group.
+   */
+  std::string m_name;
+
+  /**
+   * The tape drive quota for the user group when mounting tapes for file
+   * archival.
+   */
+  DriveQuota m_archivalDriveQuota;
+
+  /**
+   * The tape drive quota for the user group when mounting tapes for file
+   * retrieval.
+   */
+  DriveQuota m_retrievalDriveQuota;
+
+  /**
+   * The criteria of the user group to be met in order to justify mounting a
+   * tape for file archival.
+   */
+  MountCriteria m_archivalMountCriteria;
+
+  /**
+   * The criteria of the user group to be met in order to justify mounting a
+   * tape for file retrieval.
+   */
+  MountCriteria m_retrievalMountCriteria;
+
+}; // class UserGroup
+
+} // namespace cta
diff --git a/middletier/cta/VO.cpp b/middletier/cta/VO.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..539b97e5e6be50f1a514293a9ec32b48b52d7b4a
--- /dev/null
+++ b/middletier/cta/VO.cpp
@@ -0,0 +1,32 @@
+#include "cta/VO.hpp"
+
+//------------------------------------------------------------------------------
+// constructor
+//------------------------------------------------------------------------------
+cta::VO::VO() {
+}
+
+//------------------------------------------------------------------------------
+// destructor
+//------------------------------------------------------------------------------
+cta::VO::~VO() throw() {
+}
+
+//------------------------------------------------------------------------------
+// constructor
+//------------------------------------------------------------------------------
+cta::VO::VO(
+  const std::string &name,
+  const UserIdentity &creator,
+  const std::string &comment,
+  const time_t creationTime):
+  ConfigurationItem(creator, comment, creationTime),
+  m_name(name) {
+}
+
+//------------------------------------------------------------------------------
+// getName
+//------------------------------------------------------------------------------
+const std::string &cta::VO::getName() const throw() {
+  return m_name;
+}
diff --git a/middletier/cta/VO.hpp b/middletier/cta/VO.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..92dfa225230379cfd01d5e5653fa925df610d2c0
--- /dev/null
+++ b/middletier/cta/VO.hpp
@@ -0,0 +1,58 @@
+#pragma once
+
+#include "cta/ConfigurationItem.hpp"
+
+#include <string>
+
+namespace cta {
+
+/**
+ * Class representing a virtual organisation.
+ */
+class VO: public ConfigurationItem {
+public:
+
+  /**
+   * Constructor.
+   */
+  VO();
+
+  /**
+   * Destructor.
+   */
+  ~VO() throw();
+
+  /**
+   * Constructor.
+   *
+   * @param name The name of the virtual organisation.
+   * @param creator The identity of the user that created this configuration
+   * item.
+   * @param comment The comment describing this configuration item.
+   * @param creationTime Optionally the absolute time at which this
+   * configuration item was created.  If no value is given then the current
+   * time is used.
+   */
+  VO(
+    const std::string &name,
+    const UserIdentity &creator,
+    const std::string &comment,
+    const time_t creationTime = time(NULL));
+
+  /**
+   * Returns the name of the tape pool.
+   *
+   * @return The name of the tape pool.
+   */
+  const std::string &getName() const throw();
+
+private:
+
+  /**
+   * The name of the tape pool.
+   */
+  std::string m_name;
+
+}; // class VO
+
+} // namespace cta