docs: public synchronized void register() throws IOException {
          boolean connected = false;
          List<DiscoveryOption> discoveryOptions = localHostInfo.getRemoteDomainControllerDiscoveryOptions();
          // Loop through discovery options
          for (Iterator<DiscoveryOption> i = discoveryOptions.iterator(); i.hasNext(); ) {
             DiscoveryOption discoveryOption = i.next();
             final long timeout = CONNECTION_TIMEOUT;
             final long endTime = System.currentTimeMillis() + timeout;
             int retries = 0;
             URI masterURI = null;
             try {
                 // Determine the remote DC host and port to use
                 List<RemoteDomainControllerConnectionConfiguration> remoteDcConfigs = discoveryOption.discover();
                 while (!connected) {
                     IOException ex = null;
                     for (RemoteDomainControllerConnectionConfiguration remoteDcConfig : remoteDcConfigs) {
                         try {
                             masterURI = new URI(remoteDcConfig.getProtocol(), null, remoteDcConfig.getHost(), remoteDcConfig.getPort(), null, null, null);
                             connection.setUri(masterURI);
                             connection.connect();
                             connected = true;
                             break;
                         } catch (IOException e) {
                             // If the cause is one of the irrecoverable ones, unwrap and throw it on
                             rethrowIrrecoverableConnectionFailures(e);
  
                             HostControllerLogger.ROOT_LOGGER.cannotConnect(masterURI, e);
                             // if we're using isCachedDC, just try once then allow the poll to run in the background.
                             // this will allow us to start up without having to wait for retries to be exhausted.
                             if (hostControllerEnvironment.isUseCachedDc()) {
                                 throw e;
                             }
                             // Something else; we can retry if time remains
                             ex = e;
                         }
                     }
                     if (ex != null) {
                         if (System.currentTimeMillis() > endTime) {
                             throw HostControllerLogger.ROOT_LOGGER.connectionToMasterTimeout(ex, retries, timeout);
                         }
  
                         try {
                             ReconnectPolicy.CONNECT.wait(retries);
                             retries++;
                         } catch (InterruptedException ie) {
                             Thread.currentThread().interrupt();
                             throw HostControllerLogger.ROOT_LOGGER.connectionToMasterInterrupted();
                         }
                     }
                 }
  
                 HostControllerLogger.ROOT_LOGGER.connectedToMaster(masterURI);
                 setupHandler();
                 break;
  
             } catch (Exception e) {
                 boolean moreOptions = i.hasNext();
                 logConnectionException(masterURI, discoveryOption, moreOptions, e);
                 if (!moreOptions) {
                     throw HostControllerLogger.ROOT_LOGGER.discoveryOptionsFailureUnableToConnect(e);
                 }
             }
          }
      }