@Override
    public boolean processTimeout(TimeoutEvent timeoutEvent) {
      synchronized (messageProcessors) {
        for (SipMessageProcessor listener : messageProcessors)
          if (!listener.processTimeout(timeoutEvent, sentMsg)) return true;
      }

      // this is normaly handled by the SIP stack
      logger.error("Timeout event thrown : " + timeoutEvent.toString());

      if (timeoutEvent.isServerTransaction()) {
        logger.warn("The sender has probably not received our OK");
        return false;
      }

      Request req = timeoutEvent.getClientTransaction().getRequest();

      // get the content
      String content = null;
      try {
        content = new String(req.getRawContent(), getCharset(req));
      } catch (UnsupportedEncodingException ex) {
        logger.warn("failed to convert the message charset", ex);
        content = new String(req.getRawContent());
      }

      // to who this request has been sent ?
      ToHeader toHeader = (ToHeader) req.getHeader(ToHeader.NAME);

      if (toHeader == null) {
        logger.error("received a request without a to header");
        return false;
      }

      Contact to = opSetPersPresence.resolveContactID(toHeader.getAddress().getURI().toString());

      Message failedMessage = null;

      if (to == null) {
        logger.error(
            "timeout on a message sent to an unknown contact : "
                + toHeader.getAddress().getURI().toString());

        // we don't know what message it concerns, so create a new
        // one
        failedMessage = createMessage(content);
      } else {
        // try to retrieve the original message
        String key = ((CallIdHeader) req.getHeader(CallIdHeader.NAME)).getCallId();
        failedMessage = sentMsg.get(key);

        if (failedMessage == null) {
          // should never happen
          logger.error("Couldn't find the sent message.");

          // we don't know what the message is so create a new one
          // based on the content of the failed request.
          failedMessage = createMessage(content);
        }
      }

      // error for delivering the message
      fireMessageDeliveryFailed(
          // we don't know what message it concerns
          failedMessage, to, MessageDeliveryFailedEvent.INTERNAL_ERROR);
      return true;
    }