// Path: src/main/java/com/lowereast/guiceymongo/annotation/Annotations.java
// public class Annotations {
// 	private static class AnnotationProxy<T extends Annotation> implements InvocationHandler {
// 		private final Class<T> _annotationClass;
// 		private final List<String> _elements = Lists.newArrayList();
// 		private final Map<String, Object> _values;
// 		private final Map<String, Method> _methods = Maps.newHashMap();
// 		
// 		public AnnotationProxy(Class<T> annotationClass, Map<String, Object> values) {
// 			_values = (values == null ? Maps.<String, Object>newHashMap() : new HashMap<String, Object>(values));
// 			_annotationClass = annotationClass;
// 			for (Method method : _annotationClass.getDeclaredMethods()) {
// 				if (Modifier.isPublic(method.getModifiers()) && Modifier.isAbstract(method.getModifiers()) && method.getParameterTypes().length == 0) {
// 					String elementName = method.getName();
// 					_elements.add(elementName);
// 					_methods.put(elementName, method);
// 					Object defaultValue = method.getDefaultValue();
// 					if (defaultValue != null && !_values.containsKey(elementName))
// 						_values.put(elementName, defaultValue);
// 				}
// 			}
// 		}
// 		
// 		private static boolean isEqualToAny(Object lhs, Object... rhs) {
// 			for (Object item : rhs) {
// 				if (lhs.equals(item))
// 					return true;
// 			}
// 			return false;
// 		}
// 		
// 		private int valueHashCode(Class<?> elementType, Object value) {
// 			if (elementType.isArray()) {
// 				return Arrays.hashCode((Object[])value);
// 			} else if (isEqualToAny(elementType,
// 					byte.class, Byte.class,
// 					char.class, Character.class,
// 					double.class, Double.class,
// 					float.class, Float.class,
// 					int.class, Integer.class,
// 					long.class, Long.class,
// 					short.class, Short.class,
// 					boolean.class, Boolean.class,
// 					String.class)
// 					|| elementType.isEnum()
// 					|| elementType.isAnnotation()) {
// 				return value.hashCode();
// 			}
// 			throw new RuntimeException("This shouldn't happen");
// 		}
// 		
// 		private int calculateHashCode() {
// 			// This is specified in java.lang.Annotation.
// 			int hashCode = 0;
// 			for (String element : _elements)
// 				hashCode += (127 * element.hashCode()) ^ valueHashCode(_methods.get(element).getReturnType(), _values.get(element));
// 			return hashCode;
// 		}
// 		
// 		private boolean checkEquals(Object other) throws Throwable {
// 			if (!_annotationClass.isAssignableFrom(other.getClass()))
// 				return false;
// 			for (String element : _elements) {
// 				Method method = _methods.get(element);
// 				method.setAccessible(true);
// 				Object value = _values.get(element);
// 				Object otherValue = method.invoke(other);
// 				if (!value.equals(otherValue))
// 					return false;
// 			}
// 			return true;
// 		}
// 		
// 		private String buildString() {
// 			StringBuilder builder = new StringBuilder("@").append(_annotationClass.getName());
// 			if (_elements.size() > 0) {
// 				builder.append("(");
// 				for (int x = 0; x < _elements.size(); ++x) {
// 					if (x > 0)
// 						builder.append(",");
// 					builder.append(_elements.get(x)).append("=").append(_values.get(_elements.get(x)));
// 				}
// 				builder.append(")");
// 			}
// 			return builder.toString();
// 		}
// 		
// 		// http://java.sun.com/j2se/1.5.0/docs/api/java/lang/annotation/Annotation.html
// 		public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// 			String methodName = method.getName();
// 
// 			if ("annotationType".equals(methodName)) {
// 				return _annotationClass;
// 			} else if ("equals".equals(methodName)) {
// 				return checkEquals(args[0]);
// 			} else if ("hashCode".equals(methodName)) {
// 				return calculateHashCode();
// 			} else if ("toString".equals(methodName)) {
// 				return buildString();
// 			} else if (_elements.contains(methodName)) {
// 				return _values.get(methodName);
// 			}
// 			throw new RuntimeException();
// 		}
// 	}
// 	
// 	public static <T extends Annotation> T proxy(Class<T> annotationClass) {
// 		return proxy(annotationClass, null);
// 	}
// 	
// 	@SuppressWarnings("unchecked")
// 	public static <T extends Annotation> T proxy(Class<T> annotationClass, Map<String, Object> values) {
// 		return (T)Proxy.newProxyInstance(annotationClass.getClassLoader(), new Class[] { annotationClass, Serializable.class }, new AnnotationProxy(annotationClass, values));
// 	}
// }


import com.google.inject.internal.ImmutableMap;
import com.lowereast.guiceymongo.annotation.Annotations;
import com.lowereast.guiceymongo.guice.annotation.GuiceyMongoBucket;
import com.lowereast.guiceymongo.guice.annotation.GuiceyMongoCollection;
import com.lowereast.guiceymongo.guice.annotation.GuiceyMongoDatabase;
/**
 *      Copyright (C) 2010 Lowereast Software
 *
 *   Licensed under the Apache License, Version 2.0 (the "License");
 *   you may not use this file except in compliance with the License.
 *   You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *   Unless required by applicable law or agreed to in writing, software
 *   distributed under the License is distributed on an "AS IS" BASIS,
 *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *   See the License for the specific language governing permissions and
 *   limitations under the License.
 */

package com.lowereast.guiceymongo.guice.spi;


final class AnnotationUtil {
	private AnnotationUtil() {}
	
