// Path: src/main/java/javafixes/collection/CollectionUtil.java
// @SafeVarargs
// public static <T> ArrayList<T> newList(T... values) {
//     ArrayList<T> list = new ArrayList<T>(values.length);
//     Collections.addAll(list, values);
//     return list;
// }
// 
// Path: src/main/java/javafixes/math/Decimal.java
// public static Decimal d(long unscaledValue, int scale) throws ArithmeticException {
//     return decimal(unscaledValue, scale);
// }
// 
// Path: src/main/java/javafixes/math/Decimal.java
// public static Decimal decimal(long unscaledValue, int scale) throws ArithmeticException {
//     while (unscaledValue != 0
//             && ((int) unscaledValue & 1) == 0
//             && unscaledValue % 10 == 0) {
//         unscaledValue /= 10;
// 
//         if (scale == Integer.MIN_VALUE) {
//             throw new ArithmeticException(format("Scale underflow - can't set scale to less than '%d'", Integer.MIN_VALUE));
//         }
//         scale--;
//     }
// 
//     return new LongDecimal(unscaledValue, scale);
// }
// 
// Path: src/test/java/javafixes/test/Random.java
// @SafeVarargs
// public static int randomInt(int from, int to, Function<Integer, Boolean>... validityConditions) {
//     return generateValidValue(
//             // typecast it to long as otherwise we could get int overflow
//             () -> (int) ((long) (Math.random() * ((long) to - (long) from + 1L)) + (long) from),
//             validityConditions
//     );
// }


import org.junit.Test;
import java.math.RoundingMode;
import java.util.List;
import static javafixes.collection.CollectionUtil.newList;
import static javafixes.math.Decimal.d;
import static javafixes.math.Decimal.decimal;
import static javafixes.test.Random.randomInt;
import static org.hamcrest.Matchers.equalTo;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.fail;
                "-100000000000000000000000005.5"
        ).forEach(value -> {
            for (RoundingMode roundingMode : RoundingMode.values()) {
                assertThat(decimal(value).descaleTo(1, roundingMode), equalTo(decimal(value)));
                assertThat(decimal(value).descaleTo(Integer.MAX_VALUE, roundingMode), equalTo(decimal(value)));
                assertThat(decimal(value).descaleTo(randomInt(2, Integer.MAX_VALUE - 1), roundingMode), equalTo(decimal(value)));
            }
        });

        newList(
                "100000000000000000000000005.501",
                "100000000000000000000000002.501",
                "100000000000000000000000001.001",
                "100000000000000000000000000.001",
                "-100000000000000000000000000.001",
                "-100000000000000000000000001.001",
                "-100000000000000000000000002.501",
                "-100000000000000000000000005.501"
        ).forEach(value -> {
            for (RoundingMode roundingMode : RoundingMode.values()) {
                assertThat(decimal(value).descaleTo(3, roundingMode), equalTo(decimal(value)));
                assertThat(decimal(value).descaleTo(Integer.MAX_VALUE, roundingMode), equalTo(decimal(value)));
                assertThat(decimal(value).descaleTo(randomInt(4, Integer.MAX_VALUE - 1), roundingMode), equalTo(decimal(value)));
            }
        });
    }

    @Test
    public void shouldWorkForDerivedMethods() {
        List<Decimal> numbers = newList(
// Path: src/main/java/javafixes/collection/CollectionUtil.java
// @SafeVarargs
// public static <T> ArrayList<T> newList(T... values) {
//     ArrayList<T> list = new ArrayList<T>(values.length);
//     Collections.addAll(list, values);
//     return list;
// }
// 
// Path: src/main/java/javafixes/math/Decimal.java
// public static Decimal d(long unscaledValue, int scale) throws ArithmeticException {
//     return decimal(unscaledValue, scale);
// }
// 
// Path: src/main/java/javafixes/math/Decimal.java
// public static Decimal decimal(long unscaledValue, int scale) throws ArithmeticException {
//     while (unscaledValue != 0
//             && ((int) unscaledValue & 1) == 0
//             && unscaledValue % 10 == 0) {
//         unscaledValue /= 10;
// 
//         if (scale == Integer.MIN_VALUE) {
//             throw new ArithmeticException(format("Scale underflow - can't set scale to less than '%d'", Integer.MIN_VALUE));
//         }
//         scale--;
//     }
// 
//     return new LongDecimal(unscaledValue, scale);
// }
// 
// Path: src/test/java/javafixes/test/Random.java
// @SafeVarargs
// public static int randomInt(int from, int to, Function<Integer, Boolean>... validityConditions) {
//     return generateValidValue(
//             // typecast it to long as otherwise we could get int overflow
//             () -> (int) ((long) (Math.random() * ((long) to - (long) from + 1L)) + (long) from),
//             validityConditions
//     );
// }


// Path: src/test/java/javafixes/math/DecimalDescaleTest.java
import org.junit.Test;
import java.math.RoundingMode;
import java.util.List;
import static javafixes.collection.CollectionUtil.newList;
import static javafixes.math.Decimal.d;
import static javafixes.math.Decimal.decimal;
import static javafixes.test.Random.randomInt;
import static org.hamcrest.Matchers.equalTo;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.fail;

                "-100000000000000000000000005.5"
        ).forEach(value -> {
            for (RoundingMode roundingMode : RoundingMode.values()) {
                assertThat(decimal(value).descaleTo(1, roundingMode), equalTo(decimal(value)));
                assertThat(decimal(value).descaleTo(Integer.MAX_VALUE, roundingMode), equalTo(decimal(value)));
                assertThat(decimal(value).descaleTo(randomInt(2, Integer.MAX_VALUE - 1), roundingMode), equalTo(decimal(value)));
            }
        });

        newList(
                "100000000000000000000000005.501",
                "100000000000000000000000002.501",
                "100000000000000000000000001.001",
                "100000000000000000000000000.001",
                "-100000000000000000000000000.001",
                "-100000000000000000000000001.001",
                "-100000000000000000000000002.501",
                "-100000000000000000000000005.501"
        ).forEach(value -> {
            for (RoundingMode roundingMode : RoundingMode.values()) {
                assertThat(decimal(value).descaleTo(3, roundingMode), equalTo(decimal(value)));
                assertThat(decimal(value).descaleTo(Integer.MAX_VALUE, roundingMode), equalTo(decimal(value)));
                assertThat(decimal(value).descaleTo(randomInt(4, Integer.MAX_VALUE - 1), roundingMode), equalTo(decimal(value)));
            }
        });
    }

    @Test
    public void shouldWorkForDerivedMethods() {
        List<Decimal> numbers = newList(
                d("5.5"), d("2.5"), d("1.6"), d("1.1"), d("1.0"), d("-1.0"),