private void updateLocatorList(LocatorListResponse response) {
    if (response == null) {
      return;
    }
    isBalanced = response.isBalanced();
    List<ServerLocation> locatorResponse = response.getLocators();

    List<HostAndPort> newLocatorAddresses = new ArrayList<>(locatorResponse.size());
    List<HostAndPort> newOnlineLocators = new ArrayList<>(locatorResponse.size());

    Set<HostAndPort> badLocators = new HashSet<>(initialLocators);

    for (ServerLocation locator : locatorResponse) {
      HostAndPort hostAddress = new HostAndPort(locator.getHostName(), locator.getPort());
      newLocatorAddresses.add(hostAddress);
      newOnlineLocators.add(hostAddress);
      badLocators.remove(hostAddress);
    }

    addBadLocators(newLocatorAddresses, badLocators);

    LocatorList newLocatorList = new LocatorList(newLocatorAddresses);

    LocatorList oldLocators = locators.getAndSet(newLocatorList);
    onlineLocators.set(new LocatorList(newOnlineLocators));
    pool.getStats().setLocatorCount(newLocatorAddresses.size());

    if (logger.isInfoEnabled()
        || !locatorCallback.getClass().equals(LocatorDiscoveryCallbackAdapter.class)) {
      List<InetSocketAddress> newLocators = newLocatorList.getLocators();
      ArrayList<InetSocketAddress> removedLocators = new ArrayList<>(oldLocators.getLocators());
      removedLocators.removeAll(newLocators);

      ArrayList<InetSocketAddress> addedLocators = new ArrayList<>(newLocators);
      addedLocators.removeAll(oldLocators.getLocators());
      if (!addedLocators.isEmpty()) {
        locatorCallback.locatorsDiscovered(Collections.unmodifiableList(addedLocators));
        logger.info("AutoConnectionSource discovered new locators {}", addedLocators);
      }
      if (!removedLocators.isEmpty()) {
        locatorCallback.locatorsRemoved(Collections.unmodifiableList(removedLocators));
        logger.info("AutoConnectionSource dropping previously discovered locators {}",
            removedLocators);
      }
    }

  }
key is the InetSocketAddress of the locator. value will be an exception if we have already
found the locator to be dead. value will be null if we last saw it alive.
geode-core/src/main/java/org/apache/geode/cache/client/internal/AutoConnectionSourceImpl.java