/** Invoked for SIP INVITE requests. */
  @Override
  protected void doInvite(final SipServletRequest req) throws ServletException, IOException {
    if (req.isInitial()) {
      // Get a reference to the Proxy helper.
      final Proxy proxy = req.getProxy();

      // Set Proxy parameters to control various aspects of the proxying
      // operation:
      proxy.setRecordRoute(true);
      proxy.setSupervised(true);
      // Set the flag indicates the working mode. True for Follow-Me; false for
      // Find-me.

      proxy.setParallel(m_parallel);

      // Proxies a SIP request to the specified set of destinations.
      proxy.proxyTo(m_targets);
    }
  }
    public void dispatch() throws DispatcherException {
      final SipServletRequestImpl sipServletRequest = (SipServletRequestImpl) sipServletMessage;
      final Request request = (Request) sipServletRequest.getMessage();
      final ServerTransaction inviteTransaction =
          ((ServerTransactionExt) sipServletRequest.getTransaction())
              .getCanceledInviteTransaction();

      if (inviteTransaction == null) {
        if (logger.isDebugEnabled()) {
          logger.debug(
              "couldn't find the original invite transaction for this cancel "
                  + request
                  + ", it may be a retransmission and the transaction has already been terminated");
        }
        return;
      }
      final TransactionApplicationData inviteAppData =
          (TransactionApplicationData) inviteTransaction.getApplicationData();
      if (inviteAppData == null) {
        if (logger.isDebugEnabled()) {
          logger.debug(
              "couldn't find the original transaction app data for this cancel "
                  + request
                  + ", it may be a retransmission and the transaction has already been terminated or is being cleaned up");
        }
        return;
      }
      final SipServletRequestImpl inviteRequest =
          (SipServletRequestImpl) inviteAppData.getSipServletMessage();
      final MobicentsSipSession sipSession = inviteRequest.getSipSession();
      sipServletRequest.setSipSession(sipSession);
      sipSession.setRequestsPending(0);

      if (logger.isDebugEnabled()) {
        logger.debug(
            "message associated with the inviteAppData " + "of the CANCEL " + inviteRequest);
      }
      if (logger.isDebugEnabled()) {
        logger.debug(
            "invite transaction associated with the inviteAppData "
                + "of the CANCEL "
                + inviteTransaction);
      }
      if (logger.isDebugEnabled()) {
        logger.debug(
            "app data of the invite transaction associated with the inviteAppData "
                + "of the CANCEL "
                + inviteAppData);
      }
      if (logger.isDebugEnabled()) {
        logger.debug(
            "routing state of the INVITE request for the CANCEL = "
                + inviteRequest.getRoutingState());
      }
      final MobicentsSipApplicationSession sipApplicationSession =
          sipSession.getSipApplicationSession();
      final SipContext sipContext = sipApplicationSession.getSipContext();
      try {
        sipContext.enterSipApp(sipApplicationSession, sipSession);
        final Proxy proxy = sipSession.getProxy();
        if (proxy != null) {
          if (logger.isDebugEnabled()) {
            logger.debug("proxying the CANCEL " + sipServletRequest);
          }
          // Routing State : PROXY case
          if (!RoutingState.PROXIED.equals(inviteRequest.getRoutingState())) {
            // 10.2.6 if the original request has not been proxied yet the container
            // responds to it with a 487 final response
            try {
              send487Response(inviteTransaction, inviteRequest);
            } catch (IllegalStateException iae) {
              logger.info("request already proxied, dropping the cancel");
              return;
            }
          } else {
            // otherwise, all branches are cancelled, and response processing continues as usual
            proxy.cancel();
          }
          // Fix for Issue 796 : SIP servlet (simple proxy) does not receive "Cancel" requests.
          // (http://code.google.com/p/mobicents/issues/detail?id=796)
          // JSR 289 Section 10.2.6 Receiving CANCEL : In either case, the application is
          // subsequently invoked with the CANCEL request
          try {
            callServlet(sipServletRequest);
          } catch (ServletException e) {
            throw new DispatcherException(
                Response.SERVER_INTERNAL_ERROR,
                "An unexpected servlet exception occured while routing the following CANCEL "
                    + request,
                e);
          } catch (IOException e) {
            throw new DispatcherException(
                Response.SERVER_INTERNAL_ERROR,
                "An unexpected IO exception occured while routing the following CANCEL " + request,
                e);
          } catch (Throwable e) {
            throw new DispatcherException(
                Response.SERVER_INTERNAL_ERROR,
                "An unexpected exception occured while routing the following CANCEL " + request,
                e);
          }
        } else if (RoutingState.FINAL_RESPONSE_SENT.equals(inviteRequest.getRoutingState())) {
          if (logger.isDebugEnabled()) {
            logger.debug("the final response has already been sent, nothing to do here");
          }
        } else {

          if (logger.isDebugEnabled()) {
            logger.debug("invite transaction of the CANCEL " + inviteTransaction);
          }
          if (logger.isDebugEnabled()) {
            logger.debug(
                "invite message : 1xx response was generated ? "
                    + ((SipServletRequestImpl) inviteAppData.getSipServletMessage())
                        .is1xxResponseGenerated());
          }
          if (logger.isDebugEnabled()) {
            logger.debug(
                "invite message : Final response was generated ? "
                    + ((SipServletRequestImpl) inviteAppData.getSipServletMessage())
                        .isFinalResponseGenerated());
          }

          if (logger.isDebugEnabled()) {
            logger.debug("replying 487 to INVITE cancelled");
          }
          // otherwise it means that this is for the app
          try {
            send487Response(inviteTransaction, inviteRequest);
          } catch (IllegalStateException iae) {
            logger.info("request already proxied, dropping the cancel");
            return;
          }
          try {
            callServlet(sipServletRequest);
          } catch (ServletException e) {
            throw new DispatcherException(
                Response.SERVER_INTERNAL_ERROR,
                "An unexpected servlet exception occured while routing the following CANCEL "
                    + request,
                e);
          } catch (IOException e) {
            throw new DispatcherException(
                Response.SERVER_INTERNAL_ERROR,
                "An unexpected IO exception occured while routing the following CANCEL " + request,
                e);
          } catch (Throwable e) {
            throw new DispatcherException(
                Response.SERVER_INTERNAL_ERROR,
                "An unexpected exception occured while routing the following CANCEL " + request,
                e);
          }
        }
      } finally {
        sipContext.exitSipApp(sipApplicationSession, sipSession);
      }
    }