/**
   * Pings initial members. Removes self before returning vector of initial members. Uses IP
   * multicast or gossiping, depending on parameters.
   */
  void findInitialMembers() {
    PingRsp ping_rsp;

    synchronized (initial_mbrs) {
      findInitialMbrsAttempts++; // GemStoneAddition

      initial_mbrs.removeAllElements();
      initial_mbrs_received = false;
      gms.passDown(new Event(Event.FIND_INITIAL_MBRS));

      // the initial_mbrs_received flag is needed when passDown() is executed on the same thread, so
      // when
      // it returns, a response might actually have been received (even though the initial_mbrs
      // might still be empty)
      while /*GemStoneAddition*/ (initial_mbrs_received == false) {
        try {
          initial_mbrs
              .wait(); // gms.join_timeout+1000); // GemStoneAddition bug #34274 - don't wait
                       // forever
        } catch (InterruptedException e) { // GemStoneAddition
          Thread.currentThread().interrupt();
          initial_mbrs_received = true; // suppress any late updates
          // process whatever he have now.  Note that since we are
          // stilled synchronized on initial_mbrs, asynchronous updates
          // won't come in before we return a result.
        }
      }

      for (int i = 0; i < initial_mbrs.size(); i++) {
        ping_rsp = (PingRsp) initial_mbrs.elementAt(i);
        if (ping_rsp.own_addr != null
            && gms.local_addr != null
            && ping_rsp.own_addr.equals(gms.local_addr)) {
          initial_mbrs.removeElementAt(i);
          break;
        }
      }
      if (findInitialMbrsAttempts > 2) {
        // GemStoneAddition: bug #50785 - if we have made some rounds using
        // best-guess coordinator candidates from other processes that have
        // yet to join the group then we stop trusting this gossip
        // because it can just ping-pong around between members that are
        // still trying to join.  See PingWaiter.getPossibleCoordinator().
        List<PingRsp> removals = new ArrayList<PingRsp>(initial_mbrs.size());
        for (int i = 0; i < initial_mbrs.size(); i++) {
          ping_rsp = (PingRsp) initial_mbrs.elementAt(i);
          if (ping_rsp.own_addr != null
              && !ping_rsp.isServer()
              && !ping_rsp.getCoordAddress().equals(ping_rsp.own_addr)) {
            removals.add(ping_rsp);
          }
        }
        initial_mbrs.removeAll(removals);
      }
    }
  }