// Path: 1_valueobjects/3_cglib/src/main/java/org/zalando/techtalks/hackingjava/valueobjects/cglib/DtoFactory.java
// static Class<?> createBeanClass(
// /* fully qualified class name */
// final String className,
// /* bean properties, name -> type */
// final Map<String, Class<?>> properties) {
// 
//     final BeanGenerator beanGenerator = new BeanGenerator();
// 
// /* use our own hard coded class name instead of a real naming policy */
//     beanGenerator.setNamingPolicy(new NamingPolicy() {
//         @Override public String getClassName(final String prefix,
//                                              final String source,
//                                              final Object key,
//                                              final Predicate names) {
//             return className;
//         }
//     });
//     BeanGenerator.addProperties(beanGenerator, properties);
//     return (Class<?>) beanGenerator.createClass();
// }


import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import java.time.LocalDate;
import java.util.List;
import static org.zalando.techtalks.hackingjava.valueobjects.cglib.DtoFactory.createBeanClass;
package org.zalando.techtalks.hackingjava.valueobjects.cglib;



public class UserFactory {
    public static Object createUser(final String firstName,
                                    final String lastName,
                                    final LocalDate birthDate,
                                    final String street,
                                    final int zipCode,
                                    final String city) {

        final Object address = DtoFactory.instantiateDto(Types.ADDRESS, ImmutableMap.of(
            "street", street, "zipCode", zipCode, "city", city
        ));
        final ImmutableList<Object> addresses = ImmutableList.of(address);
        final Object user = DtoFactory.instantiateDto(Types.USER,
                                                      ImmutableMap.of("firstName", firstName,
                                                                      "lastName", lastName,
                                                                      "addresses", addresses,
                                                                      "birthDate", birthDate),
                                                      ImmutableList.of("lastName",
                                                                       "firstName",
                                                                       "birthDate")
        );
        return user;
    }


    static class Types {
        private static final String PACKAGE = "org.zalando.techtalks.hackingjava.valueobjects.cglib.dto";
        private static final Class<?> USER;
        private static final Class<?> ADDRESS;

        static {
// Path: 1_valueobjects/3_cglib/src/main/java/org/zalando/techtalks/hackingjava/valueobjects/cglib/DtoFactory.java
// static Class<?> createBeanClass(
// /* fully qualified class name */
// final String className,
// /* bean properties, name -> type */
// final Map<String, Class<?>> properties) {
// 
//     final BeanGenerator beanGenerator = new BeanGenerator();
// 
// /* use our own hard coded class name instead of a real naming policy */
//     beanGenerator.setNamingPolicy(new NamingPolicy() {
//         @Override public String getClassName(final String prefix,
//                                              final String source,
//                                              final Object key,
//                                              final Predicate names) {
//             return className;
//         }
//     });
//     BeanGenerator.addProperties(beanGenerator, properties);
//     return (Class<?>) beanGenerator.createClass();
// }


// Path: 1_valueobjects/3_cglib/src/main/java/org/zalando/techtalks/hackingjava/valueobjects/cglib/UserFactory.java
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import java.time.LocalDate;
import java.util.List;
import static org.zalando.techtalks.hackingjava.valueobjects.cglib.DtoFactory.createBeanClass;

package org.zalando.techtalks.hackingjava.valueobjects.cglib;



public class UserFactory {
    public static Object createUser(final String firstName,
                                    final String lastName,
                                    final LocalDate birthDate,
                                    final String street,
                                    final int zipCode,
                                    final String city) {

        final Object address = DtoFactory.instantiateDto(Types.ADDRESS, ImmutableMap.of(
            "street", street, "zipCode", zipCode, "city", city
        ));
        final ImmutableList<Object> addresses = ImmutableList.of(address);
        final Object user = DtoFactory.instantiateDto(Types.USER,
                                                      ImmutableMap.of("firstName", firstName,
                                                                      "lastName", lastName,
                                                                      "addresses", addresses,
                                                                      "birthDate", birthDate),
                                                      ImmutableList.of("lastName",
                                                                       "firstName",
                                                                       "birthDate")
        );
        return user;
    }


    static class Types {
        private static final String PACKAGE = "org.zalando.techtalks.hackingjava.valueobjects.cglib.dto";
        private static final Class<?> USER;
        private static final Class<?> ADDRESS;

        static {
            USER = createBeanClass(PACKAGE + ".User",