class ISDACompliantScheduleGenerator {

  public static LocalDate[] getIntegrationNodesAsDates(final LocalDate startDate, final LocalDate endDate, final LocalDate[] disCurveDates, final LocalDate[] spreadCurveDates) {
    ArgumentChecker.notNull(startDate, "null startDate");
    ArgumentChecker.notNull(endDate, "null endDate");
    ArgumentChecker.noNulls(disCurveDates, "nulls in disCurveDates");
    ArgumentChecker.noNulls(spreadCurveDates, "nulls in spreadCurveDates");

    ArgumentChecker.isTrue(endDate.isAfter(startDate), "endDate of {} is not after startDate of {}", endDate.toString(), startDate.toString());

    final int nDisCurvePoints = disCurveDates.length;
    final int nSpreadCurvePoints = spreadCurveDates.length;

    final LinkedHashSet<LocalDate> set = new LinkedHashSet<>(2 + nDisCurvePoints + nSpreadCurvePoints);
    set.add(startDate);
    for (final LocalDate date : disCurveDates) {
      set.add(date);
    }
    for (final LocalDate date : spreadCurveDates) {
      set.add(date);
    }
    set.add(endDate);

    final int n = set.size();
    final LocalDate[] res = new LocalDate[n];
    set.toArray(res);
    Arrays.sort(res);

    // remove dates strictly before startDate and strictly after endDate
    int a = 0;
    int b = n - 1;
    while (res[a].isBefore(startDate)) {
      a++;
    }
    while (res[b].isAfter(endDate)) {
      b--;
    }
    final int newLength = b - a + 1;
    if (newLength == n) {
      return res; // nothing got chopped off
    }

    final LocalDate[] res2 = new LocalDate[newLength];
    System.arraycopy(res, a, res2, 0, newLength);
    return res2;
  }

}