diff --git a/mediachanger/AcsProxy.hpp b/mediachanger/AcsProxy.hpp
index a6529c7d2d7c62a0674eb25731b33c0b5a4a381a..e25cf9ef973ae3714ee7d323f4e71d96fa3d8d56 100644
--- a/mediachanger/AcsProxy.hpp
+++ b/mediachanger/AcsProxy.hpp
@@ -48,8 +48,7 @@ public:
    * @param vid The volume identifier of the tape to be mounted.
    * @param librarySlot The slot in the library that contains the tape drive.
    */
-  virtual void mountTapeReadOnly(const std::string &vid,
-    const cta::mediachanger::AcsLibrarySlot &librarySlot) = 0;
+  virtual void mountTapeReadOnly(const std::string &vid, const AcsLibrarySlot &librarySlot) = 0;
   
   /**
    * Request the CASTOR ACS daemon to mount the specifed tape for read/write
@@ -58,8 +57,7 @@ public:
    * @param vid The volume identifier of the tape to be mounted.
    * @param librarySlot The slot in the library that contains the tape drive.
    */
-  virtual void mountTapeReadWrite(const std::string &vid,
-    const cta::mediachanger::AcsLibrarySlot &librarySlot) = 0;
+  virtual void mountTapeReadWrite(const std::string &vid, const AcsLibrarySlot &librarySlot) = 0;
   
   /**
    * Request the CASTOR ACS daemon to dismount the specifed tape from the tape
@@ -68,8 +66,7 @@ public:
    * @param vid The volume identifier of the tape to be mounted.
    * @param librarySlot The slot in the library that contains the tape drive.
    */
-  virtual void dismountTape(const std::string &vid,
-    const cta::mediachanger::AcsLibrarySlot &librarySlot) = 0;
+  virtual void dismountTape(const std::string &vid, const AcsLibrarySlot &librarySlot) = 0;
 
   /**
    * Request the CASTOR ACS daemon to forcefully dismount the specifed tape
@@ -82,8 +79,7 @@ public:
    * @param vid The volume identifier of the tape to be mounted.
    * @param librarySlot The slot in the library that contains the tape drive.
    */
-  virtual void forceDismountTape(const std::string &vid,
-    const cta::mediachanger::AcsLibrarySlot &librarySlot) = 0;
+  virtual void forceDismountTape(const std::string &vid, const AcsLibrarySlot &librarySlot) = 0;
 
 }; // class AcsProxy
 
