// Path: src/main/java/com/lowereast/guiceymongo/GuiceyMongoEvalException.java
// @SuppressWarnings("serial")
// public class GuiceyMongoEvalException extends MongoException {
// 	private static String _errorPrefix = "eval failed: { \"errno\" : -3.0 , \"errmsg\" : \"invoke failed: JS Error: ";
// 	
// 	private String _type;
// 	
// 	private GuiceyMongoEvalException(String exceptionType, String exceptionMessage) {
// 		super(exceptionMessage);
// 		_type = exceptionType;
// 	}
// 	
// 	public String getType() {
// 		return _type;
// 	}
// 	
// 	/**
// 	 * Will create a MongoEvalException if the exception passed in was created from an eval command.  Otherwise the exception passed in will be returned.
// 	 * @param e
// 	 * @return MongoEvalException if applicable, otherwise the exception passed in
// 	 */
// 	public static MongoException create(MongoException e) {
// 		String errorString = e.getMessage();
// 		if (errorString.startsWith(_errorPrefix)) {
// 			int length = _errorPrefix.length();
// 			int colonLocation = errorString.indexOf(':', length);
// 			String type = errorString.substring(length, colonLocation).trim();
// 			String message = errorString.substring(colonLocation + 1, errorString.indexOf('"', colonLocation)).trim();
// 			return new GuiceyMongoEvalException(type, message);
// 		}
// 		return e;
// 	}
// }
// 
// Path: src/main/java/com/lowereast/guiceymongo/data/DataWrapper.java
// public interface DataWrapper<T extends IsData> {
// 	T wrap(DBObject backing);
// }
// 
// Path: src/main/java/com/lowereast/guiceymongo/data/IsData.java
// public interface IsData {
// }
// 
// Path: src/main/java/com/lowereast/guiceymongo/data/IsWrapper.java
// public interface IsWrapper<T extends IsData> {
// 	DBObject getDBObject();
// }
// 
// Path: src/main/java/com/lowereast/guiceymongo/guice/GuiceyMongo.java
// public final class GuiceyMongo {
// 	private GuiceyMongo() {}
// 
// 	public static Builders.Configuration configure(String configurationName) {
// 		return new BuilderImpls.Configuration(configurationName);
// 	}
// 	
// 	public static Builders.Connection configureConnection(String connectionName) {
// 		return new BuilderImpls.Connection(connectionName);
// 	}
// 	
// 	public static Module chooseConfiguration(final String configurationName) {
// 		return new Module() {
// 			public void configure(Binder binder) {
// 				GuiceyMongoUtil.setCurrentConfiguration(binder.skipSources(GuiceyMongo.class), configurationName);
// 			}
// 		};
// 	}
// 	
// 	@SuppressWarnings("unchecked")
// 	public static Module javascriptProxy(Class<?> proxyInterface, String databaseKey) {
// 		return new JavascriptProxy(proxyInterface, databaseKey);
// 	}
// }


