@Override
 public synchronized void removePool(HostConnectionPool<CL> pool) {
   allPools.removePool(pool);
   for (TokenHostConnectionPoolPartition<CL> partition : tokenToPartitionMap.values()) {
     partition.removePool(pool);
   }
 }
 @SuppressWarnings("unchecked")
 @Override
 public int compare(Object arg0, Object arg1) {
   TokenHostConnectionPoolPartition<CL> partition =
       (TokenHostConnectionPoolPartition<CL>) arg0;
   RingPosition token = (RingPosition) arg1;
   return partition.id().compareTo(token);
 }
 @SuppressWarnings("unchecked")
 @Override
 public int compare(Object arg0, Object arg1) {
   TokenHostConnectionPoolPartition<CL> partition0 =
       (TokenHostConnectionPoolPartition<CL>) arg0;
   TokenHostConnectionPoolPartition<CL> partition1 =
       (TokenHostConnectionPoolPartition<CL>) arg1;
   return partition0.id().compareTo(partition1.id());
 }
 @Override
 public synchronized void addPool(HostConnectionPool<CL> pool) {
   allPools.addPool(pool);
 }
  @SuppressWarnings("unchecked")
  @Override
  /**
   * Update the list of pools using the provided mapping of start token to collection of hosts that
   * own the token
   */
  public synchronized boolean setPools(Collection<HostConnectionPool<CL>> ring) {
    boolean didChange = false;

    Set<HostConnectionPool<CL>> allPools = Sets.newHashSet();

    // Create a mapping of end token to a list of hosts that own the token
    Map<RingPosition, List<HostConnectionPool<CL>>> tokenHostMap = Maps.newHashMap();
    for (HostConnectionPool<CL> pool : ring) {
      allPools.add(pool);
      if (!this.allPools.hasPool(pool)) didChange = true;

      for (TokenRange range : pool.getHost().getTokenRanges()) {
        RingPosition endToken = partitioner.getRingPositionForToken(range.getEndToken());
        List<HostConnectionPool<CL>> partition = tokenHostMap.get(endToken);
        if (partition == null) {
          partition = Lists.newArrayList();
          tokenHostMap.put(endToken, partition);
        }
        partition.add(pool);
      }
    }

    // Temporary list of token that will be removed if not found in the new ring
    Set<RingPosition> tokensToRemove = Sets.newHashSet(tokenHostMap.keySet());

    // Iterate all tokens
    for (Entry<RingPosition, List<HostConnectionPool<CL>>> entry : tokenHostMap.entrySet()) {
      RingPosition token = entry.getKey();
      tokensToRemove.remove(token);

      // Add a new partition or modify an existing one
      TokenHostConnectionPoolPartition<CL> partition = tokenToPartitionMap.get(token);
      if (partition == null) {
        partition = makePartition(token);
        tokenToPartitionMap.put(token, partition);
        didChange = true;
      }
      if (partition.setPools(entry.getValue())) didChange = true;
    }

    // Remove the tokens that are no longer in the ring
    for (RingPosition token : tokensToRemove) {
      tokenHostMap.remove(token);
      didChange = true;
    }

    // Sort partitions by token
    if (didChange) {
      List<TokenHostConnectionPoolPartition<CL>> partitions =
          Lists.newArrayList(tokenToPartitionMap.values());
      Collections.sort(partitions, partitionComparator);
      this.allPools.setPools(allPools);
      refresh();
      this.sortedRing.set(Collections.unmodifiableList(partitions));
    }

    return didChange;
  }