/**
   * Dispatches a message to the appropriate receiver.
   *
   * <p>It will buffer the message under the following conditions: 1) The MessageReceiver is not yet
   * registered. 2) The MessageReceiver is a PastryAppl, and localNode.isReady() == false
   *
   * @param msg the message.
   * @return true if message could be dispatched, false otherwise.
   */
  public boolean dispatchMessage(Message msg) {
    if (msg.getDestination() == 0) {
      Logger logger =
          localNode.getEnvironment().getLogManager().getLogger(MessageDispatch.class, null);
      if (logger.level <= Logger.WARNING)
        logger.logException(
            "Message " + msg + "," + msg.getClass().getName() + " has no destination.",
            new Exception("Stack Trace"));
      return false;
    }
    // NOTE: There is no safety issue with calling localNode.isReady() because this is on the
    // PastryThread, and the only way to set a node ready is also on the ready thread.
    PastryAppl mr = (PastryAppl) addressBook.get(Integer.valueOf(msg.getDestination()));

    if (mr == null) {
      if ((logger.level <= Logger.FINE) || (localNode.isReady() && (logger.level <= Logger.INFO))) {
        logger.log(
            "Dropping message "
                + msg
                + " because the application address "
                + msg.getDestination()
                + " is unknown.");
      }
      return false;
    } else {
      mr.receiveMessage(msg);
      return true;
    }
  }
 public PastryAppl getDestination(Message msg) {
   return getDestinationByAddress(msg.getDestination());
 }