import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.Proxy;
import java.util.List;
import java.util.Map;
import com.google.inject.Binder;
import com.google.inject.Inject;
import com.google.inject.Injector;
import com.google.inject.Key;
import com.google.inject.Module;
import com.google.inject.Provider;
import com.google.inject.internal.Lists;
import com.google.inject.internal.Maps;
import com.lowereast.guiceymongo.GuiceyMongoEvalException;
import com.lowereast.guiceymongo.annotation.ItemType;
import com.lowereast.guiceymongo.data.DataWrapper;
import com.lowereast.guiceymongo.data.IsData;
import com.lowereast.guiceymongo.data.IsWrapper;
import com.lowereast.guiceymongo.guice.GuiceyMongo;
import com.mongodb.DB;
import com.mongodb.DBObject;
import com.mongodb.MongoException;
					
					String methodName = method.getName();
					Class<?> methodReturnType = method.getReturnType();
					Class<?>[] argumentTypes = method.getParameterTypes();
					
					if (Void.class.equals(methodReturnType) || void.class.equals(methodReturnType)) {
						if (argumentTypes.length == 0) {
							invocation = new VoidNoArgInvocation(methodName);
						} else {
							invocation = new VoidInvocation(methodName, argumentTypes);
						}
					} else {
						invocation = new ReturningInvocation(methodReturnType, method, argumentTypes);
					}
					
					_invocations.put(method, invocation);
				}
			}
		}
		
		public Object invoke(Object proxy, java.lang.reflect.Method method, Object[] args) throws Throwable {
			if (Object.class.equals(method.getDeclaringClass())) {
				return method.invoke(this, args);
			}
			try {
				Invocation invocation = _invocations.get(method);
				if (invocation == null)
					throw new RuntimeException();
				return invocation.invoke(_database, args);
			} catch (MongoException e) {
// Path: src/main/java/com/lowereast/guiceymongo/GuiceyMongoEvalException.java
// @SuppressWarnings("serial")
// public class GuiceyMongoEvalException extends MongoException {
// 	private static String _errorPrefix = "eval failed: { \"errno\" : -3.0 , \"errmsg\" : \"invoke failed: JS Error: ";
// 	
// 	private String _type;
// 	
// 	private GuiceyMongoEvalException(String exceptionType, String exceptionMessage) {
// 		super(exceptionMessage);
// 		_type = exceptionType;
// 	}
// 	
// 	public String getType() {
// 		return _type;
// 	}
// 	
// 	/**
// 	 * Will create a MongoEvalException if the exception passed in was created from an eval command.  Otherwise the exception passed in will be returned.
// 	 * @param e
// 	 * @return MongoEvalException if applicable, otherwise the exception passed in
// 	 */
// 	public static MongoException create(MongoException e) {
// 		String errorString = e.getMessage();
// 		if (errorString.startsWith(_errorPrefix)) {
// 			int length = _errorPrefix.length();
// 			int colonLocation = errorString.indexOf(':', length);
// 			String type = errorString.substring(length, colonLocation).trim();
// 			String message = errorString.substring(colonLocation + 1, errorString.indexOf('"', colonLocation)).trim();
// 			return new GuiceyMongoEvalException(type, message);
// 		}
// 		return e;
// 	}
// }
// 
// Path: src/main/java/com/lowereast/guiceymongo/data/DataWrapper.java
// public interface DataWrapper<T extends IsData> {
// 	T wrap(DBObject backing);
// }
// 
// Path: src/main/java/com/lowereast/guiceymongo/data/IsData.java
// public interface IsData {
// }
// 
// Path: src/main/java/com/lowereast/guiceymongo/data/IsWrapper.java
// public interface IsWrapper<T extends IsData> {
// 	DBObject getDBObject();
// }
// 
// Path: src/main/java/com/lowereast/guiceymongo/guice/GuiceyMongo.java
// public final class GuiceyMongo {
// 	private GuiceyMongo() {}
// 
// 	public static Builders.Configuration configure(String configurationName) {
// 		return new BuilderImpls.Configuration(configurationName);
// 	}
// 	
// 	public static Builders.Connection configureConnection(String connectionName) {
// 		return new BuilderImpls.Connection(connectionName);
// 	}
// 	
// 	public static Module chooseConfiguration(final String configurationName) {
// 		return new Module() {
// 			public void configure(Binder binder) {
// 				GuiceyMongoUtil.setCurrentConfiguration(binder.skipSources(GuiceyMongo.class), configurationName);
// 			}
// 		};
// 	}
// 	
// 	@SuppressWarnings("unchecked")
// 	public static Module javascriptProxy(Class<?> proxyInterface, String databaseKey) {
// 		return new JavascriptProxy(proxyInterface, databaseKey);
// 	}
// }


// Path: src/main/java/com/lowereast/guiceymongo/guice/spi/JavascriptProxy.java
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.Proxy;
import java.util.List;
import java.util.Map;
import com.google.inject.Binder;
import com.google.inject.Inject;
import com.google.inject.Injector;
import com.google.inject.Key;
import com.google.inject.Module;
import com.google.inject.Provider;
import com.google.inject.internal.Lists;
import com.google.inject.internal.Maps;
import com.lowereast.guiceymongo.GuiceyMongoEvalException;
import com.lowereast.guiceymongo.annotation.ItemType;
import com.lowereast.guiceymongo.data.DataWrapper;
import com.lowereast.guiceymongo.data.IsData;
import com.lowereast.guiceymongo.data.IsWrapper;
import com.lowereast.guiceymongo.guice.GuiceyMongo;
import com.mongodb.DB;
import com.mongodb.DBObject;
import com.mongodb.MongoException;

					
					String methodName = method.getName();
					Class<?> methodReturnType = method.getReturnType();
					Class<?>[] argumentTypes = method.getParameterTypes();
					
					if (Void.class.equals(methodReturnType) || void.class.equals(methodReturnType)) {
						if (argumentTypes.length == 0) {
							invocation = new VoidNoArgInvocation(methodName);
						} else {
							invocation = new VoidInvocation(methodName, argumentTypes);
						}
					} else {
						invocation = new ReturningInvocation(methodReturnType, method, argumentTypes);
					}
					
					_invocations.put(method, invocation);
				}
			}
		}
		
		public Object invoke(Object proxy, java.lang.reflect.Method method, Object[] args) throws Throwable {
			if (Object.class.equals(method.getDeclaringClass())) {
				return method.invoke(this, args);
			}
			try {
				Invocation invocation = _invocations.get(method);
				if (invocation == null)
					throw new RuntimeException();
				return invocation.invoke(_database, args);
			} catch (MongoException e) {
				throw GuiceyMongoEvalException.create(e);