docs: private boolean advance(Calendar cal)
      {
          final boolean isTraceOn = TraceComponent.isAnyTracingEnabled();
          if (isTraceOn && tc.isEntryEnabled())
              Tr.entry(tc, "advance: " + toString(cal));
  
          // Loop until all conditions are satisfied.  Whenever the value of a
          // field is advanced, all of the more specific fields are reset, and the
          // loop is restarted to recheck constraints.
          //
          // For example, if now="2000-01-01 11:00:00" and hour="1,12",
          // year="2001", we first advance to "2001-01-01 00:00:00" and then to
          // "2001-01-01 01:00:00".  Note that it would be incorrect to not
          // clear the hour field as this would result in "2001-01-01 12:00:00".
          //
          // Note that if MONTH is being advanced, DAY_OF_MONTH must be reset
          // before advancing MONTH to avoid overflow when transitioning from
          // 31-Jan to Feb.  Theoretically, leap seconds would require SECOND to be
          // reset before modifying other values, but java.util.Calendar does not
          // recognize leap seconds, so this is done for consistency only.
          //
          // Since SECOND, MINUTE, HOUR_OF_DAY, and MONTH can only be range values,
          // we reset them to the lowest value in the allowed range to avoid
          // useless loop iterations.  For example, if now="2000-01-01 11:00:00"
          // and second="10" day="2", we first advance SECOND to 10, then we
          // advance the DAY_OF_MONTH to 2.  At this point, there is no reason to
          // reset SECOND to 0 since we will just loop and advance it back to 10.
          //
          // Because this implementation uses java.util.Calendar, spring DST will
          // skip hour(2) (display time jumps from 1:59:59 to 3:00:00), and autumn
          // DST will execute hour(1) only once (adding a second to a Calendar with
          // time 1:00:00 results in 2:00:00 regardless of whether it is the
          // "first" or "second" 1AM).
          for (;;)
          {
              if (cal.getTimeInMillis() > end)
              {
                  if (isTraceOn && tc.isEntryEnabled())
                      Tr.exit(tc, "advance: failed: " + toString(cal));
                  return false;
              }
  
              if (seconds != WILD_CARD)
              {
                  int second = cal.get(Calendar.SECOND);
                  if (!contains(seconds, second))
                  {
                      advance(cal, Calendar.SECOND, Calendar.MINUTE, seconds, second);
  
                      if (isTraceOn && tc.isDebugEnabled())
                          Tr.debug(tc, "advanced second: " + toString(cal));
                      continue;
                  }
              }
  
              if (minutes != WILD_CARD)
              {
                  int minute = cal.get(Calendar.MINUTE);
                  if (!contains(minutes, minute))
                  {
                      cal.set(Calendar.SECOND, firstOfWildCard(seconds)); // d659945.1
                      advance(cal, Calendar.MINUTE, Calendar.HOUR_OF_DAY, minutes, minute);
  
                      if (isTraceOn && tc.isDebugEnabled())
                          Tr.debug(tc, "advanced minute: " + toString(cal));
                      continue;
                  }
              }
  
              if (hours != WILD_CARD)
              {
                  int hour = cal.get(Calendar.HOUR_OF_DAY);
                  if (!contains(hours, hour))
                  {
                      // d659945.1 - Reset fields using firstOfWildCard.
                      cal.set(Calendar.SECOND, firstOfWildCard(seconds));
                      cal.set(Calendar.MINUTE, firstOfWildCard(minutes));
                      advance(cal, Calendar.HOUR_OF_DAY, Calendar.DAY_OF_MONTH, hours, hour);
  
                      if (isTraceOn && tc.isDebugEnabled())
                          Tr.debug(tc, "advanced hour: " + toString(cal));
                      continue;
                  }
              }
  
              if (advanceDayIfNeeded(cal))
              {
                  if (isTraceOn && tc.isDebugEnabled())
                      Tr.debug(tc, "advanced day: " + toString(cal));
  
                  // d659945.2 - Variable range bounds can result in expressions that
                  // never match for any month (for example, "30--2"), so ensure that
                  // we terminate when we advance past year 9999.
                  int year = cal.get(Calendar.YEAR);
                  if (year > ScheduleExpressionParser.MAXIMUM_YEAR)
                  {
                      if (isTraceOn && tc.isEntryEnabled())
                          Tr.exit(tc, "advance: failed: " + toString(cal));
                      return false;
                  }
  
                  continue;
              }
  
              if (months != WILD_CARD)
              {
                  int month = cal.get(Calendar.MONTH);
                  if (!contains(months, month))
                  {
                      // d659945.1 - Reset fields using firstOfWildCard.
                      cal.set(Calendar.SECOND, firstOfWildCard(seconds));
                      cal.set(Calendar.MINUTE, firstOfWildCard(minutes));
                      cal.set(Calendar.HOUR_OF_DAY, firstOfWildCard(hours));
                      cal.set(Calendar.DAY_OF_MONTH, 1);
  
                      advance(cal, Calendar.MONTH, Calendar.YEAR, months, month);
  
                      if (isTraceOn && tc.isDebugEnabled())
                          Tr.debug(tc, "advanced month: " + toString(cal));
                      continue;
                  }
              }
  
              int year = cal.get(Calendar.YEAR);
              if (years == null)
              {
                  if (year > ScheduleExpressionParser.MAXIMUM_YEAR) // d665298
                  {
                      if (isTraceOn && tc.isEntryEnabled())
                          Tr.exit(tc, "advance: failed: " + toString(cal));
                      return false;
                  }
              }
              else
              {
                  if (!years.get(year - ScheduleExpressionParser.MINIMUM_YEAR)) // d665298
                  {
                      // d659945.1 - Reset fields using firstOfWildCard.
                      cal.set(Calendar.SECOND, firstOfWildCard(seconds));
                      cal.set(Calendar.MINUTE, firstOfWildCard(minutes));
                      cal.set(Calendar.HOUR_OF_DAY, firstOfWildCard(hours));
                      cal.set(Calendar.DAY_OF_MONTH, 1);
                      cal.set(Calendar.MONTH, firstOfWildCard(months));
  
                      if (!advanceYear(cal, year))
                      {
                          if (isTraceOn && tc.isEntryEnabled())
                              Tr.exit(tc, "advance: failed to advance past year " + year);
                          return false;
                      }
  
                      if (isTraceOn && tc.isDebugEnabled())
                          Tr.debug(tc, "advanced year: " + toString(cal));
                      continue;
                  }
              }
  
              break;
          }
  
          if (isTraceOn && tc.isEntryEnabled())
              Tr.exit(tc, "advance: " + toString(cal));
          return true;
      }