@SuppressWarnings("unchecked")
	private ClassNode newConcreteTrait(final TraitInfo info) {
		final Type interfaceType = Type.getType(info.getInterfase());
		final Type superType = Type.getType(info.getImplementation());
		final String implName = superType.getInternalName();
		final ClassNode cn = new ClassNode();
		final List<Method> toImplement = info.getToImplement();
		final Map<Class<?>, Class<?>> parentTraits = info.getParentTraits();
		cn.version = Opcodes.V1_6;
		cn.access = Opcodes.ACC_PUBLIC;
		cn.name = implName + "Concrete";
		cn.superName = implName;

		newParamConstructor(cn, types(toImplement.size(), interfaceType));

		// add trait fields, one for each possible method overload
		for (int i = 0; i < toImplement.size(); i++) {
			cn.fields.add(new FieldNode(Opcodes.ACC_PUBLIC, "overload" + i, interfaceType.getDescriptor(), null, null));
		}

		{
			int i = 0;
			for (final Method method : toImplement) {
				final FieldInfo fi = new FieldInfo("overload" + i, interfaceType.getInternalName(), interfaceType.getDescriptor());
				cn.methods.add(newAdapterMethod(cn.name, method, fi));
				i++;
			}
		}

		// add fields for parent classes
		{
			int i = 0;
			for (final Entry<Class<?>, Class<?>> parent : parentTraits.entrySet()) {
				final Type parentInterfaceType = Type.getType(parent.getKey());
				final String fieldName = "parent" + i;
				cn.fields.add(new FieldNode(Opcodes.ACC_PUBLIC, fieldName, parentInterfaceType.getDescriptor(), null, null));
				final FieldInfo fi = new FieldInfo(fieldName, parentInterfaceType.getInternalName(), parentInterfaceType.getDescriptor());
				for (final Method method : parent.getValue().getDeclaredMethods()) {
					cn.methods.add(newAdapterMethod(cn.name, method, fi));
				}
				i++;
			}
		}

		return cn;
	}