diff --git a/tapeserver/CMakeLists.txt b/tapeserver/CMakeLists.txt
index 850f95e40cdfb5781a318693c8e881533893b14d..dab2e913625e5fb2c4a8243634e6972fe79488b6 100644
--- a/tapeserver/CMakeLists.txt
+++ b/tapeserver/CMakeLists.txt
@@ -2,12 +2,12 @@ cmake_minimum_required (VERSION 2.6)
 
 # Old CASTOR's tapeserverd daemon code
 add_subdirectory (castor)
-add_subdirectory (test)
 
 # CTA's cta-taped code
 add_subdirectory (daemon)
-# The tape session's threads are in a separate directory
 add_subdirectory (session)
+# The tape session's threads are in a separate directory (session, but compiled
+# from the previous one to create a single library).
 
 add_executable (cta-taped cta-taped.cpp)
 target_link_libraries(cta-taped
diff --git a/tapeserver/castor/messages/Constants.cpp b/tapeserver/castor/messages/Constants.cpp
index 03f17238d2da330c9ff3a59b8accf7507c47e3fa..e5004756d91c5a17f0164f7d3e51d9f1830be3eb 100644
--- a/tapeserver/castor/messages/Constants.cpp
+++ b/tapeserver/castor/messages/Constants.cpp
@@ -64,10 +64,6 @@ const char *castor::messages::msgTypeToString(const MsgType msgType) throw() {
     return "TapeMountedForMigration";
   case MSG_TYPE_TAPEMOUNTEDFORRECALL:
     return "TapeMountedForRecall";
-  case MSG_TYPE_TAPEUNMOUNTSTARTED:
-    return "TapeUnmounStarted";
-  case MSG_TYPE_TAPEUNMOUNTED:
-    return "TapeUnmounted";
   case MSG_TYPE_LABELERROR:
     return "LabelError";
   case MSG_TYPE_ACSMOUNTTAPEREADONLY:
diff --git a/tapeserver/castor/messages/Constants.hpp b/tapeserver/castor/messages/Constants.hpp
index fec86464f2c78ba82d3b85e7ffd8110f1957463b..c72b20f254298231cea3c523726437abf69bef20 100644
--- a/tapeserver/castor/messages/Constants.hpp
+++ b/tapeserver/castor/messages/Constants.hpp
@@ -50,8 +50,6 @@ enum MsgType {
   /* 15 */ MSG_TYPE_STOPPROCESSFORKER,
   /* 16 */ MSG_TYPE_TAPEMOUNTEDFORMIGRATION,
   /* 17 */ MSG_TYPE_TAPEMOUNTEDFORRECALL,
-  /* 18 */ MSG_TYPE_TAPEUNMOUNTSTARTED,
-  /* 19 */ MSG_TYPE_TAPEUNMOUNTED,
   /* 20 */ MSG_TYPE_LABELERROR,
   /* 21 */ MSG_TYPE_ACSMOUNTTAPEREADONLY,
   /* 22 */ MSG_TYPE_ACSMOUNTTAPEREADWRITE,
diff --git a/tapeserver/castor/messages/TapeserverProxyDummy.cpp b/tapeserver/castor/messages/TapeserverProxyDummy.cpp
index c632fa86a7c1cde3d616a85c15b2c336093b245f..61b926552349f7844fc0174affb60495a166279a 100644
--- a/tapeserver/castor/messages/TapeserverProxyDummy.cpp
+++ b/tapeserver/castor/messages/TapeserverProxyDummy.cpp
@@ -22,48 +22,21 @@
 #include "castor/messages/TapeserverProxyDummy.hpp"
 
 //------------------------------------------------------------------------------
-// gotArchiveJobFromCTA
+// reportState
 //------------------------------------------------------------------------------
-uint32_t castor::messages::TapeserverProxyDummy::gotArchiveJobFromCTA(
-  const std::string &vid, const std::string &unitName, const uint32_t nbFiles) {
-  return 0;
-}
-
-//------------------------------------------------------------------------------
-// gotRetrieveJobFromCTA
-//------------------------------------------------------------------------------
-void castor::messages::TapeserverProxyDummy::gotRetrieveJobFromCTA(
-  const std::string &vid, const std::string &unitName) {
-}
-
-//------------------------------------------------------------------------------
-// gotRecallJobFromTapeGateway
-//------------------------------------------------------------------------------
-void castor::messages::TapeserverProxyDummy::gotRecallJobFromTapeGateway(
-  const std::string &vid, const std::string &unitName) {
-}
+void castor::messages::TapeserverProxyDummy::reportState(const cta::tape::session::SessionState state, 
+  const cta::tape::session::SessionType type, const std::string& vid) {}
 
 //------------------------------------------------------------------------------
-// gotRecallJobFromReadTp
+// reportHeartbeat
 //------------------------------------------------------------------------------
-void castor::messages::TapeserverProxyDummy::gotRecallJobFromReadTp(
-  const std::string &vid, const std::string &unitName) {
-}
+void castor::messages::TapeserverProxyDummy::reportHeartbeat(uint64_t totalTapeBytesMoved, uint64_t totalDiskBytesMoved) {}
 
 //------------------------------------------------------------------------------
-// gotMigrationJobFromTapeGateway
-//------------------------------------------------------------------------------
-uint32_t castor::messages::TapeserverProxyDummy::gotMigrationJobFromTapeGateway(
-  const std::string &vid, const std::string &unitName) {
-  return 0;
-}
-
-//------------------------------------------------------------------------------
-// gotMigrationJobFromWriteTp
+// gotRetrieveJobFromCTA
 //------------------------------------------------------------------------------
-uint32_t castor::messages::TapeserverProxyDummy::gotMigrationJobFromWriteTp(
+void castor::messages::TapeserverProxyDummy::gotRetrieveJobFromCTA(
   const std::string &vid, const std::string &unitName) {
-  return 0;
 }
 
 //------------------------------------------------------------------------------
diff --git a/tapeserver/castor/messages/TapeserverProxyDummy.hpp b/tapeserver/castor/messages/TapeserverProxyDummy.hpp
index 097ddf2cb6bd1a6ffe828d1535dc63b522b05b7e..19e9e3424e090770ff5eef45a725f3785b21fe0b 100644
--- a/tapeserver/castor/messages/TapeserverProxyDummy.hpp
+++ b/tapeserver/castor/messages/TapeserverProxyDummy.hpp
@@ -27,146 +27,43 @@ namespace castor {
 namespace messages {
 
 /**
- * A dummy tapeserverd-proxy.
+ * A dummy taped-proxy.
  */
-class TapeserverProxyDummy: public cta::daemon::TapedProxy {
+class TapeserverProxyDummy: public cta::tape::daemon::TapedProxy {
 public:
   
-  /**
-   * Notifies the tapeserverd daemon that the mount-session child-process got
-   * an archive job from CTA
-   *
-   * @param vid The tape to be mounted for recall.
-   * @param unitName The unit name of the tape drive.
-   * @return The number of files currently stored on the tape
-   */
-  virtual uint32_t gotArchiveJobFromCTA(const std::string &vid,
-    const std::string &unitName, const uint32_t nbFiles);
-  
-  /**
-   * Notifies the tapeserverd daemon that the mount-session child-process got
-   * a retrieve job from CTA
-   *
-   * @param vid The tape to be mounted for recall.
-   * @param unitName The unit name of the tape drive.
-   */
-  virtual void gotRetrieveJobFromCTA(const std::string &vid,
-    const std::string &unitName);
-
-  /**
-   * Notifies the tapeserverd daemon that the mount-session child-process got
-   * a recall job from the tapegatewayd daemon.
-   *
-   * @param vid The tape to be mounted for recall.
-   * @param unitName The unit name of the tape drive.
-   */
-  void gotRecallJobFromTapeGateway(const std::string &vid,
-    const std::string &unitName);
-
-  /**
-   * Notifies the tapeserverd daemon that the mount-session child-process got
-   * a recall job from the readtp command-line tool.
-   *
-   * @param vid The tape to be mounted for recall.
-   * @param unitName The unit name of the tape drive.
-   */
-  void gotRecallJobFromReadTp(const std::string &vid,
-    const std::string &unitName);
+  void reportState(const cta::tape::session::SessionState state,
+    const cta::tape::session::SessionType type, 
+    const std::string & vid) override;
 
-  /**
-   * Notifies the tapeserverd daemon that the mount-session child-process got
-   * a migration job from the tapegatewayd daemon.
-   *
-   * @param vid The tape to be mounted for recall.
-   * @param unitName The unit name of the tape drive.
-   * @return The number of files currently stored on the tape as given by the
-   * vmgrd daemon.
-   */
-  uint32_t gotMigrationJobFromTapeGateway(const std::string &vid,
-    const std::string &unitName);
-
-  /**
-   * Notifies the tapeserverd daemon that the mount-session child-process got
-   * a migration job from the writetp command-line tool.
-   *
-   * @param vid The tape to be mounted for recall.
-   * @param unitName The unit name of the tape drive.
-   * @return The number of files currently stored on the tape as given by the
-   * vmgrd daemon.
-   */
-  uint32_t gotMigrationJobFromWriteTp(const std::string &vid,
-    const std::string &unitName);
+  void reportHeartbeat(uint64_t totalTapeBytesMoved, uint64_t totalDiskBytesMoved) override;
+  
+  void gotRetrieveJobFromCTA(const std::string &vid,
+    const std::string &unitName) override;
 
-  /**
-   * Notifies the tapeserverd daemon that the specified tape has been mounted.
-   *
-   * @param vid The tape to be mounted for recall.
-   * @param unitName The unit name of the tape drive.
-   */
   void tapeMountedForRecall(const std::string &vid,
-    const std::string &unitName);
+    const std::string &unitName) override;
 
-  /**
-   * Notifies the tapeserverd daemon that the specified tape has been mounted.
-   *
-   * @param vid The tape to be mounted for recall.
-   * @param unitName The unit name of the tape drive.
-   */
   void tapeMountedForMigration(const std::string &vid,
-    const std::string &unitName);
+    const std::string &unitName) override;
 
-  /**
-   * Notifies the tapeserverd daemon that the specified tape is unmounting.
-   *
-   * @param vid The tape to be mounted for recall.
-   * @param unitName The unit name of the tape drive.
-   */
   void tapeUnmountStarted(const std::string &vid,
-    const std::string &unitName);
+    const std::string &unitName) override;
 
-  /**
-   * Notifies the tapeserverd daemon that the specified tape has been unmounted.
-   *
-   * @param vid The tape to be mounted for recall.
-   * @param unitName The unit name of the tape drive.
-   */
   void tapeUnmounted(const std::string &vid,
-    const std::string &unitName);
+    const std::string &unitName) override;
 
-  /**
-   * Notifies the tapeserverd daemon that the data-transfer session is still
-   * alive and gives an indication of how much data has been moved.
-   *
-   * @param unitName The unit name of the tape drive.
-   * @param nbBlocksMoved Delta value giving the number of blocks moved
-   * since the last heartbeat message.
-   */
   void notifyHeartbeat(const std::string &unitName,
-    const uint64_t nbBlocksMoved);
+    const uint64_t nbBlocksMoved) override;
   
-  /**
-   * Sends a new set of parameters, to be logged by the mother process when the
-   * transfer session is over.
-   * @param params: a vector of log parameters
-   */
-  virtual void addLogParams(const std::string &unitName,
-    const std::list<castor::log::Param> & params);
+  void addLogParams(const std::string &unitName,
+    const std::list<castor::log::Param> & params) override;
   
-  /**
-   * Sends a list of parameters to remove from the end of session logging.
-   */
-  virtual void deleteLogParams(const std::string &unitName,
-    const std::list<std::string> & paramNames);
+  void deleteLogParams(const std::string &unitName,
+    const std::list<std::string> & paramNames) override;
   
-  /**
-   * Notifies the tapeserverd daemon that a label session has encountered the
-   * specified error.
-   *
-   * @param unitName The unit name of the tape drive.
-   * @param message The error message.
-   */
   void labelError(const std::string &unitName,
-    const std::string &message);
+    const std::string &message) override;
 
 }; // class TapeserverProxyDummy
 
diff --git a/tapeserver/castor/messages/TapeserverProxyZmq.cpp b/tapeserver/castor/messages/TapeserverProxyZmq.cpp
index 43449e30a4949b15843dd8c55186d4d0b5063a92..4d2b92133de8734d7f22f341f0c00bec3a74d3d5 100644
--- a/tapeserver/castor/messages/TapeserverProxyZmq.cpp
+++ b/tapeserver/castor/messages/TapeserverProxyZmq.cpp
@@ -45,13 +45,31 @@
 // constructor
 //------------------------------------------------------------------------------
 castor::messages::TapeserverProxyZmq::TapeserverProxyZmq(log::Logger &log, 
-  const unsigned short serverPort, void *const zmqContext) throw():
+  const unsigned short serverPort, void *const zmqContext,
+  const std::string &driveName) throw():
   m_log(log),
