/**
  * Called by join(). Installs the view returned by calling Coord.handleJoin() and becomes
  * coordinator.
  */
 private boolean installView(View new_view) {
   Vector mems = new_view.getMembers();
   if (log.isDebugEnabled()) log.debug("new_view=" + new_view);
   if (gms.local_addr == null || mems == null || !mems.contains(gms.local_addr)) {
     if (log.isErrorEnabled())
       log.error(
           "I (" + gms.local_addr + ") am not member of " + mems + ", will not install view");
     return false;
   }
   gms.installView(new_view);
   gms.becomeParticipant();
   gms.passUp(new Event(Event.BECOME_SERVER));
   gms.passDown(new Event(Event.BECOME_SERVER));
   return true;
 }
  /**
   * GemStoneAddition - new protocol to allow a member to assume the role of coordinator in a system
   * that has lost all eligible coordinators
   *
   * @param mbr the address of this stack
   * @param failedCoordinator (optional) the address of the coordinator that held the view
   * @return true if able to become coordinator, false if not
   */
  boolean becomeGroupCoordinator(Address mbr, Address failedCoordinator) {
    int sentRequests = 0;
    Digest initial_digest;
    ViewId view_id;
    Vector mbrs;
    Vector imbrs;
    synchronized (initial_mbrs) {
      imbrs = (Vector) initial_mbrs.clone();
    }

    // get the current view from one of the members and then
    // form a new group
    GMS.GmsHeader hdr = new GMS.GmsHeader(GMS.GmsHeader.GET_VIEW);
    for (int i = 0; i < imbrs.size(); i++) {
      PingRsp rsp = (PingRsp) imbrs.get(i);
      Message getView = new Message();
      getView.setDest(rsp.getAddress());
      getView.putHeader(GMS.name, hdr);
      gms.passDown(new Event(Event.MSG, getView));
    }

    // wait up to ack-collection-time for responses
    sentRequests = imbrs.size();
    long endTime = System.currentTimeMillis() + gms.view_ack_collection_timeout;
    while (true) {
      synchronized (this.getViewLock) {
        long timeLeft = endTime - System.currentTimeMillis();
        if (this.getViewResponses >= sentRequests || timeLeft <= 0) {
          break;
        }
        try {
          this.getViewLock.wait(timeLeft);
        } catch (InterruptedException ie) {
          Thread.currentThread().interrupt();
          throw gms.stack.gfBasicFunctions.getSystemConnectException(
              ExternalStrings.ClientGmsImpl_INTERRUPTED_WHILE_BECOMING_COORDINATOR_OF_EXISTING_GROUP
                  .toLocalizedString());
        }
      }
    }

    if (this.getViewResponse == null) {
      throw gms.stack.gfBasicFunctions.getSystemConnectException(
          ExternalStrings
              .ClientGmsImpl_UNABLE_TO_BECOME_COORDINATOR_OF_EXISTING_GROUP_BECAUSE_NO_VIEW_RESPONSES_WERE_RECEIVED
              .toLocalizedString());
    }

    View theView = this.getViewResponse.getView();

    Address theCreator = theView.getCreator();

    if (theCreator != null && theCreator.preferredForCoordinator()) {
      if (failedCoordinator == null && theView.containsMember(theCreator)) {
        // locator was shut down and restarted.  Other members reported no coordinator
        // but now there is one, so two eligible coordinators are being started
        // simultaneously.  Return false to allow the other one to win
        //          log.getLogWriterI18n().info(JGroupsStrings.ONE_ARG, "DEBUG: failedCoordinator is
        // null and view creator is "
        //            + theCreator);
        return false;
      }

      if (failedCoordinator != null && !theCreator.equals(failedCoordinator)) {
        // the locator or its machine failed and this is a new locator starting
        // up.  Another locator has already installed itself as the coordinator,
        // so return false to let it win
        //          log.getLogWriterI18n().info(JGroupsStrings.ONE_ARG, "DEBUG: failedCoordinator is
        // " + failedCoordinator + " and view creator is "
        //            + theCreator);
        return false;
      }
    }

    mbrs = theView.getMembers();
    mbrs.add(
        mbr); // add myself in  (was .add(0, mbr) prior to 2013 cedar release but this caused elder
              // init problems with colocated secure locators)

    // create the initial digest.  it will be filled in with gossip soon enough
    initial_digest = this.getViewResponse.getDigest();
    initial_digest.add(
        gms.local_addr, 0, 0); // initial seqno mcast by me will be 1 (highest seen +1)
    gms.setDigest(initial_digest);

    view_id =
        new ViewId(
            mbr, theView.getVid().getId() + 1); // create singleton view with mbr as only member
    View new_view = new View(view_id, mbrs);
    gms.installView(new_view);
    gms.becomeCoordinator(null); // not really necessary - installView() should do it

    gms.ucastViewChange(new_view); // tell the world

    gms.passUp(new Event(Event.BECOME_SERVER));
    gms.passDown(new Event(Event.BECOME_SERVER));

    gms.notifyOfCoordinator(gms.local_addr);

    log.getLogWriter()
        .info(ExternalStrings.ClientGmsImpl_RECREATED_DISTRIBUTED_SYSTEM_GROUP_0, gms.view);
    return true;
  }