private Map<String, String> queryExhibitors(Exhibitors localExhibitors) {
    Map<String, String> values = newValues();

    long start = System.currentTimeMillis();
    int retries = 0;
    boolean done = false;
    while (!done) {
      List<String> hostnames = Lists.newArrayList(localExhibitors.getHostnames());
      if (hostnames.size() == 0) {
        done = true;
      } else {
        String hostname = hostnames.get(random.nextInt(hostnames.size()));
        try {
          String encoded =
              restClient.getRaw(hostname, localExhibitors.getRestPort(), restUriPath, MIME_TYPE);
          values.putAll(decodeExhibitorList(encoded));
          done = true;
        } catch (Throwable e) {
          if (retryPolicy.allowRetry(
              retries++, System.currentTimeMillis() - start, RetryLoop.getDefaultRetrySleeper())) {
            log.warn("Couldn't get servers from Exhibitor. Retrying.", e);
          } else {
            log.error("Couldn't get servers from Exhibitor. Giving up.", e);
            done = true;
          }
        }
      }
    }

    return values;
  }
  @VisibleForTesting
  protected void poll() {
    Exhibitors localExhibitors = exhibitors.get();
    Map<String, String> values = queryExhibitors(localExhibitors);

    int count = getCountFromValues(values);
    if (count == 0) {
      log.warn("0 count returned from Exhibitors. Using backup connection values.");
      values = useBackup(localExhibitors);
      count = getCountFromValues(values);
    }

    if (count > 0) {
      int port = Integer.parseInt(values.get(VALUE_PORT));
      StringBuilder newConnectionString = new StringBuilder();
      List<String> newHostnames = Lists.newArrayList();

      for (int i = 0; i < count; ++i) {
        if (newConnectionString.length() > 0) {
          newConnectionString.append(",");
        }
        String server = values.get(VALUE_SERVER_PREFIX + i);
        newConnectionString.append(server).append(":").append(port);
        newHostnames.add(server);
      }

      String newConnectionStringValue = newConnectionString.toString();
      if (!newConnectionStringValue.equals(connectionString.get())) {
        log.info(
            "Connection string has changed. Old value (%s), new value (%s)",
            connectionString.get(), newConnectionStringValue);
      }
      Exhibitors newExhibitors =
          new Exhibitors(
              newHostnames,
              localExhibitors.getRestPort(),
              new Exhibitors.BackupConnectionStringProvider() {
                @Override
                public String getBackupConnectionString() throws Exception {
                  return masterExhibitors
                      .get()
                      .getBackupConnectionString(); // this may be overloaded by clients. Make sure
                                                    // there is always a method call to get the
                                                    // value.
                }
              });
      connectionString.set(newConnectionStringValue);
      exhibitors.set(newExhibitors);
    }
  }
  private Map<String, String> useBackup(Exhibitors localExhibitors) {
    Map<String, String> values = newValues();

    try {
      String backupConnectionString = localExhibitors.getBackupConnectionString();

      int thePort = -1;
      int count = 0;
      for (String spec : backupConnectionString.split(",")) {
        spec = spec.trim();
        String[] parts = spec.split(":");
        if (parts.length == 2) {
          String hostname = parts[0];
          int port = Integer.parseInt(parts[1]);
          if (thePort < 0) {
            thePort = port;
          } else if (port != thePort) {
            log.warn("Inconsistent port in connection component: " + spec);
          }
          values.put(VALUE_SERVER_PREFIX + count, hostname);
          ++count;
        } else {
          log.warn("Bad backup connection component: " + spec);
        }
      }
      values.put(VALUE_COUNT, Integer.toString(count));
      values.put(VALUE_PORT, Integer.toString(thePort));
    } catch (Exception e) {
      log.error("Couldn't get backup connection string", e);
    }
    return values;
  }