@GET
  @Path("/{studyOID}/getSchedule")
  @Produces(MediaType.APPLICATION_XML)
  public String getSchedule(
      @Context HttpServletRequest request,
      @Context HttpServletResponse response,
      @Context ServletContext context,
      @PathParam("studyOID") String studyOID,
      @RequestHeader("Authorization") String authorization)
      throws Exception {

    String ssoid = request.getParameter("studySubjectOID");
    StudySubjectDAO ssdao = new StudySubjectDAO<String, ArrayList>(dataSource);
    StudySubjectBean ssBean = ssdao.findByOid(ssoid);
    if (!mayProceedSubmission(studyOID, ssBean)) return null;

    HashMap<String, String> urlCache =
        (HashMap<String, String>) context.getAttribute("pformURLCache");
    context.getAttribute("subjectContextCache");
    if (ssoid == null) {
      return "<error>studySubjectOID is null :(</error>";
    }

    try {
      // Need to retrieve crf's for next event
      StudyEventDAO eventDAO = new StudyEventDAO(getDataSource());
      StudyEventBean nextEvent = (StudyEventBean) eventDAO.getNextScheduledEvent(ssoid);
      CRFVersionDAO versionDAO = new CRFVersionDAO(getDataSource());
      ArrayList<CRFVersionBean> crfs =
          versionDAO.findDefCRFVersionsByStudyEvent(nextEvent.getStudyEventDefinitionId());
      PFormCache cache = PFormCache.getInstance(context);
      for (CRFVersionBean crfVersion : crfs) {
        String enketoURL = cache.getPFormURL(studyOID, crfVersion.getOid());
        String contextHash =
            cache.putSubjectContext(
                ssoid,
                String.valueOf(nextEvent.getStudyEventDefinitionId()),
                String.valueOf(nextEvent.getSampleOrdinal()),
                crfVersion.getOid());
      }
    } catch (Exception e) {
      LOGGER.debug(e.getMessage());
      LOGGER.debug(ExceptionUtils.getStackTrace(e));
      return "<error>" + e.getMessage() + "</error>";
    }

    response.setHeader("Content-Type", "text/xml; charset=UTF-8");
    response.setHeader("Content-Disposition", "attachment; filename=\"schedule.xml\";");
    response.setContentType("text/xml; charset=utf-8");
    return "<result>success</result>";
  }
  /**
   * Organize objects in a certain way so that we can show to Users on UI. step1 : Get StudyEvent ,
   * eventCrf , crfVersion from studyEventId.
   *
   * @param crfViewSpecificOrderedObjects
   * @param ruleSet
   * @param rule
   * @return
   */
  private HashMap<RuleBulkExecuteContainer, HashMap<RuleBulkExecuteContainerTwo, Set<String>>>
      populateForCrfBasedRulesView(
          HashMap<RuleBulkExecuteContainer, HashMap<RuleBulkExecuteContainerTwo, Set<String>>>
              crfViewSpecificOrderedObjects,
          RuleSetBean ruleSet,
          RuleBean rule,
          String result,
          StudyBean currentStudy,
          List<RuleActionBean> actions) {

    // step1
    StudyEventBean studyEvent =
        (StudyEventBean)
            getStudyEventDao()
                .findByPK(
                    Integer.valueOf(
                        getExpressionService()
                            .getStudyEventDefenitionOrdninalCurated(
                                ruleSet.getTarget().getValue())));
    EventCRFBean eventCrf =
        (EventCRFBean)
            getEventCrfDao()
                .findAllByStudyEventAndCrfOrCrfVersionOid(
                    studyEvent, getExpressionService().getCrfOid(ruleSet.getTarget().getValue()))
                .get(0);
    CRFVersionBean crfVersion =
        (CRFVersionBean) getCrfVersionDao().findByPK(eventCrf.getCRFVersionId());

    RuleBulkExecuteContainer key =
        new RuleBulkExecuteContainer(crfVersion.getName(), rule, result, actions);
    String key2String =
        getExpressionService()
            .getCustomExpressionUsedToCreateView(
                ruleSet.getTarget().getValue(), studyEvent.getSampleOrdinal());
    String studyEventDefinitionName =
        getExpressionService()
            .getStudyEventDefinitionFromExpression(ruleSet.getTarget().getValue(), currentStudy)
            .getName();
    studyEventDefinitionName += " [" + studyEvent.getSampleOrdinal() + "]";
    // String itemGroupName =
    // getExpressionService().getItemGroupNameAndOrdinal(ruleSet.getTarget().getValue());
    // String itemName =
    // getExpressionService().getItemGroupExpression(ruleSet.getTarget().getValue()).getName();

    String itemGroupName =
        getExpressionService().getItemGroupNameAndOrdinal(ruleSet.getTarget().getValue());
    ItemGroupBean itemGroupBean =
        getExpressionService().getItemGroupExpression(ruleSet.getTarget().getValue());
    ItemBean itemBean =
        getExpressionService().getItemExpression(ruleSet.getTarget().getValue(), itemGroupBean);
    String itemName = itemBean.getName();

    RuleBulkExecuteContainerTwo key2 =
        new RuleBulkExecuteContainerTwo(
            key2String, studyEvent, studyEventDefinitionName, itemGroupName, itemName);
    StudySubjectBean studySubject =
        (StudySubjectBean) getStudySubjectDao().findByPK(studyEvent.getStudySubjectId());

    if (crfViewSpecificOrderedObjects.containsKey(key)) {
      HashMap<RuleBulkExecuteContainerTwo, Set<String>> k = crfViewSpecificOrderedObjects.get(key);
      if (k.containsKey(key2)) {
        k.get(key2).add(String.valueOf(studySubject.getLabel()));
      } else {
        HashSet<String> values = new HashSet<String>();
        values.add(String.valueOf(studySubject.getLabel()));
        k.put(key2, values);
      }
    } else {
      HashMap<RuleBulkExecuteContainerTwo, Set<String>> k =
          new HashMap<RuleBulkExecuteContainerTwo, Set<String>>();
      HashSet<String> values = new HashSet<String>();
      values.add(String.valueOf(studySubject.getLabel()));
      k.put(key2, values);
      crfViewSpecificOrderedObjects.put(key, k);
    }
    return crfViewSpecificOrderedObjects;
  }