	public static ClonedConfiguration clonedConfiguration(String configuration) {
// Path: src/main/java/com/lowereast/guiceymongo/annotation/Annotations.java
// public class Annotations {
// 	private static class AnnotationProxy<T extends Annotation> implements InvocationHandler {
// 		private final Class<T> _annotationClass;
// 		private final List<String> _elements = Lists.newArrayList();
// 		private final Map<String, Object> _values;
// 		private final Map<String, Method> _methods = Maps.newHashMap();
// 		
// 		public AnnotationProxy(Class<T> annotationClass, Map<String, Object> values) {
// 			_values = (values == null ? Maps.<String, Object>newHashMap() : new HashMap<String, Object>(values));
// 			_annotationClass = annotationClass;
// 			for (Method method : _annotationClass.getDeclaredMethods()) {
// 				if (Modifier.isPublic(method.getModifiers()) && Modifier.isAbstract(method.getModifiers()) && method.getParameterTypes().length == 0) {
// 					String elementName = method.getName();
// 					_elements.add(elementName);
// 					_methods.put(elementName, method);
// 					Object defaultValue = method.getDefaultValue();
// 					if (defaultValue != null && !_values.containsKey(elementName))
// 						_values.put(elementName, defaultValue);
// 				}
// 			}
// 		}
// 		
// 		private static boolean isEqualToAny(Object lhs, Object... rhs) {
// 			for (Object item : rhs) {
// 				if (lhs.equals(item))
// 					return true;
// 			}
// 			return false;
// 		}
// 		
// 		private int valueHashCode(Class<?> elementType, Object value) {
// 			if (elementType.isArray()) {
// 				return Arrays.hashCode((Object[])value);
// 			} else if (isEqualToAny(elementType,
// 					byte.class, Byte.class,
// 					char.class, Character.class,
// 					double.class, Double.class,
// 					float.class, Float.class,
// 					int.class, Integer.class,
// 					long.class, Long.class,
// 					short.class, Short.class,
// 					boolean.class, Boolean.class,
// 					String.class)
// 					|| elementType.isEnum()
// 					|| elementType.isAnnotation()) {
// 				return value.hashCode();
// 			}
// 			throw new RuntimeException("This shouldn't happen");
// 		}
// 		
// 		private int calculateHashCode() {
// 			// This is specified in java.lang.Annotation.
// 			int hashCode = 0;
// 			for (String element : _elements)
// 				hashCode += (127 * element.hashCode()) ^ valueHashCode(_methods.get(element).getReturnType(), _values.get(element));
// 			return hashCode;
// 		}
// 		
// 		private boolean checkEquals(Object other) throws Throwable {
// 			if (!_annotationClass.isAssignableFrom(other.getClass()))
// 				return false;
// 			for (String element : _elements) {
// 				Method method = _methods.get(element);
// 				method.setAccessible(true);
// 				Object value = _values.get(element);
// 				Object otherValue = method.invoke(other);
// 				if (!value.equals(otherValue))
// 					return false;
// 			}
// 			return true;
// 		}
// 		
// 		private String buildString() {
// 			StringBuilder builder = new StringBuilder("@").append(_annotationClass.getName());
// 			if (_elements.size() > 0) {
// 				builder.append("(");
// 				for (int x = 0; x < _elements.size(); ++x) {
// 					if (x > 0)
// 						builder.append(",");
// 					builder.append(_elements.get(x)).append("=").append(_values.get(_elements.get(x)));
// 				}
// 				builder.append(")");
// 			}
// 			return builder.toString();
// 		}
// 		
// 		// http://java.sun.com/j2se/1.5.0/docs/api/java/lang/annotation/Annotation.html
// 		public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// 			String methodName = method.getName();
// 
// 			if ("annotationType".equals(methodName)) {
// 				return _annotationClass;
// 			} else if ("equals".equals(methodName)) {
// 				return checkEquals(args[0]);
// 			} else if ("hashCode".equals(methodName)) {
// 				return calculateHashCode();
// 			} else if ("toString".equals(methodName)) {
// 				return buildString();
// 			} else if (_elements.contains(methodName)) {
// 				return _values.get(methodName);
// 			}
// 			throw new RuntimeException();
// 		}
// 	}
// 	
// 	public static <T extends Annotation> T proxy(Class<T> annotationClass) {
// 		return proxy(annotationClass, null);
// 	}
// 	
// 	@SuppressWarnings("unchecked")
// 	public static <T extends Annotation> T proxy(Class<T> annotationClass, Map<String, Object> values) {
// 		return (T)Proxy.newProxyInstance(annotationClass.getClassLoader(), new Class[] { annotationClass, Serializable.class }, new AnnotationProxy(annotationClass, values));
// 	}
// }


// Path: src/main/java/com/lowereast/guiceymongo/guice/spi/AnnotationUtil.java
import com.google.inject.internal.ImmutableMap;
import com.lowereast.guiceymongo.annotation.Annotations;
import com.lowereast.guiceymongo.guice.annotation.GuiceyMongoBucket;
import com.lowereast.guiceymongo.guice.annotation.GuiceyMongoCollection;
import com.lowereast.guiceymongo.guice.annotation.GuiceyMongoDatabase;

/**
 *      Copyright (C) 2010 Lowereast Software
 *
 *   Licensed under the Apache License, Version 2.0 (the "License");
 *   you may not use this file except in compliance with the License.
 *   You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *   Unless required by applicable law or agreed to in writing, software
 *   distributed under the License is distributed on an "AS IS" BASIS,
 *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *   See the License for the specific language governing permissions and
 *   limitations under the License.
 */

package com.lowereast.guiceymongo.guice.spi;


final class AnnotationUtil {
	private AnnotationUtil() {}
	
	public static ClonedConfiguration clonedConfiguration(String configuration) {
		return Annotations.proxy(ClonedConfiguration.class, ImmutableMap.<String, Object>of("configuration", configuration));