@Override
  public List<String> getTermIdsForAcademicCalendar(String acalId, ContextInfo context)
      throws InvalidParameterException, MissingParameterException, OperationFailedException,
          PermissionDeniedException, DoesNotExistException {
    // Perform an atp search to get the search results
    List<String> includedTermIds = new ArrayList<String>();

    // Get a list of term types
    List<TypeTypeRelationInfo> typeRelations =
        typeService.getTypeTypeRelationsByOwnerAndType(
            AtpServiceConstants.ATP_PARENT_TERM_GROUPING_TYPE_KEY,
            TypeServiceConstants.TYPE_TYPE_RELATION_GROUP_TYPE_KEY,
            context);
    List<String> termTypeIds = new ArrayList<String>();
    for (TypeTypeRelationInfo typeRelation : typeRelations) {
      termTypeIds.add(typeRelation.getRelatedTypeKey());
    }

    SearchRequestInfo searchRequestInfo =
        new SearchRequestInfo(AtpSearchServiceConstants.ATP_SEARCH_RELATED_ATP_IDS_BY_ATP_ID);
    searchRequestInfo.addParam(AtpSearchServiceConstants.ATP_QUERYPARAM_PARENT_ATP_ID, acalId);
    searchRequestInfo.addParam(
        AtpSearchServiceConstants.ATP_QUERYPARAM_RELATED_ATP_TYPES, termTypeIds);
    SearchResultInfo results = atpService.search(searchRequestInfo, context);

    for (SearchResultRowInfo row : results.getRows()) {
      for (SearchResultCellInfo cell : row.getCells()) {
        if (AtpSearchServiceConstants.ATP_RESULTCOLUMN_RELATED_ATP_ID.equals(cell.getKey())) {
          includedTermIds.add(cell.getValue());
        }
      }
    }

    return includedTermIds;
  }
  @Override
  public List<String> getRelatedAtpIdsForParentAtpIdAndRelationType(
      String atpId, String relationTypeKey, ContextInfo context)
      throws InvalidParameterException, MissingParameterException, OperationFailedException,
          PermissionDeniedException, DoesNotExistException {
    // Perform an atp search to get the search results
    List<String> includedTermIds = new ArrayList<String>();

    SearchRequestInfo searchRequestInfo =
        new SearchRequestInfo(AtpSearchServiceConstants.ATP_SEARCH_RELATED_ATP_IDS_BY_ATP_ID);
    searchRequestInfo.addParam(AtpSearchServiceConstants.ATP_QUERYPARAM_PARENT_ATP_ID, atpId);
    searchRequestInfo.addParam(
        AtpSearchServiceConstants.ATP_QUERYPARAM_RELATION_TYPE, relationTypeKey);
    SearchResultInfo results = atpService.search(searchRequestInfo, context);

    if (results != null && !results.getRows().isEmpty()) {
      for (SearchResultRowInfo row : results.getRows()) {
        for (SearchResultCellInfo cell : row.getCells()) {
          if (AtpSearchServiceConstants.ATP_RESULTCOLUMN_RELATED_ATP_ID.equals(cell.getKey())) {
            includedTermIds.add(cell.getValue());
          }
        }
      }
    }

    return includedTermIds;
  }
  protected static void continueFromCreateCopyCourseOfferingInfo(
      CourseOfferingCreateWrapper coWrapper, CourseInfo course, TermInfo term) {

    ContextInfo contextInfo = ContextUtils.createDefaultContextInfo();
    int firstValue = 0;

    try {
      List<CourseOfferingInfo> courseOfferingInfos =
          CourseOfferingManagementUtil.getCourseOfferingService()
              .getCourseOfferingsByCourseAndTerm(course.getId(), term.getId(), contextInfo);

      coWrapper.setCourse(course);
      coWrapper.setCreditCount(
          CourseOfferingViewHelperUtil.trimTrailing0(
              CourseOfferingManagementUtil.getLrcService()
                  .getResultValue(
                      course
                          .getCreditOptions()
                          .get(firstValue)
                          .getResultValueKeys()
                          .get(firstValue),
                      contextInfo)
                  .getValue()));
      coWrapper.setShowAllSections(true);
      coWrapper.setShowCopyCourseOffering(false);
      coWrapper.setShowTermOfferingLink(true);

      coWrapper.setContextBar(
          CourseOfferingContextBar.NEW_INSTANCE(
              coWrapper.getTerm(),
              coWrapper.getSocInfo(),
              CourseOfferingManagementUtil.getStateService(),
              CourseOfferingManagementUtil.getAcademicCalendarService(),
              contextInfo));

      coWrapper.getExistingTermOfferings().clear();
      coWrapper.getExistingOfferingsInCurrentTerm().clear();

      for (CourseOfferingInfo courseOfferingInfo : courseOfferingInfos) {
        if (StringUtils.equals(
            courseOfferingInfo.getStateKey(), LuiServiceConstants.LUI_CO_STATE_OFFERED_KEY)) {
          CourseOfferingEditWrapper co = new CourseOfferingEditWrapper(courseOfferingInfo);
          co.setGradingOption(
              CourseOfferingManagementUtil.getGradingOption(
                  courseOfferingInfo.getGradingOptionId()));
          coWrapper.getExistingOfferingsInCurrentTerm().add(co);
        }
      }

      // Get past 5 years CO
      Calendar termStart = Calendar.getInstance();
      termStart.setTime(term.getStartDate());
      String termYear = Integer.toString(termStart.get(Calendar.YEAR));
      String termMonth = Integer.toString((termStart.get(Calendar.MONTH) + 1));
      String termDayOfMonth = Integer.toString((termStart.getActualMaximum(Calendar.DAY_OF_MONTH)));

      org.kuali.student.r2.core.search.dto.SearchRequestInfo searchRequest =
          new org.kuali.student.r2.core.search.dto.SearchRequestInfo(
              CourseOfferingHistorySearchImpl.PAST_CO_SEARCH.getKey());
      searchRequest.addParam(
          CourseOfferingHistorySearchImpl.COURSE_ID, coWrapper.getCourse().getId());

      searchRequest.addParam(
          CourseOfferingHistorySearchImpl.TARGET_DAY_OF_MONTH_PARAM, termDayOfMonth);
      searchRequest.addParam(CourseOfferingHistorySearchImpl.TARGET_MONTH_PARAM, termMonth);
      searchRequest.addParam(CourseOfferingHistorySearchImpl.TARGET_YEAR_PARAM, termYear);
      searchRequest.addParam(
          CourseOfferingHistorySearchImpl.SearchParameters.CROSS_LIST_SEARCH_ENABLED,
          BooleanUtils.toStringTrueFalse(true));
      org.kuali.student.r2.core.search.dto.SearchResultInfo searchResult =
          CourseOfferingManagementUtil.getSearchService().search(searchRequest, null);

      List<String> courseOfferingIds = new ArrayList<String>(searchResult.getTotalResults());

      /* Checks whether the course is cross-listed and Set the codes that are cross listed to the cross-listed list */

      for (org.kuali.student.r2.core.search.dto.SearchResultRowInfo row : searchResult.getRows()) {
        for (SearchResultCellInfo cellInfo : row.getCells()) {
          String value = StringUtils.EMPTY;
          if (cellInfo.getValue() != null) {
            value = cellInfo.getValue();
          }
          if (CourseOfferingHistorySearchImpl.SearchResultColumns.CO_ID.equals(cellInfo.getKey())) {
            courseOfferingIds.add(value);
          } else if (CourseOfferingHistorySearchImpl.SearchResultColumns.IS_CROSS_LISTED.equals(
              cellInfo.getValue())) {
            coWrapper.setCrossListedCo(BooleanUtils.toBoolean(value));
          } else if (CourseOfferingHistorySearchImpl.SearchResultColumns.CROSS_LISTED_COURSES
              .equals(cellInfo.getKey())) {
            coWrapper.setAlternateCOCodes(Arrays.asList(StringUtils.split(value, ",")));
          }
        }
      }

      /*
       * Avoid duplicates in case there is a cross Listed
       */
      HashSet hs = new HashSet();
      hs.addAll(courseOfferingIds);
      courseOfferingIds.clear();
      courseOfferingIds.addAll(hs);

      courseOfferingInfos =
          CourseOfferingManagementUtil.getCourseOfferingService()
              .getCourseOfferingsByIds(courseOfferingIds, contextInfo);

      for (CourseOfferingInfo courseOfferingInfo : courseOfferingInfos) {
        CourseOfferingEditWrapper co = new CourseOfferingEditWrapper(courseOfferingInfo);
        TermInfo termInfo =
            CourseOfferingManagementUtil.getAcademicCalendarService()
                .getTerm(courseOfferingInfo.getTermId(), contextInfo);
        co.setTerm(termInfo);
        co.setGradingOption(
            CourseOfferingManagementUtil.getGradingOption(courseOfferingInfo.getGradingOptionId()));
        co.setAlternateCOCodes(coWrapper.getAlternateCOCodes());
        coWrapper.getExistingTermOfferings().add(co);
      }
    } catch (Exception e) {
      throw new RuntimeException(e);
    }
  }