@RequestMapping(value = path + "change-vote")
  @ResponseBody
  public Request changeVoteDo(
      @RequestParam(value = phoneNumber) String inputNumber,
      @RequestParam(value = entityUidParam) String eventUid,
      @RequestParam(value = "response") String response)
      throws URISyntaxException {

    final User user = userManager.findByInputNumber(inputNumber, null);
    final Event vote = eventBroker.load(eventUid);

    USSDMenu menu;
    if (vote.getEventStartDateTime().isBefore(Instant.now())) {
      menu = new USSDMenu(getMessage(thisSection, "change", "error", user));
    } else {
      // todo: replace this hack once responses are handled better
      EventRSVPResponse voteResponse =
          "abstain".equals(response)
              ? EventRSVPResponse.MAYBE
              : EventRSVPResponse.fromString(response);
      eventLogBroker.rsvpForEvent(vote.getUid(), user.getUid(), voteResponse);
      menu = new USSDMenu(getMessage(thisSection, "change", "done", response, user));
    }

    menu.addMenuOption(
        voteMenus + "details" + entityUidUrlSuffix + eventUid + "&back=open",
        getMessage(thisSection, "change", optionsKey + "back", user));
    menu.addMenuOptions(optionsHomeExit(user));

    return menuBuilder(menu);
  }
  @RequestMapping(value = path + "details")
  @ResponseBody
  public Request viewVoteDetails(
      @RequestParam(value = phoneNumber) String inputNumber,
      @RequestParam(value = entityUidParam) String eventUid,
      @RequestParam(value = "back") String backMenu)
      throws URISyntaxException {
    // todo: decide whether to allow users to change the closing time (& permissions, of course)
    // todo: have some way of counting reminders and only allow once unless paid account
    // todo: reconsider whether to save URL here, might want to set back to null

    User user =
        userManager.findByInputNumber(
            inputNumber, saveVoteMenu("details", eventUid) + "&back=" + backMenu);
    Event vote = eventBroker.load(eventUid);
    boolean futureEvent = vote.getEventStartDateTime().isAfter(Instant.now());
    ResponseTotalsDTO voteResults = eventLogBroker.getResponseCountForEvent(vote);

    USSDMenu menu;

    if (futureEvent) {
      EventLog userResponse =
          eventLogRepository.findByEventAndUserAndEventLogType(vote, user, EventLogType.RSVP);

      String responseText;
      List<String> otherResponses;
      if (userResponse == null || !userResponse.hasValidResponse()) {
        responseText = "not voted yet";
        otherResponses = Arrays.asList("yes", "no", "abstain");
      } else {
        switch (userResponse.getResponse()) {
          case YES:
            responseText = "yes";
            otherResponses = Arrays.asList("no", "abstain");
            break;
          case NO:
            responseText = "no";
            otherResponses = Arrays.asList("yes", "abstain");
            break;
          case MAYBE:
            responseText = "abstain";
            otherResponses = Arrays.asList("yes", "no");
            break;
          default:
            responseText = "not voted yet";
            otherResponses = Arrays.asList("yes", "no", "abstain");
            break;
        }
      }

      final String suffix = entityUidUrlSuffix + eventUid;
      final String[] fields =
          new String[] {
            vote.getAncestorGroup().getName(""),
            vote.getName(),
            "" + (voteResults.getNumberOfUsers() - voteResults.getNumberNoRSVP()),
            responseText
          };

      menu = new USSDMenu(getMessage(thisSection, "details", "future." + promptKey, fields, user));
      for (String voteOption : otherResponses) {
        menu.addMenuOption(
            voteMenus + "change-vote" + suffix + "&response=" + voteOption,
            getMessage(thisSection, "details", optionsKey + "change", voteOption, user));
      }

    } else {
      String[] fields =
          new String[] {
            vote.getAncestorGroup().getName(""),
            vote.getName(),
            "" + voteResults.getYes(),
            "" + voteResults.getNo(),
            "" + voteResults.getMaybe(),
            "" + voteResults.getNumberNoRSVP()
          };
      menu = new USSDMenu(getMessage(thisSection, "details", promptKey, fields, user));
    }

    menu.addMenuOption(
        voteMenus + backMenu, getMessage(thisSection, "details", optionsKey + "back", user));

    return menuBuilder(menu);
  }