/**
   * Work through the chosen messages sending what we have left and stopping once we get to an
   * unfilled slot or the end of the array.
   */
  private void onChosen(PaxosMessage proposal) {
    chosen.set(proposal.getInstanceNum(), (ChatMessage) proposal.getValue());
    if (proposal.getInstanceNum() >= nextInstance) nextInstance = proposal.getInstanceNum() + 1;

    while (lastSent + 1 < chosen.size()) {
      ChatMessage toSend = chosen.get(lastSent + 1);
      if (toSend != null) {
        if (nodeIsLeader()) sendToClients(toSend);
        lastSent++;
      } else {
        break; // There is still a missing slot.
      }
    }
  }
  @Override
  public void handlePropose(PaxosMessage proposal) {
    if (preparedFor > proposal.getProposeNum()) return;

    ensureSize(accepted, proposal.getInstanceNum() + 1);
    ensureSize(chosen, proposal.getInstanceNum() + 1);

    accepted.set(proposal.getInstanceNum(), (ChatMessage) proposal.getValue());
    // Send accept to all
    /* sendAllMessage(new DefaultPaxosMessage(proposal.getInstanceNum(),
    proposal.getProposeNum(),
    id,
    PaxosMessageType.ACCEPTED,
    proposal.getValue())); */
    // Silently accept proposals
  }
  @Override
  public void handleAccepted(PaxosMessage proposal) {
    ensureSize(chosen, proposal.getInstanceNum() + 1); // Prevent NPE

    if (chosen.get(proposal.getInstanceNum()) != null)
      return; // Something has already been chosen so I dont care anymore.

    List<PaxosMessage> acceptedVotes = proposalAcceptedVotes.get(proposal.getInstanceNum());
    if (acceptedVotes == null) {
      acceptedVotes = new ArrayList<PaxosMessage>();
      acceptedVotes.add(proposal);
      proposalAcceptedVotes.put(proposal.getInstanceNum(), acceptedVotes);
    } else {
      for (PaxosMessage acceptedVote : acceptedVotes) {
        if (proposal.getProposerId() == acceptedVote.getProposerId())
          return; // This person is reaffirming their acceptance of this instances proposal.
      }
      acceptedVotes.add(proposal);
      proposalAcceptedVotes.put(proposal.getInstanceNum(), acceptedVotes);
    }
    // handle being chosen
    if (proposalAcceptedVotes.get(proposal.getInstanceNum()).size() >= serverSet.getQuorumSize()) {
      onChosen(proposal);
    }
  }