static long handleSubdayRepeat(DateTime startDate, RRule rrule) {
   long millis;
   switch (rrule.getFreq()) {
     case HOURLY:
       millis = DateUtilities.ONE_HOUR;
       break;
     case MINUTELY:
       millis = DateUtilities.ONE_MINUTE;
       break;
     default:
       throw new RuntimeException(
           "Error handing subday repeat: " + rrule.getFreq()); // $NON-NLS-1$
   }
   long newDueDate = startDate.getMillis() + millis * rrule.getInterval();
   return Task.createDueDate(Task.URGENCY_SPECIFIC_DAY_TIME, newDueDate);
 }
  private static long handleMonthlyRepeat(
      DateTime original, DateValue startDateAsDV, boolean hasDueTime, RRule rrule) {
    if (original.isLastDayOfMonth()) {
      int interval = rrule.getInterval();

      DateTime newDateTime = original.plusMonths(interval);
      long time = newDateTime.withDayOfMonth(newDateTime.getNumberOfDaysInMonth()).getMillis();
      if (hasDueTime) {
        return Task.createDueDate(Task.URGENCY_SPECIFIC_DAY_TIME, time);
      } else {
        return Task.createDueDate(Task.URGENCY_SPECIFIC_DAY, time);
      }
    } else {
      return invokeRecurrence(rrule, original, startDateAsDV);
    }
  }
  private static long handleWeeklyRepeatAfterComplete(
      RRule rrule, Date original, boolean hasDueTime) {
    List<WeekdayNum> byDay = rrule.getByDay();
    long newDate = original.getTime();
    newDate += DateUtilities.ONE_WEEK * (rrule.getInterval() - 1);
    Calendar date = Calendar.getInstance();
    date.setTimeInMillis(newDate);

    Collections.sort(byDay, weekdayCompare);
    WeekdayNum next = findNextWeekday(byDay, date);

    do {
      date.add(Calendar.DATE, 1);
    } while (date.get(Calendar.DAY_OF_WEEK) != next.wday.javaDayNum);

    long time = date.getTimeInMillis();
    if (hasDueTime) return Task.createDueDate(Task.URGENCY_SPECIFIC_DAY_TIME, time);
    else return Task.createDueDate(Task.URGENCY_SPECIFIC_DAY, time);
  }
  private static long handleWeeklyRepeatAfterComplete(
      RRule rrule, DateTime original, boolean hasDueTime) {
    List<WeekdayNum> byDay = rrule.getByDay();
    long newDate = original.getMillis();
    newDate += DateUtilities.ONE_WEEK * (rrule.getInterval() - 1);
    DateTime date = new DateTime(newDate);

    Collections.sort(byDay, weekdayCompare);
    WeekdayNum next = findNextWeekday(byDay, date);

    do {
      date = date.plusDays(1);
    } while (date.getDayOfWeek() != next.wday.javaDayNum);

    long time = date.getMillis();
    if (hasDueTime) {
      return Task.createDueDate(Task.URGENCY_SPECIFIC_DAY_TIME, time);
    } else {
      return Task.createDueDate(Task.URGENCY_SPECIFIC_DAY, time);
    }
  }