@Override
  public void addContent(Request notifyRequest, SubscriptionRequest request)
      throws ParseException, InvalidArgumentException {
    String content = new String(request.getRequest().getRawContent(), StandardCharsets.UTF_8);

    UserPresence presence = presenceService.getPresence(request.getUser());

    if (isEmpty(content)) {
      ContentTypeHeader contentTypeHeader =
          headerFactory.createContentTypeHeader("multipart", "mixed");
      contentTypeHeader.setParameter(MultipartMimeContentImpl.BOUNDARY, SIPR_BOUNDARY);

      notifyRequest.setContent(
          getInitialMultipartContent(contentTypeHeader, presence).toString(), contentTypeHeader);
    } else {
      String eventResponse = getEventResponse(presence, content);
      presenceService.savePresence(presence);

      ContentTypeHeader eventHeader = getAsFeatureEventHeader();
      notifyRequest.setContent(eventResponse, eventHeader);
      sender.sendNotifyToAllSubscribers(request, eventHeader, eventResponse);
    }
  }
  /**
   * Construct a <tt>Request</tt> represent a new message.
   *
   * @param to the <tt>Contact</tt> to send <tt>message</tt> to
   * @param message the <tt>Message</tt> to send.
   * @return a Message Request destined to the contact
   * @throws OperationFailedException if an error occurred during the creation of the request
   */
  Request createMessageRequest(Contact to, Message message) throws OperationFailedException {
    Address toAddress = null;
    try {
      toAddress = sipProvider.parseAddressString(to.getAddress());
    } catch (ParseException exc) {
      // Shouldn't happen
      logger.error("An unexpected error occurred while" + "constructing the address", exc);
      throw new OperationFailedException(
          "An unexpected error occurred while" + "constructing the address",
          OperationFailedException.INTERNAL_ERROR,
          exc);
    }

    // Call ID
    CallIdHeader callIdHeader = this.sipProvider.getDefaultJainSipProvider().getNewCallId();

    // CSeq
    CSeqHeader cSeqHeader = null;

    try {
      // protect seqN
      synchronized (this) {
        cSeqHeader = this.sipProvider.getHeaderFactory().createCSeqHeader(seqN++, Request.MESSAGE);
      }
    } catch (InvalidArgumentException ex) {
      // Shouldn't happen
      logger.error("An unexpected error occurred while" + "constructing the CSeqHeadder", ex);
      throw new OperationFailedException(
          "An unexpected error occurred while" + "constructing the CSeqHeadder",
          OperationFailedException.INTERNAL_ERROR,
          ex);
    } catch (ParseException exc) {
      // shouldn't happen
      logger.error("An unexpected error occurred while" + "constructing the CSeqHeadder", exc);
      throw new OperationFailedException(
          "An unexpected error occurred while" + "constructing the CSeqHeadder",
          OperationFailedException.INTERNAL_ERROR,
          exc);
    }

    // FromHeader and ToHeader
    String localTag = SipMessageFactory.generateLocalTag();
    FromHeader fromHeader = null;
    ToHeader toHeader = null;
    try {
      // FromHeader
      fromHeader =
          this.sipProvider
              .getHeaderFactory()
              .createFromHeader(sipProvider.getOurSipAddress(toAddress), localTag);

      // ToHeader
      toHeader = this.sipProvider.getHeaderFactory().createToHeader(toAddress, null);
    } catch (ParseException ex) {
      // these two should never happen.
      logger.error(
          "An unexpected error occurred while" + "constructing the FromHeader or ToHeader", ex);
      throw new OperationFailedException(
          "An unexpected error occurred while" + "constructing the FromHeader or ToHeader",
          OperationFailedException.INTERNAL_ERROR,
          ex);
    }

    // ViaHeaders
    ArrayList<ViaHeader> viaHeaders = this.sipProvider.getLocalViaHeaders(toAddress);

    // MaxForwards
    MaxForwardsHeader maxForwards = this.sipProvider.getMaxForwardsHeader();

    // Content params
    ContentTypeHeader contTypeHeader;
    ContentLengthHeader contLengthHeader;
    try {
      contTypeHeader =
          this.sipProvider
              .getHeaderFactory()
              .createContentTypeHeader(getType(message), getSubType(message));

      if (!DEFAULT_MIME_ENCODING.equalsIgnoreCase(message.getEncoding()))
        contTypeHeader.setParameter("charset", message.getEncoding());

      contLengthHeader =
          this.sipProvider.getHeaderFactory().createContentLengthHeader(message.getSize());
    } catch (ParseException ex) {
      // these two should never happen.
      logger.error("An unexpected error occurred while" + "constructing the content headers", ex);
      throw new OperationFailedException(
          "An unexpected error occurred while" + "constructing the content headers",
          OperationFailedException.INTERNAL_ERROR,
          ex);
    } catch (InvalidArgumentException exc) {
      // these two should never happen.
      logger.error(
          "An unexpected error occurred while" + "constructing the content length header", exc);
      throw new OperationFailedException(
          "An unexpected error occurred while" + "constructing the content length header",
          OperationFailedException.INTERNAL_ERROR,
          exc);
    }

    Request req;
    try {
      req =
          this.sipProvider
              .getMessageFactory()
              .createRequest(
                  toHeader.getAddress().getURI(),
                  Request.MESSAGE,
                  callIdHeader,
                  cSeqHeader,
                  fromHeader,
                  toHeader,
                  viaHeaders,
                  maxForwards,
                  contTypeHeader,
                  message.getRawData());
    } catch (ParseException ex) {
      // shouldn't happen
      logger.error("Failed to create message Request!", ex);
      throw new OperationFailedException(
          "Failed to create message Request!", OperationFailedException.INTERNAL_ERROR, ex);
    }

    req.addHeader(contLengthHeader);

    return req;
  }
  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();
    }
  }