code: public List<StreamShardHandle> discoverNewShardsToSubscribe() throws InterruptedException {
  
  		List<StreamShardHandle> newShardsToSubscribe = new LinkedList<>();
  
  		GetShardListResult shardListResult = kinesis.getShardList(subscribedStreamsToLastDiscoveredShardIds);
  		if (shardListResult.hasRetrievedShards()) {
  			Set<String> streamsWithNewShards = shardListResult.getStreamsWithRetrievedShards();
  
  			for (String stream : streamsWithNewShards) {
  				List<StreamShardHandle> newShardsOfStream = shardListResult.getRetrievedShardListOfStream(stream);
  				for (StreamShardHandle newShard : newShardsOfStream) {
  					int hashCode = shardAssigner.assign(newShard, totalNumberOfConsumerSubtasks);
  					if (isThisSubtaskShouldSubscribeTo(hashCode, totalNumberOfConsumerSubtasks, indexOfThisConsumerSubtask)) {
  						newShardsToSubscribe.add(newShard);
  					}
  				}
  
  				advanceLastDiscoveredShardOfStream(
  					stream, shardListResult.getLastSeenShardOfStream(stream).getShard().getShardId());
  			}
  		}
  
  		return newShardsToSubscribe;
  	}
docs: A utility function that does the following:
  
  <p>1. Find new shards for each stream that we haven't seen before
  2. For each new shard, determine whether this consumer subtask should subscribe to them;
  if yes, it is added to the returned list of shards
  3. Update the subscribedStreamsToLastDiscoveredShardIds state so that we won't get shards
  that we have already seen before the next time this function is called