// Path: src/main/java/com/naskar/fluentquery/impl/MethodRecordProxy.java
// public interface MethodRecordProxy<T> {
// 	
// 	Method getCalledMethod();
// 	
// 	T getProxy();
// 
// 	void clear();
// 
// 	List<Method> getMethods();
// 
// 	void setExecute(boolean b);
// 	
// }
// 
// Path: src/main/java/com/naskar/fluentquery/impl/TypeUtils.java
// public class TypeUtils {
// 	
// 	private static MethodRecordProxyFactory recordFactory;
// 	
// 	static {
// 		recordFactory = new MethodRecordProxyFactory() {
// 			public <T> MethodRecordProxy<T> create(Class<T> clazz) {
// 				return new MethodRecordProxyCGLib<T>(clazz);
// 			}
// 		};
// 	}
// 	
// 	public static void setMethodRecordProxyFactory(MethodRecordProxyFactory f) {
// 		recordFactory = f;
// 	}
// 	
// 	public static <E> E createInstance(Class<E> clazz) {
// 		try {
// 			return clazz.newInstance();
// 		} catch (Exception e) {
// 			throw new RuntimeException(e);
// 		}
// 	}
// 	
// 	public static <T> MethodRecordProxy<T> createProxy(Class<T> clazz) {
// 		return recordFactory.create(clazz);
// 	}
// 	
// 	private TypeUtils () {
// 	}
// 
// 	private static final Set<Class<?>> VALUE_TYPE = getValuesTypes();
// 
// 	public static boolean isValueType(Class<?> clazz) {
// 		return VALUE_TYPE.contains(clazz);
// 	}
// 
// 	private static Set<Class<?>> getValuesTypes() {
// 		Set<Class<?>> types = new HashSet<Class<?>>();
// 		
// 		types.add(Character.class);
// 		types.add(String.class);
// 		types.add(Boolean.class);
// 		types.add(Byte.class);
// 		types.add(Short.class);
// 		types.add(Integer.class);
// 		types.add(Long.class);
// 		types.add(Float.class);
// 		types.add(Double.class);
// 		types.add(Void.class);
// 		
// 		return types;
// 	}
// 
// }


import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Consumer;
import com.naskar.fluentquery.impl.MethodRecordProxy;
import com.naskar.fluentquery.impl.TypeUtils;
package com.naskar.fluentquery.mapping;



public class Mapping<T> {
	
	private Class<T> clazz;
	private String tableName;
	
	private Map<List<Method>, String> columns;
	
	private MethodRecordProxy<T> proxy;

	public Mapping<T> to(Class<T> clazz, String tableName) {
		this.clazz = clazz;
		this.tableName = tableName;
		this.proxy = TypeUtils.createProxy(clazz);
		this.columns = new HashMap<List<Method>, String>();
		return this;
	}
	
	public Mapping<T> map(Consumer<T> action, String columnName) {
		proxy.clear();
		action.accept(proxy.getProxy());
		columns.put(new ArrayList<Method>(proxy.getMethods()), columnName);
		return this;
	}
	
	public Class<T> getClazz() {
		return clazz;
	}
	
	public String getTableName() {
		return tableName;
	}
	
	public String getColumnName(List<Method> key) {
		return this.columns.get(key);
	}
	
// Path: src/main/java/com/naskar/fluentquery/impl/MethodRecordProxy.java
// public interface MethodRecordProxy<T> {
// 	
// 	Method getCalledMethod();
// 	
// 	T getProxy();
// 
// 	void clear();
// 
// 	List<Method> getMethods();
// 
// 	void setExecute(boolean b);
// 	
// }
// 
// Path: src/main/java/com/naskar/fluentquery/impl/TypeUtils.java
// public class TypeUtils {
// 	
// 	private static MethodRecordProxyFactory recordFactory;
// 	
// 	static {
// 		recordFactory = new MethodRecordProxyFactory() {
// 			public <T> MethodRecordProxy<T> create(Class<T> clazz) {
// 				return new MethodRecordProxyCGLib<T>(clazz);
// 			}
// 		};
// 	}
// 	
// 	public static void setMethodRecordProxyFactory(MethodRecordProxyFactory f) {
// 		recordFactory = f;
// 	}
// 	
// 	public static <E> E createInstance(Class<E> clazz) {
// 		try {
// 			return clazz.newInstance();
// 		} catch (Exception e) {
// 			throw new RuntimeException(e);
// 		}
// 	}
// 	
// 	public static <T> MethodRecordProxy<T> createProxy(Class<T> clazz) {
// 		return recordFactory.create(clazz);
// 	}
// 	
// 	private TypeUtils () {
// 	}
// 
// 	private static final Set<Class<?>> VALUE_TYPE = getValuesTypes();
// 
// 	public static boolean isValueType(Class<?> clazz) {
// 		return VALUE_TYPE.contains(clazz);
// 	}
// 
// 	private static Set<Class<?>> getValuesTypes() {
// 		Set<Class<?>> types = new HashSet<Class<?>>();
// 		
// 		types.add(Character.class);
// 		types.add(String.class);
// 		types.add(Boolean.class);
// 		types.add(Byte.class);
// 		types.add(Short.class);
// 		types.add(Integer.class);
// 		types.add(Long.class);
// 		types.add(Float.class);
// 		types.add(Double.class);
// 		types.add(Void.class);
// 		
// 		return types;
// 	}
// 
// }


// Path: src/main/java/com/naskar/fluentquery/mapping/Mapping.java
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Consumer;
import com.naskar.fluentquery.impl.MethodRecordProxy;
import com.naskar.fluentquery.impl.TypeUtils;

package com.naskar.fluentquery.mapping;



public class Mapping<T> {
	
	private Class<T> clazz;
	private String tableName;
	
	private Map<List<Method>, String> columns;
	
	private MethodRecordProxy<T> proxy;

	public Mapping<T> to(Class<T> clazz, String tableName) {
		this.clazz = clazz;
		this.tableName = tableName;
		this.proxy = TypeUtils.createProxy(clazz);
		this.columns = new HashMap<List<Method>, String>();
		return this;
	}
	
	public Mapping<T> map(Consumer<T> action, String columnName) {
		proxy.clear();
		action.accept(proxy.getProxy());
		columns.put(new ArrayList<Method>(proxy.getMethods()), columnName);
		return this;
	}
	
	public Class<T> getClazz() {
		return clazz;
	}
	
	public String getTableName() {
		return tableName;
	}
	
	public String getColumnName(List<Method> key) {
		return this.columns.get(key);
	}
	
	protected MethodRecordProxy<T> getProxy() {