/**
  * Creates the delegate connection factory.
  *
  * @return The delegate connection factory.
  */
 private synchronized ConnectionFactory createDelegate() {
   if (myDelegate == null) {
     bootstrap();
     if (myDelegate == null) {
       LOG.warn("Could not bootstrap a connection to the MongoDB servers.");
       throw new CannotConnectException(
           "Could not bootstrap a connection to the MongoDB servers.");
     }
   }
   return myDelegate;
 }
  /**
   * Re-bootstraps the environment. Normally this method is only called once during the constructor
   * of the factory to initialize the delegate but users can reset the delegate by manually invoking
   * this method.
   *
   * <p>A bootstrap will issue one commands to the first working MongoDB process. The reply to the
   * {@link IsMaster} command is used to detect connecting to a mongos <tt>process</tt> and by
   * extension a Sharded configuration.
   *
   * <p>If not using a Sharded configuration then the server status is checked for a <tt>repl</tt>
   * element. If present a Replication Set configuration is assumed.
   *
   * <p>If neither a Sharded or Replication Set is being used then a plain socket connection factory
   * is used.
   */
  protected void bootstrap() {
    final SocketConnectionFactory socketFactory = createSocketFactory(myConfig);
    socketFactory.setMetrics(myMetrics);

    ProxiedConnectionFactory factory = socketFactory;

    // Authentication has to be right on top of the physical
    // connection.
    if (myConfig.isAuthenticating()) {
      factory = new AuthenticationConnectionFactory(factory, myConfig);
    }

    try {
      // Use the socket factories cluster.
      final Cluster cluster = socketFactory.getCluster();
      for (final InetSocketAddress addr : myConfig.getServerAddresses()) {
        Connection conn = null;
        final FutureReplyCallback future = new FutureReplyCallback();
        try {
          conn = factory.connect(cluster.add(addr), myConfig);

          conn.send(new IsMaster(), future);
          final Reply reply = future.get();

          // Close the connection now that we have the reply.
          IOUtils.close(conn);

          final List<Document> results = reply.getResults();
          if (!results.isEmpty()) {
            final Document doc = results.get(0);

            if (isMongos(doc)) {
              LOG.debug("Sharded bootstrap to {}.", addr);
              cluster.clear(); // not needed.
              myDelegate = bootstrapSharded(factory);
            } else if (isReplicationSet(doc)) {
              LOG.debug("Replica-set bootstrap to {}.", addr);
              cluster.clear(); // not needed.
              myDelegate = bootstrapReplicaSet(factory);
            } else {
              LOG.debug("Simple MongoDB bootstrap to {}.", addr);
              myDelegate = factory;
            }
            factory = null; // Don't close.
            return;
          }
        } catch (final IOException ioe) {
          LOG.warn(ioe, "I/O error during bootstrap to {}.", addr);
        } catch (final InterruptedException e) {
          LOG.warn(e, "Interrupted during bootstrap to {}.", addr);
        } catch (final ExecutionException e) {
          LOG.warn(e, "Error during bootstrap to {}.", addr);
        } finally {
          IOUtils.close(
              conn, Level.WARNING, "I/O error shutting down bootstrap connection to " + addr + ".");
        }
      }
    } finally {
      IOUtils.close(factory);
    }
  }