public void processMessage(Request request, ServerTransaction serverTransaction) {
    try {
      SipProvider sipProvider = imUA.getSipProvider();
      MessageFactory messageFactory = imUA.getMessageFactory();
      HeaderFactory headerFactory = imUA.getHeaderFactory();
      AddressFactory addressFactory = imUA.getAddressFactory();

      InstantMessagingGUI instantMessagingGUI = imUA.getInstantMessagingGUI();
      ListenerInstantMessaging listenerInstantMessaging =
          instantMessagingGUI.getListenerInstantMessaging();
      ChatSessionManager chatSessionManager = listenerInstantMessaging.getChatSessionManager();
      ChatSession chatSession = null;
      String fromURL = IMUtilities.getKey(request, "From");
      if (chatSessionManager.hasAlreadyChatSession(fromURL))
        chatSession = chatSessionManager.getChatSession(fromURL);
      else chatSession = chatSessionManager.createChatSession(fromURL);

      DebugIM.println("IMMessageProcessing, processMEssage(), ChatSession:" + chatSession);
      DebugIM.println("Processing MESSAGE in progress...");

      // Send an OK
      Response response = messageFactory.createResponse(Response.OK, request);
      // Contact header:
      SipURI sipURI = addressFactory.createSipURI(null, imUA.getIMAddress());
      sipURI.setPort(imUA.getIMPort());
      sipURI.setTransportParam(imUA.getIMProtocol());
      Address contactAddress = addressFactory.createAddress(sipURI);
      ContactHeader contactHeader = headerFactory.createContactHeader(contactAddress);
      response.setHeader(contactHeader);
      ToHeader toHeader = (ToHeader) response.getHeader(ToHeader.NAME);
      if (toHeader.getTag() == null) {
        // It is the first message without a TO tag
        toHeader.setTag(new Integer((int) (Math.random() * 10000)).toString());
      }

      if (chatSession.isEstablishedSession()) {
        DebugIM.println("The Session already exists");
        serverTransaction.sendResponse(response);
        DebugIM.println("OK replied to the MESSAGE:\n" + response.toString());
      } else {
        DebugIM.println("The Session does not exists yet. ");
        serverTransaction.sendResponse(response);
        DebugIM.println("OK replied to the MESSAGE:\n" + response.toString());

        Dialog dialog = serverTransaction.getDialog();
        if (dialog == null) {
          DebugIM.println("ERROR, IMProcessing, processMessage(), the dialog is null");
          return;
        }
        // We need to store the dialog:
        chatSession.setDialog(dialog);
        chatSession.setEstablishedSession(true);
        DebugIM.println("The DIALOG object has been stored in the ChatSession");
      }

      Object content = request.getContent();
      String text = null;
      if (content instanceof String) text = (String) content;
      else if (content instanceof byte[]) {
        text = new String((byte[]) content);
      } else {
      }
      if (text != null) {
        chatSession.displayRemoteText(text);
      }
    } catch (Exception ex) {
      ex.printStackTrace();
    }
  }
  /**
   * Implements {@link MethodProcessor#processRequest(RequestEvent)}. Handles only NOTIFY requests
   * because they are the only requests concerning event package subscribers and if the processing
   * of a given request requires event package-specific handling, delivers the request to the
   * matching Subscription instance. Examples of such event package-specific handling include
   * handling the termination of an existing Subscription and processing the bodies of the NOTIFY
   * requests for active Subscriptions.
   *
   * @param requestEvent a <tt>RequestEvent</tt> specifying the SIP <tt>Request</tt> to be processed
   * @return <tt>true</tt> if the SIP <tt>Request</tt> specified by <tt>requestEvent</tt> was
   *     processed; otherwise, <tt>false</tt>
   */
  @Override
  public boolean processRequest(RequestEvent requestEvent) {
    Request request = requestEvent.getRequest();

    EventHeader eventHeader = (EventHeader) request.getHeader(EventHeader.NAME);
    if ((eventHeader == null) || !eventPackage.equalsIgnoreCase(eventHeader.getEventType())) {
      /*
       * We are not concerned by this request, perhaps another listener
       * is. So don't send a 489 / Bad event answer here.
       */
      return false;
    }

    if (!Request.NOTIFY.equals(request.getMethod())) return false;

    if (logger.isDebugEnabled()) logger.debug("notify received");

    SubscriptionStateHeader sstateHeader =
        (SubscriptionStateHeader) request.getHeader(SubscriptionStateHeader.NAME);
    // notify must contain one (rfc3265)
    if (sstateHeader == null) {
      logger.error("no subscription state in this request");
      return false;
    }
    String sstate = sstateHeader.getState();

    ServerTransaction serverTransaction = getOrCreateServerTransaction(requestEvent);

    // first handle the case of a contact still pending
    // it's possible if the NOTIFY arrives before the OK
    CallIdHeader callIdHeader = (CallIdHeader) request.getHeader(CallIdHeader.NAME);
    String callId = callIdHeader.getCallId();
    Subscription subscription = getSubscription(callId);

    // see if the notify correspond to an existing subscription
    if ((subscription == null) && !SubscriptionStateHeader.TERMINATED.equalsIgnoreCase(sstate)) {
      if (logger.isDebugEnabled()) logger.debug("subscription not found for callId " + callId);

      // send a 481 response (rfc3625)
      Response response;
      try {
        response =
            protocolProvider
                .getMessageFactory()
                .createResponse(Response.CALL_OR_TRANSACTION_DOES_NOT_EXIST, request);
      } catch (ParseException e) {
        logger.error("failed to create the 481 response", e);
        return false;
      }

      try {
        serverTransaction.sendResponse(response);
      } catch (SipException e) {
        logger.error("failed to send the response", e);
      } catch (InvalidArgumentException e) {
        // should not happen
        logger.error("invalid argument provided while trying to send the response", e);
      }
      return true;
    }

    // if we don't understand the content
    ContentTypeHeader ctheader = (ContentTypeHeader) request.getHeader(ContentTypeHeader.NAME);
    if ((ctheader != null) && !ctheader.getContentSubType().equalsIgnoreCase(contentSubType)) {
      // send a 415 response (rfc3261)
      Response response;
      try {
        response =
            protocolProvider
                .getMessageFactory()
                .createResponse(Response.UNSUPPORTED_MEDIA_TYPE, request);
      } catch (ParseException e) {
        logger.error("failed to create the OK response", e);
        return false;
      }

      // we want PIDF
      AcceptHeader acceptHeader;
      try {
        acceptHeader =
            protocolProvider.getHeaderFactory().createAcceptHeader("application", contentSubType);
      } catch (ParseException e) {
        // should not happen
        logger.error("failed to create the accept header", e);
        return false;
      }
      response.setHeader(acceptHeader);

      try {
        serverTransaction.sendResponse(response);
      } catch (SipException e) {
        logger.error("failed to send the response", e);
      } catch (InvalidArgumentException e) {
        // should not happen
        logger.error("invalid argument provided while trying" + " to send the response", e);
      }
    }

    // if the presentity doesn't want of us anymore
    if (SubscriptionStateHeader.TERMINATED.equalsIgnoreCase(sstate)) {
      // if we requested this end of subscription, subscription == null
      if (subscription != null) {
        removeSubscription(callId, subscription);
        subscription.processTerminatedRequest(requestEvent, sstateHeader.getReasonCode());
      }
    }

    // send an OK response
    Response response;
    try {
      response = protocolProvider.getMessageFactory().createResponse(Response.OK, request);
    } catch (ParseException e) {
      logger.error("failed to create the OK response", e);
      return false;
    }

    try {
      serverTransaction.sendResponse(response);
    } catch (SipException e) {
      logger.error("failed to send the response", e);
    } catch (InvalidArgumentException e) {
      // should not happen
      logger.error("invalid argument provided while trying to send the response", e);
    }

    // transform the presence document in new presence status
    if (subscription != null)
      subscription.processActiveRequest(requestEvent, request.getRawContent());

    return true;
  }