code: public void updateGroupMembers(long logIndex, Collection<Endpoint> members) {
          assert committedGroupMembers == lastGroupMembers
                  : "Cannot update group members to: " + members + " at log index: " + logIndex + " because last group members: "
                  + lastGroupMembers + " is different than committed group members: " + committedGroupMembers;
          assert lastGroupMembers.index() < logIndex
                  : "Cannot update group members to: " + members + " at log index: " + logIndex + " because last group members: "
                  + lastGroupMembers + " has a bigger log index.";
  
          RaftGroupMembers newGroupMembers = new RaftGroupMembers(logIndex, members, localEndpoint);
          committedGroupMembers = lastGroupMembers;
          lastGroupMembers = newGroupMembers;
  
          if (leaderState != null) {
              for (Endpoint endpoint : members) {
                  if (!committedGroupMembers.isKnownMember(endpoint)) {
                      leaderState.add(endpoint, log.lastLogOrSnapshotIndex());
                  }
              }
  
              for (Endpoint endpoint : committedGroupMembers.remoteMembers()) {
                  if (!members.contains(endpoint)) {
                      leaderState.remove(endpoint);
                  }
              }
          }
      }
docs: Initializes the last applied group members with the members and logIndex.
  This method expects there's no uncommitted membership changes, committed members are the same as
  the last applied members.
  
  Leader state is updated for the members which don't exist in committed members and committed members
  those don't exist in latest applied members are removed.
  
  @param logIndex log index of membership change
  @param members latest applied members