@Override
  public DateTimeValueRange range(ChronoField field) {

    switch (field) {
      case DAY_OF_MONTH:
      case DAY_OF_WEEK:
      case MICRO_OF_DAY:
      case MICRO_OF_SECOND:
      case HOUR_OF_DAY:
      case HOUR_OF_AMPM:
      case MINUTE_OF_DAY:
      case MINUTE_OF_HOUR:
      case SECOND_OF_DAY:
      case SECOND_OF_MINUTE:
      case MILLI_OF_DAY:
      case MILLI_OF_SECOND:
      case NANO_OF_DAY:
      case NANO_OF_SECOND:
      case CLOCK_HOUR_OF_DAY:
      case CLOCK_HOUR_OF_AMPM:
      case EPOCH_DAY:
      case EPOCH_MONTH:
        return field.range();
    }
    Calendar jcal = Calendar.getInstance(LOCALE);
    int fieldIndex;
    switch (field) {
      case ERA:
        return DateTimeValueRange.of(jcal.getMinimum(Calendar.ERA) - JapaneseEra.ERA_OFFSET,
            jcal.getMaximum(Calendar.ERA) - JapaneseEra.ERA_OFFSET);
      case YEAR:
      case YEAR_OF_ERA:
        return DateTimeValueRange.of(LocalDate.MIN_YEAR, jcal.getGreatestMinimum(Calendar.YEAR),
            jcal.getLeastMaximum(Calendar.YEAR), LocalDate.MAX_YEAR);
      case MONTH_OF_YEAR:
        return DateTimeValueRange.of(jcal.getMinimum(Calendar.MONTH) + 1, jcal.getGreatestMinimum(Calendar.MONTH) + 1,
            jcal.getLeastMaximum(Calendar.MONTH) + 1, jcal.getMaximum(Calendar.MONTH) + 1);
      case DAY_OF_YEAR:
        fieldIndex = Calendar.DAY_OF_YEAR;
        break;
      default :
        // TODO: review the remaining fields
        throw new UnsupportedOperationException("Unimplementable field: " + field);
    }
    return DateTimeValueRange.of(jcal.getMinimum(fieldIndex), jcal.getGreatestMinimum(fieldIndex),
        jcal.getLeastMaximum(fieldIndex), jcal.getMaximum(fieldIndex));
  }