diff --git a/mediachanger/AcsProxyDummy.cpp b/mediachanger/AcsProxyDummy.cpp
deleted file mode 100644
index 6456849416a9828bd295164efbf28279f276eb8d..0000000000000000000000000000000000000000
--- a/mediachanger/AcsProxyDummy.cpp
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * The CERN Tape Archive(CTA) project
- * Copyright(C) 2015  CERN
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- *(at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "mediachanger/AcsProxyDummy.hpp"
-
-//------------------------------------------------------------------------------
-// mountTapeReadOnly
-//------------------------------------------------------------------------------
-void cta::mediachanger::AcsProxyDummy::mountTapeReadOnly(const std::string &vid,
-  const cta::mediachanger::AcsLibrarySlot &librarySlot) {
-}
-
-//------------------------------------------------------------------------------
-// mountTapeForMigration
-//------------------------------------------------------------------------------
-void cta::mediachanger::AcsProxyDummy::mountTapeReadWrite(const std::string &vid,
-  const cta::mediachanger::AcsLibrarySlot &librarySlot) {
-}
-
-//------------------------------------------------------------------------------
-// dismountTape
-//------------------------------------------------------------------------------
-void cta::mediachanger::AcsProxyDummy::dismountTape(const std::string &vid,
-  const cta::mediachanger::AcsLibrarySlot &librarySlot) {
-}
-
-//------------------------------------------------------------------------------
-// dismountTape
-//------------------------------------------------------------------------------
-void cta::mediachanger::AcsProxyDummy::forceDismountTape(const std::string &vid,
-  const cta::mediachanger::AcsLibrarySlot &librarySlot) {
-}
diff --git a/mediachanger/AcsProxyDummy.hpp b/mediachanger/AcsProxyDummy.hpp
deleted file mode 100644
index ded0c804e5cc1a476bfdf87ab9fd4bcef264b5b2..0000000000000000000000000000000000000000
--- a/mediachanger/AcsProxyDummy.hpp
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * The CERN Tape Archive(CTA) project
- * Copyright(C) 2015  CERN
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- *(at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#pragma once
-
-#include "mediachanger/AcsProxy.hpp"
-
-namespace cta {
-namespace mediachanger {
-
-/**
- * Concrete class implementimg a dummy AcsProxy.
- */
-class AcsProxyDummy: public AcsProxy {
-public:
-
-  /**
-   * Request the CASTOR ACS daemon to mount the specified tape for read-only
-   * access into the tape drive in the specified library slot.
-   *
-   * @param vid The volume identifier of the tape to be mounted.
-   * @param librarySlot The slot in the library that contains the tape drive.
-   */ 
-  void mountTapeReadOnly(const std::string &vid,
-    const cta::mediachanger::AcsLibrarySlot &librarySlot);
-    
-  /** 
-   * Request the CASTOR ACS daemon to mount the specifed tape for read/write
-   * access into the tape drive in the specified library slot.
-   *    
-   * @param vid The volume identifier of the tape to be mounted.
-   * @param librarySlot The slot in the library that contains the tape drive.
-   */
-  void mountTapeReadWrite(const std::string &vid,
-    const cta::mediachanger::AcsLibrarySlot &librarySlot);
-    
-  /** 
-   * Request the CASTOR ACS daemon to dismount the specifed tape from the tape
-   * drive in the specified library slot.
-   *
-   * @param vid The volume identifier of the tape to be mounted.
-   * @param librarySlot The slot in the library that contains the tape drive.
-   */
-  void dismountTape(const std::string &vid,
-    const cta::mediachanger::AcsLibrarySlot &librarySlot);
-
-  /**
-   * Request the CASTOR ACS daemon to forcefully dismount the specifed tape
-   * from the tape drive in the specified library slot.  Forcefully means
-   * rewinding and ejecting the tape if necessary.
-   *
-   * @param vid The volume identifier of the tape to be mounted.
-   * @param librarySlot The slot in the library that contains the tape drive.
-   */
-  void forceDismountTape(const std::string &vid,
-    const cta::mediachanger::AcsLibrarySlot &librarySlot);
-
-}; // class AcsProxyDummy
-
-} // namespace mediachanger
-} // namespace cta
-
diff --git a/mediachanger/AcsProxyZmq.cpp b/mediachanger/AcsProxyZmq.cpp
index 24298e73b7171c03721d006b4edfdad42cc31512..9a56fc49bd0d8bdfda4bf752738c3f5331eee8e5 100644
--- a/mediachanger/AcsProxyZmq.cpp
+++ b/mediachanger/AcsProxyZmq.cpp
@@ -167,8 +167,7 @@ Frame createAcsForceDismountTapeFrame(const std::string &vid, const AcsLibrarySl
 //------------------------------------------------------------------------------
 // constructor
 //------------------------------------------------------------------------------
-AcsProxyZmq::AcsProxyZmq(const unsigned short serverPort,
-  void *const zmqContext) throw():
+AcsProxyZmq::AcsProxyZmq(void *const zmqContext, const unsigned short serverPort) throw():
   m_serverPort(serverPort),
   m_serverSocket(zmqContext, ZMQ_REQ) {
   connectZmqSocketToLocalhost(m_serverSocket, serverPort);
diff --git a/mediachanger/AcsProxyZmq.hpp b/mediachanger/AcsProxyZmq.hpp
index 35964190551135c99ce5373e8dcfa1649afbde8c..652da4f8130e51a29dd408e1bcf00174a9448c7c 100644
--- a/mediachanger/AcsProxyZmq.hpp
+++ b/mediachanger/AcsProxyZmq.hpp
@@ -19,6 +19,7 @@
 #pragma once
 
 #include "mediachanger/AcsProxy.hpp"
+#include "mediachanger/Constants.hpp"
 #include "mediachanger/ZmqSocketMT.hpp"
 
 #include <mutex>
@@ -35,11 +36,11 @@ public:
   /**
    * Constructor.
    *
+   * @param zmqContext The ZMQ context.
    * @param serverPort The TCP/IP port on which the CASTOR ACS daemon is
    * listening for ZMQ messages.
-   * @param zmqContext The ZMQ context.
    */
-  AcsProxyZmq(const unsigned short serverPort, void *const zmqContext) throw();
+  AcsProxyZmq(void *const zmqContext, const unsigned short serverPort = ACS_PORT) throw();
 
   /**
    * Request the CASTOR ACS daemon to mount the specified tape for read-only
@@ -48,8 +49,7 @@ public:
    * @param vid The volume identifier of the tape to be mounted.
    * @param librarySlot The slot in the library that contains the tape drive.
    */
-  void mountTapeReadOnly(const std::string &vid,
-    const cta::mediachanger::AcsLibrarySlot &librarySlot);
+  void mountTapeReadOnly(const std::string &vid, const AcsLibrarySlot &librarySlot);
 
   /** 
    * Request the CASTOR ACS daemon to mount the specifed tape for read/write
@@ -58,8 +58,7 @@ public:
    * @param vid The volume identifier of the tape to be mounted.
    * @param librarySlot The slot in the library that contains the tape drive.
    */
-  void mountTapeReadWrite(const std::string &vid,
-    const cta::mediachanger::AcsLibrarySlot &librarySlot);
+  void mountTapeReadWrite(const std::string &vid, const AcsLibrarySlot &librarySlot);
 
   /** 
    * Request the CASTOR ACS daemon to dismount the specifed tape from the tape
@@ -68,8 +67,7 @@ public:
    * @param vid The volume identifier of the tape to be mounted.
    * @param librarySlot The slot in the library that contains the tape drive.
    */
-  void dismountTape(const std::string &vid,
-    const cta::mediachanger::AcsLibrarySlot &librarySlot);
+  void dismountTape(const std::string &vid, const AcsLibrarySlot &librarySlot);
 
   /**
    * Request the CASTOR ACS daemon to forcefully dismount the specifed tape
@@ -79,8 +77,7 @@ public:
    * @param vid The volume identifier of the tape to be mounted.
    * @param librarySlot The slot in the library that contains the tape drive.
    */
-  void forceDismountTape(const std::string &vid,
-    const cta::mediachanger::AcsLibrarySlot &librarySlot);
+  void forceDismountTape(const std::string &vid, const AcsLibrarySlot &librarySlot);
 
 private:
   
diff --git a/mediachanger/CMakeLists.txt b/mediachanger/CMakeLists.txt
index c4f51976cce827516a6f9c7b695f22667abd93bd..9a2661f5b7b374c908a9957aa3683ea7c1005d3b 100644
--- a/mediachanger/CMakeLists.txt
+++ b/mediachanger/CMakeLists.txt
@@ -25,7 +25,6 @@ PROTOBUF_GENERATE_CPP(ProtoSources ProtoHeaders ${ProtoFiles})
 set (MEDIACHANGER_LIB_SRC_FILES
   AcsLibrarySlot.cpp
   AcsProxy.cpp
-  AcsProxyDummy.cpp
   AcsProxyZmq.cpp
   CmdLine.cpp
   CmdLineTool.cpp
@@ -41,7 +40,6 @@ set (MEDIACHANGER_LIB_SRC_FILES
   MessageHeader.cpp
   messages.cpp
   MmcProxy.cpp
-  MmcProxyDummy.cpp
   MmcProxyLog.cpp
   MmcProxyNotSupported.cpp
   ${ProtoSources}
@@ -49,12 +47,12 @@ set (MEDIACHANGER_LIB_SRC_FILES
   RmcMarshal.hpp
   RmcMountMsgBody.cpp
   RmcProxy.cpp
-  RmcProxyDummy.cpp
   RmcProxyTcpIp.cpp
   RmcUnmountMsgBody.cpp
   ScsiLibrarySlot.cpp
   SmartZmqContext.cpp
   TapeLibraryType.cpp
+  ZmqContextSingleton.cpp
   ZmqMsg.cpp
   ZmqSocket.cpp
   ZmqSocketMT.cpp
@@ -78,7 +76,6 @@ set (MEDIACHANGER_UNIT_TESTS_LIB_SRC_FILES
   IoTest.cpp
   LibrarySlotParserTest.cpp
   ManualLibrarySlotTest.cpp
-  MediaChangerFacadeTest.cpp
   MountCmdLine.cpp
   MountCmdLineTest.cpp
   ScsiLibrarySlotTest.cpp)
diff --git a/mediachanger/Constants.hpp b/mediachanger/Constants.hpp
index 6b990d0dae82d84d19b1e1a6f5266710de56deb9..2280fe87f6b2c766061a5781740f5e1285d2a3cb 100644
--- a/mediachanger/Constants.hpp
+++ b/mediachanger/Constants.hpp
@@ -98,10 +98,16 @@ const unsigned short ACS_PORT = 54521;
  */
 const unsigned short RMC_PORT = 5014;
 
+/**
+ * The network timeout of rmc communications should be several minutes due
+ * to the time it takes to mount and unmount tapes.
+ */
+const int RMC_NET_TIMEOUT = 600; // Timeout in seconds
+
 /**
  * The maximum number of attempts a retriable RMC request should be issued.
  */
-const int RMC_MAXRQSTATTEMPTS = 10;
+const int RMC_MAX_RQST_ATTEMPTS = 10;
 
 /**
  * The magic number to identify taped messages.
diff --git a/mediachanger/DismountCmdLine.cpp b/mediachanger/DismountCmdLine.cpp
index ac84c1627d3af4e5dc3c371b730ad5a125d22ef7..d2bca894f4c5f541e97152874d47c0217dba045f 100644
--- a/mediachanger/DismountCmdLine.cpp
+++ b/mediachanger/DismountCmdLine.cpp
@@ -133,6 +133,13 @@ bool cta::mediachanger::DismountCmdLine::getForce() const throw() {
   return m_force;
 }
 
+//------------------------------------------------------------------------------
+// getProgramName
+//------------------------------------------------------------------------------
+std::string cta::mediachanger::DismountCmdLine::getProgramName() {
+  return "cta-mediachanger-dismount";
+}
+
 //------------------------------------------------------------------------------
 // processOption
 //------------------------------------------------------------------------------
@@ -166,10 +173,10 @@ void cta::mediachanger::DismountCmdLine::processOption(const int opt) {
 // getUsage
 //------------------------------------------------------------------------------
 std::string cta::mediachanger::DismountCmdLine::getUsage() throw() {
-  return
+  return std::string() +
   "Usage:\n"
   "\n"
-  "  cta-mediachanger-dismount [options] VID DRIVE_SLOT\n"
+  "  " + getProgramName() + " [options] VID DRIVE_SLOT\n"
   "\n"
   "Where:\n"
   "\n"
diff --git a/mediachanger/DismountCmdLine.hpp b/mediachanger/DismountCmdLine.hpp
index 9ff6783997ff6994642d9045798be30d55c4e436..9eef614ec885c74ff141d2dbd2f6c167f20f240f 100644
--- a/mediachanger/DismountCmdLine.hpp
+++ b/mediachanger/DismountCmdLine.hpp
@@ -109,6 +109,13 @@ public:
    */
   bool getForce() const throw();
 
+  /**
+   * Return sthe program name.
+   *
+   * @return sthe program name.
+   */
+  static std::string getProgramName();
+
 private:
 
   /**
diff --git a/mediachanger/DismountCmdMain.cpp b/mediachanger/DismountCmdMain.cpp
index 643077eb44ff096d5817342fb00b928b7512c557..39fb9d6dadd95e176628f3823fbcf86e9d95be9f 100644
--- a/mediachanger/DismountCmdMain.cpp
+++ b/mediachanger/DismountCmdMain.cpp
@@ -17,13 +17,10 @@
  */
 
 #include "common/exception/Exception.hpp"
+#include "common/log/StdoutLogger.hpp"
 #include "common/utils/utils.hpp"
-#include "mediachanger/AcsProxyZmq.hpp"
 #include "mediachanger/DismountCmd.hpp"
 #include "mediachanger/DismountCmdLine.hpp"
-#include "mediachanger/RmcProxyTcpIp.hpp"
-#include "mediachanger/MmcProxyNotSupported.hpp"
-#include "mediachanger/SmartZmqContext.hpp"
 
 #include <exception>
 #include <google/protobuf/stubs/common.h>
@@ -73,24 +70,8 @@ int main(const int argc, char *const *const argv) {
 static int exceptionThrowingMain(const int argc, char *const *const argv) {
   using namespace cta;
 
-  const int sizeOfIOThreadPoolForZMQ = 1;
-  mediachanger::SmartZmqContext
-    zmqContext(mediachanger::SmartZmqContext::instantiateZmqContext(sizeOfIOThreadPoolForZMQ));
-  mediachanger::AcsProxyZmq acs(mediachanger::ACS_PORT, zmqContext.get());
-
-  mediachanger::MmcProxyNotSupported mmc;
-
-  const unsigned short rmcPort = mediachanger::RMC_PORT;
-
-  const unsigned int rmcMaxRqstAttempts = mediachanger::RMC_MAXRQSTATTEMPTS;
-
-  // The network timeout of rmc communications should be several minutes due
-  // to the time it takes to mount and unmount tapes
-  const int rmcNetTimeout = 600; // Timeout in seconds
-
-  mediachanger::RmcProxyTcpIp rmc(rmcPort, rmcNetTimeout, rmcMaxRqstAttempts);
-
-  mediachanger::MediaChangerFacade mc(acs, mmc, rmc);
+  log::StdoutLogger log(mediachanger::DismountCmdLine::getProgramName());
+  mediachanger::MediaChangerFacade mc(log);
   
   mediachanger::DismountCmd cmd(std::cin, std::cout, std::cerr, mc);
 
diff --git a/mediachanger/MediaChangerFacade.cpp b/mediachanger/MediaChangerFacade.cpp
index be335cce1fd7dd51548e2353b4e6822334768688..7398e60cc7ee15144bbbdd0927c526537ea80ed0 100644
--- a/mediachanger/MediaChangerFacade.cpp
+++ b/mediachanger/MediaChangerFacade.cpp
@@ -16,7 +16,12 @@
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
+#include "mediachanger/AcsProxyZmq.hpp"
+#include "mediachanger/Constants.hpp"
 #include "mediachanger/MediaChangerFacade.hpp"
+#include "mediachanger/MmcProxyLog.hpp"
+#include "mediachanger/RmcProxyTcpIp.hpp"
+#include "mediachanger/ZmqContextSingleton.hpp"
 #include "common/exception/Exception.hpp"
 
 namespace cta {
@@ -25,46 +30,37 @@ namespace mediachanger {
 //------------------------------------------------------------------------------
 // constructor
 //------------------------------------------------------------------------------
-MediaChangerFacade::MediaChangerFacade(
-  AcsProxy &acs,
-  MmcProxy &mmc,
-  RmcProxy &rmc) throw():
-  m_acs(acs),
-  m_mmc(mmc),
-  m_rmc(rmc) {
-}
-
-//------------------------------------------------------------------------------
-// constructor
-//------------------------------------------------------------------------------
-MediaChangerFacade::MediaChangerFacade(
-  AcsProxy &acs,
-  RmcProxy &rmc) throw():
-  m_acs(acs),
-  m_mmc(m_mmcNotSupported),
-  m_rmc(rmc) {
+MediaChangerFacade::MediaChangerFacade(log::Logger &log, void *const zmqContext) throw():
+  m_log(log),
+  m_zmqContext(zmqContext) {
 }
 
 //------------------------------------------------------------------------------
 // mountTapeReadOnly
 //------------------------------------------------------------------------------
-void MediaChangerFacade::mountTapeReadOnly(
-  const std::string &vid, const LibrarySlot &slot) {
+void MediaChangerFacade::mountTapeReadOnly(const std::string &vid, const LibrarySlot &slot) {
   try {
     const TapeLibraryType libraryType = slot.getLibraryType();
 
     // Dispatch the appropriate helper method depending on library slot type
     switch(libraryType) {
     case TAPE_LIBRARY_TYPE_ACS:
-      return m_acs.mountTapeReadOnly(vid,
-        dynamic_cast<const AcsLibrarySlot&>(slot));
+      {
+        AcsProxyZmq acs(m_zmqContext);
+        return acs.mountTapeReadOnly(vid, dynamic_cast<const AcsLibrarySlot&>(slot));
+      }
     case TAPE_LIBRARY_TYPE_MANUAL:
-      return m_mmc.mountTapeReadOnly(vid,
-        dynamic_cast<const ManualLibrarySlot&>(slot));
+      {
+        MmcProxyLog mmc(m_log);
+        return mmc.mountTapeReadOnly(vid, dynamic_cast<const ManualLibrarySlot&>(slot));
+      }
     case TAPE_LIBRARY_TYPE_SCSI:
-      // SCSI media-changers to not support read-only mounts
-      return m_rmc.mountTapeReadWrite(vid,
-         dynamic_cast<const ScsiLibrarySlot&>(slot));
+      {
+        RmcProxyTcpIp rmc;
+
+        // SCSI media-changers to not support read-only mounts
+        return rmc.mountTapeReadWrite(vid, dynamic_cast<const ScsiLibrarySlot&>(slot));
+      }
     default:
       {
         // Should never get here
@@ -85,22 +81,27 @@ void MediaChangerFacade::mountTapeReadOnly(
 //------------------------------------------------------------------------------
 // mountTapeReadWrite
 //------------------------------------------------------------------------------
-void MediaChangerFacade::mountTapeReadWrite(
-  const std::string &vid, const LibrarySlot &slot) {
+void MediaChangerFacade::mountTapeReadWrite(const std::string &vid, const LibrarySlot &slot) {
   try {
     const TapeLibraryType libraryType = slot.getLibraryType();
 
     // Dispatch the appropriate helper method depending on library slot type
     switch(libraryType) {
     case TAPE_LIBRARY_TYPE_ACS: 
-      return m_acs.mountTapeReadWrite(vid,
-        dynamic_cast<const AcsLibrarySlot&>(slot));
+      {
+        AcsProxyZmq acs(m_zmqContext);
+        return acs.mountTapeReadWrite(vid, dynamic_cast<const AcsLibrarySlot&>(slot));
+      }
     case TAPE_LIBRARY_TYPE_MANUAL: 
-      return m_mmc.mountTapeReadWrite(vid,
-        dynamic_cast<const ManualLibrarySlot&>(slot));
+      {
+        MmcProxyLog mmc(m_log);
+        return mmc.mountTapeReadWrite(vid, dynamic_cast<const ManualLibrarySlot&>(slot));
+      }
     case TAPE_LIBRARY_TYPE_SCSI:
-      return m_rmc.mountTapeReadWrite(vid,
-        dynamic_cast<const ScsiLibrarySlot&>(slot));
+      {
+        RmcProxyTcpIp rmc;
+        return rmc.mountTapeReadWrite(vid, dynamic_cast<const ScsiLibrarySlot&>(slot));
+      }
     default:
       {
         // Should never get here
@@ -121,22 +122,27 @@ void MediaChangerFacade::mountTapeReadWrite(
 //------------------------------------------------------------------------------
 // dismountTape
 //------------------------------------------------------------------------------
-void MediaChangerFacade::dismountTape(
-  const std::string &vid, const LibrarySlot &slot) {
+void MediaChangerFacade::dismountTape(const std::string &vid, const LibrarySlot &slot) {
   try {
     const TapeLibraryType libraryType = slot.getLibraryType();
   
     // Dispatch the appropriate helper method depending on library slot type
     switch(libraryType) {
     case TAPE_LIBRARY_TYPE_ACS:
-      return m_acs.dismountTape(vid,
-        dynamic_cast<const AcsLibrarySlot&>(slot));
+      {
+        AcsProxyZmq acs(m_zmqContext);
+        return acs.dismountTape(vid, dynamic_cast<const AcsLibrarySlot&>(slot));
+      }
     case TAPE_LIBRARY_TYPE_MANUAL:
-      return m_mmc.dismountTape(vid,
-        dynamic_cast<const ManualLibrarySlot&>(slot));
+      {
+        MmcProxyLog mmc(m_log);
+        return mmc.dismountTape(vid, dynamic_cast<const ManualLibrarySlot&>(slot));
+      }
     case TAPE_LIBRARY_TYPE_SCSI:
-      return m_rmc.dismountTape(vid,
-        dynamic_cast<const ScsiLibrarySlot&>(slot));
+      {
+        RmcProxyTcpIp rmc;
+        return rmc.dismountTape(vid, dynamic_cast<const ScsiLibrarySlot&>(slot));
+      }
     default:
       {
         // Should never get here
@@ -157,22 +163,27 @@ void MediaChangerFacade::dismountTape(
 //------------------------------------------------------------------------------
 // forceDismountTape
 //------------------------------------------------------------------------------
-void MediaChangerFacade::forceDismountTape(
-  const std::string &vid, const LibrarySlot &slot) {
+void MediaChangerFacade::forceDismountTape(const std::string &vid, const LibrarySlot &slot) {
   try {
     const TapeLibraryType libraryType = slot.getLibraryType();
 
     // Dispatch the appropriate helper method depending on library slot type
     switch(libraryType) {
     case TAPE_LIBRARY_TYPE_ACS:
-      return m_acs.forceDismountTape(vid,
-        dynamic_cast<const AcsLibrarySlot&>(slot));
+      {
+        AcsProxyZmq acs(m_zmqContext);
+        return acs.forceDismountTape(vid, dynamic_cast<const AcsLibrarySlot&>(slot));
+      }
     case TAPE_LIBRARY_TYPE_MANUAL:
-      return m_mmc.forceDismountTape(vid,
-        dynamic_cast<const ManualLibrarySlot&>(slot));
+      {
+        MmcProxyLog mmc(m_log);
+        return mmc.forceDismountTape(vid, dynamic_cast<const ManualLibrarySlot&>(slot));
+      }
     case TAPE_LIBRARY_TYPE_SCSI:
-      return m_rmc.forceDismountTape(vid,
-        dynamic_cast<const ScsiLibrarySlot&>(slot));
+      {
+        RmcProxyTcpIp rmc;
+        return rmc.forceDismountTape(vid, dynamic_cast<const ScsiLibrarySlot&>(slot));
+      }
     default:
       {
         // Should never get here
diff --git a/mediachanger/MediaChangerFacade.hpp b/mediachanger/MediaChangerFacade.hpp
index 758ba7802132b9b51c889eb3a985801e1a4f4308..7fdab7f331e04171388e04f7b540d0c1ba063f59 100644
--- a/mediachanger/MediaChangerFacade.hpp
+++ b/mediachanger/MediaChangerFacade.hpp
@@ -18,23 +18,17 @@
 
 #pragma once
 
+#include "common/log/Logger.hpp"
 #include "mediachanger/LibrarySlot.hpp"
-#include "mediachanger/MmcProxy.hpp"
-#include "mediachanger/MmcProxyNotSupported.hpp"
-#include "mediachanger/RmcProxy.hpp"
-#include "mediachanger/AcsProxy.hpp"
+#include "mediachanger/ZmqContextSingleton.hpp"
 
-#include <unistd.h>
-#include <sys/types.h>
+#include <string>
 
 namespace cta {
 namespace mediachanger {
 
 /**
- * Provides a facade to three communications proxies: acs, manual and rmc.
- *
- * This facade will forward requests to mount and dismount tapes to the
- * appropriate communications proxy based on the type of library slot.
+ * A facade to multiple types of tape media changer.
  */
 class MediaChangerFacade {
 public:
@@ -42,21 +36,12 @@ public:
   /**
    * Constructor.
    *
-   * @param acs Proxy object representing the CASTOR ACS daemon.
-   * @param mmc Proxy object representing the manual media-changer.
-   * @param rmc Proxy object representing the rmcd daemon.
-   */
-  MediaChangerFacade(AcsProxy &acs, MmcProxy &mmc, RmcProxy &rmc) throw();
-
-  /**
-   * Constructor.
-   *
-   * Use this constructor when manual media-changers are not to be supported.
-   *
-   * @param acs Proxy object representing the CASTOR ACS daemon.
-   * @param rmc Proxy object representing the rmcd daemon.
+   * @param log Object representing the API to the CTA logging system.
+   * @param zmqContext The ZMQ context.  There is usually one ZMQ context within
+   * a program.  Set this parameter in order for the MediaChangerFacade to share
+   * an already existing ZMQ context.
    */
-  MediaChangerFacade(AcsProxy &acs, RmcProxy &rmc) throw();
+  MediaChangerFacade(log::Logger &log, void *const zmqContext = ZmqContextSingleton::instance()) throw();
 
   /**
    * Requests the media changer to mount the specified tape for read-only
@@ -104,25 +89,14 @@ public:
 private:
 
   /**
-   * Proxy object representing the CASTOR ACS daemon.
-   */
-  AcsProxy &m_acs;
-
-  /**
-   * Proxy object representing the manual media-changer.
-   */
-  MmcProxy &m_mmc;
-
-  /**
-   * Proxy object representing the rmcd daemon.
+   * Object representing the API to the CTA logging system.
    */
-  RmcProxy &m_rmc;
+  log::Logger &m_log;
 
   /**
-   * The manual media-changer proxy object that is used when manual
-   * media-changers are not to be supported.
+   * The ZMQ context.
    */
-  MmcProxyNotSupported m_mmcNotSupported;
+  void *m_zmqContext;
 
 }; // class MediaChangerFacade
 
diff --git a/mediachanger/MediaChangerFacadeTest.cpp b/mediachanger/MediaChangerFacadeTest.cpp
deleted file mode 100644
index df9f78ad8b38220e5fd7f8b04b32697a14313ceb..0000000000000000000000000000000000000000
--- a/mediachanger/MediaChangerFacadeTest.cpp
+++ /dev/null
@@ -1,340 +0,0 @@
-/*
- * The CERN Tape Archive(CTA) project
- * Copyright(C) 2015  CERN
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- *(at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "mediachanger/LibrarySlot.hpp"
-#include "mediachanger/LibrarySlotParser.hpp"
-#include "mediachanger/MediaChangerFacade.hpp"
-
-#include <gtest/gtest.h>
-#include <iostream>
-#include <memory>
-#include <sstream>
-
-namespace unitTests {
-
-class cta_mediachanger_MediaChangerFacadeTest : public ::testing::Test {
-protected:
-
-  struct MockAcsProxy: public cta::mediachanger::AcsProxy {
-    unsigned int nbTimesMountTapeReadOnlyCalled;
-    unsigned int nbTimesMountTapeReadWriteCalled;
-    unsigned int nbTimesDismountTapeCalled;
-    unsigned int nbTimesForceDismountTapeCalled;
-
-    MockAcsProxy():
-      nbTimesMountTapeReadOnlyCalled(0),
-      nbTimesMountTapeReadWriteCalled(0),
-      nbTimesDismountTapeCalled(0),
-      nbTimesForceDismountTapeCalled(0) {
-    }
-
-    void mountTapeReadOnly(const std::string &vid,
-      const cta::mediachanger::AcsLibrarySlot &librarySlot) {
-      nbTimesMountTapeReadOnlyCalled++;
-    }
-    
-    void mountTapeReadWrite(const std::string &vid,
-      const cta::mediachanger::AcsLibrarySlot &librarySlot) {
-      nbTimesMountTapeReadWriteCalled++;
-    }
-
-    void dismountTape(const std::string &vid,
-      const cta::mediachanger::AcsLibrarySlot &librarySlot) {
-      nbTimesDismountTapeCalled++;
-    }
-
-    void forceDismountTape(const std::string &vid,
-      const cta::mediachanger::AcsLibrarySlot &librarySlot) {
-      nbTimesForceDismountTapeCalled++;
-    }
-  }; // struct MockAcsProxy
-
-  struct MockMmcProxy: public cta::mediachanger::MmcProxy {
-    unsigned int nbTimesMountTapeReadOnlyCalled;
-    unsigned int nbTimesMountTapeReadWriteCalled;
-    unsigned int nbTimesDismountTapeCalled;
-    unsigned int nbTimesForceDismountTapeCalled;
-
-    MockMmcProxy():
-      nbTimesMountTapeReadOnlyCalled(0),
-      nbTimesMountTapeReadWriteCalled(0),
-      nbTimesDismountTapeCalled(0),
-      nbTimesForceDismountTapeCalled(0) {
-    }
-
-    void mountTapeReadOnly(const std::string &vid,
-      const cta::mediachanger::ManualLibrarySlot &librarySlot) {
-      nbTimesMountTapeReadOnlyCalled++;
-    }
-
-    void mountTapeReadWrite(const std::string &vid,
-      const cta::mediachanger::ManualLibrarySlot &librarySlot) {
-      nbTimesMountTapeReadWriteCalled++;
-    }
-
-    void dismountTape(const std::string &vid,
-      const cta::mediachanger::ManualLibrarySlot &librarySlot) {
-      nbTimesDismountTapeCalled++;
-    }
-
-    void forceDismountTape(const std::string &vid,
-      const cta::mediachanger::ManualLibrarySlot &librarySlot) {
-      nbTimesForceDismountTapeCalled++;
-    }
-  }; // struct MockMmcProxy
-
-  struct MockRmcProxy: public cta::mediachanger::RmcProxy {
-    unsigned int nbTimesMountTapeReadOnlyCalled;
-    unsigned int nbTimesMountTapeReadWriteCalled;
-    unsigned int nbTimesDismountTapeCalled;
-    unsigned int nbTimesForceDismountTapeCalled;
-
-    MockRmcProxy():
-      nbTimesMountTapeReadOnlyCalled(0),
-      nbTimesMountTapeReadWriteCalled(0),
-      nbTimesDismountTapeCalled(0),
-      nbTimesForceDismountTapeCalled(0) {
-    }
-
-    void mountTapeReadOnly(const std::string &vid,
-      const cta::mediachanger::ScsiLibrarySlot &librarySlot) {
-      nbTimesMountTapeReadOnlyCalled++;
-    }
-
-    void mountTapeReadWrite(const std::string &vid,
-      const cta::mediachanger::ScsiLibrarySlot &librarySlot) {
-      nbTimesMountTapeReadWriteCalled++;
-    }
-
-    void dismountTape(const std::string &vid,
-      const cta::mediachanger::ScsiLibrarySlot &librarySlot) {
-      nbTimesDismountTapeCalled++;
-    }
-
-    void forceDismountTape(const std::string &vid,
-      const cta::mediachanger::ScsiLibrarySlot &librarySlot) {
-      nbTimesForceDismountTapeCalled++;
-    }
-  }; // struct MockRmcProxy
-
-  MockAcsProxy m_acs; // ACS
-  MockMmcProxy m_mmc; // Manual
-  MockRmcProxy m_rmc; // SCSI
-
-  const std::string m_vid;
-
-  const cta::mediachanger::LibrarySlot *m_acsSlot;
-  const cta::mediachanger::LibrarySlot *m_mmcSlot;
-  const cta::mediachanger::LibrarySlot *m_rmcSlot;
-
-  cta_mediachanger_MediaChangerFacadeTest():
-    m_vid("123456"),
-    m_acsSlot(cta::mediachanger::LibrarySlotParser::parse("acs1,2,3,4")),
-    m_mmcSlot(cta::mediachanger::LibrarySlotParser::parse("manual")),
-    m_rmcSlot(cta::mediachanger::LibrarySlotParser::parse("smc1")) {
-  }
-
-  ~cta_mediachanger_MediaChangerFacadeTest() {
-    delete(m_acsSlot);
-    delete(m_mmcSlot);
-    delete(m_rmcSlot);
-  }
-
-  virtual void SetUp() {
-    m_acs.nbTimesMountTapeReadOnlyCalled  = 0;
-    m_acs.nbTimesMountTapeReadWriteCalled = 0;
-    m_acs.nbTimesDismountTapeCalled       = 0;
-
-    m_mmc.nbTimesMountTapeReadOnlyCalled  = 0;
-    m_mmc.nbTimesMountTapeReadWriteCalled = 0;
-    m_mmc.nbTimesDismountTapeCalled       = 0;
-
-    m_rmc.nbTimesMountTapeReadWriteCalled = 0;
-    m_rmc.nbTimesDismountTapeCalled       = 0;
-  }
-
-  virtual void TearDown() {
-    SetUp();
-  }
-
-}; // class cta_mediachanger_MediaChangerFacadeTest
-
-TEST_F(cta_mediachanger_MediaChangerFacadeTest, mountTapeReadOnlyAcs) {
-  using namespace cta::mediachanger;
-
-  MediaChangerFacade facade(m_acs, m_mmc, m_rmc);
-  facade.mountTapeReadOnly(m_vid, *m_acsSlot);
-
-  ASSERT_EQ(1, m_acs.nbTimesMountTapeReadOnlyCalled);
-  ASSERT_EQ(0, m_acs.nbTimesMountTapeReadWriteCalled);
-  ASSERT_EQ(0, m_acs.nbTimesDismountTapeCalled);
-
-  ASSERT_EQ(0, m_mmc.nbTimesMountTapeReadOnlyCalled);
-  ASSERT_EQ(0, m_mmc.nbTimesMountTapeReadWriteCalled);
-  ASSERT_EQ(0, m_mmc.nbTimesDismountTapeCalled);
-
-  ASSERT_EQ(0, m_rmc.nbTimesMountTapeReadWriteCalled);
-  ASSERT_EQ(0, m_rmc.nbTimesDismountTapeCalled);
-}
-
-TEST_F(cta_mediachanger_MediaChangerFacadeTest, mountTapeReadOnlyMmc) {
-  using namespace cta::mediachanger;
-
-  MediaChangerFacade facade(m_acs, m_mmc, m_rmc);
-  facade.mountTapeReadOnly(m_vid, *m_mmcSlot);
-
-  ASSERT_EQ(0, m_acs.nbTimesMountTapeReadOnlyCalled);
-  ASSERT_EQ(0, m_acs.nbTimesMountTapeReadWriteCalled);
-  ASSERT_EQ(0, m_acs.nbTimesDismountTapeCalled);
-
-  ASSERT_EQ(1, m_mmc.nbTimesMountTapeReadOnlyCalled);
-  ASSERT_EQ(0, m_mmc.nbTimesMountTapeReadWriteCalled);
-  ASSERT_EQ(0, m_mmc.nbTimesDismountTapeCalled);
-
-  ASSERT_EQ(0, m_rmc.nbTimesMountTapeReadWriteCalled);
-  ASSERT_EQ(0, m_rmc.nbTimesDismountTapeCalled);
-}
-
-TEST_F(cta_mediachanger_MediaChangerFacadeTest, mountTapeReadOnlyRmc) {
-  using namespace cta::mediachanger;
-
-  MediaChangerFacade facade(m_acs, m_mmc, m_rmc);
-  facade.mountTapeReadOnly(m_vid, *m_rmcSlot);
-
-  ASSERT_EQ(0, m_acs.nbTimesMountTapeReadOnlyCalled);
-  ASSERT_EQ(0, m_acs.nbTimesMountTapeReadWriteCalled);
-  ASSERT_EQ(0, m_acs.nbTimesDismountTapeCalled);
-
-  ASSERT_EQ(0, m_mmc.nbTimesMountTapeReadOnlyCalled);
-  ASSERT_EQ(0, m_mmc.nbTimesMountTapeReadWriteCalled);
-  ASSERT_EQ(0, m_mmc.nbTimesDismountTapeCalled);
-
-  // SCSI tape-libraries do not support mounting tapes for read-only access
-  ASSERT_EQ(1, m_rmc.nbTimesMountTapeReadWriteCalled);
-  ASSERT_EQ(0, m_rmc.nbTimesDismountTapeCalled);
-}
-
-TEST_F(cta_mediachanger_MediaChangerFacadeTest, mountTapeReadWriteAcs) {
-  using namespace cta::mediachanger;
-
-  MediaChangerFacade facade(m_acs, m_mmc, m_rmc);
-  facade.mountTapeReadWrite(m_vid, *m_acsSlot);
-
-  ASSERT_EQ(0, m_acs.nbTimesMountTapeReadOnlyCalled);
-  ASSERT_EQ(1, m_acs.nbTimesMountTapeReadWriteCalled);
-  ASSERT_EQ(0, m_acs.nbTimesDismountTapeCalled);
-
-  ASSERT_EQ(0, m_mmc.nbTimesMountTapeReadOnlyCalled);
-  ASSERT_EQ(0, m_mmc.nbTimesMountTapeReadWriteCalled);
-  ASSERT_EQ(0, m_mmc.nbTimesDismountTapeCalled);
-
-  ASSERT_EQ(0, m_rmc.nbTimesMountTapeReadWriteCalled);
-  ASSERT_EQ(0, m_rmc.nbTimesDismountTapeCalled);
-}
-
-TEST_F(cta_mediachanger_MediaChangerFacadeTest, mountTapeReadWriteMmc) {
-  using namespace cta::mediachanger;
-
-  MediaChangerFacade facade(m_acs, m_mmc, m_rmc);
-  facade.mountTapeReadWrite(m_vid, *m_mmcSlot);
-
-  ASSERT_EQ(0, m_acs.nbTimesMountTapeReadOnlyCalled);
-  ASSERT_EQ(0, m_acs.nbTimesMountTapeReadWriteCalled);
-  ASSERT_EQ(0, m_acs.nbTimesDismountTapeCalled);
-
-  ASSERT_EQ(0, m_mmc.nbTimesMountTapeReadOnlyCalled);
-  ASSERT_EQ(1, m_mmc.nbTimesMountTapeReadWriteCalled);
-  ASSERT_EQ(0, m_mmc.nbTimesDismountTapeCalled);
-
-  ASSERT_EQ(0, m_rmc.nbTimesMountTapeReadWriteCalled);
-  ASSERT_EQ(0, m_rmc.nbTimesDismountTapeCalled);
-}
-
-TEST_F(cta_mediachanger_MediaChangerFacadeTest, mountTapeReadWriteRmc) {
-  using namespace cta::mediachanger;
-
-  MediaChangerFacade facade(m_acs, m_mmc, m_rmc);
-  facade.mountTapeReadWrite(m_vid, *m_rmcSlot);
-
-  ASSERT_EQ(0, m_acs.nbTimesMountTapeReadOnlyCalled);
-  ASSERT_EQ(0, m_acs.nbTimesMountTapeReadWriteCalled);
-  ASSERT_EQ(0, m_acs.nbTimesDismountTapeCalled);
-
-  ASSERT_EQ(0, m_mmc.nbTimesMountTapeReadOnlyCalled);
-  ASSERT_EQ(0, m_mmc.nbTimesMountTapeReadWriteCalled);
-  ASSERT_EQ(0, m_mmc.nbTimesDismountTapeCalled);
-
-  ASSERT_EQ(1, m_rmc.nbTimesMountTapeReadWriteCalled);
-  ASSERT_EQ(0, m_rmc.nbTimesDismountTapeCalled);
-}
-
-TEST_F(cta_mediachanger_MediaChangerFacadeTest, dismountTapeAcs) {
-  using namespace cta::mediachanger;
-
-  MediaChangerFacade facade(m_acs, m_mmc, m_rmc);
-  facade.dismountTape(m_vid, *m_acsSlot);
-
-  ASSERT_EQ(0, m_acs.nbTimesMountTapeReadOnlyCalled);
-  ASSERT_EQ(0, m_acs.nbTimesMountTapeReadWriteCalled);
-  ASSERT_EQ(1, m_acs.nbTimesDismountTapeCalled);
-
-  ASSERT_EQ(0, m_mmc.nbTimesMountTapeReadOnlyCalled);
-  ASSERT_EQ(0, m_mmc.nbTimesMountTapeReadWriteCalled);
-  ASSERT_EQ(0, m_mmc.nbTimesDismountTapeCalled);
-
-  ASSERT_EQ(0, m_rmc.nbTimesMountTapeReadWriteCalled);
-  ASSERT_EQ(0, m_rmc.nbTimesDismountTapeCalled);
-}
-
-TEST_F(cta_mediachanger_MediaChangerFacadeTest, dismountTapeMmc) {
-  using namespace cta::mediachanger;
-
-  MediaChangerFacade facade(m_acs, m_mmc, m_rmc);
-  facade.dismountTape(m_vid, *m_mmcSlot);
-
-  ASSERT_EQ(0, m_acs.nbTimesMountTapeReadOnlyCalled);
-  ASSERT_EQ(0, m_acs.nbTimesMountTapeReadWriteCalled);
-  ASSERT_EQ(0, m_acs.nbTimesDismountTapeCalled);
-
-  ASSERT_EQ(0, m_mmc.nbTimesMountTapeReadOnlyCalled);
-  ASSERT_EQ(0, m_mmc.nbTimesMountTapeReadWriteCalled);
-  ASSERT_EQ(1, m_mmc.nbTimesDismountTapeCalled);
-
-  ASSERT_EQ(0, m_rmc.nbTimesMountTapeReadWriteCalled);
-  ASSERT_EQ(0, m_rmc.nbTimesDismountTapeCalled);
-}
-
-TEST_F(cta_mediachanger_MediaChangerFacadeTest, dismountTapeRmc) {
-  using namespace cta::mediachanger;
-
-  MediaChangerFacade facade(m_acs, m_mmc, m_rmc);
-  facade.dismountTape(m_vid, *m_rmcSlot);
-
-  ASSERT_EQ(0, m_acs.nbTimesMountTapeReadOnlyCalled);
-  ASSERT_EQ(0, m_acs.nbTimesMountTapeReadWriteCalled);
-  ASSERT_EQ(0, m_acs.nbTimesDismountTapeCalled);
-
-  ASSERT_EQ(0, m_mmc.nbTimesMountTapeReadOnlyCalled);
-  ASSERT_EQ(0, m_mmc.nbTimesMountTapeReadWriteCalled);
-  ASSERT_EQ(0, m_mmc.nbTimesDismountTapeCalled);
-
-  ASSERT_EQ(0, m_rmc.nbTimesMountTapeReadWriteCalled);
-  ASSERT_EQ(1, m_rmc.nbTimesDismountTapeCalled);
-}
-
-} // namespace unitTests
diff --git a/mediachanger/MmcProxyDummy.cpp b/mediachanger/MmcProxyDummy.cpp
deleted file mode 100644
index 67fcd2b3b73b855c84bbb3babbea551ccda8a14b..0000000000000000000000000000000000000000
--- a/mediachanger/MmcProxyDummy.cpp
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * The CERN Tape Archive(CTA) project
- * Copyright(C) 2015  CERN
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- *(at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "mediachanger/MmcProxyDummy.hpp"
-
-//------------------------------------------------------------------------------
-// mountTapeReadOnly
-//------------------------------------------------------------------------------
-void cta::mediachanger::MmcProxyDummy::mountTapeReadOnly(
-  const std::string &vid, const ManualLibrarySlot &librarySlot) {
-}
-
-//------------------------------------------------------------------------------
-// mountTapeReadWrite
-//------------------------------------------------------------------------------
-void cta::mediachanger::MmcProxyDummy::mountTapeReadWrite(
-  const std::string &vid, const ManualLibrarySlot &librarySlot) {
-}
-
-//------------------------------------------------------------------------------
-// dismountTape
-//------------------------------------------------------------------------------
-void cta::mediachanger::MmcProxyDummy::dismountTape(
-  const std::string &vid, const ManualLibrarySlot &librarySlot) {
-}
-
-//------------------------------------------------------------------------------
-// forceDismountTape
-//------------------------------------------------------------------------------
-void cta::mediachanger::MmcProxyDummy::forceDismountTape(
-  const std::string &vid, const ManualLibrarySlot &librarySlot) {
-}
diff --git a/mediachanger/MmcProxyDummy.hpp b/mediachanger/MmcProxyDummy.hpp
deleted file mode 100644
index 0c0931f7b34b54fad74657e59be124be6d6ebd4d..0000000000000000000000000000000000000000
--- a/mediachanger/MmcProxyDummy.hpp
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * The CERN Tape Archive(CTA) project
- * Copyright(C) 2015  CERN
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- *(at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#pragma once
-
-#include "mediachanger/MmcProxy.hpp"
-
-namespace cta {
-namespace mediachanger {
-
-/**
- * Concrete class implementing a dummy MmcProxyDummy.
- */
-class MmcProxyDummy: public MmcProxy {
-public:
-
-  /**
-   * Requests the media changer to mount the specified tape for read-only
-   * access into the drive in the specified library slot.
-   *
-   * Please note that this method provides a best-effort service because not all
-   * media changers support read-only mounts.
-   *
-   * @param vid The volume identifier of the tape.
-   * @param librarySlot The library slot containing the tape drive.
-   */
-  void mountTapeReadOnly(const std::string &vid,
-    const ManualLibrarySlot &librarySlot);
-
-  /**
-   * Requests the media changer to mount the specified tape for read/write
-   * access into the drive in the specified library slot.
-   *
-   * @param vid The volume identifier of the tape.
-   * @param librarySlot The library slot containing the tape drive.
-   */
-  void mountTapeReadWrite(const std::string &vid,
-    const ManualLibrarySlot &librarySlot);
-
-  /** 
-   * Requests the media changer to dismount the specified tape from the
-   * drive in the specifed library slot.
-   *
-   * @param vid The volume identifier of the tape.
-   * @param librarySlot The library slot containing the tape drive.
-   */
-  void dismountTape(const std::string &vid,
-    const ManualLibrarySlot &librarySlot);
-
-  /**
-   * Request the CASTOR ACS daemon to forcefully dismount the specifed tape
-   * from the tape drive in the specified library slot.  Forcefully means
-   * rewinding and ejecting the tape if necessary.
-   *
-   * Please note that this method provides a best-effort service because not all
-   * media changers support forceful dismounts.
-   *
-   * @param vid The volume identifier of the tape to be mounted.
-   * @param librarySlot The slot in the library that contains the tape drive.
-   */
-  void forceDismountTape(const std::string &vid,
-    const ManualLibrarySlot &librarySlot);
-
-}; // class MmcProxyDummy
-
-} // namespace mediachanger
-} // namespace cta
diff --git a/mediachanger/MmcProxyLog.hpp b/mediachanger/MmcProxyLog.hpp
index aac6189d668836af9da367492a22dfc25f3e1a17..83d044fdc761185dccd56bb4eaa184a5d0275e15 100644
--- a/mediachanger/MmcProxyLog.hpp
+++ b/mediachanger/MmcProxyLog.hpp
@@ -34,7 +34,7 @@ public:
   /**
    * Constructor.
    *
-   * @param log Object representing the API to the CASTOR logging system.
+   * @param log Object representing the API to the CTA logging system.
    */
   MmcProxyLog(log::Logger &log) throw();
 
@@ -48,8 +48,7 @@ public:
    * @param vid The volume identifier of the tape.
    * @param librarySlot The library slot containing the tape drive.
    */
-  void mountTapeReadOnly(const std::string &vid,
-    const ManualLibrarySlot &librarySlot);
+  void mountTapeReadOnly(const std::string &vid, const ManualLibrarySlot &librarySlot);
 
   /**
    * Requests the media changer to mount the specified tape for read/write
@@ -58,8 +57,7 @@ public:
    * @param vid The volume identifier of the tape.
    * @param librarySlot The library slot containing the tape drive.
    */
-  void mountTapeReadWrite(const std::string &vid,
-    const ManualLibrarySlot &librarySlot);
+  void mountTapeReadWrite(const std::string &vid, const ManualLibrarySlot &librarySlot);
 
   /** 
    * Requests the media changer to dismount the specified tape from the
@@ -68,8 +66,7 @@ public:
    * @param vid The volume identifier of the tape.
    * @param librarySlot The library slot containing the tape drive.
    */
-  void dismountTape(const std::string &vid,
-    const ManualLibrarySlot &librarySlot);
+  void dismountTape(const std::string &vid, const ManualLibrarySlot &librarySlot);
 
   /** 
    * Requests the media changer to forcefully dismount the specified tape from
@@ -82,13 +79,12 @@ public:
    * @param vid The volume identifier of the tape.
    * @param librarySlot The library slot containing the tape drive.
    */
-  void forceDismountTape(const std::string &vid,
-    const ManualLibrarySlot &librarySlot);
+  void forceDismountTape(const std::string &vid, const ManualLibrarySlot &librarySlot);
 
 private:
 
   /**
-   * Object representing the API to the CASTOR logging system.
+   * Object representing the API to the CTA logging system.
    */
   log::Logger &m_log;
 
diff --git a/mediachanger/MountCmdLine.cpp b/mediachanger/MountCmdLine.cpp
index b8959106d31016452e348f6000a262bf39515cfa..81e5624f774b20c6a71b30db8b09e1cd5f46cfac 100644
--- a/mediachanger/MountCmdLine.cpp
+++ b/mediachanger/MountCmdLine.cpp
@@ -157,10 +157,10 @@ void cta::mediachanger::MountCmdLine::processOption(const int opt) {
 // getUsage
 //------------------------------------------------------------------------------
 std::string cta::mediachanger::MountCmdLine::getUsage() throw() {
-  return
+  return std::string() +
   "Usage:\n"
   "\n"
-  "  cta-mediachanger-mount [options] VID DRIVE_SLOT\n"
+  "  " + getProgramName() + " [options] VID DRIVE_SLOT\n"
   "\n"
   "Where:\n"
   "\n"
@@ -222,3 +222,10 @@ const cta::mediachanger::LibrarySlot &cta::mediachanger::MountCmdLine::
   }
   return *m_driveLibrarySlot;
 }
+
+//------------------------------------------------------------------------------
+// getProgramName
+//------------------------------------------------------------------------------
+std::string cta::mediachanger::MountCmdLine::getProgramName() {
+  return "cta-mediachanger-mount";
+}
diff --git a/mediachanger/MountCmdLine.hpp b/mediachanger/MountCmdLine.hpp
index b2887604bdcb66168a5a13781f04b729100a82ef..1bdc8b84316ddc68faba573d9ea8315528916267 100644
--- a/mediachanger/MountCmdLine.hpp
+++ b/mediachanger/MountCmdLine.hpp
@@ -112,6 +112,13 @@ public:
    */
   const LibrarySlot &getDriveLibrarySlot() const;
 
+  /**
+   * Return sthe program name.
+   *
+   * @return sthe program name.
+   */
+  static std::string getProgramName();
+
 private:
 
   /**
diff --git a/mediachanger/MountCmdMain.cpp b/mediachanger/MountCmdMain.cpp
index 27a51b391ce71c9d7a6571b298aa5c1ad0ca1884..53bfaee72c1672017ad311452e6c0656d0b6aeb1 100644
--- a/mediachanger/MountCmdMain.cpp
+++ b/mediachanger/MountCmdMain.cpp
@@ -16,14 +16,11 @@
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-#include "mediachanger/RmcProxyTcpIp.hpp"
-#include "mediachanger/MmcProxyNotSupported.hpp"
-#include "mediachanger/MountCmd.hpp"
-#include "mediachanger/MountCmdLine.hpp"
-#include "mediachanger/AcsProxyZmq.hpp"
-#include "mediachanger/SmartZmqContext.hpp"
 #include "common/exception/Exception.hpp"
+#include "common/log/StdoutLogger.hpp"
 #include "common/utils/utils.hpp"
+#include "mediachanger/MountCmd.hpp"
+#include "mediachanger/MountCmdLine.hpp"
 
 #include <exception>
 #include <google/protobuf/stubs/common.h>
@@ -72,25 +69,8 @@ int main(const int argc, char *const *const argv) {
 static int exceptionThrowingMain(const int argc, char *const *const argv) {
   using namespace cta;
 
-  const int sizeOfIOThreadPoolForZMQ = 1;
-  mediachanger::SmartZmqContext
-    zmqContext(mediachanger::SmartZmqContext::instantiateZmqContext(sizeOfIOThreadPoolForZMQ));
-  mediachanger::AcsProxyZmq acs(mediachanger::ACS_PORT, zmqContext.get());
-
-  mediachanger::MmcProxyNotSupported mmc;
-
-  const unsigned short rmcPort = mediachanger::RMC_PORT;
-
-  const unsigned int rmcMaxRqstAttempts = mediachanger::RMC_MAXRQSTATTEMPTS;
-
-  // The network timeout of rmc communications should be several minutes due
-  // to the time it takes to mount and unmount tapes
-  const int rmcNetTimeout = 600; // Timeout in seconds
-
-  mediachanger::RmcProxyTcpIp rmc(rmcPort, rmcNetTimeout, rmcMaxRqstAttempts);
-
-  mediachanger::MediaChangerFacade mc(acs, mmc, rmc);
-  
+  log::StdoutLogger log(mediachanger::MountCmdLine::getProgramName());
+  mediachanger::MediaChangerFacade mc(log);
   mediachanger::MountCmd cmd(std::cin, std::cout, std::cerr, mc);
 
   return cmd.exceptionThrowingMain(argc, argv);
diff --git a/mediachanger/RmcProxyDummy.cpp b/mediachanger/RmcProxyDummy.cpp
deleted file mode 100644
index 45fea9f44e82ce8e9f10c986d7d73ee40fd3c068..0000000000000000000000000000000000000000
--- a/mediachanger/RmcProxyDummy.cpp
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * The CERN Tape Archive(CTA) project
- * Copyright(C) 2015  CERN
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- *(at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "mediachanger/RmcProxyDummy.hpp"
-
-namespace cta {
-namespace mediachanger {
-
-//------------------------------------------------------------------------------
-// mountTapeReadOnly
-//------------------------------------------------------------------------------
-void RmcProxyDummy::mountTapeReadOnly(const std::string &vid,
-  const ScsiLibrarySlot &librarySlot) {
-}
-
-//------------------------------------------------------------------------------
-// mountTapeReadWrite
-//------------------------------------------------------------------------------
-void RmcProxyDummy::mountTapeReadWrite(const std::string &vid,
-  const ScsiLibrarySlot &librarySlot) {
-}
-
-//------------------------------------------------------------------------------
-// dismountTape
-//------------------------------------------------------------------------------
-void RmcProxyDummy::dismountTape(const std::string &vid,
-  const ScsiLibrarySlot &librarySlot) {
-}
-
-//------------------------------------------------------------------------------
-// forceDismountTape
-//------------------------------------------------------------------------------
-void RmcProxyDummy::forceDismountTape(const std::string &vid,
-  const ScsiLibrarySlot &librarySlot) {
-}
-
-} // namespace mediachanger
-} // namespace cta
diff --git a/mediachanger/RmcProxyDummy.hpp b/mediachanger/RmcProxyDummy.hpp
deleted file mode 100644
index e6fd53af4a6f0a8940e12e0d1371cea7b547c8f8..0000000000000000000000000000000000000000
--- a/mediachanger/RmcProxyDummy.hpp
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * The CERN Tape Archive(CTA) project
- * Copyright(C) 2015  CERN
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- *(at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#pragma once
-
-#include "mediachanger/RmcProxy.hpp"
-
-#include <string>
-
-namespace cta {
-namespace mediachanger {
-
-/**
- * Concrete class implementing a dummy RmcProxyDummy.
- */
-class RmcProxyDummy: public RmcProxy {
-public:
-
-  /**
-   * Requests the media changer to mount the specified tape for read-only
-   * access into the drive in the specified library slot.
-   *
-   * Please note that this method provides a best-effort service because not all
-   * media changers support read-only mounts.
-   *
-   * @param vid The volume identifier of the tape.
-   * @param librarySlot The library slot containing the tape drive.
-   */
-  void mountTapeReadOnly(const std::string &vid,
-    const ScsiLibrarySlot &librarySlot);
-
-  /**
-   * Requests the media changer to mount of the specified tape for read/write
-   * access into the drive in the specified library slot.
-   *
-   * @param vid The volume identifier of the tape.
-   * @param librarySlot The library slot containing the tape drive.
-   */
-  void mountTapeReadWrite(const std::string &vid,
-    const ScsiLibrarySlot &librarySlot);
-
-  /** 
-   * Requests the media changer to dismount of the specified tape from the
-   * drive in the specifed library slot.
-   *
-   * @param vid The volume identifier of the tape.
-   * @param librarySlot The library slot containing the tape drive.
-   */
-  void dismountTape(const std::string &vid,
-    const ScsiLibrarySlot &librarySlot);
-
-  /**
-   * Requests the media changer to forcefully dismount the specified tape from
-   * the drive in the specifed library slot.  Forcefully means rewinding and
-   * ejecting the tape where necessary.
-   *
-   * Please note that this method provides a best-effort service because not all
-   * media changers support forceful dismounts.
-   *
-   * @param vid The volume identifier of the tape.
-   * @param librarySlot The library slot containing the tape drive.
-   */
-  void forceDismountTape(const std::string &vid,
-    const ScsiLibrarySlot &librarySlot);
-
-}; // class RmcProxyDummy
-
-} // namespace mediachanger
-} // namespace cta
diff --git a/mediachanger/RmcProxyTcpIp.hpp b/mediachanger/RmcProxyTcpIp.hpp
index 1884d01bd172749c2390b1efe60e64b7d85acfc8..befeb53bd2884c1dd01fd0e2afac60263a400e01 100644
--- a/mediachanger/RmcProxyTcpIp.hpp
+++ b/mediachanger/RmcProxyTcpIp.hpp
@@ -20,6 +20,7 @@
 
 #include "common/SmartFd.hpp"
 #include "common/utils/utils.hpp"
+#include "mediachanger/Constants.hpp"
 #include "mediachanger/io.hpp"
 #include "mediachanger/MessageHeader.hpp"
 #include "mediachanger/RmcMountMsgBody.hpp"
@@ -67,9 +68,9 @@ public:
    * request should be issued.
    */
   RmcProxyTcpIp(
-    const unsigned short rmcPort,
-    const int netTimeout,
-    const unsigned int maxRqstAttempts) throw();
+    const unsigned short rmcPort = RMC_PORT,
+    const int netTimeout = RMC_NET_TIMEOUT,
+    const unsigned int maxRqstAttempts = RMC_MAX_RQST_ATTEMPTS) throw();
 
   /**
    * Destructor.
@@ -86,8 +87,7 @@ public:
    * @param vid The volume identifier of the tape.
    * @param librarySlot The library slot containing the tape drive.
    */
-  void mountTapeReadOnly(const std::string &vid,
-    const mediachanger::ScsiLibrarySlot &librarySlot);
+  void mountTapeReadOnly(const std::string &vid, const ScsiLibrarySlot &librarySlot);
 
   /**
    * Requests the media changer to mount of the specified tape for read/write
@@ -96,8 +96,7 @@ public:
    * @param vid The volume identifier of the tape.
    * @param librarySlot The library slot containing the tape drive.
    */
-  void mountTapeReadWrite(const std::string &vid,
-    const mediachanger::ScsiLibrarySlot &librarySlot);
+  void mountTapeReadWrite(const std::string &vid, const ScsiLibrarySlot &librarySlot);
 
   /** 
    * Requests the media changer to dismount of the specified tape from the
@@ -106,8 +105,7 @@ public:
    * @param vid The volume identifier of the tape.
    * @param librarySlot The library slot containing the tape drive.
    */
-  void dismountTape(const std::string &vid,
-    const mediachanger::ScsiLibrarySlot &librarySlot);
+  void dismountTape(const std::string &vid, const ScsiLibrarySlot &librarySlot);
 
   /**
    * Requests the media changer to forcefully dismount the specified tape from
@@ -120,8 +118,7 @@ public:
    * @param vid The volume identifier of the tape.
    * @param librarySlot The library slot containing the tape drive.
    */
-  void forceDismountTape(const std::string &vid,
-    const mediachanger::ScsiLibrarySlot &librarySlot);
+  void forceDismountTape(const std::string &vid, const ScsiLibrarySlot &librarySlot);
 
 protected:
 
diff --git a/mediachanger/ZmqContextSingleton.cpp b/mediachanger/ZmqContextSingleton.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..e6d48767b091865d660ad9cfac5f34fbcb8521ae
--- /dev/null
+++ b/mediachanger/ZmqContextSingleton.cpp
@@ -0,0 +1,67 @@
+/*
+ * 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 "ZmqContextSingleton.hpp"
+#include "common/exception/Exception.hpp"
+#include "common/utils/utils.hpp"
+
+#include <zmq.h>
+
+namespace cta {
+namespace mediachanger {
+
+//------------------------------------------------------------------------------
+// s_mutex
+//------------------------------------------------------------------------------
+std::mutex ZmqContextSingleton::s_mutex;
+
+//------------------------------------------------------------------------------
+// s_instance
+//------------------------------------------------------------------------------
+void *ZmqContextSingleton::s_instance = nullptr;
+
+//------------------------------------------------------------------------------
+// instance
+//------------------------------------------------------------------------------
+void *ZmqContextSingleton::instance() {
+  try {
+    std::lock_guard<std::mutex> lock(s_mutex);
+
+    if(nullptr == s_instance) {
+      const int sizeOfIOThreadPoolForZMQ = 1;
+      s_instance = zmq_init(sizeOfIOThreadPoolForZMQ);
+      const int savedErrno = errno;
+
+      if(nullptr == s_instance) {
+        const std::string message = utils::errnoToString(savedErrno);
+        exception::Exception ex;
+        ex.getMessage() << "Call to zmq_init(sizeOfIOThreadPoolForZMQ=" << sizeOfIOThreadPoolForZMQ << ") failed: " << 
+          message;
+        throw ex;
+      }
+    }
+    return s_instance;
+  } catch(exception::Exception &ex) {
+    throw exception::Exception(std::string(__FUNCTION__) + " failed: " + ex.getMessage().str());
+  } catch(std::exception &se) {
+    throw exception::Exception(std::string(__FUNCTION__) + " failed: " + se.what());
+  }
+}
+
+} // namespace mediachanger
+} // namespace cta
diff --git a/mediachanger/ZmqContextSingleton.hpp b/mediachanger/ZmqContextSingleton.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..ec5a10b3a57376c3bc328265e50a8ecb9b8eb9c3
--- /dev/null
+++ b/mediachanger/ZmqContextSingleton.hpp
@@ -0,0 +1,76 @@
+/*
+ * 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 <memory>
+#include <mutex>
+
+namespace cta {
+namespace mediachanger {
+
+/**
+ * A singleton version of a ZMQ context.
+ *
+ * Please note that this class INTENTIONALLY does NOT terminate the ZMQ context
+ * because ZMQ sends an abort on exit when cleaned up this way under some
+ * circumstances, so we purposely do not clean up the context (zmq_term) and
+ * leave a resource leak, which in our use case is a one-off situation per
+ * process.
+ */
+class ZmqContextSingleton {
+public:
+
+  /**
+   * Returns the single instance of the ZMQ context.
+   */
+  static void *instance();
+
+  /**
+   * It should not be possible to make instances of this class.
+   */
+  ZmqContextSingleton() = delete;
+
+  /**
+   * It should not be possible to copy instances of this class.
+   */
+  ZmqContextSingleton(const ZmqContextSingleton &) = delete;
+
+  /**
+   * It should not be possible to assign instances of this class.
+   */
+  void operator=(const ZmqContextSingleton &) = delete;
+
+private:
+
+  /**
+   * Mutex used to implement a critical region around the implementation of the
+   * instance() method.
+   */
+  static std::mutex s_mutex;
+
+  /**
+   * The single instance of a ZMQ context.  A value of NULL means the ZMQ
+   * context has not yet been created.
+   */
+  static void *s_instance;
+
+}; // class ZmqContextSingleton
+
+} // namespace mediachanger
+} // namespace cta
diff --git a/tapeserver/castor/tape/tapeserver/daemon/DataTransferSessionTest.cpp b/tapeserver/castor/tape/tapeserver/daemon/DataTransferSessionTest.cpp
index fddcf1d15cb2a8796873c3af1449c74306a41beb..745f732dd83e62c4bab2ece8d611484ea6db362a 100644
--- a/tapeserver/castor/tape/tapeserver/daemon/DataTransferSessionTest.cpp
+++ b/tapeserver/castor/tape/tapeserver/daemon/DataTransferSessionTest.cpp
@@ -35,15 +35,13 @@
 #include "castor/tape/tapeserver/drive/FakeDrive.hpp"
 #include "catalogue/InMemoryCatalogue.hpp"
 #include "common/exception/Exception.hpp"
+#include "common/log/DummyLogger.hpp"
 #include "common/log/StringLogger.hpp"
 #include "common/make_unique.hpp"
 #include "common/processCap/ProcessCapDummy.hpp"
 #include "common/threading/Threading.hpp"
 #include "common/utils/utils.hpp"
-#include "mediachanger/AcsProxyDummy.hpp"
 #include "mediachanger/MediaChangerFacade.hpp"
-#include "mediachanger/MmcProxyDummy.hpp"
-#include "mediachanger/RmcProxyDummy.hpp"
 //#include "smc_struct.h"
 //#include "scheduler/DummyScheduler.hpp"
 #include "scheduler/OStoreDB/OStoreDBFactory.hpp"
@@ -436,10 +434,8 @@ TEST_P(DataTransferSessionTest, DataTransferSessionGooddayRecall) {
   castorConf.bulkRequestRecallMaxBytes = UINT64_C(100)*1000*1000*1000;
   castorConf.bulkRequestRecallMaxFiles = 1000;
   castorConf.nbDiskThreads = 1;
-  cta::mediachanger::AcsProxyDummy acs;
-  cta::mediachanger::MmcProxyDummy mmc;
-  cta::mediachanger::RmcProxyDummy rmc;
-  cta::mediachanger::MediaChangerFacade mc(acs, mmc, rmc);
+  cta::log::DummyLogger dummyLog("dummy");
+  cta::mediachanger::MediaChangerFacade mc(dummyLog);
   cta::server::ProcessCap capUtils;
   castor::messages::TapeserverProxyDummy initialProcess;
   castor::tape::tapeserver::daemon::DataTransferSession sess("tapeHost", logger, mockSys,
@@ -629,10 +625,8 @@ TEST_P(DataTransferSessionTest, DataTransferSessionWrongRecall) {
   castorConf.bulkRequestRecallMaxBytes = UINT64_C(100)*1000*1000*1000;
   castorConf.bulkRequestRecallMaxFiles = 1000;
   castorConf.nbDiskThreads = 1;
-  cta::mediachanger::AcsProxyDummy acs;
-  cta::mediachanger::MmcProxyDummy mmc;
-  cta::mediachanger::RmcProxyDummy rmc;
-  cta::mediachanger::MediaChangerFacade mc(acs, mmc, rmc);
+  cta::log::DummyLogger dummyLog("dummy");
+  cta::mediachanger::MediaChangerFacade mc(dummyLog);
   cta::server::ProcessCap capUtils;
   castor::messages::TapeserverProxyDummy initialProcess;
   DataTransferSession sess("tapeHost", logger, mockSys,
@@ -791,10 +785,8 @@ TEST_P(DataTransferSessionTest, DataTransferSessionNoSuchDrive) {
   DataTransferConfig castorConf;
   castorConf.bufsz = 1024;
   castorConf.nbBufs = 10;
-  cta::mediachanger::AcsProxyDummy acs;
-  cta::mediachanger::MmcProxyDummy mmc;
-  cta::mediachanger::RmcProxyDummy rmc;
-  cta::mediachanger::MediaChangerFacade mc(acs, mmc, rmc);
+  cta::log::DummyLogger dummyLog("dummy");
+  cta::mediachanger::MediaChangerFacade mc(dummyLog);
   castor::messages::TapeserverProxyDummy initialProcess;
   cta::server::ProcessCapDummy capUtils;
   DataTransferSession sess("tapeHost", logger, mockSys,
@@ -938,10 +930,8 @@ TEST_P(DataTransferSessionTest, DataTransferSessionFailtoMount) {
   castorConf.bulkRequestRecallMaxBytes = UINT64_C(100)*1000*1000*1000;
   castorConf.bulkRequestRecallMaxFiles = 1000;
   castorConf.nbDiskThreads = 3;
-  cta::mediachanger::AcsProxyDummy acs;
-  cta::mediachanger::MmcProxyDummy mmc;
-  cta::mediachanger::RmcProxyDummy rmc;
-  cta::mediachanger::MediaChangerFacade mc(acs, mmc, rmc);
+  cta::log::DummyLogger dummyLog("dummy");
+  cta::mediachanger::MediaChangerFacade mc(dummyLog);
   cta::server::ProcessCap capUtils;
   castor::messages::TapeserverProxyDummy initialProcess;
   DataTransferSession sess("tapeHost", logger, mockSys,
@@ -1065,10 +1055,8 @@ TEST_P(DataTransferSessionTest, DataTransferSessionGooddayMigration) {
   castorConf.bulkRequestRecallMaxBytes = UINT64_C(100)*1000*1000*1000;
   castorConf.bulkRequestRecallMaxFiles = 1000;
   castorConf.nbDiskThreads = 1;
-  cta::mediachanger::AcsProxyDummy acs;
-  cta::mediachanger::MmcProxyDummy mmc;
-  cta::mediachanger::RmcProxyDummy rmc;
-  cta::mediachanger::MediaChangerFacade mc(acs, mmc, rmc);
+  cta::log::DummyLogger dummyLog("dummy");
+  cta::mediachanger::MediaChangerFacade mc(dummyLog);
   cta::server::ProcessCap capUtils;
   castor::messages::TapeserverProxyDummy initialProcess;
   DataTransferSession sess("tapeHost", logger, mockSys, driveConfig, mc, initialProcess, capUtils, castorConf, scheduler);
@@ -1205,10 +1193,8 @@ TEST_P(DataTransferSessionTest, DataTransferSessionMissingFilesMigration) {
   castorConf.bulkRequestRecallMaxBytes = UINT64_C(100)*1000*1000*1000;
   castorConf.bulkRequestRecallMaxFiles = 1000;
   castorConf.nbDiskThreads = 1;
-  cta::mediachanger::AcsProxyDummy acs;
-  cta::mediachanger::MmcProxyDummy mmc;
-  cta::mediachanger::RmcProxyDummy rmc;
-  cta::mediachanger::MediaChangerFacade mc(acs, mmc, rmc);
+  cta::log::DummyLogger dummyLog("dummy");
+  cta::mediachanger::MediaChangerFacade mc(dummyLog);
   cta::server::ProcessCap capUtils;
   castor::messages::TapeserverProxyDummy initialProcess;
   DataTransferSession sess("tapeHost", logger, mockSys, driveConfig, mc, initialProcess, capUtils, castorConf, scheduler);
@@ -1339,10 +1325,8 @@ TEST_P(DataTransferSessionTest, DataTransferSessionTapeFullMigration) {
   castorConf.bulkRequestRecallMaxBytes = UINT64_C(100)*1000*1000*1000;
   castorConf.bulkRequestRecallMaxFiles = 1000;
   castorConf.nbDiskThreads = 1;
-  cta::mediachanger::AcsProxyDummy acs;
-  cta::mediachanger::MmcProxyDummy mmc;
-  cta::mediachanger::RmcProxyDummy rmc;
-  cta::mediachanger::MediaChangerFacade mc(acs, mmc, rmc);
+  cta::log::DummyLogger dummyLog("dummy");
+  cta::mediachanger::MediaChangerFacade mc(dummyLog);
   cta::server::ProcessCap capUtils;
   castor::messages::TapeserverProxyDummy initialProcess;
   DataTransferSession sess("tapeHost", logger, mockSys, driveConfig, mc, initialProcess, capUtils, castorConf, scheduler);
@@ -1487,10 +1471,8 @@ TEST_P(DataTransferSessionTest, DataTransferSessionTapeFullOnFlushMigration) {
   castorConf.bulkRequestRecallMaxBytes = UINT64_C(100)*1000*1000*1000;
   castorConf.bulkRequestRecallMaxFiles = 1000;
   castorConf.nbDiskThreads = 1;
-  cta::mediachanger::AcsProxyDummy acs;
-  cta::mediachanger::MmcProxyDummy mmc;
-  cta::mediachanger::RmcProxyDummy rmc;
-  cta::mediachanger::MediaChangerFacade mc(acs, mmc, rmc);
+  cta::log::DummyLogger dummyLog("dummy");
+  cta::mediachanger::MediaChangerFacade mc(dummyLog);
   cta::server::ProcessCap capUtils;
   castor::messages::TapeserverProxyDummy initialProcess;
   DataTransferSession sess("tapeHost", logger, mockSys, driveConfig, mc, initialProcess, capUtils, castorConf, scheduler);
diff --git a/tapeserver/castor/tape/tapeserver/daemon/RecallTaskInjectorTest.cpp b/tapeserver/castor/tape/tapeserver/daemon/RecallTaskInjectorTest.cpp
index 0777c40e11e98fa7f1549385d921a4ad14fcd058..b67cba9d307f22cdaec9353cd4b66289aacf73de 100644
--- a/tapeserver/castor/tape/tapeserver/daemon/RecallTaskInjectorTest.cpp
+++ b/tapeserver/castor/tape/tapeserver/daemon/RecallTaskInjectorTest.cpp
@@ -21,19 +21,17 @@
  * @author Castor Dev team, castor-dev@cern.ch
  *****************************************************************************/
 
-#include "common/log/StringLogger.hpp"
 #include "castor/messages/TapeserverProxyDummy.hpp"
-#include "common/processCap/ProcessCapDummy.hpp"
 #include "castor/tape/tapeserver/daemon/DiskWriteThreadPool.hpp"
 #include "castor/tape/tapeserver/daemon/RecallTaskInjector.hpp"
 #include "castor/tape/tapeserver/daemon/TapeServerReporter.hpp"
 #include "castor/tape/tapeserver/daemon/TapeReadSingleThread.hpp"
 #include "castor/tape/tapeserver/daemon/TaskWatchDog.hpp"
 #include "castor/tape/tapeserver/drive/FakeDrive.hpp"
-#include "mediachanger/AcsProxyDummy.hpp"
+#include "common/log/DummyLogger.hpp"
+#include "common/log/StringLogger.hpp"
+#include "common/processCap/ProcessCapDummy.hpp"
 #include "mediachanger/MediaChangerFacade.hpp"
-#include "mediachanger/MmcProxyDummy.hpp"
-#include "mediachanger/RmcProxyDummy.hpp"
 #include "scheduler/SchedulerDatabase.hpp"
 #include "scheduler/testingMocks/MockRetrieveMount.hpp"
 
@@ -154,10 +152,8 @@ namespace unitTests
     std::unique_ptr<cta::SchedulerDatabase::RetrieveMount> dbrm(new TestingDatabaseRetrieveMount());
     MockRecallReportPacker mrrp(&trm,lc);
     FakeDiskWriteThreadPool diskWrite(mrrp,rwd,lc);
-    cta::mediachanger::AcsProxyDummy acs;
-    cta::mediachanger::MmcProxyDummy mmc;
-    cta::mediachanger::RmcProxyDummy rmc;
-    cta::mediachanger::MediaChangerFacade mc(acs, mmc, rmc);
+    cta::log::DummyLogger dummyLog("dummy");
+    cta::mediachanger::MediaChangerFacade mc(log);
     castor::messages::TapeserverProxyDummy initialProcess;
     castor::tape::tapeserver::daemon::VolumeInfo volume;
     volume.vid="V12345";
@@ -216,10 +212,8 @@ namespace unitTests
     std::unique_ptr<cta::SchedulerDatabase::RetrieveMount> dbrm(new TestingDatabaseRetrieveMount());
     MockRecallReportPacker mrrp(&trm,lc);
     FakeDiskWriteThreadPool diskWrite(mrrp,rwd,lc);
-    cta::mediachanger::AcsProxyDummy acs;
-    cta::mediachanger::MmcProxyDummy mmc;
-    cta::mediachanger::RmcProxyDummy rmc;
-    cta::mediachanger::MediaChangerFacade mc(acs, mmc, rmc);
+    cta::log::DummyLogger dummyLog("dummy");
+    cta::mediachanger::MediaChangerFacade mc(dummyLog);
     castor::messages::TapeserverProxyDummy initialProcess;  
     castor::tape::tapeserver::daemon::VolumeInfo volume;
     volume.vid="V12345";
diff --git a/tapeserver/daemon/DriveHandler.cpp b/tapeserver/daemon/DriveHandler.cpp
index 8325a447276945347433345eeb364a6f4b86f12e..23550db835aa356124468cfdf9d010b3ec6b2138 100644
--- a/tapeserver/daemon/DriveHandler.cpp
+++ b/tapeserver/daemon/DriveHandler.cpp
@@ -22,10 +22,6 @@
 #include "common/processCap/ProcessCap.hpp"
 #include "DriveHandler.hpp"
 #include "DriveHandlerProxy.hpp"
-#include "mediachanger/AcsProxyZmq.hpp"
-#include "mediachanger/MmcProxyLog.hpp"
-#include "mediachanger/RmcProxyTcpIp.hpp"
-#include "mediachanger/SmartZmqContext.hpp"
 #include "objectstore/Backend.hpp"
 #include "objectstore/BackendFactory.hpp"
 #include "objectstore/BackendVFS.hpp"
@@ -916,20 +912,7 @@ int DriveHandler::runChild() {
     cta::server::ProcessCap capUtils;
     
     // Mounting management.
-    const int sizeOfIOThreadPoolForZMQ = 1;
-    mediachanger::SmartZmqContext zmqContext(
-      mediachanger::SmartZmqContext::instantiateZmqContext(sizeOfIOThreadPoolForZMQ));
-    mediachanger::AcsProxyZmq acs(mediachanger::ACS_PORT, zmqContext.get());
-
-    cta::mediachanger::MmcProxyLog mmc(m_processManager.logContext().logger());
-    // The network timeout of rmc communications should be several minutes due
-    // to the time it takes to mount and unmount tapes
-    const int rmcNetTimeout = 600; // Timeout in seconds
-
-    cta::mediachanger::RmcProxyTcpIp rmc(cta::mediachanger::RMC_PORT, rmcNetTimeout,
-      cta::mediachanger::RMC_MAXRQSTATTEMPTS);
-    
-    cta::mediachanger::MediaChangerFacade mediaChangerFacade(acs, mmc, rmc);
+    cta::mediachanger::MediaChangerFacade mediaChangerFacade(m_processManager.logContext().logger());
     
     castor::tape::System::realWrapper sWrapper;
     
@@ -959,20 +942,7 @@ int DriveHandler::runChild() {
     cta::server::ProcessCap capUtils;
     
     // Mounting management.
-    const int sizeOfIOThreadPoolForZMQ = 1;
-    mediachanger::SmartZmqContext zmqContext(
-      mediachanger::SmartZmqContext::instantiateZmqContext(sizeOfIOThreadPoolForZMQ));
-    mediachanger::AcsProxyZmq acs(mediachanger::ACS_PORT, zmqContext.get());
-
-    cta::mediachanger::MmcProxyLog mmc(m_processManager.logContext().logger());
-    // The network timeout of rmc communications should be several minutes due
-    // to the time it takes to mount and unmount tapes
-    const int rmcNetTimeout = 600; // Timeout in seconds
-
-    cta::mediachanger::RmcProxyTcpIp rmc(cta::mediachanger::RMC_PORT, rmcNetTimeout,
-      cta::mediachanger::RMC_MAXRQSTATTEMPTS);
-    
-    cta::mediachanger::MediaChangerFacade mediaChangerFacade(acs, mmc, rmc);
+    cta::mediachanger::MediaChangerFacade mediaChangerFacade(m_processManager.logContext().logger());
     
     castor::tape::System::realWrapper sWrapper;