// Path: src/main/java/com/insightfullogic/multiinherit/common/ResolutionInfo.java
// public final class ResolutionInfo {
// 
// 	private final String name;
// 	private final Class<?>[] parameterTypes;
// 
// 	public ResolutionInfo(final Method method) {
// 		super();
// 		name = method.getName();
// 		parameterTypes = method.getParameterTypes();
// 	}
// 
// 	@Override
// 	public int hashCode() {
// 		final int prime = 31;
// 		int result = 1;
// 		result = prime * result + ((name == null) ? 0 : name.hashCode());
// 		result = prime * result + Arrays.hashCode(parameterTypes);
// 		return result;
// 	}
// 
// 	@Override
// 	public boolean equals(final Object obj) {
// 		if (this == obj)
// 			return true;
// 		if (obj == null)
// 			return false;
// 		if (getClass() != obj.getClass())
// 			return false;
// 		final ResolutionInfo other = (ResolutionInfo) obj;
// 		if (name == null) {
// 			if (other.name != null)
// 				return false;
// 		} else if (!name.equals(other.name))
// 			return false;
// 		if (!Arrays.equals(parameterTypes, other.parameterTypes))
// 			return false;
// 		return true;
// 	}
// }


import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.util.Map;
import com.insightfullogic.multiinherit.common.ResolutionInfo;

package com.insightfullogic.multiinherit.reflection;



class MultiInvocationHandler implements InvocationHandler {

	private final Map<Class<?>, Object> cache;
	private final Map<ResolutionInfo, Method> preferences;

	public MultiInvocationHandler(final Map<Class<?>, Object> lookup, final Map<ResolutionInfo, Method> preferences) {
		super();
		cache = lookup;
		this.preferences = preferences;
	}

	@Override
	public Object invoke(final Object proxy, Method method, final Object[] args) throws Throwable {
		final Method preferred = preferences.get(new ResolutionInfo(method));
		if (preferred != null) {
			method = preferred;
		}

// Path: src/main/java/com/insightfullogic/multiinherit/common/ResolutionInfo.java
// public final class ResolutionInfo {
// 
// 	private final String name;
// 	private final Class<?>[] parameterTypes;
// 
// 	public ResolutionInfo(final Method method) {
// 		super();
// 		name = method.getName();
// 		parameterTypes = method.getParameterTypes();
// 	}
// 
// 	@Override
// 	public int hashCode() {
// 		final int prime = 31;
// 		int result = 1;
// 		result = prime * result + ((name == null) ? 0 : name.hashCode());
// 		result = prime * result + Arrays.hashCode(parameterTypes);
// 		return result;
// 	}
// 
// 	@Override
// 	public boolean equals(final Object obj) {
// 		if (this == obj)
// 			return true;
// 		if (obj == null)
// 			return false;
// 		if (getClass() != obj.getClass())
// 			return false;
// 		final ResolutionInfo other = (ResolutionInfo) obj;
// 		if (name == null) {
// 			if (other.name != null)
// 				return false;
// 		} else if (!name.equals(other.name))
// 			return false;
// 		if (!Arrays.equals(parameterTypes, other.parameterTypes))
// 			return false;
// 		return true;
// 	}
// }


// Path: src/main/java/com/insightfullogic/multiinherit/reflection/MultiInvocationHandler.java
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.util.Map;
import com.insightfullogic.multiinherit.common.ResolutionInfo;

package com.insightfullogic.multiinherit.reflection;



class MultiInvocationHandler implements InvocationHandler {

	private final Map<Class<?>, Object> cache;
	private final Map<ResolutionInfo, Method> preferences;

	public MultiInvocationHandler(final Map<Class<?>, Object> lookup, final Map<ResolutionInfo, Method> preferences) {
		super();
		cache = lookup;
		this.preferences = preferences;
	}

	@Override
	public Object invoke(final Object proxy, Method method, final Object[] args) throws Throwable {
		final Method preferred = preferences.get(new ResolutionInfo(method));
		if (preferred != null) {
			method = preferred;
		}

		final Object obj = cache.get(method.getDeclaringClass());
