/**
   * Overridable method for custom processing after the message has been processed by the SMTP
   * agent. Includes the tracking information if available and the message direction. For passivity,
   * this method calls {@link #onPostprocessMessage(Mail, MessageProcessResult)} by default after
   * performing its operations.
   *
   * @param mail The incoming mail message. The contents of the message may have changed from when
   *     it was originally received.
   * @param result Contains results of the message processing including the resulting message.
   * @param isOutgoing Indicate the direction of the message: incoming or outgoing.
   * @param tx Contains tracking information if available.
   */
  protected void onPostprocessMessage(
      Mail mail, MessageProcessResult result, boolean isOutgoing, Tx tx) {
    // if there are rejected recipients and an outgoing IMF message, then we may need to send a DSN
    // message
    boolean sendDSN = false;
    if (isOutgoing
        && tx != null
        && tx.getMsgType() == TxMessageType.IMF
        && result.getProcessedMessage().hasRejectedRecipients()) {
      final boolean timely = TxUtil.isReliableAndTimelyRequested(tx);
      if ((timely && this.autoDSNForTimelyAndReliable) || (!timely && this.autoDSNForGeneral))
        sendDSN = true;
    }

    if (sendDSN) sendDSN(tx, result.getProcessedMessage().getRejectedRecipients(), true);

    this.onPostprocessMessage(mail, result);
  }
  /**
   * Overridable method for custom processing when a message is rejected by the SMTP agent. Includes
   * the tracking information if available and the message direction. For passivity, this method
   * calls {@link #onMessageRejected(Mail, NHINDAddressCollection, NHINDAddress, Throwable)} by
   * default after performing its operations.
   *
   * @param message The mail message that the agent attempted to process.
   * @param recipients A collection of recipients that this message was intended to be delievered
   *     to.
   * @param sender The sender of the message.
   * @param isOutgoing Indicate the direction of the message: incoming or outgoing.
   * @param tx Contains tracking information if available. Generally this information will only be
   *     available for outgoing messages as rejected incoming messages more than likely will not
   *     have been decrypted yet.
   * @param t Exception thrown by the agent when the message was rejected. May be null;
   */
  protected void onMessageRejected(
      Mail mail,
      NHINDAddressCollection recipients,
      NHINDAddress sender,
      boolean isOutgoing,
      Tx tx,
      Throwable t) {
    // if this is an outgoing IMF message, then we may need to send a DSN message
    boolean sendDSN = false;
    if (isOutgoing && tx != null && tx.getMsgType() == TxMessageType.IMF) {
      final boolean timely = TxUtil.isReliableAndTimelyRequested(tx);
      if ((timely && this.autoDSNForTimelyAndReliable) || (!timely && this.autoDSNForGeneral))
        sendDSN = true;
    }

    if (sendDSN) sendDSN(tx, recipients, true);

    this.onMessageRejected(mail, recipients, sender, t);
  }