// Path: src/main/java/com/exmertec/dummie/generator/data/DataGenerator.java
// public abstract class DataGenerator {
// 
//     private final List<FieldValueGenerator> generators;
// 
//     private final Set<String> randomFieldKeys;
// 
//     private final Set<Class<?>> randomFieldType;
// 
//     protected DataCache dataCache;
// 
//     protected GenerationStrategy strategy;
// 
//     public DataGenerator(GenerationStrategy strategy) {
//         this(strategy, new KeyValueDataCache());
//     }
// 
//     public DataGenerator(GenerationStrategy strategy, DataCache dataCache) {
//         this.dataCache = dataCache;
//         this.strategy = strategy;
// 
//         generators = new ArrayList<FieldValueGenerator>();
//         randomFieldKeys = new HashSet<String>();
//         randomFieldType = new HashSet<Class<?>>();
// 
//         addDefaultGenerators();
//     }
// 
//     private void addDefaultGenerators() {
//         generators.add(new StringFieldValueGenerator());
//         generators.add(new ListFieldValueGenerator());
//         generators.add(new MapFieldValueGenerator());
//         generators.add(new SetFieldValueGenerator());
//         generators.add(new BooleanFieldValueGenerator());
//         generators.add(new ByteFieldValueGenerator());
//         generators.add(new CharacterFieldValueGenerator());
//         generators.add(new DoubleFieldValueGenerator());
//         generators.add(new FloatFieldValueGenerator());
//         generators.add(new IntegerFieldValueGenerator());
//         generators.add(new LongFieldValueGenerator());
//         generators.add(new ShortFieldValueGenerator());
//         generators.add(new EnumFieldValueGenerator());
//         generators.add(new BigDecimalFieldValueGenerator());
//     }
// 
//     public Object getData(Field field) {
//         Class<?> fieldType = field.getType();
//         Object value = dataCache.getCachedData(fieldType, field.getName());
//         if (value == null) {
//             FieldValueGenerator generator = getGenerator(fieldType, field.getName());
//             if (generator != null) {
//                 value = generator.generate(this, field);
//             }
//         }
//         return value;
//     }
// 
//     public Object getData(Class<?> dataType, String key) {
//         Object value = dataCache.getCachedData(dataType, key);
//         if (value == null) {
//             FieldValueGenerator generator = getGenerator(dataType, key);
//             if (generator != null) {
//                 value = generator.generate(this, dataType, key);
//             }
//         }
//         return value;
//     }
// 
//     public <T> void cacheData(Class<T> dataType, String key, Object value) {
//         dataCache.cacheData(dataType, key, value);
//     }
// 
//     public <T> void cacheData(Class<T> clazz, Object value) {
//         dataCache.cacheData(clazz, value);
//     }
// 
//     public  <T> void dynamicCacheData(Class<T> dataType, String key, Object value) {
//         if (getStrategy(dataType, key) == GenerationStrategy.DEFAULT) {
//             dataCache.cacheData(dataType, key, value);
//         }
//     }
// 
//     public void random(Class<?> clazz) {
//         randomFieldType.add(clazz);
//     }
// 
//     public void random(String key) {
//         randomFieldKeys.add(key);
//     }
// 
//     protected GenerationStrategy getStrategy(Class<?> dataType, String key) {
//         return randomFieldType.contains(dataType) || randomFieldKeys.contains(key) ?
//             GenerationStrategy.RANDOM : strategy;
//     }
// 
//     protected FieldValueGenerator switchGeneratorStrategy(FieldValueGenerator generator,
//                                                           Class<?> dataType, String key) {
//         generator.setStrategy(getStrategy(dataType, key));
//         return generator;
//     }
// 
//     private FieldValueGenerator getGenerator(Class<?> dataType, String key) {
//         return switchGeneratorStrategy(getCachedGenerator(dataType), dataType, key);
//     }
// 
//     private FieldValueGenerator getCachedGenerator(Class<?> dataType) {
//         for (FieldValueGenerator generator: generators) {
//             if (generator.isMatchType(dataType)) {
//                 return generator;
//             }
//         }
// 
//         return getDefaultFieldValueGenerator(dataType);
//     }
// 
//     protected abstract FieldValueGenerator getDefaultFieldValueGenerator(Class<?> dataType);
// }
// 
// Path: src/main/java/com/exmertec/dummie/generator/Inflater.java
// public class Inflater {
//     private static <T> void inflateFields(T instance, DataGenerator dataGenerator, Class<T> classType) throws
//         IllegalAccessException, InvocationTargetException {
//         Field[] fields = classType.getDeclaredFields();
//         PropertyUtilsBean propertyUtils = BeanUtilsBean.getInstance().getPropertyUtils();
// 
//         for (Field field : fields) {
//             if (!propertyUtils.isWriteable(instance, field.getName())) {
//                 continue;
//             }
// 
//             Object value = dataGenerator.getData(field);
//             BeanUtils.setProperty(instance, field.getName(), value);
//         }
//     }
// 
//     public static <T> void inflateInstance(T instance, DataGenerator cache, Class<T> type) throws
//         InvocationTargetException, IllegalAccessException {
//         if (type != null) {
//             inflateFields(instance, cache, type);
//             inflateInstance(instance, cache, type.getSuperclass());
//         }
//     }
// }


