diff --git a/include/ExceptionHandlingDecorator.h b/include/ExceptionHandlingDecorator.h
index 2859cf875a2f4cf294e5bcce1add5fb3eef86167..b00765318698a2a60c7c78b2d2be5f35b0f387be 100644
--- a/include/ExceptionHandlingDecorator.h
+++ b/include/ExceptionHandlingDecorator.h
@@ -48,17 +48,24 @@ namespace ChimeraTK {
 
     void setOwner(EntityOwner* owner);
 
+    void doPostRead(TransferType type, bool hasNewData) override;
+
+    void doPostWrite(TransferType type, bool dataLost) override;
+
+    void doPreRead(TransferType type) override;
+
    protected:
     using ChimeraTK::NDRegisterAccessor<UserType>::buffer_2D;
     DeviceModule& deviceModule;
 
-    bool hasSeenException{true};
+    bool previousReadFailed{true};
 
-    bool genericTransfer(std::function<bool(void)> callable, bool updateOwnerValidityFlag = true);
     void setOwnerValidity(bool hasExceptionNow);
     boost::shared_ptr<NDRegisterAccessor<UserType>> _recoveryAccessor{nullptr};
     EntityOwner* _owner = {nullptr};
     VariableDirection _direction;
+
+    bool transferAllowed{false};
   };
 
   DECLARE_TEMPLATE_FOR_CHIMERATK_USER_TYPES(ExceptionHandlingDecorator);
