@RequestMapping(value = "edit_research_output", method = RequestMethod.GET)
  public ModelAndView editFollowUp(
      @RequestParam(value = "pid", required = false) Integer projectId,
      @RequestParam(value = "rid", required = false) Integer researchOutputId,
      HttpServletRequest request)
      throws Exception {

    Map<String, Object> m = new HashMap<String, Object>();
    Person person = (Person) request.getAttribute("person");
    if (person == null) {
      return new ModelAndView(new RedirectView(redirectIfNoAccount, false));
    } else if (!person.isResearcher()) {
      m.put("error_message", adviserWarning);
    } else if (projectId == null) {
      m.put("error_message", "No project id specified");
    } else {
      ProjectWrapper pw = this.projectDao.getProjectForIdOrCode(Integer.toString(projectId));
      ResearchOutput ro = null;
      for (ResearchOutput tmp : pw.getResearchOutputs()) {
        if (tmp.getId().equals(researchOutputId)) {
          ro = tmp;
          break;
        }
      }
      m.put("researchOutput", ro);
    }
    this.augmentModel(m);
    return new ModelAndView("edit_research_output", m);
  }
  @RequestMapping(value = "edit_research_output", method = RequestMethod.POST)
  public ModelAndView processEditFollowUp(
      @Valid @ModelAttribute("researchOutput") ResearchOutput ro,
      BindingResult bResult,
      HttpServletRequest request)
      throws Exception {

    Map<String, Object> m = new HashMap<String, Object>();
    if (bResult.hasErrors()) {
      m.put("researchOutput", ro);
      this.augmentModel(m);
      return new ModelAndView("edit_research_output", m);
    }
    Person person = (Person) request.getAttribute("person");
    if (person == null) {
      return new ModelAndView(new RedirectView(redirectIfNoAccount, false));
    } else if (!person.isResearcher()) {
      m.put("error_message", adviserWarning);
      return new ModelAndView("edit_research_output", m);
    } else {
      try {
        this.projectDao.addOrUpdateResearchOutput(ro);
        return new ModelAndView(new RedirectView("view_project?id=" + ro.getProjectId(), true));
      } catch (Exception e) {
        m.put("error_message", e.getMessage());
        m.put("researchOutput", ro);
        return new ModelAndView("edit_research_output", m);
      }
    }
  }
  @RequestMapping(value = "add_research_output", method = RequestMethod.GET)
  public ModelAndView addResearchOutput(
      @RequestParam(value = "pid", required = false) Integer projectId, HttpServletRequest request)
      throws Exception {

    Map<String, Object> m = new HashMap<String, Object>();
    Person person = (Person) request.getAttribute("person");
    if (person == null) {
      return new ModelAndView(new RedirectView(redirectIfNoAccount, false));
    } else if (!person.isResearcher()) {
      m.put("error_message", adviserWarning);
    } else if (projectId == null) {
      m.put("error_message", "No project id specified");
    } else {
      ResearchOutput ro = new ResearchOutput();
      ro.setProjectId(projectId);
      m.put("researchOutput", ro);
    }
    this.augmentModel(m);
    return new ModelAndView("add_research_output", m);
  }
  @RequestMapping(value = "add_research_output", method = RequestMethod.POST)
  public ModelAndView processAddResearchOutput(
      @Valid @ModelAttribute("researchOutput") ResearchOutput ro,
      BindingResult bResult,
      HttpServletRequest request)
      throws Exception {

    Map<String, Object> m = new HashMap<String, Object>();
    if (bResult.hasErrors()) {
      m.put("researchOutput", ro);
      this.augmentModel(m);
      return new ModelAndView("add_research_output", m);
    }
    Person person = (Person) request.getAttribute("person");
    if (person == null) {
      return new ModelAndView(new RedirectView(redirectIfNoAccount, false));
    } else if (!person.isResearcher()) {
      m.put("error_message", adviserWarning);
      return new ModelAndView("add_research_output", m);
    } else {
      ro.setDate(new SimpleDateFormat("yyyy-MM-dd").format(new Date()));
      ro.setResearcherId(person.getId());
      try {
        this.projectDao.addOrUpdateResearchOutput(ro);
        this.emailUtil.sendNewResearchOutputEmail(
            person.getFullName(),
            person.getEmail(),
            this.getResearchOutputTypeMap().get(ro.getTypeId()),
            ro.getDescription(),
            ro.getProjectId());
        return new ModelAndView(new RedirectView("view_project?id=" + ro.getProjectId(), true));
      } catch (Exception e) {
        m.put("error_message", e.getMessage());
        return new ModelAndView("add_research_output", m);
      }
    }
  }