int TRI_StopReplicationApplier (TRI_replication_applier_t* applier,
                                bool resetError) {
  int res;

  res = TRI_ERROR_NO_ERROR;
  
  LOG_TRACE("requesting replication applier stop");
 
  TRI_WriteLockReadWriteLock(&applier->_statusLock);

  if (! applier->_state._active) {
    TRI_WriteUnlockReadWriteLock(&applier->_statusLock);

    return res;
  }

  res = StopApplier(applier, resetError);
  TRI_WriteUnlockReadWriteLock(&applier->_statusLock);
 
  // join the thread without the status lock (otherwise it would probably not join) 
  if (res == TRI_ERROR_NO_ERROR) {
    res = TRI_JoinThread(&applier->_thread);
  }
  else {
    // keep original error code
    TRI_JoinThread(&applier->_thread);
  }
  
  SetTerminateFlag(applier, false);

  LOG_INFO("stopped replication applier for database '%s'",
           applier->_databaseName);
  
  return res;
}
int TRI_ShutdownReplicationApplier (TRI_replication_applier_t* applier) {
  if (applier == nullptr) {
    return TRI_ERROR_NO_ERROR;
  }

  LOG_TRACE("requesting replication applier shutdown");

  if (applier->_vocbase->_type == TRI_VOCBASE_TYPE_COORDINATOR) {
    return TRI_ERROR_CLUSTER_UNSUPPORTED;
  }

  TRI_WriteLockReadWriteLock(&applier->_statusLock);

  if (! applier->_state._active) {
    TRI_WriteUnlockReadWriteLock(&applier->_statusLock);

    return TRI_ERROR_NO_ERROR;
  }

  int res = StopApplier(applier, true);

  TRI_WriteUnlockReadWriteLock(&applier->_statusLock);

  // join the thread without the status lock (otherwise it would probably not join)
  if (res == TRI_ERROR_NO_ERROR) {
    res = TRI_JoinThread(&applier->_thread);
  }
  else {
    // stop the thread but keep original error code
    int res2 = TRI_JoinThread(&applier->_thread);

    if (res2 != TRI_ERROR_NO_ERROR) {
      LOG_ERROR("could not join replication applier for database '%s': %s",
                applier->_databaseName,
                TRI_errno_string(res2));
    }
  }

  SetTerminateFlag(applier, false);
  
  TRI_WriteLockReadWriteLock(&applier->_statusLock);
  // really abort all ongoing transactions
  applier->abortRunningRemoteTransactions();

  TRI_WriteUnlockReadWriteLock(&applier->_statusLock);

  LOG_INFO("stopped replication applier for database '%s'",
           applier->_databaseName);

  return res;
}