public byte[] buildClass(ClassDefinition core, ClassLoader classLoader)
      throws IOException, SecurityException, IllegalArgumentException, ClassNotFoundException,
          NoSuchMethodException, IllegalAccessException, InvocationTargetException,
          InstantiationException, NoSuchFieldException {

    FieldVisitor fv;
    MethodVisitor mv;

    // get the method bitmask
    BitSet mask = traitRegistry.getFieldMask(trait.getName(), core.getDefinedClass().getName());

    String name = TraitFactory.getPropertyWrapperName(trait, core);

    String internalWrapper = BuildUtils.getInternalType(name);
    String descrCore = Type.getDescriptor(core.getDefinedClass());
    String internalCore = Type.getInternalName(core.getDefinedClass());

    ClassWriter cw =
        createClassWriter(
            classLoader,
            ACC_PUBLIC + ACC_SUPER,
            internalWrapper,
            Type.getDescriptor(Object.class)
                + Type.getDescriptor(Map.class)
                + Type.getDescriptor(MapWrapper.class),
            //
            // "Ljava/lang/Object;Ljava/util/Map<Ljava/lang/String;Ljava/lang/Object;>;Lorg/drools/factmodel/traits/MapWrapper;",
            Type.getInternalName(Object.class),
            new String[] {
              Type.getInternalName(Map.class),
              Type.getInternalName(MapWrapper.class),
              Type.getInternalName(Serializable.class)
            });

    cw.visitInnerClass(
        Type.getInternalName(Map.Entry.class),
        Type.getInternalName(Map.class),
        "Entry",
        ACC_PUBLIC + ACC_STATIC + ACC_ABSTRACT + ACC_INTERFACE);

    {
      fv = cw.visitField(0, "object", descrCore, null, null);
      fv.visitEnd();
    }

    {
      fv =
          cw.visitField(
              0,
              "map",
              Type.getDescriptor(Map.class),
              "Ljava/util/Map<Ljava/lang/String;Ljava/lang/Object;>;",
              null);
      fv.visitEnd();
    }

    {
      mv =
          cw.visitMethod(
              ACC_PUBLIC,
              "<init>",
              "(" + descrCore + Type.getDescriptor(Map.class) + ")V",
              "(" + descrCore + "Ljava/util/Map<Ljava/lang/String;Ljava/lang/Object;>;)V",
              null);
      mv.visitCode();
      mv.visitVarInsn(ALOAD, 0);
      mv.visitMethodInsn(INVOKESPECIAL, Type.getInternalName(Object.class), "<init>", "()V");
      mv.visitVarInsn(ALOAD, 0);
      mv.visitVarInsn(ALOAD, 1);
      mv.visitFieldInsn(PUTFIELD, internalWrapper, "object", descrCore);
      mv.visitVarInsn(ALOAD, 0);
      mv.visitVarInsn(ALOAD, 2);
      mv.visitFieldInsn(PUTFIELD, internalWrapper, "map", Type.getDescriptor(Map.class));

      mv.visitVarInsn(ALOAD, 1);
      mv.visitVarInsn(ALOAD, 2);
      mv.visitMethodInsn(
          INVOKEVIRTUAL,
          internalCore,
          "_setDynamicProperties",
          "(" + Type.getDescriptor(Map.class) + ")V");

      initSoftFields(mv, trait, core, internalWrapper, mask, 2);

      mv.visitInsn(RETURN);
      mv.visitMaxs(0, 0);
      mv.visitEnd();
    }

    buildSize(cw, name, core.getClassName(), trait, core, mask);

    buildIsEmpty(cw, name, core.getClassName(), trait, core, mask);

    buildGet(cw, name, core.getClassName(), trait, core, mask);

    buildPut(cw, name, core.getClassName(), trait, core, mask);

    buildClear(cw, name, core.getClassName(), trait, core, mask);

    buildRemove(cw, name, core.getClassName(), trait, core, mask);

    buildContainsKey(cw, name, core.getClassName(), trait, core, mask);

    buildContainsValue(cw, name, core.getClassName(), trait, core, mask);

    buildKeyset(cw, name, core.getClassName(), trait, core, mask);

    buildValues(cw, name, core.getClassName(), trait, core, mask);

    buildEntryset(cw, name, core.getClassName(), trait, core, mask);

    buildCommonMethods(cw, name);

    cw.visitEnd();

    return cw.toByteArray();
  }