Program: 40880
Project: 40880
Buggy source:
@FiberOnly private void doAppendMessage(final Request<RpcWireRequest,RpcReply> request){
  final AppendEntries appendMessage=request.getRequest().getAppendMessage();
  if (appendMessage.getTerm() < currentTerm) {
    AppendEntriesReply m=new AppendEntriesReply(currentTerm,false,0);
    RpcReply reply=new RpcReply(m);
    request.reply(reply);
    return;
  }
  if (appendMessage.getTerm() > currentTerm) {
    setCurrentTerm(appendMessage.getTerm());
  }
  if (myState != State.FOLLOWER) {
    haltLeader();
  }
  lastRPC=info.currentTimeMillis();
  long theLeader=appendMessage.getLeaderId();
  if (whosLeader != theLeader) {
    LOG.debug("String_Node_Str",myId,theLeader);
    whosLeader=theLeader;
    stateChangeChannel.publish(new ReplicatorInstanceEvent(ReplicatorInstanceEvent.EventType.LEADER_ELECTED,this,whosLeader,info.currentTimeMillis(),null));
  }
  long msgPrevLogIndex=appendMessage.getPrevLogIndex();
  long msgPrevLogTerm=appendMessage.getPrevLogTerm();
  if (msgPrevLogIndex != 0 && log.getLogTerm(msgPrevLogIndex) != msgPrevLogTerm) {
    AppendEntriesReply m=new AppendEntriesReply(currentTerm,false,log.getLastIndex());
    RpcReply reply=new RpcReply(m);
    request.reply(reply);
    return;
  }
  if (appendMessage.getEntriesList().isEmpty()) {
    AppendEntriesReply m=new AppendEntriesReply(currentTerm,true,0);
    RpcReply reply=new RpcReply(m);
    request.reply(reply);
    long newCommitIndex=Math.min(appendMessage.getCommitIndex(),log.getLastIndex());
    if (newCommitIndex > lastCommittedIndex) {
      lastCommittedIndex=newCommitIndex;
      notifyLastCommitted();
    }
    return;
  }
  ListenableFuture<ArrayList<LogEntry>> entriesToCommitFuture=validateAndFixLocalLog(request,appendMessage);
  Futures.addCallback(entriesToCommitFuture,new FutureCallback<ArrayList<LogEntry>>(){
    @Override public void onSuccess(    ArrayList<LogEntry> entriesToCommit){
      ListenableFuture<Boolean> logCommitNotification=log.logEntries(entriesToCommit);
      Futures.addCallback(logCommitNotification,new FutureCallback<Boolean>(){
        @Override public void onSuccess(        Boolean result){
          AppendEntriesReply m=new AppendEntriesReply(currentTerm,true,0);
          RpcReply reply=new RpcReply(m);
          request.reply(reply);
          lastCommittedIndex=Math.min(appendMessage.getCommitIndex(),log.getLastIndex());
          notifyLastCommitted();
        }
        @Override public void onFailure(        Throwable t){
          AppendEntriesReply m=new AppendEntriesReply(currentTerm,false,0);
          RpcReply reply=new RpcReply(m);
          request.reply(reply);
        }
      }
,fiber);
    }
    @Override public void onFailure(    Throwable t){
      AppendEntriesReply m=new AppendEntriesReply(currentTerm,false,0);
      RpcReply reply=new RpcReply(m);
      request.reply(reply);
    }
  }
,fiber);
}

Fixed version (ground truth):
@FiberOnly private void doAppendMessage(final Request<RpcWireRequest,RpcReply> request){
  final AppendEntries appendMessage=request.getRequest().getAppendMessage();
  if (appendMessage.getTerm() < currentTerm) {
    AppendEntriesReply m=new AppendEntriesReply(currentTerm,false,0);
    RpcReply reply=new RpcReply(m);
    request.reply(reply);
    return;
  }
  if (appendMessage.getTerm() > currentTerm) {
    setCurrentTerm(appendMessage.getTerm());
  }
  if (myState != State.FOLLOWER) {
    haltLeader();
  }
  lastRPC=info.currentTimeMillis();
  long theLeader=appendMessage.getLeaderId();
  if (whosLeader != theLeader) {
    LOG.debug("String_Node_Str",myId,theLeader);
    whosLeader=theLeader;
    stateChangeChannel.publish(new ReplicatorInstanceEvent(ReplicatorInstanceEvent.EventType.LEADER_ELECTED,this,whosLeader,info.currentTimeMillis(),null));
  }
  long msgPrevLogIndex=appendMessage.getPrevLogIndex();
  long msgPrevLogTerm=appendMessage.getPrevLogTerm();
  if (msgPrevLogIndex != 0 && log.getLogTerm(msgPrevLogIndex) != msgPrevLogTerm) {
    AppendEntriesReply m=new AppendEntriesReply(currentTerm,false,log.getLastIndex());
    RpcReply reply=new RpcReply(m);
    request.reply(reply);
    return;
  }
  if (appendMessage.getEntriesList().isEmpty()) {
    AppendEntriesReply m=new AppendEntriesReply(currentTerm,true,0);
    RpcReply reply=new RpcReply(m);
    request.reply(reply);
    long newCommitIndex=Math.min(appendMessage.getCommitIndex(),log.getLastIndex());
    setLastCommittedIndex(newCommitIndex);
    return;
  }
  ListenableFuture<ArrayList<LogEntry>> entriesToCommitFuture=validateAndFixLocalLog(request,appendMessage);
  Futures.addCallback(entriesToCommitFuture,new FutureCallback<ArrayList<LogEntry>>(){
    @Override public void onSuccess(    ArrayList<LogEntry> entriesToCommit){
      ListenableFuture<Boolean> logCommitNotification=log.logEntries(entriesToCommit);
      Futures.addCallback(logCommitNotification,new FutureCallback<Boolean>(){
        @Override public void onSuccess(        Boolean result){
          AppendEntriesReply m=new AppendEntriesReply(currentTerm,true,0);
          RpcReply reply=new RpcReply(m);
          request.reply(reply);
          long newCommitIndex=Math.min(appendMessage.getCommitIndex(),log.getLastIndex());
          setLastCommittedIndex(newCommitIndex);
        }
        @Override public void onFailure(        Throwable t){
          AppendEntriesReply m=new AppendEntriesReply(currentTerm,false,0);
          RpcReply reply=new RpcReply(m);
          request.reply(reply);
        }
      }
,fiber);
    }
    @Override public void onFailure(    Throwable t){
      AppendEntriesReply m=new AppendEntriesReply(currentTerm,false,0);
      RpcReply reply=new RpcReply(m);
      request.reply(reply);
    }
  }
,fiber);
}