/**
   * Computes the back-off timer and schedules the specified retransmission task.
   *
   * @param exchange the exchange
   * @param task the retransmission task
   */
  protected void prepareRetransmission(Exchange exchange, RetransmissionTask task) {
    /*
     * For a new confirmable message, the initial timeout is set to a
     * random number between ACK_TIMEOUT and (ACK_TIMEOUT *
     * ACK_RANDOM_FACTOR)
     */
    int timeout;
    if (exchange.getFailedTransmissionCount() == 0) {
      timeout = getRandomTimeout(ack_timeout, (int) (ack_timeout * ack_random_factor));
    } else {
      timeout = (int) (ack_timeout_scale * exchange.getCurrentTimeout());
    }
    exchange.setCurrentTimeout(timeout);

    ScheduledFuture<?> f = executor.schedule(task, timeout, TimeUnit.MILLISECONDS);
    exchange.setRetransmissionHandle(f);
  }