class ProposerSelector {

  public Address selectProposerForRound(final ConsensusRoundIdentifier roundIdentifier) {
    checkArgument(roundIdentifier.getRoundNumber() >= 0);
    checkArgument(roundIdentifier.getSequenceNumber() > 0);

    final long prevBlockNumber = roundIdentifier.getSequenceNumber() - 1;
    final Optional<BlockHeader> maybeParentHeader = blockchain.getBlockHeader(prevBlockNumber);
    if (!maybeParentHeader.isPresent()) {
      LOG.trace("Unable to determine proposer for requested block {}", prevBlockNumber);
      throw new RuntimeException("Unable to determine past proposer");
    }

    final BlockHeader blockHeader = maybeParentHeader.get();
    final Address prevBlockProposer = blockInterface.getProposerOfBlock(blockHeader);
    final Collection<Address> validatorsForRound =
        voteTallyCache.getVoteTallyAfterBlock(blockHeader).getValidators();

    if (!validatorsForRound.contains(prevBlockProposer)) {
      return handleMissingProposer(prevBlockProposer, validatorsForRound, roundIdentifier);
    } else {
      return handleWithExistingProposer(prevBlockProposer, validatorsForRound, roundIdentifier);
    }
  }

  public  ProposerSelector(
      final Blockchain blockchain,
      final BlockInterface blockInterface,
      final boolean changeEachBlock,
      final VoteTallyCache voteTallyCache);

}