+  m_driveName(driveName),
   m_serverPort(serverPort),
   m_serverSocket(zmqContext, ZMQ_REQ) {
   connectZmqSocketToLocalhost(m_serverSocket, serverPort);
 }
 
+//------------------------------------------------------------------------------
+// reportState
+//------------------------------------------------------------------------------
+void castor::messages::TapeserverProxyZmq::reportState(const cta::tape::session::SessionState state,
+  const cta::tape::session::SessionType type, const std::string& vid) {
+  if ((type == cta::tape::session::SessionType::Archive) 
+      && (state == cta::tape::session::SessionState::Mounting)) {
+    gotArchiveJobFromCTA(vid, m_driveName, 0);
+  }
+}
+
+//------------------------------------------------------------------------------
+// reportHeartbeat
+//------------------------------------------------------------------------------
+void castor::messages::TapeserverProxyZmq::reportHeartbeat(uint64_t totalTapeBytesMoved, uint64_t totalDiskBytesMoved) {}
+
 //------------------------------------------------------------------------------
 // gotArchiveJobFromCTA
 //------------------------------------------------------------------------------
@@ -275,120 +293,6 @@ castor::messages::Frame castor::messages::TapeserverProxyZmq::
   }
 }
 
-//------------------------------------------------------------------------------
-// tapeUnmountStarted
-//------------------------------------------------------------------------------
-void castor::messages::TapeserverProxyZmq::tapeUnmountStarted(
-  const std::string &vid, const std::string &unitName) {   
-  MutexLocker lock(&m_mutex);
-
-  try {
-    const Frame rqst = createTapeUnmountStartedFrame(vid, unitName);
-    sendFrame(m_serverSocket, rqst);
-  
-    ReturnValue reply;
-    recvTapeReplyOrEx(m_serverSocket, reply);
-    if(0 != reply.value()) {
-      // Should never get here
-      castor::exception::Exception ex;
-      ex.getMessage() << "Received an unexpected return value"
-        ": expected=0 actual=" << reply.value();
-      throw ex;
-    }
-  } catch(castor::exception::Exception &ne) {
-    castor::exception::Exception ex;
-    ex.getMessage() <<
-      "Failed to notify tapeserver of start of tape unmount: " <<
-      "vid=" << vid << " unitName=" << unitName << ": " <<
-      ne.getMessage().str();
-    throw ex;
-  }
-}
-
-//------------------------------------------------------------------------------
-// createTapeUnmountStartedFrame
-//------------------------------------------------------------------------------
-castor::messages::Frame castor::messages::TapeserverProxyZmq::
-  createTapeUnmountStartedFrame(const std::string &vid,
-  const std::string &unitName) {
-  try {
-    Frame frame;
-
-    frame.header = messages::protoTapePreFillHeader();
-    frame.header.set_msgtype(messages::MSG_TYPE_TAPEUNMOUNTSTARTED);
-    frame.header.set_bodysignature("PIPO");
-
-    TapeUnmountStarted body;
-    body.set_vid(vid);
-    body.set_unitname(unitName);
-    frame.serializeProtocolBufferIntoBody(body);
-
-    return frame;
-  } catch(castor::exception::Exception &ne) {
-    castor::exception::Exception ex;
-    ex.getMessage() << "Failed to create TapeUnmountStarted frame: " <<
-      ne.getMessage().str();
-    throw ex;
-  }
-}
-
-//------------------------------------------------------------------------------
-// tapeUnmounted
-//------------------------------------------------------------------------------
-void castor::messages::TapeserverProxyZmq::tapeUnmounted(
-  const std::string &vid, const std::string &unitName) {
-  MutexLocker lock(&m_mutex);
-
-  try {
-    const Frame rqst = createTapeUnmountedFrame(vid, unitName);
-    sendFrame(m_serverSocket, rqst);
-  
-    ReturnValue reply;
-    recvTapeReplyOrEx(m_serverSocket, reply);
-    if(0 != reply.value()) {
-      // Should never get here
-      castor::exception::Exception ex;
-      ex.getMessage() << "Received an unexpected return value"
-        ": expected=0 actual=" << reply.value();
-      throw ex;
-    }
-  } catch(castor::exception::Exception &ne) {
-    castor::exception::Exception ex;
-    ex.getMessage() <<
-      "Failed to notify tapeserver that tape is unmounted: " <<
-      "vid=" << vid << " unitName=" << unitName << ": " <<
-      ne.getMessage().str();
-    throw ex;
-  }
-}
-
-//------------------------------------------------------------------------------
-// createTapeUnmountedFrame
-//------------------------------------------------------------------------------
-castor::messages::Frame castor::messages::TapeserverProxyZmq::
-  createTapeUnmountedFrame(const std::string &vid,
-  const std::string &unitName) {
-  try {
-    Frame frame;
-
-    frame.header = messages::protoTapePreFillHeader();
-    frame.header.set_msgtype(messages::MSG_TYPE_TAPEUNMOUNTED);
-    frame.header.set_bodysignature("PIPO");
-
-    TapeUnmounted body;
-    body.set_vid(vid);
-    body.set_unitname(unitName);
-    frame.serializeProtocolBufferIntoBody(body);
-
-    return frame;
-  } catch(castor::exception::Exception &ne) {
-    castor::exception::Exception ex;
-    ex.getMessage() << "Failed to create TapeUnmounted frame: " <<
-      ne.getMessage().str();
-    throw ex;
-  }
-}
-
 //-----------------------------------------------------------------------------
 // notifyHeartbeat
 //-----------------------------------------------------------------------------
