// Path: src/main/java/com/insightfullogic/multiinherit/api/MultiInjector.java
// public interface MultiInjector {
// 	
// 	public <T> T getInstance(Class<T> combined);
// 	
// }
// 
// Path: src/main/java/com/insightfullogic/multiinherit/api/TypeHierachyException.java
// public class TypeHierachyException extends RuntimeException {
// 
// 	public TypeHierachyException(final String message) {
// 		super(message);
// 	}
// 
// 	/**
// 	 * 
// 	 */
// 	private static final long serialVersionUID = -2994395832274210972L;
// 
// }


import static java.util.Arrays.asList;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;
import org.objectweb.asm.tree.AnnotationNode;
import org.objectweb.asm.tree.ClassNode;
import org.objectweb.asm.tree.FieldInsnNode;
import org.objectweb.asm.tree.FieldNode;
import org.objectweb.asm.tree.InsnList;
import org.objectweb.asm.tree.InsnNode;
import org.objectweb.asm.tree.MethodInsnNode;
import org.objectweb.asm.tree.MethodNode;
import org.objectweb.asm.tree.VarInsnNode;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.google.inject.Inject;
import com.google.inject.Injector;
import com.insightfullogic.multiinherit.api.MultiInjector;
import com.insightfullogic.multiinherit.api.Prefer;
import com.insightfullogic.multiinherit.api.TraitWith;
import com.insightfullogic.multiinherit.api.TypeHierachyException;
				final FieldNode field = new FieldNode(Opcodes.ACC_PUBLIC, fieldName, descriptor, null, null);

				// The Trait case:
				final TraitWith traitWith = inter.getAnnotation(TraitWith.class);
				if (traitWith != null) {
					final Class<?> impl = traitWith.value();
					immediateTraits.add(inter);
					addTrait(combined, traits, inter, impl);
				} else {
					field.visibleAnnotations = asList(new AnnotationNode(injectAnn));
				}

				final String internal = Type.getInternalName(inter);
				cn.interfaces.add(internal);
				cn.fields.add(field);

				for (final Method meth : inter.getMethods()) {
					methods.put(meth, new FieldInfo(fieldName, internal, Type.getDescriptor(inter)));
				}
			}

			// Validate trait final method implementations
			for (final Class<?> key : immediateTraits) {
				final TraitInfo info = traits.get(key);
				for (final Class<?> parent : info.getParentTraits().values()) {
					removeImplementedMethods(parent, info.getToImplement());
				}
				final List<Method> toImplement = new ArrayList<Method>(info.getToImplement());
				removeImplementedMethods(combined, toImplement);
				if (!toImplement.isEmpty()) {
// Path: src/main/java/com/insightfullogic/multiinherit/api/MultiInjector.java
// public interface MultiInjector {
// 	
// 	public <T> T getInstance(Class<T> combined);
// 	
// }
// 
// Path: src/main/java/com/insightfullogic/multiinherit/api/TypeHierachyException.java
// public class TypeHierachyException extends RuntimeException {
// 
// 	public TypeHierachyException(final String message) {
// 		super(message);
// 	}
// 
// 	/**
// 	 * 
// 	 */
// 	private static final long serialVersionUID = -2994395832274210972L;
// 
// }


// Path: src/main/java/com/insightfullogic/multiinherit/generation/GenerationMultiInjector.java
import static java.util.Arrays.asList;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;
import org.objectweb.asm.tree.AnnotationNode;
import org.objectweb.asm.tree.ClassNode;
import org.objectweb.asm.tree.FieldInsnNode;
import org.objectweb.asm.tree.FieldNode;
import org.objectweb.asm.tree.InsnList;
import org.objectweb.asm.tree.InsnNode;
import org.objectweb.asm.tree.MethodInsnNode;
import org.objectweb.asm.tree.MethodNode;
import org.objectweb.asm.tree.VarInsnNode;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.google.inject.Inject;
import com.google.inject.Injector;
import com.insightfullogic.multiinherit.api.MultiInjector;
import com.insightfullogic.multiinherit.api.Prefer;
import com.insightfullogic.multiinherit.api.TraitWith;
import com.insightfullogic.multiinherit.api.TypeHierachyException;

				final FieldNode field = new FieldNode(Opcodes.ACC_PUBLIC, fieldName, descriptor, null, null);

				// The Trait case:
				final TraitWith traitWith = inter.getAnnotation(TraitWith.class);
				if (traitWith != null) {
					final Class<?> impl = traitWith.value();
					immediateTraits.add(inter);
					addTrait(combined, traits, inter, impl);
				} else {
					field.visibleAnnotations = asList(new AnnotationNode(injectAnn));
				}

				final String internal = Type.getInternalName(inter);
				cn.interfaces.add(internal);
				cn.fields.add(field);

				for (final Method meth : inter.getMethods()) {
					methods.put(meth, new FieldInfo(fieldName, internal, Type.getDescriptor(inter)));
				}
			}

			// Validate trait final method implementations
			for (final Class<?> key : immediateTraits) {
				final TraitInfo info = traits.get(key);
				for (final Class<?> parent : info.getParentTraits().values()) {
					removeImplementedMethods(parent, info.getToImplement());
				}
				final List<Method> toImplement = new ArrayList<Method>(info.getToImplement());
				removeImplementedMethods(combined, toImplement);
				if (!toImplement.isEmpty()) {
					throw new TypeHierachyException(MessageFormat.format(