public YearMonthDurationAttribute(boolean negative, long years,
                                      long months)
        throws IllegalArgumentException {
        super(identifierURI);
        this.negative = negative;
        this.years = years;
        this.months = months;

        // Convert all the components except nanoseconds to milliseconds

        // If any of the components is big (too big to be an int),
        // use the BigInteger class to do the math so we can detect
        // overflow.
        if ((years > Integer.MAX_VALUE) || (months > Integer.MAX_VALUE)) {
            if (big12 == null) {
                big12 = BigInteger.valueOf(12);
                bigMaxLong = BigInteger.valueOf(Long.MAX_VALUE);
            }
            BigInteger bigMonths = BigInteger.valueOf(months);
            BigInteger bigYears = BigInteger.valueOf(years);

            BigInteger bigTotal = bigYears.multiply(big12).add(bigMonths);

            // If the result is bigger than Long.MAX_VALUE, we have an
            // overflow. Indicate an error (should be a processing error,
            // since it can be argued that we should handle gigantic
            // values for this).
            if (bigTotal.compareTo(bigMaxLong) == 1)
                throw new IllegalArgumentException("total number of " +
                                                   "months " +
                                                   "exceeds Long.MAX_VALUE");
            // If no overflow, convert to a long.
            totalMonths = bigTotal.longValue();
            if (negative)
                totalMonths = - totalMonths;
        } else {
            // The numbers are small, so do it the fast way.
            totalMonths = ((years * 12) + months) * (negative ? -1 : 1);
        }
    }