class UserSyncService {

    @VisibleForTesting
    void addUsersToGroups(FreeIpaClient freeIpaClient, Multimap<String, String> groupMapping, BiConsumer<String, String> warnings)
            throws FreeIpaClientException {
        LOGGER.debug("adding users to groups: [{}]", groupMapping);
        for (String group : groupMapping.keySet()) {
            for (List<String> users : Iterables.partition(groupMapping.get(group), maxSubjectsPerRequest)) {
                LOGGER.debug("adding users [{}] to group [{}]", users, group);
                try {
                    RPCResponse<Group> groupAddMemberResponse = freeIpaClient.groupAddMembers(group, users);
                    List<String> members = Optional.ofNullable(groupAddMemberResponse.getResult().getMemberUser()).orElse(List.of());
                    if (members.containsAll(users)) {
                        LOGGER.debug("Successfully added users {} to {}", users, groupAddMemberResponse.getResult());
                    } else {
                        // TODO specialize RPCResponse completed/failed objects
                        LOGGER.error("Failed to add {} to group '{}': {}", users, group, groupAddMemberResponse.getFailed());
                        warnings.accept(group, String.format("Failed to add users to group: %s", groupAddMemberResponse.getFailed()));
                    }
                } catch (FreeIpaClientException e) {
                    LOGGER.error("Failed to add {} to group '{}'", users, group, e);
                    warnings.accept(group, String.format("Failed to add users %s to group: %s", users, e.getMessage()));
                    checkIfClientStillUsable(e);
                }
            }
        }
    }

}