/**
   * Initializes and binds a socket that on a random port number. The method would try to bind on a
   * random port and retry 5 times until a free port is found.
   *
   * @return the socket that we have initialized on a randomport number.
   */
  private DatagramSocket initRandomPortSocket() {
    DatagramSocket resultSocket = null;
    String bindRetriesStr =
        NetaddrActivator.getConfigurationService().getString(BIND_RETRIES_PROPERTY_NAME);

    int bindRetries = 5;

    if (bindRetriesStr != null) {
      try {
        bindRetries = Integer.parseInt(bindRetriesStr);
      } catch (NumberFormatException ex) {
        logger.error(
            bindRetriesStr
                + " does not appear to be an integer. "
                + "Defaulting port bind retries to "
                + bindRetries,
            ex);
      }
    }

    int currentlyTriedPort = NetworkUtils.getRandomPortNumber();

    // we'll first try to bind to a random port. if this fails we'll try
    // again (bindRetries times in all) until we find a free local port.
    for (int i = 0; i < bindRetries; i++) {
      try {
        resultSocket = new DatagramSocket(currentlyTriedPort);
        // we succeeded - break so that we don't try to bind again
        break;
      } catch (SocketException exc) {
        if (exc.getMessage().indexOf("Address already in use") == -1) {
          logger.fatal(
              "An exception occurred while trying to create" + "a local host discovery socket.",
              exc);
          resultSocket = null;
          return null;
        }
        // port seems to be taken. try another one.
        logger.debug("Port " + currentlyTriedPort + " seems in use.");
        currentlyTriedPort = NetworkUtils.getRandomPortNumber();
        logger.debug("Retrying bind on port " + currentlyTriedPort);
      }
    }

    return resultSocket;
  }
  /**
   * Create a multicast socket and join the multicast group. This method creates a multicast socket
   * that is used to broadcast The <CODE>DiscoveryResponder</CODE> will then join the multicast
   * group and send a join message. This method has no effect if the <CODE>DiscoveryResponder</CODE>
   * is <CODE>ONLINE</CODE> or <CODE>STOPPING</CODE> or <CODE>STARTING</CODE>.
   *
   * @exception IOException The creation of the Multicast socket failed.
   */
  public void start() throws IOException {
    if (state == OFFLINE) {
      changeState(STARTING);
      if (cmf == null) {
        if (logger.finerOn()) {
          logger.finer("start ", "Can't start discoveryResponder: JDMK MBeanServer is not set");
        }
        return;
      }

      // ----------------
      // Create a new obj to receive multicast msg ;
      // ----------------
      try {
        if (logger.finerOn()) {
          logger.finer("start ", "Create a new responder");
        }
        responder =
            new ActualResponder(multicastGroup, multicastPort, getTimeToLive(), cmf, spy, this);

        if (local != null) {
          responder.setLocalHost(local);
        }

        // NPCTE fix for bugId 4499338, esc 0, 04 Sept 2001
        if (usrInet != null) {
          responder.setInterface(usrInet);

          if (logger.finerOn()) {
            logger.finer("start ", "set interface to " + usrInet);
          }
        }
        // end of NPCTE fix for bugId 4499338

        if (noEvent != null) responder.noEvent();

        if (logger.finerOn()) {
          logger.finer("start ", "call responder connect");
        }
        responder.connectToGroup();

        // ----------------
        // Create a new thread to receive multicast msg ;
        // ----------------
        // responderThread = cmf.getThreadAllocatorSrvIf().obtainThread(responderObjectName,
        // responder);
        responderThread = new Thread(responder);
        responderThread.setName("Multicast responder");

        // ----------------
        // Start thread
        // ----------------
        responderThread.start();

        // ----------------
        // Update state
        // ----------------
        // changeState(ONLINE) ;
      } catch (SocketException e) {
        if (logger.finestOn()) {
          logger.finest("start", e);
        }
        throw new IOException(e.getMessage());

      } catch (IOException e) {
        // ------------------------
        // Keep exception for us
        // ------------------------
        if (logger.finestOn()) {
          logger.finest("start ", e);
        }
        throw e;
      } catch (NullPointerException e) {
        // ------------------------
        // the set group did not worked
        // ------------------------
        if (logger.finestOn()) {
          logger.finest("start ", e);
        }
        throw new IOException(e.getMessage());
      }
    } else {
      if (logger.finerOn()) {
        logger.finer("start ", "Responder is not OFFLINE");
      }
    }
  }