import com.exmertec.dummie.generator.data.DataGenerator;
import com.exmertec.dummie.generator.Inflater;
package com.exmertec.dummie;


public class DummyBuilder<T> {
    private final Class<T> type;
    private final DataGenerator dataGenerator;

    public DummyBuilder(Class<T> type, DataGenerator dataGenerator) {
        this.type = type;
        this.dataGenerator = dataGenerator;
    }

    public T build() {
        try {
            T instance = type.newInstance();
// Path: src/main/java/com/exmertec/dummie/generator/data/DataGenerator.java
// public abstract class DataGenerator {
// 
//     private final List<FieldValueGenerator> generators;
// 
//     private final Set<String> randomFieldKeys;
// 
//     private final Set<Class<?>> randomFieldType;
// 
//     protected DataCache dataCache;
// 
//     protected GenerationStrategy strategy;
// 
//     public DataGenerator(GenerationStrategy strategy) {
//         this(strategy, new KeyValueDataCache());
//     }
// 
//     public DataGenerator(GenerationStrategy strategy, DataCache dataCache) {
//         this.dataCache = dataCache;
//         this.strategy = strategy;
// 
//         generators = new ArrayList<FieldValueGenerator>();
//         randomFieldKeys = new HashSet<String>();
//         randomFieldType = new HashSet<Class<?>>();
// 
//         addDefaultGenerators();
//     }
// 
//     private void addDefaultGenerators() {
//         generators.add(new StringFieldValueGenerator());
//         generators.add(new ListFieldValueGenerator());
//         generators.add(new MapFieldValueGenerator());
//         generators.add(new SetFieldValueGenerator());
//         generators.add(new BooleanFieldValueGenerator());
//         generators.add(new ByteFieldValueGenerator());
//         generators.add(new CharacterFieldValueGenerator());
//         generators.add(new DoubleFieldValueGenerator());
//         generators.add(new FloatFieldValueGenerator());
//         generators.add(new IntegerFieldValueGenerator());
//         generators.add(new LongFieldValueGenerator());
//         generators.add(new ShortFieldValueGenerator());
//         generators.add(new EnumFieldValueGenerator());
//         generators.add(new BigDecimalFieldValueGenerator());
//     }
// 
//     public Object getData(Field field) {
//         Class<?> fieldType = field.getType();
//         Object value = dataCache.getCachedData(fieldType, field.getName());
//         if (value == null) {
//             FieldValueGenerator generator = getGenerator(fieldType, field.getName());
//             if (generator != null) {
//                 value = generator.generate(this, field);
//             }
//         }
//         return value;
//     }
// 
//     public Object getData(Class<?> dataType, String key) {
//         Object value = dataCache.getCachedData(dataType, key);
//         if (value == null) {
//             FieldValueGenerator generator = getGenerator(dataType, key);
//             if (generator != null) {
//                 value = generator.generate(this, dataType, key);
//             }
//         }
//         return value;
//     }
// 
//     public <T> void cacheData(Class<T> dataType, String key, Object value) {
//         dataCache.cacheData(dataType, key, value);
//     }
// 
//     public <T> void cacheData(Class<T> clazz, Object value) {
//         dataCache.cacheData(clazz, value);
//     }
// 
//     public  <T> void dynamicCacheData(Class<T> dataType, String key, Object value) {
//         if (getStrategy(dataType, key) == GenerationStrategy.DEFAULT) {
//             dataCache.cacheData(dataType, key, value);
//         }
//     }
// 
//     public void random(Class<?> clazz) {
//         randomFieldType.add(clazz);
//     }
// 
//     public void random(String key) {
//         randomFieldKeys.add(key);
//     }
// 
//     protected GenerationStrategy getStrategy(Class<?> dataType, String key) {
//         return randomFieldType.contains(dataType) || randomFieldKeys.contains(key) ?
//             GenerationStrategy.RANDOM : strategy;
//     }
// 
//     protected FieldValueGenerator switchGeneratorStrategy(FieldValueGenerator generator,
//                                                           Class<?> dataType, String key) {
//         generator.setStrategy(getStrategy(dataType, key));
//         return generator;
//     }
// 
//     private FieldValueGenerator getGenerator(Class<?> dataType, String key) {
//         return switchGeneratorStrategy(getCachedGenerator(dataType), dataType, key);
//     }
// 
//     private FieldValueGenerator getCachedGenerator(Class<?> dataType) {
//         for (FieldValueGenerator generator: generators) {
//             if (generator.isMatchType(dataType)) {
//                 return generator;
//             }
//         }
// 
//         return getDefaultFieldValueGenerator(dataType);
//     }
// 
//     protected abstract FieldValueGenerator getDefaultFieldValueGenerator(Class<?> dataType);
// }
// 
// Path: src/main/java/com/exmertec/dummie/generator/Inflater.java
// public class Inflater {
//     private static <T> void inflateFields(T instance, DataGenerator dataGenerator, Class<T> classType) throws
//         IllegalAccessException, InvocationTargetException {
//         Field[] fields = classType.getDeclaredFields();
//         PropertyUtilsBean propertyUtils = BeanUtilsBean.getInstance().getPropertyUtils();
// 
//         for (Field field : fields) {
//             if (!propertyUtils.isWriteable(instance, field.getName())) {
//                 continue;
//             }
// 
//             Object value = dataGenerator.getData(field);
//             BeanUtils.setProperty(instance, field.getName(), value);
//         }
//     }
// 
//     public static <T> void inflateInstance(T instance, DataGenerator cache, Class<T> type) throws
//         InvocationTargetException, IllegalAccessException {
//         if (type != null) {
//             inflateFields(instance, cache, type);
//             inflateInstance(instance, cache, type.getSuperclass());
//         }
//     }
// }


// Path: src/main/java/com/exmertec/dummie/DummyBuilder.java
import com.exmertec.dummie.generator.data.DataGenerator;
import com.exmertec.dummie.generator.Inflater;

package com.exmertec.dummie;


public class DummyBuilder<T> {
    private final Class<T> type;
    private final DataGenerator dataGenerator;

    public DummyBuilder(Class<T> type, DataGenerator dataGenerator) {
        this.type = type;
        this.dataGenerator = dataGenerator;
    }

    public T build() {
        try {
            T instance = type.newInstance();
            Inflater.inflateInstance(instance, dataGenerator, type);