// Path: lib/src/main/java/tk/zielony/randomdata/DataContext.java
// public class DataContext {
// 
//     private static final String LOCALE = "locale";
//     public static final String NAME = "name";
// 
//     protected final List<Map<String, Object>> stack = new ArrayList<>();
// 
//     void save() {
//         HashMap<String, Object> contextData = (HashMap<String, Object>) stack.get(stack.size() - 1);
//         HashMap<String, Object> clone = (HashMap<String, Object>) contextData.clone();
//         stack.add(clone);
//     }
// 
//     public DataContext() {
//         stack.add(new HashMap<>());
//     }
// 
//     void restore() {
//         stack.remove(stack.size() - 1);
//     }
// 
//     public <Type> Type get(String key) {
//         return (Type) stack.get(stack.size() - 1).get(key);
//     }
// 
//     public <Type> void set(String key, Type value) {
//         stack.get(stack.size() - 1).put(key, value);
//     }
// }
// 
// Path: lib/src/main/java/tk/zielony/randomdata/Generator.java
// public abstract class Generator<Type> implements SimpleGenerator<Type> {
//     private Matcher matcher;
// 
//     protected Matcher getDefaultMatcher() {
//         return f -> true;
//     }
// 
//     public Generator<Type> withMatcher(Matcher matcher) {
//         this.matcher = matcher;
//         return this;
//     }
// 
//     public <OutType> GeneratorWithTransformer<Type, OutType> withTransformer(Transformer<Type, OutType> transformer) {
//         return new GeneratorWithTransformer<>(this, transformer);
//     }
// 
//     protected boolean match(Target target) {
//         if (matcher == null)
//             matcher = getDefaultMatcher();
//         return matcher.matches(target);
//     }
// 
//     public Type next() {
//         return next(null);
//     }
// 
//     public abstract Type next(@Nullable DataContext context);
// 
//     public void reset() {
//     }
// }
// 
// Path: lib/src/main/java/tk/zielony/randomdata/Matcher.java
// public interface Matcher {
//     boolean matches(Target target);
// }


import tk.zielony.randomdata.DataContext;
import tk.zielony.randomdata.Generator;
import tk.zielony.randomdata.Matcher;
package tk.zielony.randomdata.person;


public class StringNameGenerator extends Generator<String> {
    private StringFirstNameGenerator firstNameGenerator;
    private StringLastNameGenerator lastNameGenerator;

    public StringNameGenerator() {
        firstNameGenerator = new StringFirstNameGenerator();
        lastNameGenerator = new StringLastNameGenerator();
    }

    public StringNameGenerator(Gender gender) {
        firstNameGenerator = new StringFirstNameGenerator(gender, true, true);
        lastNameGenerator = new StringLastNameGenerator();
    }

// Path: lib/src/main/java/tk/zielony/randomdata/DataContext.java
// public class DataContext {
// 
//     private static final String LOCALE = "locale";
//     public static final String NAME = "name";
// 
//     protected final List<Map<String, Object>> stack = new ArrayList<>();
// 
//     void save() {
//         HashMap<String, Object> contextData = (HashMap<String, Object>) stack.get(stack.size() - 1);
//         HashMap<String, Object> clone = (HashMap<String, Object>) contextData.clone();
//         stack.add(clone);
//     }
// 
//     public DataContext() {
//         stack.add(new HashMap<>());
//     }
// 
//     void restore() {
//         stack.remove(stack.size() - 1);
//     }
// 
//     public <Type> Type get(String key) {
//         return (Type) stack.get(stack.size() - 1).get(key);
//     }
// 
//     public <Type> void set(String key, Type value) {
//         stack.get(stack.size() - 1).put(key, value);
//     }
// }
// 
// Path: lib/src/main/java/tk/zielony/randomdata/Generator.java
// public abstract class Generator<Type> implements SimpleGenerator<Type> {
//     private Matcher matcher;
// 
//     protected Matcher getDefaultMatcher() {
//         return f -> true;
//     }
// 
//     public Generator<Type> withMatcher(Matcher matcher) {
//         this.matcher = matcher;
//         return this;
//     }
// 
//     public <OutType> GeneratorWithTransformer<Type, OutType> withTransformer(Transformer<Type, OutType> transformer) {
//         return new GeneratorWithTransformer<>(this, transformer);
//     }
// 
//     protected boolean match(Target target) {
//         if (matcher == null)
//             matcher = getDefaultMatcher();
//         return matcher.matches(target);
//     }
// 
//     public Type next() {
//         return next(null);
//     }
// 
//     public abstract Type next(@Nullable DataContext context);
// 
//     public void reset() {
//     }
// }
// 
// Path: lib/src/main/java/tk/zielony/randomdata/Matcher.java
// public interface Matcher {
//     boolean matches(Target target);
// }


// Path: person/src/main/java/tk/zielony/randomdata/person/StringNameGenerator.java
import tk.zielony.randomdata.DataContext;
import tk.zielony.randomdata.Generator;
import tk.zielony.randomdata.Matcher;

package tk.zielony.randomdata.person;


public class StringNameGenerator extends Generator<String> {
    private StringFirstNameGenerator firstNameGenerator;
    private StringLastNameGenerator lastNameGenerator;

    public StringNameGenerator() {
        firstNameGenerator = new StringFirstNameGenerator();
        lastNameGenerator = new StringLastNameGenerator();
    }

    public StringNameGenerator(Gender gender) {
        firstNameGenerator = new StringFirstNameGenerator(gender, true, true);
        lastNameGenerator = new StringLastNameGenerator();
    }

    public StringNameGenerator(Gender gender, boolean preventDuplicates, boolean allowTwoNames) {