public void sendBye(String localSipURL, String remoteSipURL, ChatSession chatSession) {
    // Send a Bye only if there were exchanged messages!!!
    if (chatSession.isEstablishedSession()) {
      try {
        logger.debug("Sending a BYE in progress to " + remoteSipURL);

        SipProvider sipProvider = imUA.getSipProvider();

        javax.sip.Dialog dialog = chatSession.getDialog();

        Request request = dialog.createRequest(Request.BYE);

        // ProxyAuthorization header if not null:
        ProxyAuthorizationHeader proxyAuthHeader = imUA.getProxyAuthorizationHeader();
        if (proxyAuthHeader != null) request.setHeader(proxyAuthHeader);

        ClientTransaction clientTransaction = sipProvider.getNewClientTransaction(request);

        dialog.sendRequest(clientTransaction);
        logger.debug("BYE sent:\n" + request);

      } catch (Exception ex) {
        ex.printStackTrace();
      }
    } else {
      logger.debug("BYE not sent because of no exchanged messages!!!");
    }
  }
  public void sendMessage(
      String localSipURL, String remoteSipURL, String text, ChatSession chatSession) {
    try {
      DebugIM.println("IMMessageProcessing, ChatSession:" + chatSession);
      DebugIM.println("Sending a MESSAGE in progress to " + remoteSipURL);

      SipProvider sipProvider = imUA.getSipProvider();
      MessageFactory messageFactory = imUA.getMessageFactory();
      HeaderFactory headerFactory = imUA.getHeaderFactory();
      AddressFactory addressFactory = imUA.getAddressFactory();

      String proxyAddress = imUA.getProxyAddress();
      SipURI requestURI = null;
      if (proxyAddress != null) {
        requestURI = addressFactory.createSipURI(null, proxyAddress);
        requestURI.setPort(imUA.getProxyPort());
        requestURI.setTransportParam(imUA.getIMProtocol());
      } else {
        requestURI = (SipURI) addressFactory.createURI(remoteSipURL);
        requestURI.setTransportParam(imUA.getIMProtocol());
      }

      // Call-Id:
      CallIdHeader callIdHeader = null;

      // CSeq:
      CSeqHeader cseqHeader = null;

      // To header:
      ToHeader toHeader = null;

      // From Header:
      FromHeader fromHeader = null;

      //  Via header
      String branchId = Utils.generateBranchId();
      ViaHeader viaHeader =
          headerFactory.createViaHeader(
              imUA.getIMAddress(), imUA.getIMPort(), imUA.getIMProtocol(), branchId);
      Vector viaList = new Vector();
      viaList.addElement(viaHeader);

      // MaxForwards header:
      MaxForwardsHeader maxForwardsHeader = headerFactory.createMaxForwardsHeader(70);
      Dialog dialog = chatSession.getDialog();
      if (chatSession.isEstablishedSession()) {
        DebugIM.println(
            "DEBUG, IMMessageProcessing, sendMessage(), we get"
                + " the DIALOG from the ChatSession");

        Address localAddress = dialog.getLocalParty();
        Address remoteAddress = dialog.getRemoteParty();
        //  if (dialog.isServer()) {
        // We received the first MESSAGE
        fromHeader = headerFactory.createFromHeader(localAddress, dialog.getLocalTag());
        toHeader = headerFactory.createToHeader(remoteAddress, dialog.getRemoteTag());
        //  }
        //  else {

        //   }
        int cseq = dialog.getLocalSequenceNumber();
        DebugIM.println("the cseq number got from the dialog:" + cseq);
        cseqHeader = headerFactory.createCSeqHeader(cseq, "MESSAGE");

        callIdHeader = dialog.getCallId();

      } else {
        DebugIM.println(
            "DEBUG, IMMessageProcessing, sendMessage(), the "
                + " session has not been established yet! We create the first message");

        // To header:
        Address toAddress = addressFactory.createAddress(remoteSipURL);

        // From Header:
        Address fromAddress = addressFactory.createAddress(localSipURL);

        // We have to initiate the dialog: means to create the From tag
        String localTag = Utils.generateTag();
        fromHeader = headerFactory.createFromHeader(fromAddress, localTag);
        toHeader = headerFactory.createToHeader(toAddress, null);

        // CSeq:
        cseqHeader = headerFactory.createCSeqHeader(1, "MESSAGE");

        // Call-ID:
        callIdCounter++;
        callIdHeader =
            (CallIdHeader)
                headerFactory.createCallIdHeader("nist-sip-im-message-callId" + callIdCounter);
      }

      // Content-Type:
      ContentTypeHeader contentTypeHeader = headerFactory.createContentTypeHeader("text", "plain");
      contentTypeHeader.setParameter("charset", "UTF-8");

      Request request =
          messageFactory.createRequest(
              requestURI,
              "MESSAGE",
              callIdHeader,
              cseqHeader,
              fromHeader,
              toHeader,
              viaList,
              maxForwardsHeader,
              contentTypeHeader,
              text);

      // 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);
      request.setHeader(contactHeader);

      // ProxyAuthorization header if not null:
      ProxyAuthorizationHeader proxyAuthHeader = imUA.getProxyAuthorizationHeader();
      if (proxyAuthHeader != null) request.setHeader(proxyAuthHeader);

      ClientTransaction clientTransaction = sipProvider.getNewClientTransaction(request);

      if (chatSession.isEstablishedSession()) {
        dialog.sendRequest(clientTransaction);
        DebugIM.println(
            "IMessageProcessing, sendMessage(), MESSAGE sent" + " using the dialog:\n" + request);
      } else {
        clientTransaction.sendRequest();
        DebugIM.println(
            "IMessageProcessing, sendMessage(), MESSAGE sent"
                + " using a new client transaction:\n"
                + request);
      }

    } catch (Exception ex) {
      ex.printStackTrace();
    }
  }