class DefaultDateRangeLimiter implements DateRangeLimiter {

    @Override
    public @NonNull Calendar setToNearestDate(@NonNull Calendar calendar) {
        if (!selectableDays.isEmpty()) {
            Calendar newCalendar = null;
            Calendar higher = selectableDays.ceiling(calendar);
            Calendar lower = selectableDays.lower(calendar);

            if (higher == null && lower != null) newCalendar = lower;
            else if (lower == null && higher != null) newCalendar = higher;

            if (newCalendar != null || higher == null) {
                newCalendar = newCalendar == null ? calendar : newCalendar;
                TimeZone timeZone = mController == null ? TimeZone.getDefault() : mController.getTimeZone();
                newCalendar.setTimeZone(timeZone);
                return (Calendar) newCalendar.clone();
            }

            long highDistance = Math.abs(higher.getTimeInMillis() - calendar.getTimeInMillis());
            long lowDistance = Math.abs(calendar.getTimeInMillis() - lower.getTimeInMillis());

            if (lowDistance < highDistance) return (Calendar) lower.clone();
            else return (Calendar) higher.clone();
        }

        if (!disabledDays.isEmpty()) {
            Calendar forwardDate = isBeforeMin(calendar) ? getStartDate() : (Calendar) calendar.clone();
            Calendar backwardDate = isAfterMax(calendar) ? getEndDate() : (Calendar) calendar.clone();
            while (isDisabled(forwardDate) && isDisabled(backwardDate)) {
                forwardDate.add(Calendar.DAY_OF_MONTH, 1);
                backwardDate.add(Calendar.DAY_OF_MONTH, -1);
            }
            if (!isDisabled(backwardDate)) {
                return backwardDate;
            }
            if (!isDisabled(forwardDate)) {
                return forwardDate;
            }
        }

        TimeZone timezone = mController == null ? TimeZone.getDefault() : mController.getTimeZone();
        if (isBeforeMin(calendar)) {
            if (mMinDate != null) return (Calendar) mMinDate.clone();
            Calendar output = Calendar.getInstance(timezone);
            output.set(Calendar.YEAR, mMinYear);
            output.set(Calendar.MONTH, Calendar.JANUARY);
            output.set(Calendar.DAY_OF_MONTH, 1);
            return Utils.trimToMidnight(output);
        }

        if (isAfterMax(calendar)) {
            if (mMaxDate != null) return (Calendar) mMaxDate.clone();
            Calendar output = Calendar.getInstance(timezone);
            output.set(Calendar.YEAR, mMaxYear);
            output.set(Calendar.MONTH, Calendar.DECEMBER);
            output.set(Calendar.DAY_OF_MONTH, 31);
            return Utils.trimToMidnight(output);
        }

        return calendar;
    }

      DefaultDateRangeLimiter();
    @SuppressWarnings({"unchecked", "WeakerAccess"}) public  DefaultDateRangeLimiter(Parcel in);

}