public ProxyingInstantiator(Class<T> type) {

    byte[] classBytes = writeExtendingClass(type, SUFFIX);

    try {
      newType =
          ClassDefinitionUtils.defineClass(
              type.getName() + SUFFIX, classBytes, type.getClassLoader());
    } catch (Exception e) {
      throw new ObjenesisException(e);
    }
  }
 @SuppressWarnings("unchecked")
 public T newInstance() {
   try {
     return (T) newType.newInstance();
   } catch (InstantiationException e) {
     throw new ObjenesisException(e);
   } catch (IllegalAccessException e) {
     throw new ObjenesisException(e);
   }
 }
  /**
   * Will generate the bytes for a class extending the type passed in parameter. This class will
   * only have an empty default constructor
   *
   * @param type type to extend
   * @param suffix the suffix appended to the class name to create the next extending class name
   * @return the byte for the class
   * @throws ObjenesisException is something goes wrong
   */
  private static byte[] writeExtendingClass(Class<?> type, String suffix) {
    String parentClazz = classNameToInternalClassName(type.getName());
    String clazz = parentClazz + suffix;

    DataOutputStream in = null;
    ByteArrayOutputStream bIn =
        new ByteArrayOutputStream(1000); // 1000 should be large enough to fit the entire class
    try {
      in = new DataOutputStream(bIn);

      in.write(MAGIC);
      in.write(VERSION);
      in.writeShort(CONSTANT_POOL_COUNT);

      // set all the constant pool here

      // 1. class
      in.writeByte(CONSTANT_Class);
      in.writeShort(INDEX_UTF8_CLASS);

      // 2. super class
      in.writeByte(CONSTANT_Class);
      in.writeShort(INDEX_UTF8_SUPERCLASS);

      // 3. default constructor name
      in.writeByte(CONSTANT_Utf8);
      in.writeUTF(CONSTRUCTOR_NAME);

      // 4. default constructor description
      in.writeByte(CONSTANT_Utf8);
      in.writeUTF(CONSTRUCTOR_DESC);

      // 5. Code
      in.writeByte(CONSTANT_Utf8);
      in.writeUTF("Code");

      // 6. Class name
      in.writeByte(CONSTANT_Utf8);
      in.writeUTF("L" + clazz + ";");

      // 7. Class name (again)
      in.writeByte(CONSTANT_Utf8);
      in.writeUTF(clazz);

      // 8. Superclass name
      in.writeByte(CONSTANT_Utf8);
      in.writeUTF(parentClazz);

      // end of constant pool

      // access flags: We want public, ACC_SUPER is always there
      in.writeShort(ACC_PUBLIC | ACC_SUPER);

      // this class index in the constant pool
      in.writeShort(INDEX_CLASS_THIS);

      // super class index in the constant pool
      in.writeShort(INDEX_CLASS_SUPERCLASS);

      // interfaces implemented count (we have none)
      in.writeShort(0);

      // fields count (we have none)
      in.writeShort(0);

      // methods count (we have one: the default constructor)
      in.writeShort(1);

      // default constructor method_info
      in.writeShort(ACC_PUBLIC);
      in.writeShort(INDEX_UTF8_CONSTRUCTOR_NAME); // index of the method name (<init>)
      in.writeShort(INDEX_UTF8_CONSTRUCTOR_DESC); // index of the description
      in.writeShort(1); // number of attributes: only one, the code

      // code attribute of the default constructor
      in.writeShort(INDEX_UTF8_CODE_ATTRIBUTE);
      in.writeInt(CODE_ATTRIBUTE_LENGTH); // attribute length
      in.writeShort(1); // max_stack
      in.writeShort(1); // max_locals
      in.writeInt(CODE.length); // code length
      in.write(CODE);
      in.writeShort(0); // exception_table_length = 0
      in.writeShort(
          0); // attributes count = 0, no need to have LineNumberTable and LocalVariableTable

      // class attributes
      in.writeShort(0); // none. No need to have a source file attribute

    } catch (IOException e) {
      throw new ObjenesisException(e);
    } finally {
      if (in != null) {
        try {
          in.close();
        } catch (IOException e) {
          throw new ObjenesisException(e);
        }
      }
    }

    return bIn.toByteArray();
  }