/**
   * Put the JAIN-SIP stack in a state where it cannot receive any data and frees the network ports
   * used. That is to say remove JAIN-SIP <tt>ListeningPoint</tt>s and <tt>SipProvider</tt>s.
   */
  @SuppressWarnings("unchecked") // jain-sip legacy code
  private void stopListening() {
    try {
      this.secureJainSipProvider.removeSipListener(this);
      this.stack.deleteSipProvider(this.secureJainSipProvider);
      this.secureJainSipProvider = null;
      this.clearJainSipProvider.removeSipListener(this);
      this.stack.deleteSipProvider(this.clearJainSipProvider);
      this.clearJainSipProvider = null;

      Iterator<ListeningPoint> it = this.stack.getListeningPoints();
      Vector<ListeningPoint> lpointsToRemove = new Vector<ListeningPoint>();
      while (it.hasNext()) {
        lpointsToRemove.add(it.next());
      }

      it = lpointsToRemove.iterator();
      while (it.hasNext()) {
        this.stack.deleteListeningPoint(it.next());
      }

      this.stack.stop();
      if (logger.isTraceEnabled()) logger.trace("stopped listening");
    } catch (ObjectInUseException ex) {
      logger.fatal("Failed to stop listening", ex);
    }
  }
  /**
   * Initialize -- load password files etc. Password file format is name:authentication
   * domain:password
   *
   * @param pwFileName is the password file name.
   * @param Exception is thrown when the password file is bad.
   */
  public void initialize(String pwFileName) {
    try {
      XMLAuthenticationParser parser = new XMLAuthenticationParser(pwFileName);

      String def = parser.getRealm();
      if (def != null) DEFAULT_REALM = def;
      ProxyDebug.println(
          "DEBUG, DigestAuthenticationMethod, initialize()," + " the realm is:" + DEFAULT_REALM);
      Vector usersTagList = parser.getUsersTagList();
      if (usersTagList != null)
        for (int i = 0; i < usersTagList.size(); i++) {
          UserTag userTag = (UserTag) usersTagList.elementAt(i);
          String userName = userTag.getUserName();
          // String userRealm=userTag.getUserRealm();
          String userPassword = userTag.getUserPassword();
          if (userName != null) {

            if (userPassword == null) {
              ProxyDebug.println(
                  "DEBUG, DigestAuthenticationMethod, initialize(),"
                      + " the userPassword parameter does not exist for user: "******", we use the default: \""
                      + NULL_PASSWORD
                      + "\"");
              userPassword = NULL_PASSWORD;
            }
            passwordTable.put(userName + "@" + DEFAULT_REALM, userPassword);
          } else {
            ProxyDebug.println(
                "DEBUG, DigestAuthenticationMethod, initialize(),"
                    + " the userName parameter does not exist, we skip this entry!!");
          }
        }
      else
        ProxyDebug.println(
            "DEBUG, DigestAuthenticationMethod, initialize(),"
                + "Error during parsing the passwords file!");

    } catch (Exception e) {
      ProxyDebug.println("ERROR, DigestAuthenticationMethod, initialize()," + "exception raised:");
      e.printStackTrace();
    }
  }
  public void sendSubscribeToAllPresentities(Vector buddies, boolean EXPIRED) {
    try {
      logger.debug(
          "logger, IMSubscribeProcessing, sendSubscribeToAllPresentities(),"
              + " we have to subscribe to our buddies: let's send a SUBSCRIBE for each ones.");
      for (int i = 0; i < buddies.size(); i++) {
        BuddyTag buddyTag = (BuddyTag) buddies.elementAt(i);

        String buddyURI = buddyTag.getURI();

        InstantMessagingGUI imGUI = imUA.getInstantMessagingGUI();
        ListenerInstantMessaging listenerIM = imGUI.getListenerInstantMessaging();
        String localURL = listenerIM.getLocalSipURL();
        sendSubscribe(localURL, buddyURI, EXPIRED);
      }
    } catch (Exception ex) {
      ex.printStackTrace();
    }
  }
  public void sendSubscribe(String localURL, String buddyURI, boolean EXPIRED) {
    try {
      logger.debug("Sending SUBSCRIBE in progress to the buddy: " + buddyURI);
      int proxyPort = imUA.getProxyPort();
      String proxyAddress = imUA.getProxyAddress();
      String imProtocol = imUA.getIMProtocol();
      SipStack sipStack = imUA.getSipStack();
      SipProvider sipProvider = imUA.getSipProvider();
      MessageFactory messageFactory = imUA.getMessageFactory();
      HeaderFactory headerFactory = imUA.getHeaderFactory();
      AddressFactory addressFactory = imUA.getAddressFactory();

      // Request-URI:
      // URI requestURI=addressFactory.createURI(buddyURI);
      SipURI requestURI = addressFactory.createSipURI(null, proxyAddress);
      requestURI.setPort(proxyPort);
      requestURI.setTransportParam(imProtocol);

      // 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(), imProtocol, branchId);
      Vector viaList = new Vector();
      viaList.addElement(viaHeader);

      PresenceManager presenceManager = imUA.getPresenceManager();
      Presentity presentity = presenceManager.getPresentity(buddyURI);
      Dialog dialog = null;
      if (presentity != null) dialog = presentity.getDialog();

      if (dialog != null) {

        // We have to remove the subscriber and the Presentity related
        // with this Buddy...
        presenceManager.removePresentity(buddyURI);
        Subscriber subscriber = presenceManager.getSubscriber(buddyURI);
        if (subscriber == null) {
          // It means that the guy does not have us in his buddy list
          // nothing to do!!!
        } else {
          presenceManager.removeSubscriber(buddyURI);
        }

        Address localAddress = dialog.getLocalParty();
        Address remoteAddress = dialog.getRemoteParty();

        fromHeader = headerFactory.createFromHeader(localAddress, dialog.getLocalTag());
        toHeader = headerFactory.createToHeader(remoteAddress, dialog.getRemoteTag());

        long cseq = dialog.getLocalSeqNumber();
        cseqHeader = headerFactory.createCSeqHeader(cseq, "MESSAGE");

        callIdHeader = dialog.getCallId();
      } else {
        String localTag = Utils.generateTag();

        Address toAddress = addressFactory.createAddress(buddyURI);
        Address fromAddress = addressFactory.createAddress(localURL);

        fromHeader = headerFactory.createFromHeader(fromAddress, localTag);
        toHeader = headerFactory.createToHeader(toAddress, null);

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

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

      // MaxForwards header:
      MaxForwardsHeader maxForwardsHeader = headerFactory.createMaxForwardsHeader(70);

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

      RouteHeader rh = this.imUA.getRouteToProxy();
      request.setHeader(rh);

      // 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);

      ExpiresHeader expiresHeader = null;
      if (EXPIRED) {
        expiresHeader = headerFactory.createExpiresHeader(0);
      } else {
        expiresHeader = headerFactory.createExpiresHeader(presenceManager.getExpiresTime());
      }
      request.setHeader(expiresHeader);

      // WE have to add a new Header: "Event"
      Header eventHeader = headerFactory.createHeader("Event", "presence");
      request.setHeader(eventHeader);

      // Add Acceptw Header
      Header acceptHeader = headerFactory.createHeader("Accept", "application/pidf+xml");
      request.setHeader(acceptHeader);

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

      ClientTransaction clientTransaction = sipProvider.getNewClientTransaction(request);

      if (dialog != null) {
        dialog.sendRequest(clientTransaction);
      } else {
        clientTransaction.sendRequest();
      }

      logger.debug("IMSubscribeProcessing, sendSubscribe(), SUBSCRIBE sent:\n" + request);
    } catch (Exception ex) {
      ex.printStackTrace();
    }
  }
  public void sendPublish(String localURI, String status) {
    try {
      logger.debug("Sending PUBLISH in progress");
      int proxyPort = imUA.getProxyPort();
      String proxyAddress = imUA.getProxyAddress();
      String imProtocol = imUA.getIMProtocol();
      SipStack sipStack = imUA.getSipStack();
      SipProvider sipProvider = imUA.getSipProvider();
      MessageFactory messageFactory = imUA.getMessageFactory();
      HeaderFactory headerFactory = imUA.getHeaderFactory();
      AddressFactory addressFactory = imUA.getAddressFactory();

      // Request-URI:
      if (localURI.startsWith("sip:")) localURI = localURI.substring(4, localURI.length());
      SipURI requestURI = addressFactory.createSipURI(null, localURI);
      requestURI.setPort(proxyPort);
      requestURI.setTransportParam(imProtocol);

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

      // To header:
      System.out.println("XXX localURI=" + localURI);
      Address localAddress = addressFactory.createAddress("sip:" + localURI);
      ToHeader toHeader = headerFactory.createToHeader(localAddress, null);

      // From header:
      String localTag = Utils.generateTag();
      FromHeader fromHeader = headerFactory.createFromHeader(localAddress, localTag);

      // Call-ID:
      CallIdHeader callIdHeader = headerFactory.createCallIdHeader(callIdCounter + localURI);

      // CSeq:
      CSeqHeader cseqHeader = headerFactory.createCSeqHeader(1L, "PUBLISH");

      // MaxForwards header:
      MaxForwardsHeader maxForwardsHeader = headerFactory.createMaxForwardsHeader(70);

      // Create Request
      Request request =
          messageFactory.createRequest(
              requestURI,
              "PUBLISH",
              callIdHeader,
              cseqHeader,
              fromHeader,
              toHeader,
              viaList,
              maxForwardsHeader);

      // Expires header: (none, let server chose)

      // Event header:
      Header header = headerFactory.createHeader("Event", "presence");
      request.setHeader(header);

      RouteHeader routeHeader = this.imUA.getRouteToProxy();

      request.setHeader(routeHeader);

      // Content and Content-Type header:
      String basic;
      if (status.equals("offline")) basic = "closed";
      else basic = "open";

      String content =
          "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
              + "<presence xmlns=\"urn:ietf:params:xml:ns:pidf\""
              + " entity=\""
              + localURI
              + "\">\n"
              + " <tuple id=\""
              + entity
              + "\">\n"
              + "  <status>\n"
              + "   <basic>"
              + basic
              + "</basic>\n"
              + "  </status>\n"
              + "  <note>"
              + status
              + "</note>\n"
              + " </tuple>\n"
              + "</presence>";

      ContentTypeHeader contentTypeHeader =
          headerFactory.createContentTypeHeader("application", "pidf+xml");
      request.setContent(content, contentTypeHeader);

      // Content-Length header:
      ContentLengthHeader contentLengthHeader =
          headerFactory.createContentLengthHeader(content.length());
      request.setContentLength(contentLengthHeader);

      // Send request
      ClientTransaction clientTransaction = sipProvider.getNewClientTransaction(request);
      clientTransaction.sendRequest();

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