/** main loop */
  public FleaseMessage processMessage(FleaseMessage msg) {

    assert (!quit);

    /*if (Logging.isDebug())
    Logging.logMessage(Logging.LEVEL_DEBUG,this,"received %s",msg.toString());*/

    final long now = TimeSync.getLocalSystemTime();
    if (msg.getSendTimestamp() + config.getMessageTimeout() < TimeSync.getGlobalTime()) {
      // old message, ignore
      if (Logging.isDebug() && config.isDebugPrintMessages())
        Logging.logMessage(
            Logging.LEVEL_DEBUG,
            Category.replication,
            this,
            "A outdated message discarded: %s",
            msg.toString());
      return null;
    }
    if (this.waitUntilTimestamp_ms >= now) {
      if (Logging.isDebug() && config.isDebugPrintMessages())
        Logging.logMessage(
            Logging.LEVEL_DEBUG,
            Category.replication,
            this,
            "A message discarded, acceptor is still in recovery period");
      return null;
    }

    assert (msg.getCellId() != null);
    final FleaseAcceptorCell cc = getCell(msg.getCellId());

    if (cc.getViewId() < msg.getViewId()) {
      // If the local view is lower than the delivered one, the view listener has to be informed to
      // update
      // the local view. But the request can still be answered.
      viewListener.viewIdChangeEvent(msg.getCellId(), msg.getViewId());

    } else if (cc.getViewId() > msg.getViewId()
        || (cc.getViewId() == msg.getViewId() && cc.isViewInvalidated())) {
      // If the request is from an older view, or the a view that has been invalidated on this
      // AcceptorCell, the request has to be aborted.
      FleaseMessage response = new FleaseMessage(FleaseMessage.MsgType.MSG_WRONG_VIEW, msg);
      response.setViewId(cc.getViewId());
      return response;
    }

    FleaseMessage response = null;
    if (msg.getMsgType() == FleaseMessage.MsgType.MSG_PREPARE) response = handlePREPARE(msg);
    else if (msg.getMsgType() == FleaseMessage.MsgType.MSG_ACCEPT) response = handleACCEPT(msg);
    else if (msg.getMsgType() == FleaseMessage.MsgType.MSG_LEARN) handleLEARN(msg);
    /*else if (msg.getMsgType() == FleaseMessage.MsgType.MSG_GET_LEASE)
        response = handleGETLEASE(msg);
    else if (msg.getMsgType() == FleaseMessage.MsgType.MSG_RENEW_LEASE)
        response = handleRENEWINSTANCE(msg);*/
    else
      Logging.logMessage(
          Logging.LEVEL_ERROR,
          Category.replication,
          this,
          "A invalid message type received: %s",
          msg.toString());

    /*if (Logging.isDebug())
    Logging.logMessage(Logging.LEVEL_DEBUG,this,"response %s",(response != null) ? response.toString() : "<empty>");*/

    return response;
  }