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);
 }
  /** Compute next due date */
  public static long computeNextDueDate(Task task, String recurrence) throws ParseException {
    boolean repeatAfterCompletion = task.getFlag(Task.FLAGS, Task.FLAG_REPEAT_AFTER_COMPLETION);
    RRule rrule = initRRule(recurrence);

    // initialize startDateAsDV
    Date original = setUpStartDate(task, repeatAfterCompletion, rrule.getFreq());
    DateValue startDateAsDV = setUpStartDateAsDV(task, original);

    if (rrule.getFreq() == Frequency.HOURLY || rrule.getFreq() == Frequency.MINUTELY)
      return handleSubdayRepeat(original, rrule);
    else if (rrule.getFreq() == Frequency.WEEKLY
        && rrule.getByDay().size() > 0
        && repeatAfterCompletion)
      return handleWeeklyRepeatAfterComplete(rrule, original, task.hasDueTime());
    else return invokeRecurrence(rrule, original, startDateAsDV);
  }
  /** Initialize RRule instance */
  private static RRule initRRule(String recurrence) throws ParseException {
    RRule rrule = new RRule(recurrence);

    // handle the iCalendar "byDay" field differently depending on if
    // we are weekly or otherwise
    if (rrule.getFreq() != Frequency.WEEKLY) rrule.setByDay(Collections.EMPTY_LIST);

    return rrule;
  }
  /** Compute next due date */
  public static long computeNextDueDate(Task task, String recurrence, boolean repeatAfterCompletion)
      throws ParseException {
    RRule rrule = initRRule(recurrence);

    // initialize startDateAsDV
    DateTime original = setUpStartDate(task, repeatAfterCompletion, rrule.getFreq());
    DateValue startDateAsDV = setUpStartDateAsDV(task, original);

    if (rrule.getFreq() == Frequency.HOURLY || rrule.getFreq() == Frequency.MINUTELY) {
      return handleSubdayRepeat(original, rrule);
    } else if (rrule.getFreq() == Frequency.WEEKLY
        && rrule.getByDay().size() > 0
        && repeatAfterCompletion) {
      return handleWeeklyRepeatAfterComplete(rrule, original, task.hasDueTime());
    } else if (rrule.getFreq() == Frequency.MONTHLY) {
      return handleMonthlyRepeat(original, startDateAsDV, task.hasDueTime(), rrule);
    } else {
      return invokeRecurrence(rrule, original, startDateAsDV);
    }
  }