// Path: generators-core/src/main/java/io/generators/core/MoreFunctions.java
// public static Function<Long, Long> appendLuhnCheckDigit() {
//     return new LuhnCheckDigitFunction();
// }
// 
// Path: generators-core/src/main/java/io/generators/core/MoreFunctions.java
// public static Function<String, String> toLowerCase() {
//     return new ToLowerCaseFunction();
// }
// 
// Path: generators-core/src/main/java/io/generators/core/MoreFunctions.java
// public static Function<String, String> toUpperCase(@Nonnull Locale locale) {
//     return new ToUpperCaseFunction(checkNotNull(locale));
// }


import com.google.common.base.Function;
import com.google.common.collect.FluentIterable;
import java.util.List;
import java.util.Locale;
import java.util.Set;
import static com.google.common.base.Preconditions.checkArgument;
import static io.generators.core.MoreFunctions.appendLuhnCheckDigit;
import static io.generators.core.MoreFunctions.toLowerCase;
import static io.generators.core.MoreFunctions.toUpperCase;
import static java.lang.Math.pow;
    public static <T> Set<T> setFrom(int limit, Generator<T> generator) {
        return FluentIterable.from(new GeneratorIterable<>(generator)).limit(limit).toSet();
    }

    public static <T extends Enum<T>> Generator<T> randomEnum(Class<T> enumClass) {
        return new RandomEnumGenerator<>(enumClass);
    }

    /**
     * Creates Generator that appends Luhn check digit (modulus 10) to the number generated by {@code partialNumberGenerator}
     *
     * @param partialAccountNumberGenerator generator of the main part of the card number
     * @return generator that returns card/account numbers with calculated Luhn check Digit
     */
    public static Generator<Long> cardNumber(Generator<Long> partialAccountNumberGenerator) {
        return new TransformingGenerator<>(partialAccountNumberGenerator, appendLuhnCheckDigit());
    }

    public static Generator<Integer> nDigitPositiveInteger(int digits) {
        checkArgument(digits > 0 && digits < 11, "Number of digits must be between 1  and 10");
        int from = (int) pow(10, digits - 1);
        int to = (int) pow(10, digits);
        return new RandomPositiveIntegerGenerator(from, to);
    }

    public static <F, T> Generator<T> transform(Generator<F> delegate, Function<F, T> transformation) {
        return new TransformingGenerator<>(delegate, transformation);
    }

    public static Generator<String> upperCase(GeneratorOfInstance<String> delegate, Locale locale) {
// Path: generators-core/src/main/java/io/generators/core/MoreFunctions.java
// public static Function<Long, Long> appendLuhnCheckDigit() {
//     return new LuhnCheckDigitFunction();
// }
// 
// Path: generators-core/src/main/java/io/generators/core/MoreFunctions.java
// public static Function<String, String> toLowerCase() {
//     return new ToLowerCaseFunction();
// }
// 
// Path: generators-core/src/main/java/io/generators/core/MoreFunctions.java
// public static Function<String, String> toUpperCase(@Nonnull Locale locale) {
//     return new ToUpperCaseFunction(checkNotNull(locale));
// }


// Path: generators-core/src/main/java/io/generators/core/Generators.java
import com.google.common.base.Function;
import com.google.common.collect.FluentIterable;
import java.util.List;
import java.util.Locale;
import java.util.Set;
import static com.google.common.base.Preconditions.checkArgument;
import static io.generators.core.MoreFunctions.appendLuhnCheckDigit;
import static io.generators.core.MoreFunctions.toLowerCase;
import static io.generators.core.MoreFunctions.toUpperCase;
import static java.lang.Math.pow;

    public static <T> Set<T> setFrom(int limit, Generator<T> generator) {
        return FluentIterable.from(new GeneratorIterable<>(generator)).limit(limit).toSet();
    }

    public static <T extends Enum<T>> Generator<T> randomEnum(Class<T> enumClass) {
        return new RandomEnumGenerator<>(enumClass);
    }

    /**
     * Creates Generator that appends Luhn check digit (modulus 10) to the number generated by {@code partialNumberGenerator}
     *
     * @param partialAccountNumberGenerator generator of the main part of the card number
     * @return generator that returns card/account numbers with calculated Luhn check Digit
     */
    public static Generator<Long> cardNumber(Generator<Long> partialAccountNumberGenerator) {
        return new TransformingGenerator<>(partialAccountNumberGenerator, appendLuhnCheckDigit());
    }

    public static Generator<Integer> nDigitPositiveInteger(int digits) {
        checkArgument(digits > 0 && digits < 11, "Number of digits must be between 1  and 10");
        int from = (int) pow(10, digits - 1);
        int to = (int) pow(10, digits);
        return new RandomPositiveIntegerGenerator(from, to);
    }

    public static <F, T> Generator<T> transform(Generator<F> delegate, Function<F, T> transformation) {
        return new TransformingGenerator<>(delegate, transformation);
    }

    public static Generator<String> upperCase(GeneratorOfInstance<String> delegate, Locale locale) {
        return transform(delegate, toUpperCase(locale));