docs: public DefaultTokenMap refresh(
        @NonNull Collection<Node> nodes,
        @NonNull Collection<KeyspaceMetadata> keyspaces,
        @NonNull ReplicationStrategyFactory replicationStrategyFactory) {
  
      Map<CqlIdentifier, Map<String, String>> newReplicationConfigs =
          buildReplicationConfigs(keyspaces, logPrefix);
      if (newReplicationConfigs.equals(replicationConfigs)) {
        LOG.debug("[{}] Schema changes do not impact the token map, no refresh needed", logPrefix);
        return this;
      }
      ImmutableMap.Builder<Map<String, String>, KeyspaceTokenMap> newKeyspaceMapsBuilder =
          ImmutableMap.builder();
  
      // Will only be built if needed:
      Map<Token, Node> tokenToPrimary = null;
      List<Token> ring = null;
  
      for (Map<String, String> config : ImmutableSet.copyOf(newReplicationConfigs.values())) {
        KeyspaceTokenMap oldKeyspaceMap = keyspaceMaps.get(config);
        if (oldKeyspaceMap != null) {
          LOG.debug("[{}] Reusing existing keyspace-level data for {}", logPrefix, config);
          newKeyspaceMapsBuilder.put(config, oldKeyspaceMap);
        } else {
          LOG.debug("[{}] Computing new keyspace-level data for {}", logPrefix, config);
          if (tokenToPrimary == null) {
            TokenToPrimaryAndRing tmp = buildTokenToPrimaryAndRing(nodes, tokenFactory);
            tokenToPrimary = tmp.tokenToPrimary;
            ring = tmp.ring;
          }
          newKeyspaceMapsBuilder.put(
              config,
              KeyspaceTokenMap.build(
                  config,
                  tokenToPrimary,
                  ring,
                  tokenRanges,
                  tokenFactory,
                  replicationStrategyFactory,
                  logPrefix));
        }
      }
      return new DefaultTokenMap(
          tokenFactory,
          tokenRanges,
          tokenRangesByPrimary,
          newReplicationConfigs,
          newKeyspaceMapsBuilder.build(),
          logPrefix);
    }