docs: @SuppressWarnings("unchecked")
    protected AppendRequest buildAppendEntriesRequest(RaftMemberContext member, long lastIndex) {
      final RaftLogReader reader = member.getLogReader();
  
      final Indexed<RaftLogEntry> prevEntry = reader.getCurrentEntry();
  
      final DefaultRaftMember leader = raft.getLeader();
      AppendRequest.Builder builder = AppendRequest.builder()
          .withTerm(raft.getTerm())
          .withLeader(leader != null ? leader.memberId() : null)
          .withPrevLogIndex(prevEntry != null ? prevEntry.index() : reader.getFirstIndex() - 1)
          .withPrevLogTerm(prevEntry != null ? prevEntry.entry().term() : 0)
          .withCommitIndex(raft.getCommitIndex());
  
      // Build a list of entries to send to the member.
      final List<RaftLogEntry> entries = new ArrayList<>();
  
      // Build a list of entries up to the MAX_BATCH_SIZE. Note that entries in the log may
      // be null if they've been compacted and the member to which we're sending entries is just
      // joining the cluster or is otherwise far behind. Null entries are simply skipped and not
      // counted towards the size of the batch.
      // If there exists an entry in the log with size >= MAX_BATCH_SIZE the logic ensures that
      // entry will be sent in a batch of size one
      int size = 0;
  
      // Iterate through the log until the last index or the end of the log is reached.
      while (reader.hasNext()) {
        // Otherwise, read the next entry and add it to the batch.
        Indexed<RaftLogEntry> entry = reader.next();
        entries.add(entry.entry());
        size += entry.size();
        if (entry.index() == lastIndex || size >= MAX_BATCH_SIZE) {
          break;
        }
      }
  
      // Add the entries to the request builder and build the request.
      return builder.withEntries(entries).build();
    }