diff --git a/src/ExceptionHandlingDecorator.cc b/src/ExceptionHandlingDecorator.cc
index 5f7ffb83513f6991700c877784c34b113023e44e..d7380b5486e85a770862e9e9a5f08ad6262ec41c 100644
--- a/src/ExceptionHandlingDecorator.cc
+++ b/src/ExceptionHandlingDecorator.cc
@@ -21,8 +21,8 @@ namespace ChimeraTK {
 
   template<typename UserType>
   void ExceptionHandlingDecorator<UserType>::setOwnerValidity(bool hasExceptionNow) {
-    if(hasExceptionNow != hasSeenException) {
-      hasSeenException = hasExceptionNow;
+    if(hasExceptionNow != previousReadFailed) {
+      previousReadFailed = hasExceptionNow;
       if(!_owner) return;
       if(hasExceptionNow) {
         _owner->incrementExceptionCounter();
@@ -34,98 +34,59 @@ namespace ChimeraTK {
   }
 
   template<typename UserType>
-  bool ExceptionHandlingDecorator<UserType>::genericTransfer(
-      std::function<bool(void)> callable, bool updateOwnerValidityFlag) {
-    std::function<void(bool)> setOwnerValidityFunction{};
-    if(updateOwnerValidityFlag) {
-      setOwnerValidityFunction =
-          std::bind(&ExceptionHandlingDecorator<UserType>::setOwnerValidity, this, std::placeholders::_1);
+  bool ExceptionHandlingDecorator<UserType>::doWriteTransfer(ChimeraTK::VersionNumber versionNumber) {
+    if(transferAllowed) {
+      return ChimeraTK::NDRegisterAccessorDecorator<UserType>::doWriteTransfer(versionNumber);
     }
     else {
-      setOwnerValidityFunction = [](bool) {}; // do nothing if calling code does not want to invalidate data.
-    }
-
-    while(true) {
-      try {
-        if(!deviceModule.device.isOpened()) {
-          if(Application::getInstance().getLifeCycleState() != LifeCycleState::run) {
-            // If the application has not yet fully started, we cannot wait for the device to open. Instead register
-            // the variable in the DeviceMoule, so the transfer will be performed after the device is opened.
-            assert(_recoveryAccessor != nullptr); // should always be true for writeable registers with this decorator
-            return false;
-          }
-          // We artificially increase the testabel mode counter so the test does not slip out of testable mode here in case
-          // the queues are empty. At the moment, the exception handling has to be done before you get the lock back in your test.
-          // Exception handling cannot be tested in testable mode at the moment.
-          if(Application::getInstance().isTestableModeEnabled()) {
-            ++Application::getInstance().testableMode_counter;
-            Application::getInstance().testableModeUnlock("waitForDeviceOpen");
-          }
-          boost::this_thread::sleep(boost::posix_time::millisec(DeviceOpenTimeout));
-          if(Application::getInstance().isTestableModeEnabled()) {
-            Application::getInstance().testableModeLock("waitForDeviceOpen");
-            --Application::getInstance().testableMode_counter;
-          }
-          continue;
-        }
-        auto retval = callable();
-        // We do not have to relay the target's data validity. The MetaDataPropagatingDecorator already takes care of it.
-        // The ExceptionHandling decorator is used in addition, not instead of it.
-        setOwnerValidityFunction(/*hasExceptionNow = */ false);
-        return retval;
-      }
-      catch(ChimeraTK::runtime_error& e) {
-        setOwnerValidityFunction(/*hasExceptionNow = */ true);
-        deviceModule.reportException(e.what());
-        deviceModule.waitForRecovery();
-      }
+      return true; /* data loss */
     }
   }
 
-  template<typename UserType>
-  bool ExceptionHandlingDecorator<UserType>::doWriteTransfer(ChimeraTK::VersionNumber versionNumber) {
-    return genericTransfer(
-        [this, versionNumber]() {
-          return ChimeraTK::NDRegisterAccessorDecorator<UserType>::doWriteTransfer(versionNumber);
-        },
-        false);
-  }
-
   template<typename UserType>
   bool ExceptionHandlingDecorator<UserType>::doWriteTransferDestructively(ChimeraTK::VersionNumber versionNumber) {
-    return genericTransfer(
-        [this, versionNumber]() {
-          return ChimeraTK::NDRegisterAccessorDecorator<UserType>::doWriteTransferDestructively(versionNumber);
-        },
-        false);
+    if(transferAllowed) {
+      return ChimeraTK::NDRegisterAccessorDecorator<UserType>::doWriteTransferDestructively(versionNumber);
+    }
+    else {
+      return true; /* data loss */
+    }
   }
 
   template<typename UserType>
   void ExceptionHandlingDecorator<UserType>::doReadTransfer() {
-    genericTransfer([this]() { return ChimeraTK::NDRegisterAccessorDecorator<UserType>::doReadTransfer(), true; });
+    if(transferAllowed) {
+      ChimeraTK::NDRegisterAccessorDecorator<UserType>::doReadTransfer();
+    }
   }
 
   template<typename UserType>
   bool ExceptionHandlingDecorator<UserType>::doReadTransferNonBlocking() {
-    return genericTransfer(
-        [this]() { return ChimeraTK::NDRegisterAccessorDecorator<UserType>::doReadTransferNonBlocking(); });
+    if(transferAllowed) {
+      return ChimeraTK::NDRegisterAccessorDecorator<UserType>::doReadTransferNonBlocking();
+    }
+    else {
+      return false; //hasNewData
+    }
   }
 
   template<typename UserType>
   bool ExceptionHandlingDecorator<UserType>::doReadTransferLatest() {
-    return genericTransfer(
-        [this]() { return ChimeraTK::NDRegisterAccessorDecorator<UserType>::doReadTransferLatest(); });
+    if(transferAllowed) {
+      return ChimeraTK::NDRegisterAccessorDecorator<UserType>::doReadTransferLatest();
+    }
+    else {
+      return false; //hasNewData
+    }
   }
 
   template<typename UserType>
   TransferFuture ExceptionHandlingDecorator<UserType>::doReadTransferAsync() {
-    TransferFuture future;
-    genericTransfer([this, &future]() {
-      future = ChimeraTK::NDRegisterAccessorDecorator<UserType>::doReadTransferAsync();
-      return true;
-    });
-
-    return future;
+    assert(transferAllowed);
+    if(!transferAllowed) {
+      throw(ChimeraTK::logic_error("You have to implement ApplicationCore #157"));
+    }
+    return ChimeraTK::NDRegisterAccessorDecorator<UserType>::doReadTransferAsync();
   }
 
   template<typename UserType>
@@ -154,13 +115,19 @@ namespace ChimeraTK {
 
     // Now delegate call to the generic decorator, which swaps the buffer, without adding our exception handling with the generic transfer
     ChimeraTK::NDRegisterAccessorDecorator<UserType>::doPreWrite(type);
+
+    // #138 Phase 1. Change for phase 2
+    transferAllowed = (Application::getInstance().getLifeCycleState() == LifeCycleState::run);
+    assert(Application::getInstance().getLifeCycleState() != LifeCycleState::shutdown);
+    // the waiting is only necessary as a hack for phase 1 because DeviceModule::startTransfer is not there yet
+    if(transferAllowed) deviceModule.waitForRecovery();
   }
 
   template<typename UserType>
   DataValidity ExceptionHandlingDecorator<UserType>::dataValidity() const {
     // If there has been an exception  the data cannot be OK.
     // This is only considered in read mode (=feeding to the connected variable network).
-    if(_direction.dir == VariableDirection::feeding && hasSeenException) {
+    if(_direction.dir == VariableDirection::feeding && previousReadFailed) {
       return DataValidity::faulty;
     }
     // no exception, return the data validity of the accessor we are decorating
@@ -178,11 +145,86 @@ namespace ChimeraTK {
   template<typename UserType>
   void ExceptionHandlingDecorator<UserType>::setOwner(EntityOwner* owner) {
     _owner = owner;
-    if(_direction.dir == VariableDirection::feeding && hasSeenException) {
+    if(_direction.dir == VariableDirection::feeding && previousReadFailed) {
       _owner->incrementExceptionCounter(false); // do not write. We are still in the setup phase.
     }
   }
 
+  template<typename UserType>
+  void ExceptionHandlingDecorator<UserType>::doPostRead(TransferType type, bool hasNewData) {
+    bool hasException = false;
+    try {
+      this->_target->postRead(type, hasNewData);
+    }
+    catch(ChimeraTK::runtime_error& e) {
+      deviceModule.reportException(e.what());
+      hasException = true;
+    }
+    // #138 Phase 2: change if codition here
+    if(hasException) {
+      // Try to recover and read until it succeeds.
+      // We are already behind the delegated postRead, so the transfer in the target is already complemted.
+      // So we have to use a complete blocking preRead, readTransfer, postRead, i.e. _tagret->read()
+      while(true) {
+        deviceModule.waitForRecovery();
+        /* //#138 Phase 2
+         * if (!deviceModule->startTransfer()) continue;
+         * // end  of #138 Phase 2
+         */
+        try {
+          this->_target->read();
+          hasException = false;
+          hasNewData = true; // if read() returns there is always new data
+          /* //#138 Phase 2
+           * deviceModule->stopTransfer());
+           * // end  of #138 Phase 2
+           */
+          break;
+        }
+        catch(ChimeraTK::runtime_error&) {
+          /* //#138 Phase 2
+           * deviceModule->stopTransfer());
+           * // end  of #138 Phase 2
+           */
+        }
+      }
+    }
+    setOwnerValidity(hasException);
+    // only replace the user buffer if there really is new data
+    if(hasNewData) {
+      for(size_t i = 0; i < buffer_2D.size(); ++i)
+        buffer_2D[i].swap(this->_target->accessChannel(static_cast<unsigned int>(i)));
+    }
+  }
+
+  template<typename UserType>
+  void ExceptionHandlingDecorator<UserType>::doPostWrite(TransferType type, bool dataLost) {
+    try {
+      ChimeraTK::NDRegisterAccessorDecorator<UserType>::doPostWrite(type, dataLost);
+    }
+    catch(ChimeraTK::runtime_error& e) {
+      deviceModule.reportException(e.what());
+      deviceModule.waitForRecovery();
+    }
+  }
+
+  template<typename UserType>
+  void ExceptionHandlingDecorator<UserType>::doPreRead(TransferType type) {
+    /* #138 Phase 1. Change this for phase 2 */
+    /* Hack for phase 1 because DeviceModule::startTransfer is not there yet. */
+    deviceModule.waitForRecovery();
+    transferAllowed = true;
+    //    std::cout << "recovered" << std::endl;
+    //    transferAllowed = (Application::getInstance().getLifeCycleState() == LifeCycleState::run);
+    //    auto l = Application::getInstance().getLifeCycleState();
+    //    std::cout << "LifeCycleState: "
+    //              << (l == LifeCycleState::run ? "run" : (l == LifeCycleState::initialisation ? "init" : "shutdown"))
+    //              << std::endl;
+    //    assert(transferAllowed); // not true in phase 2 any more
+
+    ChimeraTK::NDRegisterAccessorDecorator<UserType>::doPreRead(type);
+  }
+
   INSTANTIATE_TEMPLATE_FOR_CHIMERATK_USER_TYPES(ExceptionHandlingDecorator);
 
 } /* namespace ChimeraTK */