// Path: jrand-core/src/main/java/me/xdrop/jrand/Generator.java
// public abstract class Generator<T> {
// 
//     private Rand randGen;
// 
//     public Generator() {
//         this.randGen = new Rand();
//     }
// 
//     public Rand random() {
//         return this.randGen;
//     }
// 
//     public abstract T gen();
// 
//     public String repeat(int times) {
//         StringBuilder sb = new StringBuilder();
//         while (times-- > 0) {
//             sb.append(gen());
//         }
//         return sb.toString();
//     }
// 
//     public String genString() {
//         return gen().toString();
//     }
// 
//     public List<T> genMany(int num) {
//         List<T> many = new ArrayList<>();
//         for (int n = 0; n < num; n++) {
//             many.add(gen());
//         }
//         return many;
//     }
// 
//     public List<T> genManyUnique(int num) {
//         List<T> many = new LinkedList<>();
//         Set<T> present = new HashSet<>();
// 
// 
//         for (int n = 0; n < num; n++) {
//             T gen;
//             do {
//                 gen = gen();
//             } while (present.contains(gen));
//             many.add(gen);
//             present.add(gen);
//         }
// 
//         return many;
//     }
// 
//     public Set<T> genManyAsSet(int num) {
//         List<T> many = new LinkedList<>();
//         for (int n = 0; n < num; n++) {
//             many.add(gen());
//         }
//         return new HashSet<>(many);
//     }
// 
// }
// 
// Path: jrand-core/src/main/java/me/xdrop/jrand/Tuple.java
// public class Tuple<K,V> {
//     K key;
//     V val;
// 
//     public Tuple(K key, V val) {
//         this.key = key;
//         this.val = val;
//     }
// 
//     public K getKey() {
//         return key;
//     }
// 
//     public void setKey(K key) {
//         this.key = key;
//     }
// 
//     public V getVal() {
//         return val;
//     }
// 
//     public void setVal(V val) {
//         this.val = val;
//     }
// 
//     public static <K,V> Tuple<K,V> from(K key, V val) {
//         return new Tuple<>(key,val);
//     }
// }
// 
// Path: jrand-core/src/main/java/me/xdrop/jrand/model/basics/enums/CHARSET.java
// public enum CHARSET {
// 
//     CHARS_LOWER(alphaLowerPoolChar),
//     CHARS_UPPER(alphaUpperPoolChar),
//     NUMBERS(numericPoolChar),
//     SYMBOLS(symbolsPoolChar);
// 
//     char[] charset;
// 
//     CHARSET(char[] set) {
//         this.charset = set;
//     }
// 
//     public char[] getCharset(){
//         return this.charset;
//     }
// 
// }


import me.xdrop.jrand.Generator;
import me.xdrop.jrand.Tuple;
import me.xdrop.jrand.annotation.Facade;
import me.xdrop.jrand.model.basics.enums.CHARSET;
import java.nio.charset.Charset;
import java.util.*;
        } else {
            return casing(Casing.UPPER);
        }
    }

    private void preparePool() {
        pool.clear();
        for (CHARSET charset: includedCharsets) {
            for (char c : charset.getCharset()){
                pool.add(c);
            }
        }
    }

    @Override
    public Character gen() {

        if (pool == null || pool.size() < 1){
            throw new RuntimeException("The character pool is empty, please ensure you call .pool()" +
                    "before continuing");
        }

        return pool.get(random().randInt(pool.size() - 1));
    }

    /**
     * When specifying a pool you can use this to generate an item from the pool
     * along with its index it in the pool
     * @return A {@link Tuple} of a character and its index in the pool
     */
// Path: jrand-core/src/main/java/me/xdrop/jrand/Generator.java
// public abstract class Generator<T> {
// 
//     private Rand randGen;
// 
//     public Generator() {
//         this.randGen = new Rand();
//     }
// 
//     public Rand random() {
//         return this.randGen;
//     }
// 
//     public abstract T gen();
// 
//     public String repeat(int times) {
//         StringBuilder sb = new StringBuilder();
//         while (times-- > 0) {
//             sb.append(gen());
//         }
//         return sb.toString();
//     }
// 
//     public String genString() {
//         return gen().toString();
//     }
// 
//     public List<T> genMany(int num) {
//         List<T> many = new ArrayList<>();
//         for (int n = 0; n < num; n++) {
//             many.add(gen());
//         }
//         return many;
//     }
// 
//     public List<T> genManyUnique(int num) {
//         List<T> many = new LinkedList<>();
//         Set<T> present = new HashSet<>();
// 
// 
//         for (int n = 0; n < num; n++) {
//             T gen;
//             do {
//                 gen = gen();
//             } while (present.contains(gen));
//             many.add(gen);
//             present.add(gen);
//         }
// 
//         return many;
//     }
// 
//     public Set<T> genManyAsSet(int num) {
//         List<T> many = new LinkedList<>();
//         for (int n = 0; n < num; n++) {
//             many.add(gen());
//         }
//         return new HashSet<>(many);
//     }
// 
// }
// 
// Path: jrand-core/src/main/java/me/xdrop/jrand/Tuple.java
// public class Tuple<K,V> {
//     K key;
//     V val;
// 
//     public Tuple(K key, V val) {
//         this.key = key;
//         this.val = val;
//     }
// 
//     public K getKey() {
//         return key;
//     }
// 
//     public void setKey(K key) {
//         this.key = key;
//     }
// 
//     public V getVal() {
//         return val;
//     }
// 
//     public void setVal(V val) {
//         this.val = val;
//     }
// 
//     public static <K,V> Tuple<K,V> from(K key, V val) {
//         return new Tuple<>(key,val);
//     }
// }
// 
// Path: jrand-core/src/main/java/me/xdrop/jrand/model/basics/enums/CHARSET.java
// public enum CHARSET {
// 
//     CHARS_LOWER(alphaLowerPoolChar),
//     CHARS_UPPER(alphaUpperPoolChar),
//     NUMBERS(numericPoolChar),
//     SYMBOLS(symbolsPoolChar);
// 
//     char[] charset;
// 
//     CHARSET(char[] set) {
//         this.charset = set;
//     }
// 
//     public char[] getCharset(){
//         return this.charset;
//     }
// 
// }


// Path: jrand-core/src/main/java/me/xdrop/jrand/generators/basics/CharacterGenerator.java
import me.xdrop.jrand.Generator;
import me.xdrop.jrand.Tuple;
import me.xdrop.jrand.annotation.Facade;
import me.xdrop.jrand.model.basics.enums.CHARSET;
import java.nio.charset.Charset;
import java.util.*;

        } else {
            return casing(Casing.UPPER);
        }
    }

    private void preparePool() {
        pool.clear();
        for (CHARSET charset: includedCharsets) {
            for (char c : charset.getCharset()){
                pool.add(c);
            }
        }
    }

    @Override
    public Character gen() {

        if (pool == null || pool.size() < 1){
            throw new RuntimeException("The character pool is empty, please ensure you call .pool()" +
                    "before continuing");
        }

        return pool.get(random().randInt(pool.size() - 1));
    }

    /**
     * When specifying a pool you can use this to generate an item from the pool
     * along with its index it in the pool
     * @return A {@link Tuple} of a character and its index in the pool
     */
    public Tuple<Character, Integer> genWithIndex() {