diff --git a/tapeserver/castor/messages/TapeserverProxyZmq.hpp b/tapeserver/castor/messages/TapeserverProxyZmq.hpp
index 7855b367b9e4df9e79b3de8ec283f14fa89036d0..16ab6926a73030ee8ce233c2b450f2dbc8c98c2e 100644
--- a/tapeserver/castor/messages/TapeserverProxyZmq.hpp
+++ b/tapeserver/castor/messages/TapeserverProxyZmq.hpp
@@ -34,9 +34,8 @@ namespace messages {
  * A concrete implementation of the interface to the internal network
  * communications of the tapeserverd daemon.
  */
-class TapeserverProxyZmq: public cta::daemon::TapedProxy {
+class TapeserverProxyZmq: public cta::tape::daemon::TapedProxy {
 public:
-
   /**
    * Constructor.
    *
@@ -46,98 +45,42 @@ public:
    * @param zmqContext The ZMQ context.
    */
   TapeserverProxyZmq(log::Logger &log, const unsigned short serverPort,
-    void *const zmqContext) throw();
+    void *const zmqContext, const std::string & driveName) throw();
+
+  void reportState(const cta::tape::session::SessionState state,
+    const cta::tape::session::SessionType type, const std::string& vid) override;
   
-  /**
-   * Notifies the tapeserverd daemon that the mount-session child-process got
-   * an archive job from CTA
-   *
-   * @param vid The tape to be mounted for recall.
-   * @param unitName The unit name of the tape drive.
-   * @return The number of files currently stored on the tape
-   */
-  virtual uint32_t gotArchiveJobFromCTA(const std::string &vid,
+  void reportHeartbeat(uint64_t totalTapeBytesMoved, uint64_t totalDiskBytesMoved) override;
+private:
+  uint32_t gotArchiveJobFromCTA(const std::string &vid,
     const std::string &unitName, const uint32_t nbFiles);
   
-  /**
-   * Notifies the tapeserverd daemon that the mount-session child-process got
-   * a retrieve job from CTA
-   *
-   * @param vid The tape to be mounted for recall.
-   * @param unitName The unit name of the tape drive.
-   */
-  virtual void gotRetrieveJobFromCTA(const std::string &vid,
-    const std::string &unitName);
+public:
+  void gotRetrieveJobFromCTA(const std::string &vid,
+    const std::string &unitName) override;
 
-  /**
-   * Notifies the tapeserverd daemon that the specified tape has been mounted.
-   *
-   * @param vid The tape to be mounted for recall.
-   * @param unitName The unit name of the tape drive.
-   */
   void tapeMountedForRecall(const std::string &vid,
-    const std::string &unitName);
+    const std::string &unitName) override;
 
-  /**
-   * Notifies the tapeserverd daemon that the specified tape has been mounted.
-   *
-   * @param vid The tape to be mounted for recall.
-   * @param unitName The unit name of the tape drive.
-   */
   void tapeMountedForMigration(const std::string &vid, 
-    const std::string &unitName);
+    const std::string &unitName) override;
   
-  /**
-   * Notifies the tapeserverd daemon that the specified tape is unmounting.
-   *
-   * @param vid The tape to be mounted for recall.
-   * @param unitName The unit name of the tape drive.
-   */
   void tapeUnmountStarted(const std::string &vid,
-    const std::string &unitName);
+    const std::string &unitName) override {}
  
-  /**
-   * Notifies the tapeserverd daemon that the specified tape has been unmounted.
-   *
-   * @param vid The tape to be mounted for recall.
-   * @param unitName The unit name of the tape drive.
-   */
   void tapeUnmounted(const std::string &vid,
-    const std::string &unitName);
+    const std::string &unitName)  override {}
  
-  /**
-   * Notifies the tapeserverd daemon that the data-transfer session is still
-   * alive and gives an indication of how much data has been moved.
-   *
-   * @param unitName The unit name of the tape drive.
-   * @param nbBlocksMoved Delta value giving the number of blocks moved
-   * since the last heartbeat message.
-   */
   void notifyHeartbeat(const std::string &unitName,
-    const uint64_t nbBlocksMoved);
+    const uint64_t nbBlocksMoved) override;
   
-  /**
-   * Sends a new set of parameters, to be logged by the mother process when the
-   * transfer session is over.
-   * @param params: a vector of log parameters
-   */
   virtual void addLogParams(const std::string &unitName,
-    const std::list<castor::log::Param> & params);
+    const std::list<castor::log::Param> & params) override;
   
-  /**
-   * Sends a list of parameters to remove from the end of session logging.
-   */
   virtual void deleteLogParams(const std::string &unitName,
-    const std::list<std::string> & paramNames);
+    const std::list<std::string> & paramNames) override;
   
-  /**
-   * Notifies the tapeserverd daemon that a label session has encountered the
-   * specified error.
-   *
-   * @param unitName The unit name of the tape drive.
-   * @param message The error message.
-   */
-  void labelError(const std::string &unitName, const std::string &message);
+  void labelError(const std::string &unitName, const std::string &message) override;
 
 private:
 
@@ -151,6 +94,11 @@ private:
    * The object representing the API of the CASTOR logging system.
    */
   log::Logger &m_log;
+  
+  /**
+   * The name of the drive managed by this proxy.
+   */
+  std::string m_driveName;
 
   /**
    * The name of the host on which the vdqmd daemon is running.
@@ -207,26 +155,6 @@ private:
   Frame createTapeMountedForMigrationFrame(const std::string &vid,
     const std::string &unitName);
 
-  /**
-   * Creates a frame containing a TapeUnmountStarted message.
-   *
-   * @param vid The volume identifier of the tape.
-   * @param unitName The unit name of the tape drive.
-   * @return The frame.
-   */
-  Frame createTapeUnmountStartedFrame(const std::string &vid,
-    const std::string &unitName);
-
-  /**
-   * Creates a frame containing a TapeUnmounted message.
-   *
-   * @param vid The volume identifier of the tape.
-   * @param unitName The unit name of the tape drive.
-   * @return The frame.
-   */
-  Frame createTapeUnmountedFrame(const std::string &vid,
-    const std::string &unitName);
-
   /**
    * Creates a frame containing a Heartbeat message.
    *
diff --git a/tapeserver/castor/tape/tapeserver/daemon/DataTransferSession.cpp b/tapeserver/castor/tape/tapeserver/daemon/DataTransferSession.cpp
index 5297c93d1dda23821477d891cc2def610761e3a4..4812d04a252ce454f15ca0efede2cb1829f22ce8 100644
--- a/tapeserver/castor/tape/tapeserver/daemon/DataTransferSession.cpp
+++ b/tapeserver/castor/tape/tapeserver/daemon/DataTransferSession.cpp
@@ -52,7 +52,7 @@ castor::tape::tapeserver::daemon::DataTransferSession::DataTransferSession(
     System::virtualWrapper & sysWrapper,
     const DriveConfig & driveConfig,
     castor::mediachanger::MediaChangerFacade & mc,
-    cta::daemon::TapedProxy & initialProcess,
+    cta::tape::daemon::TapedProxy & initialProcess,
     castor::server::ProcessCap & capUtils,
     const DataTransferConfig & castorConf,
     cta::Scheduler & scheduler): 
@@ -268,15 +268,12 @@ castor::tape::tapeserver::daemon::Session::EndOfSessionAction
       twst.setlastFseq(firstFseqFromClient-1);
       
       //we retrieved the detail from the client in execute, so at this point 
-      //we can report. We get in exchange the number of files on the tape.
-      // This function can throw an exception (usually for permission reasons)
-      // This is not a reason to put the drive down. The error is already logged
-      // upstream.
-      // Letting the exception slip through would leave the drive down.
+      //we can report we will mount the tape.
+      // TODO: create a "StartingSession" state as the mounting will happen in
+      // the to-be-created tape thread.
       // Initialise with something obviously wrong.
-      uint64_t nbOfFileOnTape = std::numeric_limits<uint64_t>::max();
       try {
-        nbOfFileOnTape = tsr.gotWriteMountDetailsFromClient();
+        tsr.gotWriteMountDetailsFromClient();
       } catch (castor::exception::Exception & e) {
         log::LogContext::ScopedParam sp1(lc, log::Param("errorMessage", e.getMessage().str()));
         lc.log(LOG_INFO, "Aborting the session after problem with mount details. Notifying the client.");
@@ -288,14 +285,6 @@ castor::tape::tapeserver::daemon::Session::EndOfSessionAction
         return MARK_DRIVE_AS_UP;
       }
 
-      //theses 2 numbers should match. Otherwise, it means the stager went mad 
-      if(firstFseqFromClient != nbOfFileOnTape + 1) {
-        std::stringstream ss;
-        ss << "First file to write's fseq(" << firstFseqFromClient << ")  and number of files on the tape (" << nbOfFileOnTape << " + 1) dont match";
-        lc.log(LOG_ERR, ss.str());
-       //no mount at all, drive to be kept up = return 0
-        return MARK_DRIVE_AS_UP;
-      }
       // We have something to do: start the session by starting all the 
       // threads.
       mm.startThreads();
diff --git a/tapeserver/castor/tape/tapeserver/daemon/DataTransferSession.hpp b/tapeserver/castor/tape/tapeserver/daemon/DataTransferSession.hpp
index 43537510a38db0a056e915954aae8255de8d2f8d..5ae9adb6dd5a089cedafa832e609c07c1a6d20ac 100644
--- a/tapeserver/castor/tape/tapeserver/daemon/DataTransferSession.hpp
+++ b/tapeserver/castor/tape/tapeserver/daemon/DataTransferSession.hpp
@@ -64,7 +64,7 @@ namespace daemon {
       System::virtualWrapper & sysWrapper,
       const DriveConfig & driveConfig,
       castor::mediachanger::MediaChangerFacade & mc,
-      cta::daemon::TapedProxy & initialProcess,
+      cta::tape::daemon::TapedProxy & initialProcess,
       castor::server::ProcessCap &capUtils,
       const DataTransferConfig & castorConf,
       cta::Scheduler &scheduler);
@@ -126,7 +126,7 @@ namespace daemon {
      * by the library. It will be used exclusively by the tape thread. */
     castor::mediachanger::MediaChangerFacade & m_mc;
     /** Reference to the tape server's parent process to report detailed status */
-    cta::daemon::TapedProxy & m_intialProcess;
+    cta::tape::daemon::TapedProxy & m_intialProcess;
     /** Object providing utilities for working UNIX capabilities. */
     castor::server::ProcessCap &m_capUtils;
     /** hostname, used to report status of the drive */
