/** Method derived from interface TimerListener. It's fired from an active Timer. */
 public void onTimeout(Timer to) {
   try {
     if (to.equals(retransmission_to) && (statusIs(STATE_TRYING) || statusIs(STATE_PROCEEDING))) {
       printLog("Retransmission timeout expired", LogLevel.HIGH);
       // retransmission only for unreliable transport
       if (true || connection_id == null) { // modified
         sip_provider.sendMessage(request);
         long timeout = 2 * retransmission_to.getTime();
         if (timeout > SipStack.max_retransmission_timeout || statusIs(STATE_PROCEEDING))
           timeout = SipStack.max_retransmission_timeout;
         retransmission_to = new Timer(timeout, retransmission_to.getLabel(), this);
         retransmission_to.start();
       } else
         printLog(
             "No retransmissions for reliable transport (" + connection_id + ")", LogLevel.LOW);
     }
     if (to.equals(transaction_to)) {
       printLog("Transaction timeout expired", LogLevel.HIGH);
       retransmission_to.halt();
       clearing_to.halt();
       sip_provider.removeSipProviderListener(transaction_id);
       changeStatus(STATE_TERMINATED);
       if (transaction_listener != null) transaction_listener.onTransTimeout(this);
       transaction_listener = null;
     }
     if (to.equals(clearing_to)) {
       printLog("Clearing timeout expired", LogLevel.HIGH);
       retransmission_to.halt();
       transaction_to.halt();
       sip_provider.removeSipProviderListener(transaction_id);
       changeStatus(STATE_TERMINATED);
     }
   } catch (Exception e) {
     printException(e, LogLevel.HIGH);
   }
 }