// Path: src/main/java/io/smartcat/ranger/distribution/UniformDistribution.java
// public class UniformDistribution implements Distribution {
// 
//     private Random random = new Random();
// 
//     @Override
//     public int nextInt(int bound) {
//         return random.nextInt(bound);
//     }
// 
//     @Override
//     public int nextInt(int lower, int upper) {
//         return random.ints(1, lower, upper).findFirst().getAsInt();
//     }
// 
//     @Override
//     public long nextLong(long bound) {
//         return random.longs(1, 0, bound).findFirst().getAsLong();
//     }
// 
//     @Override
//     public long nextLong(long lower, long upper) {
//         return random.longs(1, lower, upper).findFirst().getAsLong();
//     }
// 
//     @Override
//     public double nextDouble(double lower, double upper) {
//         return random.doubles(1, lower, upper).findFirst().getAsDouble();
//     }
// 
//     @Override
//     public boolean nextBoolean() {
//         return random.nextBoolean();
//     }
// }


import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import io.smartcat.ranger.distribution.Distribution;
import io.smartcat.ranger.distribution.UniformDistribution;
package io.smartcat.ranger.core;



/**
 * Generates random strings of specified <code>length</code> and from specified character ranges.
 */
public class RandomContentStringValue extends Value<String> {

    private static final List<Range<Character>> DEFAULT_RANGES = Arrays.asList(new Range<Character>('a', 'z'),
            new Range<Character>('A', 'Z'), new Range<Character>('0', '9'));

    private final Value<Integer> lengthValue;
    private final List<Character> possibleCharacters;
    private final Distribution distribution;

    /**
     * Constructs random content string value with specified <code>lengthValue</code> and default character range.
     *
     * @param lengthValue Value that returns integer which represents length of generated string. It should never
     *            generate length that is less than 1.
     */
    public RandomContentStringValue(Value<Integer> lengthValue) {
        this(lengthValue, DEFAULT_RANGES);
    }

    /**
     * Constructs random content string value with specified <code>lengthValue</code> and specified
     * <code>charRanges</code>.
     *
     * @param lengthValue Value that returns integer which represents length of generated string. It should never
     *            generate length that is less than 1.
     * @param charRanges Ranges of characters from which string will be constructed.
     */
    public RandomContentStringValue(Value<Integer> lengthValue, List<Range<Character>> charRanges) {
        if (lengthValue == null) {
            throw new IllegalArgumentException("lengthValue cannot be null.");
        }
        this.lengthValue = lengthValue;
        Set<Character> chars = new HashSet<>();
        for (Range<Character> range : charRanges) {
            if (!range.isIncreasing()) {
                throw new IllegalArgumentException("All ranges must be increasing.");
            }
            for (Character c = range.getBeginning(); c <= range.getEnd(); c++) {
                chars.add(c);
            }
        }
        possibleCharacters = new ArrayList<>(chars);
// Path: src/main/java/io/smartcat/ranger/distribution/UniformDistribution.java
// public class UniformDistribution implements Distribution {
// 
//     private Random random = new Random();
// 
//     @Override
//     public int nextInt(int bound) {
//         return random.nextInt(bound);
//     }
// 
//     @Override
//     public int nextInt(int lower, int upper) {
//         return random.ints(1, lower, upper).findFirst().getAsInt();
//     }
// 
//     @Override
//     public long nextLong(long bound) {
//         return random.longs(1, 0, bound).findFirst().getAsLong();
//     }
// 
//     @Override
//     public long nextLong(long lower, long upper) {
//         return random.longs(1, lower, upper).findFirst().getAsLong();
//     }
// 
//     @Override
//     public double nextDouble(double lower, double upper) {
//         return random.doubles(1, lower, upper).findFirst().getAsDouble();
//     }
// 
//     @Override
//     public boolean nextBoolean() {
//         return random.nextBoolean();
//     }
// }


// Path: src/main/java/io/smartcat/ranger/core/RandomContentStringValue.java
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import io.smartcat.ranger.distribution.Distribution;
import io.smartcat.ranger.distribution.UniformDistribution;

package io.smartcat.ranger.core;



/**
 * Generates random strings of specified <code>length</code> and from specified character ranges.
 */
public class RandomContentStringValue extends Value<String> {

    private static final List<Range<Character>> DEFAULT_RANGES = Arrays.asList(new Range<Character>('a', 'z'),
            new Range<Character>('A', 'Z'), new Range<Character>('0', '9'));

    private final Value<Integer> lengthValue;
    private final List<Character> possibleCharacters;
    private final Distribution distribution;

    /**
     * Constructs random content string value with specified <code>lengthValue</code> and default character range.
     *
     * @param lengthValue Value that returns integer which represents length of generated string. It should never
     *            generate length that is less than 1.
     */
    public RandomContentStringValue(Value<Integer> lengthValue) {
        this(lengthValue, DEFAULT_RANGES);
    }

    /**
     * Constructs random content string value with specified <code>lengthValue</code> and specified
     * <code>charRanges</code>.
     *
     * @param lengthValue Value that returns integer which represents length of generated string. It should never
     *            generate length that is less than 1.
     * @param charRanges Ranges of characters from which string will be constructed.
     */
    public RandomContentStringValue(Value<Integer> lengthValue, List<Range<Character>> charRanges) {
        if (lengthValue == null) {
            throw new IllegalArgumentException("lengthValue cannot be null.");
        }
        this.lengthValue = lengthValue;
        Set<Character> chars = new HashSet<>();
        for (Range<Character> range : charRanges) {
            if (!range.isIncreasing()) {
                throw new IllegalArgumentException("All ranges must be increasing.");
            }
            for (Character c = range.getBeginning(); c <= range.getEnd(); c++) {
                chars.add(c);
            }
        }
        possibleCharacters = new ArrayList<>(chars);
        distribution = new UniformDistribution();