/**
   * RequestMapping to accept an invitation. If everything is okay, it redirects to your new team
   * detail view.
   *
   * @param request {@link HttpServletRequest}
   * @return detail view of your new team
   * @throws UnsupportedEncodingException if the server does not support utf-8
   */
  @RequestMapping(value = "/doAcceptInvitation.shtml")
  public RedirectView doAccept(HttpServletRequest request) throws UnsupportedEncodingException {
    Person person = (Person) request.getSession().getAttribute(LoginInterceptor.PERSON_SESSION_KEY);

    Invitation invitation = getInvitationByRequest(request);
    if (invitation == null) {
      throw new IllegalArgumentException(
          "Cannot find your invitation. Invitations expire after 14 days.");
    }
    if (invitation.isDeclined()) {
      throw new RuntimeException("Invitation is Declined");
    }
    if (invitation.isAccepted()) {
      throw new IllegalStateException("Invitation is already Accepted");
    }
    String teamId = invitation.getTeamId();
    if (!StringUtils.hasText(teamId)) {
      throw new RuntimeException("Invalid invitation");
    }
    controllerUtil.getTeamById(teamId);

    String memberId = person.getId();
    grouperTeamService.addMember(teamId, person);

    Role intendedRole = invitation.getIntendedRole();
    if (isGuest(person) && Role.Admin.equals(intendedRole)) {
      // cannot make a guest Admin
      invitation.setIntendedRole(Role.Manager);
    }
    intendedRole = invitation.getIntendedRole();
    grouperTeamService.addMemberRole(
        teamId, memberId, intendedRole, teamEnvironment.getGrouperPowerUser());
    AuditLog.log(
        "User {} accepted invitation for team {} with intended role {}",
        person.getId(),
        teamId,
        intendedRole);
    invitation.setAccepted(true);
    teamInviteService.saveOrUpdate(invitation);

    return new RedirectView(
        "detailteam.shtml?team="
            + URLEncoder.encode(teamId, "utf-8")
            + "&view="
            + ViewUtil.getView(request));
  }
  /**
   * RequestMapping to decline an invitation as receiver. This URL is bypassed in {@link
   * LoginInterceptor}
   *
   * @param modelMap {@link ModelMap}
   * @param request {@link HttpServletRequest}
   * @return view for decline result
   */
  @RequestMapping(value = "/declineInvitation.shtml")
  public String decline(ModelMap modelMap, HttpServletRequest request) {
    String viewTemplate = "invitationdeclined";

    Person person = (Person) request.getSession().getAttribute(LoginInterceptor.PERSON_SESSION_KEY);

    Invitation invitation = getInvitationByRequest(request);

    if (invitation == null) {
      // even if we can't find the invitation, we'll display success!
      return viewTemplate;
    }

    invitation.setDeclined(true);
    teamInviteService.saveOrUpdate(invitation);
    AuditLog.log(
        "User {} declined invitation for team {} with intended role {}",
        person.getId(),
        invitation.getTeamId(),
        invitation.getIntendedRole());
    ViewUtil.addViewToModelMap(request, modelMap);
    return viewTemplate;
  }