/**
  * Load Listeners the given in parameter with the given classloader
  *
  * @param listenerList the list of listeners to load
  * @param classLoader the classloader to load the listeners with
  * @return true if all the listeners have been successfully loaded, false otherwise
  */
 public boolean loadListeners(String[] listeners, ClassLoader classLoader) {
   // Instantiate all the listeners
   for (String className : listeners) {
     try {
       Class listenerClass = Class.forName(className, false, classLoader);
       EventListener listener = (EventListener) listenerClass.newInstance();
       ((SipContext) sipContext).getAnnotationProcessor().processAnnotations(listener);
       SipServletImpl sipServletImpl =
           (SipServletImpl) sipContext.findChildrenByClassName(className);
       if (sipServletImpl != null) {
         listener = (EventListener) sipServletImpl.allocate();
         listenerServlets.put(listener, sipServletImpl);
       } else {
         SipServlet servlet = (SipServlet) listenerClass.getAnnotation(SipServlet.class);
         if (servlet != null) {
           sipServletImpl = (SipServletImpl) sipContext.findChildrenByName(servlet.name());
           if (sipServletImpl != null) {
             listener = (EventListener) sipServletImpl.allocate();
             listenerServlets.put(listener, sipServletImpl);
           }
         }
       }
       addListenerToBunch(listener);
     } catch (Exception e) {
       logger.fatal("Cannot instantiate listener class " + className, e);
       return false;
     }
   }
   return true;
 }
    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);
      }
    }