protected void invokePut(
      MethodVisitor mv,
      String wrapperName,
      ClassDefinition core,
      String fieldName,
      FieldDefinition field) {
    mv.visitLdcInsn(fieldName);
    mv.visitVarInsn(ALOAD, 1);
    mv.visitMethodInsn(
        INVOKEVIRTUAL,
        Type.getInternalName(String.class),
        "equals",
        "(" + Type.getDescriptor(Object.class) + ")Z");
    Label l1 = new Label();
    mv.visitJumpInsn(IFEQ, l1);

    mv.visitVarInsn(ALOAD, 2);
    if (BuildUtils.isPrimitive(field.getTypeName())) {
      TraitFactory.primitiveValue(mv, field.getTypeName());
      mv.visitVarInsn(BuildUtils.storeType(field.getTypeName()), 3);
      TraitFactory.invokeInjector(mv, wrapperName, trait, core, field, false, 3);
    } else {
      TraitFactory.invokeInjector(mv, wrapperName, trait, core, field, false, 2);
    }

    mv.visitVarInsn(ALOAD, 2);
    mv.visitInsn(ARETURN);
    mv.visitLabel(l1);
  }
  private void buildSize(
      ClassVisitor cw,
      String wrapperName,
      String coreName,
      ClassDefinition trait,
      ClassDefinition core,
      BitSet mask) {
    String internalWrapper = BuildUtils.getInternalType(wrapperName);

    MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "size", "()I", null, null);
    mv.visitCode();
    mv.visitVarInsn(ALOAD, 0);
    mv.visitFieldInsn(GETFIELD, internalWrapper, "map", Type.getDescriptor(Map.class));
    mv.visitMethodInsn(INVOKEINTERFACE, Type.getInternalName(Map.class), "size", "()I");

    int n = core.getFieldsDefinitions().size();
    for (int j = 0; j < n; j++) {
      mv.visitInsn(ICONST_1);
      mv.visitInsn(IADD);
    }

    mv.visitInsn(IRETURN);
    //        mv.visitMaxs( core.getFieldsDefinitions().size() > 0 ? 2 : 1, 1 );
    mv.visitMaxs(0, 0);
    mv.visitEnd();
  }
  private void buildIsEmpty(
      ClassVisitor cw,
      String wrapperName,
      String coreName,
      ClassDefinition trait,
      ClassDefinition core,
      BitSet mask) {
    String internalWrapper = BuildUtils.getInternalType(wrapperName);

    boolean hasHardFields = core.getFieldsDefinitions().size() > 0;

    MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "isEmpty", "()Z", null, null);
    mv.visitCode();

    if (!hasHardFields) {
      mv.visitVarInsn(ALOAD, 0);
      mv.visitFieldInsn(GETFIELD, internalWrapper, "map", Type.getDescriptor(Map.class));
      mv.visitMethodInsn(INVOKEINTERFACE, Type.getInternalName(Map.class), "isEmpty", "()Z");
    } else {
      mv.visitInsn(ICONST_0);
    }
    mv.visitInsn(IRETURN);
    //        mv.visitMaxs( 1, 1 );
    mv.visitMaxs(0, 0);
    mv.visitEnd();
  }
  private void buildContainsKey(
      ClassWriter cw,
      String name,
      String className,
      ClassDefinition trait,
      ClassDefinition core,
      BitSet mask) {
    String internalWrapper = BuildUtils.getInternalType(name);

    MethodVisitor mv =
        cw.visitMethod(
            ACC_PUBLIC, "containsKey", "(" + Type.getDescriptor(Object.class) + ")Z", null, null);
    mv.visitCode();

    for (FieldDefinition field : core.getFieldsDefinitions()) {
      invokeContainsKey(mv, field.getName());
    }

    mv.visitVarInsn(ALOAD, 0);
    mv.visitFieldInsn(GETFIELD, internalWrapper, "map", Type.getDescriptor(Map.class));
    mv.visitVarInsn(ALOAD, 1);
    mv.visitMethodInsn(
        INVOKEINTERFACE,
        Type.getInternalName(Map.class),
        "containsKey",
        "(" + Type.getDescriptor(Object.class) + ")Z");
    mv.visitInsn(IRETURN);
    //        mv.visitMaxs( 2, 2 );
    mv.visitMaxs(0, 0);
    mv.visitEnd();
  }
  private void invokeRemove(
      MethodVisitor mv,
      String wrapperName,
      ClassDefinition core,
      String fieldName,
      FieldDefinition field) {
    mv.visitLdcInsn(fieldName);
    mv.visitVarInsn(ALOAD, 1);
    mv.visitMethodInsn(
        INVOKEVIRTUAL,
        Type.getInternalName(String.class),
        "equals",
        "(" + Type.getDescriptor(Object.class) + ")Z");
    Label l1 = new Label();
    mv.visitJumpInsn(IFEQ, l1);

    TraitFactory.invokeExtractor(mv, wrapperName, trait, core, field);

    if (BuildUtils.isPrimitive(field.getTypeName())) {
      TraitFactory.valueOf(mv, field.getTypeName());
    }
    mv.visitVarInsn(ASTORE, 2);

    TraitFactory.invokeInjector(mv, wrapperName, trait, core, field, true, 1);

    mv.visitVarInsn(ALOAD, 2);
    mv.visitInsn(ARETURN);
    mv.visitLabel(l1);
  }
  private void buildClear(
      ClassWriter cw,
      String wrapperName,
      String coreName,
      ClassDefinition trait,
      ClassDefinition core,
      BitSet mask) {
    String internalWrapper = BuildUtils.getInternalType(wrapperName);

    boolean hasPrimitiveFields = false;
    boolean hasObjectFields = false;
    MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "clear", "()V", null, null);
    mv.visitCode();

    for (FieldDefinition field : core.getFieldsDefinitions()) {
      if (field.isKey()) continue;
      if (BuildUtils.isPrimitive(field.getTypeName())) {
        hasPrimitiveFields = true;
      } else {
        hasObjectFields = true;
      }
      TraitFactory.invokeInjector(mv, wrapperName, trait, core, field, true, 1);
    }

    int stack = 2;
    if (hasPrimitiveFields) {
      stack++;
    }
    if (hasObjectFields) {
      stack++;
    }

    mv.visitVarInsn(ALOAD, 0);
    mv.visitFieldInsn(GETFIELD, internalWrapper, "map", Type.getDescriptor(Map.class));
    mv.visitMethodInsn(INVOKEINTERFACE, Type.getInternalName(Map.class), "clear", "()V");

    int num = initSoftFields(mv, trait, core, internalWrapper, mask, 0);
    stack += num;

    mv.visitInsn(RETURN);
    //        mv.visitMaxs( stack , 1 );
    mv.visitMaxs(0, 0);
    mv.visitEnd();
  }
  private void buildKeyset(
      ClassVisitor cw,
      String wrapperName,
      String coreName,
      ClassDefinition trait,
      ClassDefinition core,
      BitSet mask) {
    String internalWrapper = BuildUtils.getInternalType(wrapperName);

    MethodVisitor mv =
        cw.visitMethod(
            ACC_PUBLIC,
            "keySet",
            "()" + Type.getDescriptor(Set.class),
            "()Ljava/util/Set<Ljava/lang/String;>;",
            null);
    mv.visitCode();
    mv.visitTypeInsn(NEW, Type.getInternalName(HashSet.class));
    mv.visitInsn(DUP);
    mv.visitMethodInsn(INVOKESPECIAL, Type.getInternalName(HashSet.class), "<init>", "()V");
    mv.visitVarInsn(ASTORE, 1);

    for (FieldDefinition field : core.getFieldsDefinitions()) {
      mv.visitVarInsn(ALOAD, 1);
      mv.visitLdcInsn(field.getName());
      mv.visitMethodInsn(
          INVOKEINTERFACE,
          Type.getInternalName(Set.class),
          "add",
          "(" + Type.getDescriptor(Object.class) + ")Z");
      mv.visitInsn(POP);
    }

    mv.visitVarInsn(ALOAD, 1);
    mv.visitVarInsn(ALOAD, 0);
    mv.visitFieldInsn(GETFIELD, internalWrapper, "map", Type.getDescriptor(Map.class));
    mv.visitMethodInsn(
        INVOKEINTERFACE,
        Type.getInternalName(Map.class),
        "keySet",
        "()" + Type.getDescriptor(Set.class));
    mv.visitMethodInsn(
        INVOKEINTERFACE,
        Type.getInternalName(Set.class),
        "addAll",
        "(" + Type.getDescriptor(Collection.class) + ")Z");
    mv.visitInsn(POP);
    mv.visitVarInsn(ALOAD, 1);
    mv.visitInsn(ARETURN);
    //        mv.visitMaxs( 2, 2 );
    mv.visitMaxs(0, 0);
    mv.visitEnd();
  }
  private void buildPut(
      ClassVisitor cw,
      String wrapperName,
      String coreName,
      ClassDefinition trait,
      ClassDefinition core,
      BitSet mask) {
    String internalWrapper = BuildUtils.getInternalType(wrapperName);

    MethodVisitor mv =
        cw.visitMethod(
            ACC_PUBLIC,
            "put",
            "("
                + Type.getDescriptor(String.class)
                + Type.getDescriptor(Object.class)
                + ")"
                + Type.getDescriptor(Object.class),
            null,
            null);
    mv.visitCode();

    if (core.getFieldsDefinitions().size() > 0) {
      for (FieldDefinition field : core.getFieldsDefinitions()) {
        invokePut(mv, wrapperName, core, field.getName(), field);
      }
    }

    mv.visitVarInsn(ALOAD, 0);
    mv.visitFieldInsn(GETFIELD, internalWrapper, "map", Type.getDescriptor(Map.class));
    mv.visitVarInsn(ALOAD, 1);
    mv.visitVarInsn(ALOAD, 2);
    mv.visitMethodInsn(
        INVOKEINTERFACE,
        Type.getInternalName(Map.class),
        "put",
        "("
            + Type.getDescriptor(Object.class)
            + Type.getDescriptor(Object.class)
            + ")"
            + Type.getDescriptor(Object.class));
    mv.visitInsn(ARETURN);
    //        mv.visitMaxs( 4, 5 );
    mv.visitMaxs(0, 0);
    mv.visitEnd();
  }
  public void buildCommonMethods(ClassVisitor cw, String wrapper) {

    {
      MethodVisitor mv =
          cw.visitMethod(
              ACC_PUBLIC + ACC_BRIDGE + ACC_SYNTHETIC,
              "put",
              "("
                  + Type.getDescriptor(Object.class)
                  + Type.getDescriptor(Object.class)
                  + ")"
                  + Type.getDescriptor(Object.class),
              null,
              null);
      mv.visitCode();
      mv.visitVarInsn(ALOAD, 0);
      mv.visitVarInsn(ALOAD, 1);
      mv.visitTypeInsn(CHECKCAST, Type.getInternalName(String.class));
      mv.visitVarInsn(ALOAD, 2);
      mv.visitMethodInsn(
          INVOKEVIRTUAL,
          BuildUtils.getInternalType(wrapper),
          "put",
          "("
              + Type.getDescriptor(String.class)
              + Type.getDescriptor(Object.class)
              + ")"
              + Type.getDescriptor(Object.class));
      mv.visitInsn(ARETURN);
      //            mv.visitMaxs( 3, 3 );
      mv.visitMaxs(0, 0);
      mv.visitEnd();
    }

    {
      MethodVisitor mv =
          cw.visitMethod(
              ACC_PUBLIC, "equals", "(" + Type.getDescriptor(Object.class) + ")Z", null, null);
      mv.visitCode();
      mv.visitVarInsn(ALOAD, 0);
      mv.visitVarInsn(ALOAD, 1);
      Label l0 = new Label();
      mv.visitJumpInsn(IF_ACMPNE, l0);
      mv.visitInsn(ICONST_1);
      mv.visitInsn(IRETURN);
      mv.visitLabel(l0);
      mv.visitVarInsn(ALOAD, 1);
      mv.visitTypeInsn(CHECKCAST, Type.getInternalName(MapWrapper.class));
      mv.visitVarInsn(ASTORE, 2);
      mv.visitVarInsn(ALOAD, 0);
      mv.visitFieldInsn(
          GETFIELD, BuildUtils.getInternalType(wrapper), "map", Type.getDescriptor(Map.class));
      mv.visitVarInsn(ALOAD, 2);
      mv.visitMethodInsn(
          INVOKEINTERFACE,
          Type.getInternalName(MapWrapper.class),
          "getInnerMap",
          "()" + Type.getDescriptor(Map.class));
      mv.visitMethodInsn(
          INVOKEVIRTUAL,
          Type.getInternalName(Object.class),
          "equals",
          "(" + Type.getDescriptor(Object.class) + ")Z");
      mv.visitInsn(IRETURN);
      //            mv.visitMaxs( 2, 3 );
      mv.visitMaxs(0, 0);
      mv.visitEnd();
    }

    {
      MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "hashCode", "()I", null, null);
      mv.visitCode();
      mv.visitVarInsn(ALOAD, 0);
      mv.visitFieldInsn(
          GETFIELD, BuildUtils.getInternalType(wrapper), "map", Type.getDescriptor(Map.class));
      mv.visitMethodInsn(INVOKEVIRTUAL, Type.getInternalName(Object.class), "hashCode", "()I");
      mv.visitInsn(IRETURN);
      //            mv.visitMaxs( 1, 1 );
      mv.visitMaxs(0, 0);
      mv.visitEnd();
    }

    {
      MethodVisitor mv =
          cw.visitMethod(
              ACC_PUBLIC,
              "getInnerMap",
              "()" + Type.getDescriptor(Map.class),
              "()Ljava/util/Map<Ljava/lang/String;Ljava/lang/Object;>;",
              null);
      mv.visitCode();
      mv.visitVarInsn(ALOAD, 0);
      mv.visitFieldInsn(
          GETFIELD, BuildUtils.getInternalType(wrapper), "map", Type.getDescriptor(Map.class));
      mv.visitInsn(ARETURN);
      //            mv.visitMaxs( 1, 1 );
      mv.visitMaxs(0, 0);
      mv.visitEnd();
    }

    {
      MethodVisitor mv =
          cw.visitMethod(
              ACC_PUBLIC,
              "putAll",
              "(" + Type.getDescriptor(Map.class) + ")V",
              "(Ljava/util/Map<+Ljava/lang/String;+Ljava/lang/Object;>;)V",
              null);
      mv.visitCode();
      mv.visitVarInsn(ALOAD, 1);
      mv.visitMethodInsn(
          INVOKEINTERFACE,
          Type.getInternalName(Map.class),
          "keySet",
          "()" + Type.getDescriptor(Set.class));
      mv.visitMethodInsn(
          INVOKEINTERFACE,
          Type.getInternalName(Set.class),
          "iterator",
          "()" + Type.getDescriptor(Iterator.class));
      mv.visitVarInsn(ASTORE, 2);
      Label l0 = new Label();
      mv.visitLabel(l0);
      mv.visitVarInsn(ALOAD, 2);
      mv.visitMethodInsn(INVOKEINTERFACE, Type.getInternalName(Iterator.class), "hasNext", "()Z");
      Label l1 = new Label();
      mv.visitJumpInsn(IFEQ, l1);
      mv.visitVarInsn(ALOAD, 2);
      mv.visitMethodInsn(
          INVOKEINTERFACE,
          Type.getInternalName(Iterator.class),
          "next",
          "()" + Type.getDescriptor(Object.class));
      mv.visitTypeInsn(CHECKCAST, Type.getInternalName(String.class));
      mv.visitVarInsn(ASTORE, 3);
      mv.visitVarInsn(ALOAD, 0);
      mv.visitVarInsn(ALOAD, 3);
      mv.visitVarInsn(ALOAD, 1);
      mv.visitVarInsn(ALOAD, 3);
      mv.visitMethodInsn(
          INVOKEINTERFACE,
          Type.getInternalName(Map.class),
          "get",
          "(" + Type.getDescriptor(Object.class) + ")" + Type.getDescriptor(Object.class));
      mv.visitMethodInsn(
          INVOKEVIRTUAL,
          BuildUtils.getInternalType(wrapper),
          "put",
          "("
              + Type.getDescriptor(String.class)
              + Type.getDescriptor(Object.class)
              + ")"
              + Type.getDescriptor(Object.class));
      mv.visitInsn(POP);
      mv.visitJumpInsn(GOTO, l0);
      mv.visitLabel(l1);
      mv.visitInsn(RETURN);
      //            mv.visitMaxs( 4, 4 );
      mv.visitMaxs(0, 0);
      mv.visitEnd();
    }

    {
      MethodVisitor mv =
          cw.visitMethod(
              ACC_PUBLIC, "toString", "()" + Type.getDescriptor(String.class), null, null);
      mv.visitCode();
      mv.visitTypeInsn(NEW, Type.getInternalName(StringBuilder.class));
      mv.visitInsn(DUP);
      mv.visitMethodInsn(INVOKESPECIAL, Type.getInternalName(StringBuilder.class), "<init>", "()V");
      mv.visitLdcInsn("[[");
      mv.visitMethodInsn(
          INVOKEVIRTUAL,
          Type.getInternalName(StringBuilder.class),
          "append",
          "(" + Type.getDescriptor(String.class) + ")" + Type.getDescriptor(StringBuilder.class));
      mv.visitVarInsn(ALOAD, 0);
      mv.visitMethodInsn(
          INVOKEVIRTUAL,
          BuildUtils.getInternalType(wrapper),
          "entrySet",
          "()" + Type.getDescriptor(Set.class));
      mv.visitMethodInsn(
          INVOKEVIRTUAL,
          Type.getInternalName(StringBuilder.class),
          "append",
          "(" + Type.getDescriptor(Object.class) + ")" + Type.getDescriptor(StringBuilder.class));
      mv.visitLdcInsn("]]");
      mv.visitMethodInsn(
          INVOKEVIRTUAL,
          Type.getInternalName(StringBuilder.class),
          "append",
          "(" + Type.getDescriptor(String.class) + ")" + Type.getDescriptor(StringBuilder.class));
      mv.visitMethodInsn(
          INVOKEVIRTUAL,
          Type.getInternalName(StringBuilder.class),
          "toString",
          "()" + Type.getDescriptor(String.class));
      mv.visitInsn(ARETURN);
      //            mv.visitMaxs( 2, 1 );
      mv.visitMaxs(0, 0);
      mv.visitEnd();
    }
  }
  private void buildValues(
      ClassVisitor cw,
      String wrapperName,
      String coreName,
      ClassDefinition trait,
      ClassDefinition core,
      BitSet mask) {
    String internalWrapper = BuildUtils.getInternalType(wrapperName);

    MethodVisitor mv =
        cw.visitMethod(
            ACC_PUBLIC,
            "values",
            "()" + Type.getDescriptor(Collection.class),
            "()Ljava/util/Collection<Ljava/lang/Object;>;",
            null);
    mv.visitCode();

    mv.visitTypeInsn(NEW, Type.getInternalName(ArrayList.class));
    mv.visitInsn(DUP);
    mv.visitMethodInsn(INVOKESPECIAL, Type.getInternalName(ArrayList.class), "<init>", "()V");
    mv.visitVarInsn(ASTORE, 1);

    for (FieldDefinition field : core.getFieldsDefinitions()) {
      mv.visitVarInsn(ALOAD, 1);

      TraitFactory.invokeExtractor(mv, wrapperName, trait, core, field);

      if (BuildUtils.isPrimitive(field.getTypeName())) {
        TraitFactory.valueOf(mv, field.getTypeName());
      }

      mv.visitMethodInsn(
          INVOKEINTERFACE,
          Type.getInternalName(Collection.class),
          "add",
          "(" + Type.getDescriptor(Object.class) + ")Z");
      mv.visitInsn(POP);
    }

    mv.visitVarInsn(ALOAD, 1);
    mv.visitVarInsn(ALOAD, 0);
    mv.visitFieldInsn(GETFIELD, internalWrapper, "map", Type.getDescriptor(Map.class));
    mv.visitMethodInsn(
        INVOKEINTERFACE,
        Type.getInternalName(Map.class),
        "values",
        "()" + Type.getDescriptor(Collection.class));
    mv.visitMethodInsn(
        INVOKEINTERFACE,
        Type.getInternalName(Collection.class),
        "addAll",
        "(" + Type.getDescriptor(Collection.class) + ")Z");
    mv.visitInsn(POP);
    mv.visitVarInsn(ALOAD, 1);
    mv.visitInsn(ARETURN);

    //        mv.visitMaxs( core.getFieldsDefinitions().size() > 0 ? 3 : 2, 2);
    mv.visitMaxs(0, 0);
    mv.visitEnd();
  }
  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();
  }
  private void buildContainsValue(
      ClassWriter cw,
      String wrapperName,
      String coreName,
      ClassDefinition trait,
      ClassDefinition core,
      BitSet mask) {
    String internalWrapper = BuildUtils.getInternalType(wrapperName);

    MethodVisitor mv =
        cw.visitMethod(
            ACC_PUBLIC, "containsValue", "(" + Type.getDescriptor(Object.class) + ")Z", null, null);
    mv.visitCode();

    // null check
    mv.visitVarInsn(ALOAD, 1);
    Label l99 = new Label();
    mv.visitJumpInsn(IFNONNULL, l99);

    for (FieldDefinition field : core.getFieldsDefinitions()) {
      if (!BuildUtils.isPrimitive(field.getTypeName())) {
        TraitFactory.invokeExtractor(mv, wrapperName, trait, core, field);
        Label l1 = new Label();
        mv.visitJumpInsn(IFNONNULL, l1);
        mv.visitInsn(ICONST_1);
        mv.visitInsn(IRETURN);
        mv.visitLabel(l1);
      }
    }

    mv.visitVarInsn(ALOAD, 0);
    mv.visitFieldInsn(GETFIELD, internalWrapper, "map", Type.getDescriptor(Map.class));
    mv.visitInsn(ACONST_NULL);
    mv.visitMethodInsn(
        INVOKEINTERFACE,
        Type.getInternalName(Map.class),
        "containsValue",
        "(" + Type.getDescriptor(Object.class) + ")Z");
    mv.visitInsn(IRETURN);
    mv.visitLabel(l99);

    // non-null values check
    for (FieldDefinition field : core.getFieldsDefinitions()) {

      mv.visitVarInsn(ALOAD, 1);

      TraitFactory.invokeExtractor(mv, wrapperName, trait, core, field);

      if (BuildUtils.isPrimitive(field.getTypeName())) {
        TraitFactory.valueOf(mv, field.getTypeName());
      }
      mv.visitMethodInsn(
          INVOKEVIRTUAL,
          Type.getInternalName(Object.class),
          "equals",
          "(" + Type.getDescriptor(Object.class) + ")Z");

      Label l0 = new Label();
      mv.visitJumpInsn(IFEQ, l0);
      mv.visitInsn(ICONST_1);
      mv.visitInsn(IRETURN);
      mv.visitLabel(l0);
    }

    mv.visitVarInsn(ALOAD, 0);
    mv.visitFieldInsn(GETFIELD, internalWrapper, "map", Type.getDescriptor(Map.class));
    mv.visitVarInsn(ALOAD, 1);
    mv.visitMethodInsn(
        INVOKEINTERFACE,
        Type.getInternalName(Map.class),
        "containsValue",
        "(" + Type.getDescriptor(Object.class) + ")Z");
    mv.visitInsn(IRETURN);
    //        mv.visitMaxs( core.getFieldsDefinitions().size() > 0 ? 3 : 2, 2 );
    mv.visitMaxs(0, 0);
    mv.visitEnd();
  }
  private int initSoftFields(
      MethodVisitor mv,
      ClassDefinition trait,
      ClassDefinition core,
      String internalWrapper,
      BitSet mask,
      int varNum) {
    int j = 0;
    for (FieldDefinition field : trait.getFieldsDefinitions()) {
      boolean isSoftField = TraitRegistry.isSoftField(field, j++, mask);
      if (isSoftField) {

        mv.visitVarInsn(ALOAD, varNum);
        mv.visitLdcInsn(field.resolveAlias());
        mv.visitMethodInsn(
            INVOKEINTERFACE,
            Type.getInternalName(Map.class),
            "containsKey",
            Type.getMethodDescriptor(
                Type.getType(boolean.class), new Type[] {Type.getType(Object.class)}));
        Label l0 = new Label();
        mv.visitJumpInsn(IFNE, l0);

        mv.visitVarInsn(ALOAD, varNum);
        mv.visitLdcInsn(field.resolveAlias());
        mv.visitInsn(BuildUtils.zero(field.getTypeName()));
        if (BuildUtils.isPrimitive(field.getTypeName())) {
          TraitFactory.valueOf(mv, field.getTypeName());
        }
        mv.visitMethodInsn(
            INVOKEINTERFACE,
            Type.getInternalName(Map.class),
            "put",
            Type.getMethodDescriptor(
                Type.getType(Object.class),
                new Type[] {Type.getType(Object.class), Type.getType(Object.class)}));
        mv.visitInsn(POP);

        if (core.isFullTraiting()) {
          mv.visitVarInsn(ALOAD, 0);
          mv.visitFieldInsn(
              GETFIELD, internalWrapper, "object", Type.getDescriptor(core.getDefinedClass()));
          mv.visitTypeInsn(CHECKCAST, Type.getInternalName(TraitableBean.class));
          mv.visitMethodInsn(
              INVOKEINTERFACE,
              Type.getInternalName(TraitableBean.class),
              "_getFieldTMS",
              Type.getMethodDescriptor(Type.getType(TraitFieldTMS.class), new Type[] {}));
          mv.visitVarInsn(ASTORE, 1);
          mv.visitVarInsn(ALOAD, 1);
          mv.visitLdcInsn(field.resolveAlias());
          mv.visitMethodInsn(
              INVOKEINTERFACE,
              Type.getInternalName(TraitFieldTMS.class),
              "isManagingField",
              Type.getMethodDescriptor(Type.BOOLEAN_TYPE, new Type[] {Type.getType(String.class)}));
          Label l1 = new Label();
          mv.visitJumpInsn(IFNE, l1);
          mv.visitVarInsn(ALOAD, 1);
          mv.visitLdcInsn(Type.getType(BuildUtils.getTypeDescriptor(core.getClassName())));
          mv.visitLdcInsn(field.resolveAlias());
          mv.visitMethodInsn(
              INVOKEINTERFACE,
              Type.getInternalName(TraitFieldTMS.class),
              "registerField",
              Type.getMethodDescriptor(
                  Type.VOID_TYPE,
                  new Type[] {Type.getType(Class.class), Type.getType(String.class)}));
          mv.visitLabel(l1);
        }

        mv.visitLabel(l0);
      }
    }
    return 0;
  }
  private void buildRemove(
      ClassWriter cw,
      String wrapperName,
      String coreName,
      ClassDefinition trait,
      ClassDefinition core,
      BitSet mask) {
    String internalWrapper = BuildUtils.getInternalType(wrapperName);

    MethodVisitor mv =
        cw.visitMethod(
            ACC_PUBLIC,
            "remove",
            "(" + Type.getDescriptor(Object.class) + ")" + Type.getDescriptor(Object.class),
            null,
            null);
    mv.visitCode();

    for (FieldDefinition field : core.getFieldsDefinitions()) {
      invokeRemove(mv, wrapperName, core, field.getName(), field);
    }

    int j = 0;
    int stack = 0;
    for (FieldDefinition field : trait.getFieldsDefinitions()) {
      boolean isSoftField = TraitRegistry.isSoftField(field, j++, mask);
      if (isSoftField) {
        mv.visitLdcInsn(field.getName());
        mv.visitVarInsn(ALOAD, 1);
        mv.visitMethodInsn(
            INVOKEVIRTUAL,
            Type.getInternalName(String.class),
            "equals",
            "(" + Type.getDescriptor(Object.class) + ")Z");
        Label l2 = new Label();
        mv.visitJumpInsn(IFEQ, l2);
        mv.visitVarInsn(ALOAD, 0);
        mv.visitFieldInsn(GETFIELD, internalWrapper, "map", Type.getDescriptor(Map.class));
        mv.visitLdcInsn(field.getName());
        mv.visitMethodInsn(
            INVOKEINTERFACE,
            Type.getInternalName(Map.class),
            "get",
            "(" + Type.getDescriptor(Object.class) + ")" + Type.getDescriptor(Object.class));
        mv.visitVarInsn(ASTORE, 2);
        mv.visitVarInsn(ALOAD, 0);
        mv.visitFieldInsn(GETFIELD, internalWrapper, "map", Type.getDescriptor(Map.class));
        mv.visitLdcInsn(field.getName());
        mv.visitInsn(BuildUtils.zero(field.getTypeName()));
        if (BuildUtils.isPrimitive(field.getTypeName())) {
          TraitFactory.valueOf(mv, field.getTypeName());
        }
        mv.visitMethodInsn(
            INVOKEINTERFACE,
            Type.getInternalName(Map.class),
            "put",
            "("
                + Type.getDescriptor(Object.class)
                + Type.getDescriptor(Object.class)
                + ")"
                + Type.getDescriptor(Object.class));
        mv.visitInsn(POP);
        mv.visitVarInsn(ALOAD, 2);
        mv.visitInsn(ARETURN);
        mv.visitLabel(l2);
      }
    }

    mv.visitVarInsn(ALOAD, 0);
    mv.visitFieldInsn(GETFIELD, internalWrapper, "map", Type.getDescriptor(Map.class));
    mv.visitVarInsn(ALOAD, 1);
    mv.visitMethodInsn(
        INVOKEINTERFACE,
        Type.getInternalName(Map.class),
        "remove",
        "(" + Type.getDescriptor(Object.class) + ")" + Type.getDescriptor(Object.class));
    mv.visitVarInsn(ASTORE, 2);
    mv.visitVarInsn(ALOAD, 2);
    mv.visitInsn(ARETURN);
    //        mv.visitMaxs( 4 + stack, 3 );
    mv.visitMaxs(0, 0);
    mv.visitEnd();
  }