boolean sendStartupMessage(Set recipients, Set<InetAddress> interfaces,
      String redundancyZone,
      boolean enforceUniqueZone)
      throws InterruptedException, ReplyException, IOException {
    if (Thread.interrupted()) {
      throw new InterruptedException();
    }
    StartupMessageReplyProcessor proc = new StartupMessageReplyProcessor(dm, recipients);
    boolean isSharedConfigurationEnabled = false;
    if (InternalLocator.hasLocator()) {
      isSharedConfigurationEnabled = InternalLocator.getLocator().isSharedConfigurationEnabled();
    }
    StartupMessage msg =
        new StartupMessage(InternalLocator.getLocatorStrings(), isSharedConfigurationEnabled);

    msg.setInterfaces(interfaces);
    msg.setDistributedSystemId(dm.getConfig().getDistributedSystemId());
    msg.setRedundancyZone(redundancyZone);
    msg.setEnforceUniqueZone(enforceUniqueZone);
    msg.setMcastEnabled(transport.isMcastEnabled());
    msg.setMcastPort(dm.getSystem().getOriginalConfig().getMcastPort());
    msg.setMcastHostAddress(dm.getSystem().getOriginalConfig().getMcastAddress());
    msg.setTcpDisabled(transport.isTcpDisabled());
    msg.setRecipients(recipients);
    msg.setReplyProcessorId(proc.getProcessorId());

    newlyDeparted = dm.sendOutgoing(msg); // set of departed jgroups ids
    if (newlyDeparted != null && !newlyDeparted.isEmpty()) {
      // tell the reply processor not to wait for the recipients that didn't
      // get the message
      for (final Object o : newlyDeparted) {
        InternalDistributedMember id = (InternalDistributedMember) o;
        dm.handleManagerDeparture(id, false,
            "left the membership view");
        proc.memberDeparted(dm, id, true);
      }
    }

    if (proc.stillWaiting() && logger.isDebugEnabled()) {
      logger.debug("Waiting to receive startup responses");
    }
    proc.waitForReplies();

    boolean problems;
    problems = newlyDeparted != null && newlyDeparted.size() > 0;
    // problems = problems ||
    // (unresponsive != null && unresponsive.size() > 0);
    return !problems;
  }
send the startup message and wait for responses. If timeout is zero, this waits forever for all
responses to come back. This method may throw jgroups and other io exceptions since it
interacts with the distribution manager at a low level to send the startup messages. It does
this to ensure it knows which recipients didn't receive the message.

@return whether all recipients could be contacted. The failure set can be fetched with
        getFailureSet??
geode-core/src/main/java/org/apache/geode/distributed/internal/StartupOperation.java