private void addReviewers(ChangeResource rsrc, PostResult result, Set<IdentifiedUser> reviewers)
      throws OrmException, EmailException {
    if (reviewers.isEmpty()) {
      result.reviewers = ImmutableList.of();
      return;
    }

    PatchSet.Id psid = rsrc.getChange().currentPatchSetId();
    Set<Account.Id> existing = Sets.newHashSet();
    for (PatchSetApproval psa : db.get().patchSetApprovals().byPatchSet(psid)) {
      existing.add(psa.getAccountId());
    }

    result.reviewers = Lists.newArrayListWithCapacity(reviewers.size());
    List<PatchSetApproval> toInsert = Lists.newArrayListWithCapacity(reviewers.size());
    for (IdentifiedUser user : reviewers) {
      Account.Id id = user.getAccountId();
      if (existing.contains(id)) {
        continue;
      }
      ChangeControl control = rsrc.getControl().forUser(user);
      PatchSetApproval psa = dummyApproval(control, psid, id);
      result.reviewers.add(json.format(new ReviewerInfo(id), control, ImmutableList.of(psa)));
      toInsert.add(psa);
    }
    db.get().patchSetApprovals().insert(toInsert);
    accountLoaderFactory.create(true).fill(result.reviewers);
    postAdd(rsrc.getChange(), result);
  }
  private PostResult putGroup(ChangeResource rsrc, Input input)
      throws BadRequestException, UnprocessableEntityException, OrmException, EmailException,
          IOException {
    GroupDescription.Basic group = groupsCollection.get().parseInternal(input.reviewer);
    PostResult result = new PostResult();
    if (!isLegalReviewerGroup(group.getGroupUUID())) {
      result.error = MessageFormat.format(ChangeMessages.get().groupIsNotAllowed, group.getName());
      return result;
    }

    Set<IdentifiedUser> reviewers = Sets.newLinkedHashSet();
    ChangeControl control = rsrc.getControl();
    Set<Account> members;
    try {
      members =
          groupMembersFactory
              .create(control.getCurrentUser())
              .listAccounts(group.getGroupUUID(), control.getProject().getNameKey());
    } catch (NoSuchGroupException e) {
      throw new UnprocessableEntityException(e.getMessage());
    } catch (NoSuchProjectException e) {
      throw new BadRequestException(e.getMessage());
    }

    // if maxAllowed is set to 0, it is allowed to add any number of
    // reviewers
    int maxAllowed = cfg.getInt("addreviewer", "maxAllowed", DEFAULT_MAX_REVIEWERS);
    if (maxAllowed > 0 && members.size() > maxAllowed) {
      result.error =
          MessageFormat.format(ChangeMessages.get().groupHasTooManyMembers, group.getName());
      return result;
    }

    // if maxWithoutCheck is set to 0, we never ask for confirmation
    int maxWithoutConfirmation =
        cfg.getInt("addreviewer", "maxWithoutConfirmation", DEFAULT_MAX_REVIEWERS_WITHOUT_CHECK);
    if (!input.confirmed()
        && maxWithoutConfirmation > 0
        && members.size() > maxWithoutConfirmation) {
      result.confirm = true;
      result.error =
          MessageFormat.format(
              ChangeMessages.get().groupManyMembersConfirmation, group.getName(), members.size());
      return result;
    }

    for (Account member : members) {
      if (member.isActive()) {
        IdentifiedUser user = identifiedUserFactory.create(member.getId());
        // Does not account for draft status as a user might want to let a
        // reviewer see a draft.
        if (control.forUser(user).isRefVisible()) {
          reviewers.add(user);
        }
      }
    }

    addReviewers(rsrc, result, reviewers);
    return result;
  }