docs: protected void joinInternal(Address mbr, boolean joinWithStateTransfer, boolean useFlushIfPresent) {
          long  join_attempts=0;
          gms.setLeaving(false);
          join_promise.reset();
  
          while(!gms.isLeaving()) {
              if(installViewIfValidJoinRsp(join_promise, false))
                  return;
  
              long start=System.currentTimeMillis();
              Responses responses=(Responses)gms.getDownProtocol().down(new Event(Event.FIND_INITIAL_MBRS, gms.getJoinTimeout()));
  
              // Sept 2008 (bela): return if we got a belated JoinRsp (https://jira.jboss.org/jira/browse/JGRP-687)
              if(installViewIfValidJoinRsp(join_promise, false))
                  return;
  
              responses.waitFor(gms.join_timeout);
              responses.done();
              long diff=System.currentTimeMillis() - start;
              if(responses.isEmpty()) {
                  log.info("%s: no members discovered after %d ms: creating cluster as first member", gms.local_addr, diff);
                  becomeSingletonMember(mbr);
                  return;
              }
              log.trace("%s: discovery took %d ms, members: %s", gms.local_addr, diff, responses);
  
              List<Address> coords=getCoords(responses);
  
              // We didn't get any coord responses; all responses were clients. If I'm the first of the sorted clients
              // I'll become coordinator. The others will wait and then retry the discovery and join process
              if(coords == null) { // e.g. because we have all clients only
                  if(firstOfAllClients(mbr, responses))
                      return;
              }
              else {
                  if(coords.size() > 1) {
                      log.debug("%s: found multiple coords: %s", gms.local_addr, coords);
                      Collections.shuffle(coords); // so the code below doesn't always pick the same coord
                  }
                  for(Address coord : coords) {
                      log.debug("%s: sending JOIN(%s) to %s", gms.local_addr, mbr, coord);
                      sendJoinMessage(coord, mbr, joinWithStateTransfer, useFlushIfPresent);
                      if(installViewIfValidJoinRsp(join_promise, true))
                          return;
                      log.warn("%s: JOIN(%s) sent to %s timed out (after %d ms), on try %d",
                               gms.local_addr, mbr, coord, gms.join_timeout, join_attempts);
                  }
              }
  
              if(gms.max_join_attempts > 0 && ++join_attempts >= gms.max_join_attempts) {
                  log.warn("%s: too many JOIN attempts (%d): becoming singleton", gms.local_addr, join_attempts);
                  becomeSingletonMember(mbr);
                  return;
              }
          }
      }