diff --git a/tapeserver/castor/tape/tapeserver/daemon/DiskReadTaskTest.cpp b/tapeserver/castor/tape/tapeserver/daemon/DiskReadTaskTest.cpp
index 935d5e774978da7e0821965d54535266cb46de1b..ccb456fc551d39ce94762a8b4325a34f5d562da6 100644
--- a/tapeserver/castor/tape/tapeserver/daemon/DiskReadTaskTest.cpp
+++ b/tapeserver/castor/tape/tapeserver/daemon/DiskReadTaskTest.cpp
@@ -91,7 +91,7 @@ namespace unitTests{
   class MockMigrationWatchDog: public MigrationWatchDog {
   public:
     MockMigrationWatchDog(double periodToReport,double stuckPeriod,
-    cta::daemon::TapedProxy& initialProcess,
+    cta::tape::daemon::TapedProxy& initialProcess,
     const std::string & driveUnitName,
     castor::log::LogContext lc, double pollPeriod = 0.1): 
       MigrationWatchDog(periodToReport, stuckPeriod, initialProcess, 
diff --git a/tapeserver/castor/tape/tapeserver/daemon/LabelSession.cpp b/tapeserver/castor/tape/tapeserver/daemon/LabelSession.cpp
index 719fc5c66a2998c5deb8e96408d2933bab1f4ca6..e09942bf397086714f12eba3ac0949dc70d77a13 100644
--- a/tapeserver/castor/tape/tapeserver/daemon/LabelSession.cpp
+++ b/tapeserver/castor/tape/tapeserver/daemon/LabelSession.cpp
@@ -41,7 +41,7 @@
 //------------------------------------------------------------------------------
 castor::tape::tapeserver::daemon::LabelSession::LabelSession(
   server::ProcessCap &capUtils,
-  cta::daemon::TapedProxy &tapeserver,
+  cta::tape::daemon::TapedProxy &tapeserver,
   mediachanger::MediaChangerFacade &mc, 
   const legacymsg::TapeLabelRqstMsgBody &clientRequest,
   castor::log::Logger &log,
diff --git a/tapeserver/castor/tape/tapeserver/daemon/LabelSession.hpp b/tapeserver/castor/tape/tapeserver/daemon/LabelSession.hpp
index eef5694f425ac41d5d98c84150ee41ab12e19876..2d0947ed8a9e2e9e8e2da9791f37260edb672da8 100644
--- a/tapeserver/castor/tape/tapeserver/daemon/LabelSession.hpp
+++ b/tapeserver/castor/tape/tapeserver/daemon/LabelSession.hpp
@@ -70,7 +70,7 @@ public:
    */
   LabelSession(
     server::ProcessCap &capUtils,
-    cta::daemon::TapedProxy &tapeserver,
+    cta::tape::daemon::TapedProxy &tapeserver,
     mediachanger::MediaChangerFacade &mc,
     const legacymsg::TapeLabelRqstMsgBody &clientRequest, 
     castor::log::Logger &log,
@@ -99,7 +99,7 @@ private:
   /**
    * Proxy object representing the tapeserverd daemon.
    */
-  cta::daemon::TapedProxy &m_tapeserver;
+  cta::tape::daemon::TapedProxy &m_tapeserver;
     
   /**
    * The object representing the media changer.
diff --git a/tapeserver/castor/tape/tapeserver/daemon/ProcessForker.cpp b/tapeserver/castor/tape/tapeserver/daemon/ProcessForker.cpp
index 45fafdbec11c773495ffae90a246b8a5e36c2217..ef429a091c76e23ec0334732aac418b2559e0d9b 100644
--- a/tapeserver/castor/tape/tapeserver/daemon/ProcessForker.cpp
+++ b/tapeserver/castor/tape/tapeserver/daemon/ProcessForker.cpp
@@ -555,7 +555,7 @@ castor::tape::tapeserver::daemon::Session::EndOfSessionAction
   mediachanger::MediaChangerFacade mediaChangerFacade(acs, mmc, rmc);
 
   messages::TapeserverProxyZmq tapeserver(m_log, m_config.internalPort,
-    zmqContext.get());
+    zmqContext.get(), driveConfig.getUnitName());
   
   cta::EosNS eosNs(castor::common::CastorConfiguration::getConfig().getConfEntString("TapeServer", "EOSRemoteHostAndPort"));
   std::unique_ptr<cta::objectstore::Backend> backend(
@@ -842,7 +842,7 @@ castor::tape::tapeserver::daemon::Session::EndOfSessionAction
     messages::SmartZmqContext
       zmqContext(instantiateZmqContext(sizeOfIOThreadPoolForZMQ));
     messages::TapeserverProxyZmq tapeserver(m_log, m_config.internalPort,
-      zmqContext.get());
+      zmqContext.get(), driveConfig.getUnitName());
 
     messages::AcsProxyZmq acs(acs::ACS_PORT, zmqContext.get());
 
diff --git a/tapeserver/castor/tape/tapeserver/daemon/TapeMessageHandler.cpp b/tapeserver/castor/tape/tapeserver/daemon/TapeMessageHandler.cpp
index 1706b8b14f6bc143e826d5ffb28f62d0983f95ff..f5ffabc2df0c7278f12c9c6d01808d6396e92044 100644
--- a/tapeserver/castor/tape/tapeserver/daemon/TapeMessageHandler.cpp
+++ b/tapeserver/castor/tape/tapeserver/daemon/TapeMessageHandler.cpp
@@ -204,12 +204,6 @@ castor::messages::Frame castor::tape::tapeserver::daemon::TapeMessageHandler::
 
   case messages::MSG_TYPE_TAPEMOUNTEDFORRECALL:
     return handleTapeMountedForRecall(rqst);
-
-  case messages::MSG_TYPE_TAPEUNMOUNTSTARTED:
-    return handleTapeUnmountStarted(rqst);
-
-  case messages::MSG_TYPE_TAPEUNMOUNTED:
-    return handleTapeUnmounted(rqst);
     
   case messages::MSG_TYPE_ADDLOGPARAMS:
     return handleAddLogParams(rqst);
@@ -401,48 +395,6 @@ castor::messages::Frame castor::tape::tapeserver::daemon::TapeMessageHandler::
   }
 }
 
-//------------------------------------------------------------------------------
-// handleTapeUnmountStarted
-//------------------------------------------------------------------------------
-castor::messages::Frame castor::tape::tapeserver::daemon::TapeMessageHandler::
-  handleTapeUnmountStarted(const messages::Frame& rqst) {
-  m_log(LOG_INFO, "Handling TapeUnmountStarted message");
-
-  try {
-    messages::TapeUnmountStarted rqstBody;
-    rqst.parseBodyIntoProtocolBuffer(rqstBody);
-
-    const messages::Frame reply = createReturnValueFrame(0);
-    return reply;
-  } catch(castor::exception::Exception &ne) {
-    castor::exception::Exception ex;
-    ex.getMessage() << "Failed to handle TapeUnmountStarted message: " <<
-      ne.getMessage().str();
-    throw ex;
-  }
-}
-
-//------------------------------------------------------------------------------
-// handleTapeUnmounted
-//------------------------------------------------------------------------------
-castor::messages::Frame castor::tape::tapeserver::daemon::TapeMessageHandler::
-  handleTapeUnmounted(const messages::Frame& rqst) {
-  m_log(LOG_INFO, "Handling TapeUnmounted message");
-
-  try {
-    messages::TapeUnmounted rqstBody;
-    rqst.parseBodyIntoProtocolBuffer(rqstBody);
-
-    const messages::Frame reply = createReturnValueFrame(0);
-    return reply;
-  } catch(castor::exception::Exception &ne) {
-    castor::exception::Exception ex;
-    ex.getMessage() << "Failed to handle TapeUnmounted message: " <<
-      ne.getMessage().str();
-    throw ex;
-  }
-}
-
 //------------------------------------------------------------------------------
 // handleAddLogParams
 //------------------------------------------------------------------------------
diff --git a/tapeserver/castor/tape/tapeserver/daemon/TapeMessageHandler.hpp b/tapeserver/castor/tape/tapeserver/daemon/TapeMessageHandler.hpp
index e70e26c95eb5580d4e0c028224e40c8443ab91d4..b89e99f615491e00d2abb7abc9905155ded7cb50 100644
--- a/tapeserver/castor/tape/tapeserver/daemon/TapeMessageHandler.hpp
+++ b/tapeserver/castor/tape/tapeserver/daemon/TapeMessageHandler.hpp
@@ -218,22 +218,6 @@ private:
    */
   messages::Frame handleNotifyDriveTapeMounted(const messages::Frame &rqst);
 
-  /**
-   * Handles the specified request.
-   *
-   * @param rqst The request.
-   * @return The reply.
-   */
-  messages::Frame handleTapeUnmountStarted(const messages::Frame &rqst);
-
-  /**
-   * Handles the specified request.
-   *
-   * @param rqst The request.
-   * @return The reply.
-   */
-  messages::Frame handleTapeUnmounted(const messages::Frame &rqst);
-
   /**
    * Handles the specified request.
    *
diff --git a/tapeserver/castor/tape/tapeserver/daemon/TapeServerReporter.cpp b/tapeserver/castor/tape/tapeserver/daemon/TapeServerReporter.cpp
index 905ff13231af958c8d9327eb5ae0082c9f9132e9..b74972ed837042a88394a249a99351c43e047155 100644
--- a/tapeserver/castor/tape/tapeserver/daemon/TapeServerReporter.cpp
+++ b/tapeserver/castor/tape/tapeserver/daemon/TapeServerReporter.cpp
@@ -38,7 +38,7 @@ namespace daemon {
 //constructor
 //------------------------------------------------------------------------------  
 TapeServerReporter::TapeServerReporter(
-  cta::daemon::TapedProxy& tapeserverProxy,
+  cta::tape::daemon::TapedProxy& tapeserverProxy,
   const DriveConfig& driveConfig,
   const std::string &hostname,
   const castor::tape::tapeserver::daemon::VolumeInfo &volume,
@@ -94,12 +94,9 @@ TapeServerReporter::TapeServerReporter(
 //------------------------------------------------------------------------------
 //gotWriteMountDetailsFromClient
 //------------------------------------------------------------------------------    
-  uint32_t TapeServerReporter::gotWriteMountDetailsFromClient(){
-    if(m_threadRunnig){
-      m_lc.log(LOG_ERR,"TapeServerReporter is running but calling a synchronous operation on it"
-      "Could cause a race with the underlying  zmq sockets in the proxy");
-    }
-    return m_tapeserverProxy.gotArchiveJobFromCTA(m_volume.vid, m_unitName, m_volume.nbFiles);
+  void TapeServerReporter::gotWriteMountDetailsFromClient(){
+    m_tapeserverProxy.reportState(cta::tape::session::SessionState::Mounting, 
+      cta::tape::session::SessionType::Archive, m_volume.vid);
   }
 //------------------------------------------------------------------------------
 //gotReadMountDetailsFromClient
diff --git a/tapeserver/castor/tape/tapeserver/daemon/TapeServerReporter.hpp b/tapeserver/castor/tape/tapeserver/daemon/TapeServerReporter.hpp
index c7354b3b791b7bd11c35633f5834fc1a6bc0fd58..9f80d7b7d159cc1c498866f4038cb3c2752f4a85 100644
--- a/tapeserver/castor/tape/tapeserver/daemon/TapeServerReporter.hpp
+++ b/tapeserver/castor/tape/tapeserver/daemon/TapeServerReporter.hpp
@@ -52,7 +52,7 @@ public:
    * @param lc 
    */
   TapeServerReporter(
-    cta::daemon::TapedProxy& tapeserverProxy,
+    cta::tape::daemon::TapedProxy& tapeserverProxy,
     const DriveConfig &driveConfig,
     const std::string &hostname,
     const castor::tape::tapeserver::daemon::VolumeInfo &volume,
@@ -89,7 +89,7 @@ public:
    * exchange return the number of files on the tape according to the VMGR
    * @return the number of files on the tape according to the VMGR
    */
-  uint32_t gotWriteMountDetailsFromClient();
+  void gotWriteMountDetailsFromClient();
   
   //start and wait for thread to finish
   void startThreads();
@@ -145,7 +145,7 @@ private:
    A bunch of references to proxies to send messages to the 
    * outside world when we have to
    */
-  cta::daemon::TapedProxy& m_tapeserverProxy;
+  cta::tape::daemon::TapedProxy& m_tapeserverProxy;
   
   /**
    * Log context, copied because it is in a separated thread
diff --git a/tapeserver/castor/tape/tapeserver/daemon/TaskWatchDog.hpp b/tapeserver/castor/tape/tapeserver/daemon/TaskWatchDog.hpp
index 2f7394466eb2a27c4e5bf314bdba55e14bf2b8b0..0eba9dffb37f386931955d701154db1ba35a2991 100644
--- a/tapeserver/castor/tape/tapeserver/daemon/TaskWatchDog.hpp
+++ b/tapeserver/castor/tape/tapeserver/daemon/TaskWatchDog.hpp
@@ -110,7 +110,7 @@ protected:
   /*
    *  The proxy that will receive or heartbeat notifications
    */
-  cta::daemon::TapedProxy& m_initialProcess;
+  cta::tape::daemon::TapedProxy& m_initialProcess;
   
   /**
    * The drive unit name to report
@@ -265,7 +265,7 @@ protected:
    * @param lc To log the events
    */
   TaskWatchDog(double reportPeriod,double stuckPeriod,
-         cta::daemon::TapedProxy& initialProcess,
+         cta::tape::daemon::TapedProxy& initialProcess,
           const std::string & driveUnitName,
          log::LogContext& lc, double pollPeriod = 0.1):
   m_nbOfMemblocksMoved(0), m_statsSet(false), m_pollPeriod(pollPeriod),
@@ -393,7 +393,7 @@ public:
   
   /** Pass through constructor */
   RecallWatchDog(double periodToReport,double stuckPeriod,
-    cta::daemon::TapedProxy& initialProcess,
+    cta::tape::daemon::TapedProxy& initialProcess,
     const std::string & driveUnitName,
     log::LogContext& lc, double pollPeriod = 0.1): 
   TaskWatchDog(periodToReport, stuckPeriod, initialProcess, driveUnitName, lc, 
@@ -444,7 +444,7 @@ public:
   
   /** Pass through constructor */
   MigrationWatchDog(double periodToReport,double stuckPeriod,
-    cta::daemon::TapedProxy& initialProcess,
+    cta::tape::daemon::TapedProxy& initialProcess,
     const std::string & driveUnitName,
     log::LogContext lc, double pollPeriod = 0.1): 
   TaskWatchDog(periodToReport, stuckPeriod, initialProcess, driveUnitName, lc, 
diff --git a/tapeserver/daemon/CMakeLists.txt b/tapeserver/daemon/CMakeLists.txt
index 195c8130b78f37d30436828a41d1ee45db346612..8575a07101ee6ef0c3a4f919dca674c12622b7e1 100644
--- a/tapeserver/daemon/CMakeLists.txt
+++ b/tapeserver/daemon/CMakeLists.txt
@@ -12,6 +12,7 @@ add_library(ctatapedaemon
   CommandLineParams.cpp
   ConfigurationFile.cpp
   DriveHandler.cpp
+  DriveHandlerProxy.cpp
   SignalHandler.cpp
   SourcedParameter.cpp
   SubprocessHandler.cpp
@@ -22,6 +23,9 @@ add_library(ctatapedaemon
   TpconfigLine.cpp
   Tpconfig.cpp)
 
+target_link_libraries(ctatapedaemon
+  ctatapesession)
+
 add_library(ctadaemonunittests SHARED
   ConfigurationFileTests.cpp
   TapedConfigurationTests.cpp
diff --git a/tapeserver/daemon/DriveHandler.cpp b/tapeserver/daemon/DriveHandler.cpp
index ba42dbbfbc7827732f6272c5e2481494155f680e..c21dc0dc165ffd87734d8705563590ae156aa924 100644
--- a/tapeserver/daemon/DriveHandler.cpp
+++ b/tapeserver/daemon/DriveHandler.cpp
@@ -34,8 +34,11 @@ DriveHandler::DriveHandler(const TapedConfiguration & tapedConfig, const Tpconfi
   // As the handler is started, its first duty is to create a new subprocess. This
   // will be managed by the process manager (initial request in getInitialStatus)
 }
-  
-const std::map<DriveHandler::SessionState, DriveHandler::Timeout> DriveHandler::m_timeouts = {
+
+using session::SessionState;
+using session::SessionType;
+
+const std::map<SessionState, DriveHandler::Timeout> DriveHandler::m_timeouts = {
   {SessionState::Cleaning, std::chrono::duration_cast<Timeout>(std::chrono::minutes(10))},
   {SessionState::Scheduling, std::chrono::duration_cast<Timeout>(std::chrono::minutes(5))},
   {SessionState::Mounting, std::chrono::duration_cast<Timeout>(std::chrono::minutes(10))},
@@ -69,8 +72,8 @@ SubprocessHandler::ProcessingStatus DriveHandler::fork() {
     // Check we are in the right state (sanity check)
     if (m_sessionState != SessionState::PendingFork) {
       std::stringstream err;
-      err << "In DriveHandler::fork(): called while not in the expected state: " << toString(m_sessionState)
-          << " instead of " << toString(SessionState::PendingFork);
+      err << "In DriveHandler::fork(): called while not in the expected state: " << session::toString(m_sessionState)
+          << " instead of " << session::toString(SessionState::PendingFork);
       throw exception::Exception(err.str());
     }
     // First prepare a socket pair for this new subprocess
@@ -134,49 +137,6 @@ decltype (SubprocessHandler::ProcessingStatus::nextTimeout) DriveHandler::nextTi
   }
 }
 
-std::string DriveHandler::toString(SessionState state) {
-  switch(state) {
-  case SessionState::PendingFork:
-    return "PendingFork";
-  case SessionState::Cleaning:
-    return "Cleaning";
-  case SessionState::Scheduling:
-    return "Scheduling";
-  case SessionState::Mounting:
-    return "Mounting";
-  case SessionState::Running:
-    return "Running";
-  case SessionState::Unmounting:
-    return "Unmounting";
-  case SessionState::Shutdown:
-    return "Shutdown";
-  default:
-    {
-      std::stringstream st;
-      st << "UnknownState (" << ((uint32_t) state) << ")";
-      return st.str();
-    }
-  }
-}
-
-std::string DriveHandler::toString(SessionType type) {
-  switch(type) {
-  case SessionType::Archive:
-    return "Archive";
-  case SessionType::Retrieve:
-    return "Retrieve";
-  case SessionType::Undetermined:
-    return "Undetermined";
-  default:
-    {
-      std::stringstream st;
-      st << "UnknownType (" << ((uint32_t) type) << ")";
-      return st.str();
-    }
-  }
-}
-
-
 void DriveHandler::kill() {
   // If we have a subprocess, kill it and wait for completion (if needed). We do not need to keep
   // track of the exit state as kill() mens we will not be called anymore.
@@ -225,7 +185,7 @@ SubprocessHandler::ProcessingStatus DriveHandler::processEvent() {
       {
         exception::Exception ex;
         ex.getMessage() << "In DriveHandler::processEvent(): unexpected session state:" 
-            << toString((SessionState)message.sessionstate());
+            << session::toString((SessionState)message.sessionstate());
         throw ex;
       }
     }
@@ -245,7 +205,7 @@ SubprocessHandler::ProcessingStatus DriveHandler::processScheduling(serializers:
   std::set<SessionState> expectedStates = { SessionState::Cleaning, SessionState::Scheduling };
   if (expectedStates.find(m_sessionState)==expectedStates.end()) {
     log::ScopedParamContainer params(m_processManager.logContext());
-    params.add("PreviousState", toString(m_sessionState));
+    params.add("PreviousState", session::toString(m_sessionState));
     m_processManager.logContext().log(log::WARNING, 
         "In DriveHandler::processScheduling(): unexpected previous state.");
   }
@@ -267,7 +227,7 @@ SubprocessHandler::ProcessingStatus DriveHandler::processMounting(serializers::W
   // The only transition expected is from scheduling.
   if (SessionState::Scheduling != m_sessionState) {
     log::ScopedParamContainer params(m_processManager.logContext());
-    params.add("PreviousState", toString(m_sessionState));
+    params.add("PreviousState", session::toString(m_sessionState));
     m_processManager.logContext().log(log::WARNING, 
         "In DriveHandler::processMounting(): unexpected previous state.");
   }
@@ -297,7 +257,7 @@ SubprocessHandler::ProcessingStatus DriveHandler::processRunning(serializers::Wa
   std::set<SessionState> expectedStates = { SessionState::Mounting, SessionState::Running };
   if (expectedStates.end() == expectedStates.find(m_sessionState)) {
     log::ScopedParamContainer params(m_processManager.logContext());
-    params.add("PreviousState", toString(m_sessionState));
+    params.add("PreviousState", session::toString(m_sessionState));
     m_processManager.logContext().log(log::WARNING, 
         "In DriveHandler::processRunning(): unexpected previous state.");
   }
@@ -337,7 +297,7 @@ SubprocessHandler::ProcessingStatus DriveHandler::processUnmounting(serializers:
   // This status transition is exclusively expected from running
   if (SessionState::Running != m_sessionState) {
     log::ScopedParamContainer params(m_processManager.logContext());
-    params.add("PreviousState", toString(m_sessionState));
+    params.add("PreviousState", session::toString(m_sessionState));
     m_processManager.logContext().log(log::WARNING, 
         "In DriveHandler::processUnmounting(): unexpected previous state.");
   }
@@ -365,7 +325,7 @@ SubprocessHandler::ProcessingStatus DriveHandler::processDrainingToDisk(serializ
   // This status transition is expected from unmounting.
   if (SessionState::Unmounting != m_sessionState) {
     log::ScopedParamContainer params(m_processManager.logContext());
-    params.add("PreviousState", toString(m_sessionState));
+    params.add("PreviousState", session::toString(m_sessionState));
     m_processManager.logContext().log(log::WARNING, 
         "In DriveHandler::processDrainingToDisk(): unexpected previous state.");
   }
@@ -395,7 +355,7 @@ SubprocessHandler::ProcessingStatus DriveHandler::processClosingDown(serializers
   std::set<SessionState> expectedStates = { SessionState::Mounting, SessionState::Running };
   if (expectedStates.end() == expectedStates.find(m_sessionState)) {
     log::ScopedParamContainer params(m_processManager.logContext());
-    params.add("PreviousState", toString(m_sessionState));
+    params.add("PreviousState", session::toString(m_sessionState));
     m_processManager.logContext().log(log::WARNING, 
         "In DriveHandler::processClosingDown(): unexpected previous state.");
   }
@@ -433,7 +393,7 @@ SubprocessHandler::ProcessingStatus DriveHandler::processSigChild() {
       log::ScopedParamContainer params(m_processManager.logContext());
       params.add("pid", m_pid)
             .add("Message", ex.getMessageValue())
-            .add("SessionState", toString(m_sessionState))
+            .add("SessionState", session::toString(m_sessionState))
             .add("SessionType", toString(m_sessionType));
       m_processManager.logContext().log(log::WARNING,
           "In DriveHandler::processSigChild(): failed to get child process exit code. "
diff --git a/tapeserver/daemon/DriveHandler.hpp b/tapeserver/daemon/DriveHandler.hpp
index b0ee3188173bf67e843f151c882e8bb494b27d3b..15f5a67205573c37ec2d0fac482144cf8536d821 100644
--- a/tapeserver/daemon/DriveHandler.hpp
+++ b/tapeserver/daemon/DriveHandler.hpp
@@ -23,6 +23,8 @@
 #include "TapedConfiguration.hpp"
 #include "common/threading/SocketPair.hpp"
 #include "tapeserver/daemon/WatchdogMessage.pb.h"
+#include "tapeserver/session/SessionState.hpp"
+#include "tapeserver/session/SessionType.hpp"
 #include <memory>
 
 namespace cta { namespace tape { namespace  daemon {
@@ -61,24 +63,9 @@ private:
   };
   /** Representation of the outcome of the previous session/child process. */
   PreviousSession m_previousSession=PreviousSession::Initiating;
-public:
-  /** Possible states for the current session. */
-  enum class SessionState: uint32_t  {
-    PendingFork, ///< The subprocess is not started yet.
-    Cleaning,   ///< The subprocess is cleaning up tape left in drive.
-    Scheduling, ///< The subprocess is determining what to do next.
-    Mounting,   ///< The subprocess is mounting the tape.
-    Running,    ///< The subprocess is running the data transfer.
-    Unmounting, ///< The subprocess is unmounting the tape.
-    DrainingToDisk, ///< The subprocess is flushing the memory to disk (retrieves only)
-    ClosingDown, ///< The subprocess completed all tasks and will exit
-    Shutdown    ///< The subprocess is finished after a shutdown was requested. 
-  };
 private:
-  /** Session state to string */
-  std::string toString(SessionState state);
   /** Representation of the status of the current process. */
-  SessionState m_sessionState=SessionState::PendingFork;
+  session::SessionState m_sessionState=session::SessionState::PendingFork;
   /** Helper function to handle Scheduling state report */
   SubprocessHandler::ProcessingStatus processScheduling(serializers::WatchdogMessage & message);
   /** Helper function to handle Mounting state report */
@@ -91,18 +78,9 @@ private:
   SubprocessHandler::ProcessingStatus processDrainingToDisk(serializers::WatchdogMessage & message);
   /** Helper function to handle ClosingDown state report */
   SubprocessHandler::ProcessingStatus processClosingDown(serializers::WatchdogMessage & message);
-public:
-  /** Representation of the session direction */
-  enum class SessionType: uint32_t {
-    Undetermined, ///< The initial direction for the session is undetermined.
-    Archive,      ///< Direction is disk to tape.
-    Retrieve      ///< Direction is tape to disk.
-  };
 private:
-  /** Session type to string */
-  std::string toString(SessionType type);
   /** Current session's type */
-  SessionType m_sessionType=SessionType::Undetermined;
+  session::SessionType m_sessionType=session::SessionType::Undetermined;
   /** Current session's parameters: they are accumulated during session's lifetime
    * and logged as session ends */
   log::LogContext m_sessionEndContext;
@@ -111,7 +89,7 @@ private:
   /** Convenience type */
   typedef std::chrono::milliseconds Timeout;
   /** Values for the heartbeat or completion timeouts where applicable */
-  static const std::map<SessionState, Timeout> m_timeouts;
+  static const std::map<session::SessionState, Timeout> m_timeouts;
   /** Special timeout for data movement timeout during running */
   static const Timeout m_dataMovementTimeout;
   /** When did we see the last block movement? */
diff --git a/tapeserver/session/HandlerInterface.cpp b/tapeserver/daemon/DriveHandlerProxy.cpp
similarity index 56%
rename from tapeserver/session/HandlerInterface.cpp
rename to tapeserver/daemon/DriveHandlerProxy.cpp
index 761877dcd42177ae95b1fcdc564ef4a64cb11b41..795a119afe8c86716de32d869e8bf2d68b1b456a 100644
--- a/tapeserver/session/HandlerInterface.cpp
+++ b/tapeserver/daemon/DriveHandlerProxy.cpp
@@ -16,21 +16,17 @@
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-#include "HandlerInterface.hpp"
+#include "DriveHandlerProxy.hpp"
 #include "tapeserver/daemon/WatchdogMessage.pb.h"
-#include "tapeserver/daemon/DriveHandler.hpp"
 
-namespace cta { namespace tape { namespace  session {
+namespace cta { namespace tape { namespace daemon {
 
-BaseHandlerInterface::BaseHandlerInterface(server::SocketPair& socketPair): 
-  m_socketPair(socketPair) {}
-
-void BaseHandlerInterface::announceSchedulingRound() {
-  daemon::serializers::WatchdogMessage message;
-  message.set_sessionstate((uint32_t)daemon::DriveHandler::SessionState::Scheduling);
-  message.set_sessiontype((uint32_t)daemon::DriveHandler::SessionType::Undetermined);
-  m_socketPair.send(message.SerializeAsString());
+DriveHandlerProxy::DriveHandlerProxy(server::SocketPair& socketPair): m_socketPair(socketPair) {
+  m_socketPair.close(server::SocketPair::Side::parent);
+  
 }
 
+void DriveHandlerProxy::addLogParams(const std::string& unitName, const std::list<castor::log::Param>& params) {}
+
 
-}}}  // namespace cta::tape::session
\ No newline at end of file
+}}} // namespace cta::tape::daemon
diff --git a/tapeserver/daemon/DriveHandlerProxy.hpp b/tapeserver/daemon/DriveHandlerProxy.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..b9b9eb4e508d53924fc4f9d1160e5e1f5caa3808
--- /dev/null
+++ b/tapeserver/daemon/DriveHandlerProxy.hpp
@@ -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/>.
+ */
+
+#pragma once
+
+#include "TapedProxy.hpp"
+#include "common/threading/SocketPair.hpp"
+
+namespace cta  { namespace tape { namespace daemon {
+
+/**
+ * A class sending the data transfer process reports to the daemon via a
+ * socketPair. It implements the TapedProxy interface.
+ */
+class DriveHandlerProxy: public TapedProxy {
+public:
+  /**
+   * Constructor. The constructor will close the server side of the
+   * pair.
+   * @param sopcketPair Reference to the socket pair.
+   */
+  DriveHandlerProxy(server::SocketPair & sopcketPair);
+  virtual ~DriveHandlerProxy() {}
+  void reportState(const cta::tape::session::SessionState state, const cta::tape::session::SessionType type, const std::string& vid) override;
+  void reportHeartbeat(uint64_t totalTapeBytesMoved, uint64_t totalDiskBytesMoved) override;
+  void addLogParams(const std::string& unitName, const std::list<castor::log::Param>& params) override;
+  void deleteLogParams(const std::string& unitName, const std::list<std::string>& paramNames) override;
+  void gotRetrieveJobFromCTA(const std::string& vid, const std::string& unitName) override;
+  void labelError(const std::string& unitName, const std::string& message) override;
+  void notifyHeartbeat(const std::string& unitName, const uint64_t nbBytesMoved) override;
+  void tapeMountedForMigration(const std::string& vid, const std::string& unitName) override;
+  void tapeMountedForRecall(const std::string& vid, const std::string& unitName) override;
+  void tapeUnmountStarted(const std::string& vid, const std::string& unitName) override;
+  void tapeUnmounted(const std::string& vid, const std::string& unitName) override;
+private:
+  server::SocketPair & m_socketPair;
+};
+
+}}} // namespace cta::tape::daemon
diff --git a/tapeserver/daemon/TapedProxy.cpp b/tapeserver/daemon/TapedProxy.cpp
index d0b53926272fa33456873f47538cf5b7ef55a0a8..e72695ca774963c743fb647d7140cf17d9d0770b 100644
--- a/tapeserver/daemon/TapedProxy.cpp
+++ b/tapeserver/daemon/TapedProxy.cpp
@@ -23,8 +23,11 @@
 
 #include "tapeserver/daemon/TapedProxy.hpp"
 
+namespace cta { namespace tape { namespace daemon {
+
 //-----------------------------------------------------------------------------
 // destructor
 //-----------------------------------------------------------------------------
-cta::daemon::TapedProxy::~TapedProxy() {
-}
+TapedProxy::~TapedProxy() {}
+
+}}} // namespace cta::tape::daemon
diff --git a/tapeserver/daemon/TapedProxy.hpp b/tapeserver/daemon/TapedProxy.hpp
index 02fb36f0f099119c418a1e9457ff3d43b0c03d2a..409f8b6f7a57ae4127958ce7796d5062947fe1ad 100644
--- a/tapeserver/daemon/TapedProxy.hpp
+++ b/tapeserver/daemon/TapedProxy.hpp
@@ -23,17 +23,18 @@
 
 #include "tapeserver/castor/exception/Exception.hpp"
 #include "tapeserver/castor/log/Param.hpp"
+#include "tapeserver/session/SessionState.hpp"
+#include "tapeserver/session/SessionType.hpp"
 
 #include <stdint.h>
 #include <string>
 #include <list>
 
-namespace cta {
-namespace daemon {
+namespace cta { namespace tape { namespace daemon {
 
 /**
  * Abstract class defining the interface to a proxy object representing the
- * internal network interface of the tapeserverd daemon.
+ * possible notifications sent back to main tape daemon (taped)
  */
 class TapedProxy {
 public:
@@ -44,18 +45,28 @@ public:
   virtual ~TapedProxy()  = 0;
   
   /**
-   * Notifies the tapeserverd daemon that the mount-session child-process got
-   * an archive job from CTA
-   *
-   * @param vid The tape to be mounted for recall.
-   * @param unitName The unit name of the tape drive.
-   * @return The number of files currently stored on the tape
+   * Notifies taped of a state change. Taped will validate the transition and
+   * kill the process if it is an unexpected transition.
+   * 
+   * @param state the new state.
+   * @param type the type of the session (archive, retrieve, verify, 
+   * @param vid the vid of the tape involved
+   */
+  virtual void reportState(const cta::tape::session::SessionState state,
+    const cta::tape::session::SessionType type, 
+    const std::string & vid) = 0;
+  
+  /**
+   * Report a heartbeat to taped. The data counters might or might not have changed
+   * as the sending of the heartbeat itself is an information.
+   * 
+   * @param totalTapeBytesMoved cumulated data transfered to/from tape during the session.
+   * @param totalDiskBytesMoved cumulated data transfered to/from disk during the session.
    */
-  virtual uint32_t gotArchiveJobFromCTA(const std::string &vid,
-    const std::string &unitName, const uint32_t nbFiles) = 0;
+  virtual void reportHeartbeat(uint64_t totalTapeBytesMoved, uint64_t totalDiskBytesMoved) = 0;
   
   /**
-   * Notifies the tapeserverd daemon that the mount-session child-process got
+   * Notifies taped that the mount-session child-process got
    * a retrieve job from CTA
    *
    * @param vid The tape to be mounted for recall.
@@ -65,7 +76,7 @@ public:
     const std::string &unitName) = 0;
 
   /**
-   * Notifies the tapeserverd daemon that the specified tape has been mounted.
+   * Notifies taped that the specified tape has been mounted.
    *
    * @param vid The tape to be mounted for recall.
    * @param unitName The unit name of the tape drive.
@@ -74,7 +85,7 @@ public:
     const std::string &unitName) = 0;
 
   /**
-   * Notifies the tapeserverd daemon that the specified tape has been mounted.
+   * Notifies taped that the specified tape has been mounted.
    *
    * @param vid The tape to be mounted for recall.
    * @param unitName The unit name of the tape drive.
@@ -83,7 +94,7 @@ public:
     const std::string &unitName) = 0;
 
   /**
-   * Notifies the tapeserverd daemon that the specified tape is unmounting.
+   * Notifies taped that the specified tape is unmounting.
    *
    * @param vid The tape to be mounted for recall.
    * @param unitName The unit name of the tape drive.
@@ -92,7 +103,7 @@ public:
     const std::string &unitName) = 0;
 
   /**
-   * Notifies the tapeserverd daemon that the specified tape has been unmounted.
+   * Notifies taped that the specified tape has been unmounted.
    *
    * @param vid The tape to be mounted for recall.
    * @param unitName The unit name of the tape drive.
@@ -101,8 +112,9 @@ public:
     const std::string &unitName) = 0;
 
   /**
-   * Notifies the tapeserverd daemon that the data-transfer session is still
-   * alive and gives an indication of how much data has been moved.
+   * Notifies taped that the data-transfer session is still
+   * alive and gives an indication of how much data has been on the tape
+   * and disk sides, respectively.
    *
    * @param unitName The unit name of the tape drive.
    * @param nbBytesMoved Delta value giving the number of bytes moved
@@ -137,6 +149,5 @@ public:
 
 }; // class TapeserverProxy
 
-} // namespace messages
-} // namespace castor
+}}} // namespace cta::tape::daemon
 
diff --git a/tapeserver/session/CMakeLists.txt b/tapeserver/session/CMakeLists.txt
index be3efbbcf5861d5787b82f21b09a24c7bdb04676..aabac1703ec4b329387bfe49c10d668dd6d3596e 100644
--- a/tapeserver/session/CMakeLists.txt
+++ b/tapeserver/session/CMakeLists.txt
@@ -1,4 +1,5 @@
 cmake_minimum_required (VERSION 2.6)
 
 add_library(ctatapesession
-  HandlerInterface.cpp)
\ No newline at end of file
+  SessionState.cpp
+  SessionType.cpp)
diff --git a/tapeserver/session/HandlerInterface.hpp b/tapeserver/session/HandlerInterface.hpp
deleted file mode 100644
index 632b383f27cf752b62f6b598fb3727582896c835..0000000000000000000000000000000000000000
--- a/tapeserver/session/HandlerInterface.hpp
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * The CERN Tape Archive (CTA) project
- * Copyright (C) 2015  CERN
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#pragma once
-
-#include "common/threading/SocketPair.hpp"
-#include "common/threading/Threading.hpp"
-
-namespace cta { namespace tape { namespace  session {
-
-/** A class wrapping the socket pair provided to the session process 
- * This interface provides direct access functions for simple messages
- * and accumulates the more frequent information (block transfers) and
- * accumulates error counts. This class contains the core of the reporting
- * functions, and is the (virtual) base of the 2 variants for retrieve and archive. 
- * A fourth, simplified (and base) version is used when scheduling the session,
- * before knowing whether it will be an archive or a retrieve. */
-
-class HandlerInterface: private threading::Thread {
-public:
-  HandlerInterface(server::SocketPair & socketPair);
-  
-private:
-
-};
-
-/** The base class for the HandlerInterface. This is used during tape cleaning and
- * scheduling. */
-
-class BaseHandlerInterface {
-public:
-  BaseHandlerInterface(server::SocketPair & socketPair);
-  /** Report a beginning of a scheduling round. That implicitly reports the and
-   * of the drive cleanup, when applicable. */
-  void announceSchedulingRound();
-protected:
-  /** The socket pair allowing communication with the handler in the parent process */
-  server::SocketPair & m_socketPair;  
-};
-
-}}}  // namespace cta::tape::session
diff --git a/tapeserver/session/SessionState.cpp b/tapeserver/session/SessionState.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..6feb2930c441763dc12516ccf890f6c7d052e63d
--- /dev/null
+++ b/tapeserver/session/SessionState.cpp
@@ -0,0 +1,49 @@
+/*
+ * 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 "SessionState.hpp"
+#include <sstream>
+
+namespace cta { namespace tape { namespace session {
+
+std::string toString(SessionState state) {
+  switch(state) {
+  case SessionState::PendingFork:
+    return "PendingFork";
+  case SessionState::Cleaning:
+    return "Cleaning";
+  case SessionState::Scheduling:
+    return "Scheduling";
+  case SessionState::Mounting:
+    return "Mounting";
+  case SessionState::Running:
+    return "Running";
+  case SessionState::Unmounting:
+    return "Unmounting";
+  case SessionState::Shutdown:
+    return "Shutdown";
+  default:
+    {
+      std::stringstream st;
+      st << "UnknownState (" << ((uint32_t) state) << ")";
+      return st.str();
+    }
+  }
+}
+
+}}} // namespace cta::tape::session
diff --git a/tapeserver/session/SessionState.hpp b/tapeserver/session/SessionState.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..0341ec8fc75e1b46f12aaf7bdf81331dcc9728d1
--- /dev/null
+++ b/tapeserver/session/SessionState.hpp
@@ -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/>.
+ */
+
+#pragma once
+#include <string>
+
+namespace cta { namespace tape { namespace session {
+
+/** Possible states for the tape session. */
+enum class SessionState: uint32_t  {
+  PendingFork, ///< The subprocess is not started yet.
+  Cleaning,   ///< The subprocess is cleaning up tape left in drive.
+  Scheduling, ///< The subprocess is determining what to do next.
+  Mounting,   ///< The subprocess is mounting the tape.
+  Running,    ///< The subprocess is running the data transfer.
+  Unmounting, ///< The subprocess is unmounting the tape.
+  DrainingToDisk, ///< The subprocess is flushing the memory to disk (retrieves only)
+  ClosingDown, ///< The subprocess completed all tasks and will exit
+  Shutdown    ///< The subprocess is finished after a shutdown was requested. 
+};
+/** Session state to string */
+std::string toString(SessionState state);
+
+}}} // namespace cta::tape::session
\ No newline at end of file
diff --git a/tapeserver/session/SessionType.cpp b/tapeserver/session/SessionType.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..664e81f142a0c47534d13f830d686f48f044f752
--- /dev/null
+++ b/tapeserver/session/SessionType.cpp
@@ -0,0 +1,46 @@
+/*
+ * 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 "SessionType.hpp"
+#include <sstream>
+
+namespace cta { namespace tape { namespace session {
+
+std::string toString(SessionType type) {
+  switch(type) {
+  case SessionType::Archive:
+    return "Archive";
+  case SessionType::Retrieve:
+    return "Retrieve";
+  case SessionType::Verify:
+    return "Verify";
+  case SessionType::Label:
+    return "Label";
+  case SessionType::Undetermined:
+    return "Undetermined";
+  default:
+    {
+      std::stringstream st;
+      st << "UnknownType (" << ((uint32_t) type) << ")";
+      return st.str();
+    }
+  }
+}
+
+}}} // namespace cta::tape::session
+
diff --git a/tapeserver/session/SessionType.hpp b/tapeserver/session/SessionType.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..8c9777940faf144eee5ea390a0d8f1efba1a7ba1
--- /dev/null
+++ b/tapeserver/session/SessionType.hpp
@@ -0,0 +1,35 @@
+/*
+ * The CERN Tape Archive (CTA) project
+ * Copyright (C) 2015  CERN
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#pragma once
+#include <string>
+
+namespace cta { namespace tape { namespace session {
+
+/** Possible type for the tape session. */
+enum class SessionType: uint32_t {
+    Undetermined, ///< The initial direction for the session is undetermined.
+    Archive,      ///< Direction is disk to tape.
+    Retrieve,     ///< Direction is tape to disk.
+    Verify,       ///< Read from tape to validate data.
+    Label         ///< (Re)label the tape.
+  };
+/** Session state to string */
+std::string toString(SessionType state);
+
+}}} // namespace cta::tape::s
diff --git a/tapeserver/test/CMakeLists.txt b/tapeserver/test/CMakeLists.txt
deleted file mode 100644
index 10e4c51b719e9231fdde76cdd8199610d059518e..0000000000000000000000000000000000000000
--- a/tapeserver/test/CMakeLists.txt
+++ /dev/null
@@ -1,45 +0,0 @@
-#                      CMakeLists.txt
-#
-# This file is part of the Castor project.
-# See http://castor.web.cern.ch/castor
-#
-# Copyright (C) 2003  CERN
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-#
-#
-# Eric.Cano@cern.ch
-#
-
-cmake_minimum_required (VERSION 2.6)
-
-include_directories(/usr/include/shift)
-include_directories(${CMAKE_SOURCE_DIR}/tapeserver)
-include_directories(${CMAKE_SOURCE_DIR}/tapeserver/h)
-include_directories(${CMAKE_BINARY_DIR}/tapeserver)
-include_directories(${CMAKE_BINARY_DIR})
-
-find_package (xrootd REQUIRED)
-include_directories (${XROOTD_INCLUDE_DIR})
-
-# Those tests are multi threaded. They could should also be run in 
-# helgrind/drd (and also memcheck)
-#add_executable(castorThreadedUnitTests
- # castorUnitTests.cpp
- # ../castor/server/ThreadingMTTests.cpp
- # ../castor/tape/tapeserver/daemon/DataTransferSessionTest.cpp
-# ../castor/server/ThreadingBlockingQTests.cpp
- # ../castor/tape/tapeserver/daemon/RecallTaskInjectorTest.cpp
- # ../castor/tape/tapeserver/daemon/MigrationReportPackerTest.cpp
- # ../castor/tape/tapeserver/daemon/TaskWatchDogTest.cpp
-#  ../castor/tape/tapeserver/file/CryptoPPTest.cpp
-#)
diff --git a/tapeserver/test/castorThreadedUnitTests.supp b/tapeserver/test/castorThreadedUnitTests.supp
deleted file mode 100644
index 0153e3fc0b225c4a33943a7cf786e612d88bd613..0000000000000000000000000000000000000000
--- a/tapeserver/test/castorThreadedUnitTests.supp
+++ /dev/null
@@ -1,154 +0,0 @@
-# castor unit tests suppression list
-#
-
-{
-  helgrind-unitTest-slc5-marshaling007
-  Helgrind:Race
-  fun:_ZrsIcSt11char_traitsIcESaIcEERN6castor2io11biniostreamES6_RSbIT_T0_T1_E
-}
-
-{
-  helgrind-unitTest-slc5-biniostreamclass
-  Helgrind:Race
-  fun:*castor2io11biniostream*
-}
-
-{
-  helgrind-unitTest-slc5-test-itself
-  Helgrind:Race
-  ...
-  fun:_ZN8unitTest15streamMarshaler3runEv
-}
-
-{
-  helgrind-unitTest-stream-marshalers
-  Helgrind:Race
-  ...
-  fun:_ZN6castor2io12StreamCnvSvc15unmarshalObject*
-}
-
-{
-  helgrind-unitTest-stream-biniostream-exact01
-  Helgrind:Race
-  ...
-  fun:_ZrsIcSt11char_traitsIcESaIcEERN6castor2io11biniostreamES6_RSbIT_T0_T1_E
-}
-
-{
-  helgrind-unitTest-basic-streams-in-getconfent
-  Helgrind:Race
-  ...
-  fun:_ZNSt19basic_ostringstreamIcSt11char_traitsIcESaIcEEC1ERKSsSt13_Ios_Openmode
-}
-
-{
-  helgrind-unitTest-basic-streams01
-  Helgrind:Race
-  ...
-  fun:_ZNSt15basic_stringbufIcSt11char_traitsIcESaIcEE8overflowEi
-}
-
-{
-  helgrind-unitTest-string-append-in-getconfent
-  Helgrind:Race
-  fun:_ZNSs6appendERKSs
-  ...
-  fun:getconfent
-}
-
-{
-  helgrind-unitTest-string-append-in-getconfent-from-file
-  Helgrind:Race
-  fun:_ZNSs6appendERKSs
-  ...
-  fun:getconfent_fromfile
-}
-
-{
-  helgrind-unitTest-iostream-getconfent-from-file
-  Helgrind:Race
-  fun:_ZStlsIcSt11char_traitsIcESaIcEERSt13basic_ostreamIT_T0_ES7_RKSbIS4_S5_T1_E
-}
-
-{
-  helgrind-unitTest-castor-tape-server-ClientInterface-fetchVolumeId
-  Helgrind:Race
-  ...
-  fun:_ZN6castor4tape6server15ClientInterface13fetchVolumeIdERNS2_10VolumeInfoERNS2_13RequestReportE
-}
-
-{
-  helgrind-unitTest-castor-stringLoggerCleanString
-  Helgrind:Race
-  ...
-  fun:_ZN6castor3log12StringLogger11cleanStringERKSsb
-}
-
-
-{
-  helgrind-unitTest-castor-basicStringClone
-  Helgrind:Race
-  fun:_ZNSs4_Rep8_M_cloneERKSaIcEm
-}
-
-{
-  helgrind-unitTest-castor-basicStringAppend
-  Helgrind:Race
-  fun:_ZNSs6appendERKSs
-  fun:_ZN6castor9exception9BacktraceC1Ev
-}
-
-{
-  helgrind-unitTest-castor-basicStringConstructor
-  Helgrind:Race
-  fun:_ZNSsC1ERKSs
-}
-
-{
-  helgrind-unitTest-castor-basicStringAssign
-  Helgrind:Race
-  fun:_ZNSs6assignEPKcj
-}
-
-{
-  helgrind-unitTest-castor-basicStringSize
-  Helgrind:Race
-  fun:_ZNKSs4sizeEv
-}
-
-{
-  helgrind-unitTest-castor-basicStringsCatchAll1
-  Helgrind:Race
-  fun:_ZNSs6*
-}
-
-{
-  helgrind-unitTest-castor-basicStringsCatchAll2
-  Helgrind:Race
-  fun:_ZNSs7*
-}
-
-{
-  helgrind-unitTest-castor-basicStringsGottaCatchAll
-  Helgrind:Race
-  fun:_ZNSs*
-}
-
-{
-  helgrind-unitTest-castor-basicStringslength
-  Helgrind:Race
-  fun:_ZNKSs6*
-}
-
-{
-  helgrind-unitTest-castor-basicStringsGottaCatchAllTer
-  Helgrind:Race
-  fun:_ZNKSs*
-}
-
-{
-  helgrind-unitTest-castor-zmq
-  Helgrind:Race
-  ...
-  obj:/usr/lib64/libzmq.so.3.0.0
-}
diff --git a/tapeserver/test/castorUnitTests.cpp b/tapeserver/test/castorUnitTests.cpp
deleted file mode 100644
index 8c6e062d3c75a877570ba35cef4098cd69eeb633..0000000000000000000000000000000000000000
--- a/tapeserver/test/castorUnitTests.cpp
+++ /dev/null
@@ -1,51 +0,0 @@
-/******************************************************************************
- *
- * This file is part of the Castor project.
- * See http://castor.web.cern.ch/castor
- *
- * Copyright (C) 2003  CERN
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * 
- *
- * @author Castor Dev team, castor-dev@cern.ch
- *****************************************************************************/
-
-#include "castor/BaseObject.hpp"
-
-#include <gtest/gtest.h>
-#include <gmock/gmock.h>
-#include <shift/Cthread_api.h>
-
-int main(int argc, char** argv) {
-  // The call to Cthread_init is necessary at the beginning of any program
-  // relying on the old "Cthread" collection. Calling should not have side
-  // effects.
-  Cthread_init();
-
-  // The following line must be executed to initialize Google Mock
-  // (and Google Test) before running the tests.
-  ::testing::InitGoogleMock(&argc, argv);
-  int ret = RUN_ALL_TESTS();
-  castor::BaseObject::resetServices();
-
-  // Close standard in, out and error so that valgrind can be used with the
-  // following command-line to track open file-descriptors:
-  //
-  //     valgrind --track-fds=yes
-  close(0);
-  close(1);
-  close(2);
-
-  return ret;
-}