// Path: hamcrest/hamcrest-matchers/src/main/java/it/ozimov/cirneco/hamcrest/date/utils/CalendarUtils.java
// public class CalendarUtils {
// 
//     private CalendarUtils() {
//     }
// 
//     public static Calendar fromDateToCalendar(final Date date) {
//         final Calendar cal = new GregorianCalendar();
//         cal.clear();
//         cal.setMinimalDaysInFirstWeek(4);
//         cal.setFirstDayOfWeek(Calendar.MONDAY);
//         cal.setTime(date);
// 
//         return cal;
//     }
// 
//     public static int weekDay(final Date date) {
//         return fromDateToCalendar(date).get(DAY_OF_WEEK);
//     }
// 
//     /**
//      * Returns the month from the day, i.e. a number between 1 (January) and 12 (December).
//      */
//     public static int month(final Date date) {
//         return fromDateToCalendar(date).get(MONTH) + 1;
//     }
// 
//     /**
//      * Returns the week fo the year according to the ISO 8601 standard.
//      */
//     public static int weekOfYear(final Date date) {
//         return fromDateToCalendar(date).get(Calendar.WEEK_OF_YEAR);
//     }
// 
//     public static int day(final Date date) {
//         return fromDateToCalendar(date).get(Calendar.DAY_OF_MONTH);
//     }
// 
//     public static int dayOfYear(final Date date) {
//         return fromDateToCalendar(date).get(Calendar.DAY_OF_YEAR);
//     }
// 
//     public static int year(final Date date) {
//         return fromDateToCalendar(date).get(YEAR);
//     }
// 
//     public static boolean isLeapYear(final Date date) {
//         return new GregorianCalendar().isLeapYear(year(date));
//     }
// 
//     public static boolean isAM(final Date date) {
//         return fromDateToCalendar(date).get(AM_PM) == 0;
//     }
// 
//     public static boolean isPM(final Date date) {
//         return !isAM(date);
//     }
// 
//     public static int hour12(final Date date) {
//         return fromDateToCalendar(date).get(HOUR);
//     }
// 
//     public static int hour24(final Date date) {
//         return fromDateToCalendar(date).get(HOUR_OF_DAY);
//     }
// 
//     public static int minute(final Date date) {
//         return fromDateToCalendar(date).get(MINUTE);
//     }
// 
//     public static int second(final Date date) {
//         return fromDateToCalendar(date).get(SECOND);
//     }
// 
//     public static int millisecond(final Date date) {
//         return fromDateToCalendar(date).get(MILLISECOND);
//     }
// 
// }


import com.google.common.collect.ImmutableSet;
import it.ozimov.cirneco.hamcrest.date.utils.CalendarUtils;
import org.hamcrest.Description;
import org.hamcrest.Matcher;
import org.hamcrest.TypeSafeMatcher;
import java.util.Date;
import static com.google.common.base.Preconditions.checkArgument;

    /**
     * Creates a matcher that matches when the examined {@linkplain Date} has the given values <code>year</code> and
     * <code>id</code>.
     */
    public static Matcher<Date> hasYearAndMonth(final int year, final int month) {
        return new IsDate(year, month, null);
    }

    /**
     * Creates a matcher that matches when the examined {@linkplain Date} has the given values <code>year</code>, <code>
     * id</code> and <code>day</code>.
     */
    public static Matcher<Date> hasYearMonthAndDay(final int year, final int month, final int day) {
        return new IsDate(year, month, day);
    }

    @Override
    protected boolean matchesSafely(final Date date) {
        boolean matches = true;

        if (year != null) {
            matches = year == CalendarUtils.year(date);
        }

        if (matches && (month != null)) {
            matches = month == CalendarUtils.month(date);
        }

        if (matches && (day != null)) {
// Path: hamcrest/hamcrest-matchers/src/main/java/it/ozimov/cirneco/hamcrest/date/utils/CalendarUtils.java
// public class CalendarUtils {
// 
//     private CalendarUtils() {
//     }
// 
//     public static Calendar fromDateToCalendar(final Date date) {
//         final Calendar cal = new GregorianCalendar();
//         cal.clear();
//         cal.setMinimalDaysInFirstWeek(4);
//         cal.setFirstDayOfWeek(Calendar.MONDAY);
//         cal.setTime(date);
// 
//         return cal;
//     }
// 
//     public static int weekDay(final Date date) {
//         return fromDateToCalendar(date).get(DAY_OF_WEEK);
//     }
// 
//     /**
//      * Returns the month from the day, i.e. a number between 1 (January) and 12 (December).
//      */
//     public static int month(final Date date) {
//         return fromDateToCalendar(date).get(MONTH) + 1;
//     }
// 
//     /**
//      * Returns the week fo the year according to the ISO 8601 standard.
//      */
//     public static int weekOfYear(final Date date) {
//         return fromDateToCalendar(date).get(Calendar.WEEK_OF_YEAR);
//     }
// 
//     public static int day(final Date date) {
//         return fromDateToCalendar(date).get(Calendar.DAY_OF_MONTH);
//     }
// 
//     public static int dayOfYear(final Date date) {
//         return fromDateToCalendar(date).get(Calendar.DAY_OF_YEAR);
//     }
// 
//     public static int year(final Date date) {
//         return fromDateToCalendar(date).get(YEAR);
//     }
// 
//     public static boolean isLeapYear(final Date date) {
//         return new GregorianCalendar().isLeapYear(year(date));
//     }
// 
//     public static boolean isAM(final Date date) {
//         return fromDateToCalendar(date).get(AM_PM) == 0;
//     }
// 
//     public static boolean isPM(final Date date) {
//         return !isAM(date);
//     }
// 
//     public static int hour12(final Date date) {
//         return fromDateToCalendar(date).get(HOUR);
//     }
// 
//     public static int hour24(final Date date) {
//         return fromDateToCalendar(date).get(HOUR_OF_DAY);
//     }
// 
//     public static int minute(final Date date) {
//         return fromDateToCalendar(date).get(MINUTE);
//     }
// 
//     public static int second(final Date date) {
//         return fromDateToCalendar(date).get(SECOND);
//     }
// 
//     public static int millisecond(final Date date) {
//         return fromDateToCalendar(date).get(MILLISECOND);
//     }
// 
// }


// Path: hamcrest/hamcrest-matchers/src/main/java/it/ozimov/cirneco/hamcrest/date/IsDate.java
import com.google.common.collect.ImmutableSet;
import it.ozimov.cirneco.hamcrest.date.utils.CalendarUtils;
import org.hamcrest.Description;
import org.hamcrest.Matcher;
import org.hamcrest.TypeSafeMatcher;
import java.util.Date;
import static com.google.common.base.Preconditions.checkArgument;


    /**
     * Creates a matcher that matches when the examined {@linkplain Date} has the given values <code>year</code> and
     * <code>id</code>.
     */
    public static Matcher<Date> hasYearAndMonth(final int year, final int month) {
        return new IsDate(year, month, null);
    }

    /**
     * Creates a matcher that matches when the examined {@linkplain Date} has the given values <code>year</code>, <code>
     * id</code> and <code>day</code>.
     */
    public static Matcher<Date> hasYearMonthAndDay(final int year, final int month, final int day) {
        return new IsDate(year, month, day);
    }

    @Override
    protected boolean matchesSafely(final Date date) {
        boolean matches = true;

        if (year != null) {
            matches = year == CalendarUtils.year(date);
        }

        if (matches && (month != null)) {
            matches = month == CalendarUtils.month(date);
        }

        if (matches && (day != null)) {
            matches = day == CalendarUtils.day(date);