public void generateCode(BlockScope currentScope, CodeStream codeStream, boolean valueRequired) {
    if (!valueRequired) currentScope.problemReporter().unusedObjectAllocation(this);
    int pc = codeStream.position;
    MethodBinding codegenBinding = this.binding.original();
    ReferenceBinding allocatedType = codegenBinding.declaringClass;
    codeStream.new_(allocatedType);
    boolean isUnboxing = (this.implicitConversion & TypeIds.UNBOXING) != 0;
    if (valueRequired || isUnboxing) {
      codeStream.dup();
    }
    // better highlight for allocation: display the type individually
    if (this.type != null) { // null for enum constant body
      codeStream.recordPositionsFrom(pc, this.type.sourceStart);
    } else {
      // push enum constant name and ordinal
      codeStream.ldc(String.valueOf(this.enumConstant.name));
      codeStream.generateInlinedValue(this.enumConstant.binding.id);
    }
    // handling innerclass instance allocation - enclosing instance arguments
    if (allocatedType.isNestedType()) {
      codeStream.generateSyntheticEnclosingInstanceValues(
          currentScope, allocatedType, enclosingInstance(), this);
    }
    // generate the arguments for constructor
    generateArguments(this.binding, this.arguments, currentScope, codeStream);
    // handling innerclass instance allocation - outer local arguments
    if (allocatedType.isNestedType()) {
      codeStream.generateSyntheticOuterArgumentValues(currentScope, allocatedType, this);
    }

    // invoke constructor
    if (this.syntheticAccessor == null) {
      codeStream.invoke(
          Opcodes.OPC_invokespecial, codegenBinding, null /* default declaringClass */);
    } else {
      // synthetic accessor got some extra arguments appended to its signature, which need values
      for (int i = 0,
              max = this.syntheticAccessor.parameters.length - codegenBinding.parameters.length;
          i < max;
          i++) {
        codeStream.aconst_null();
      }
      codeStream.invoke(
          Opcodes.OPC_invokespecial, this.syntheticAccessor, null /* default declaringClass */);
    }
    if (valueRequired) {
      codeStream.generateImplicitConversion(this.implicitConversion);
    } else if (isUnboxing) {
      // conversion only generated if unboxing
      codeStream.generateImplicitConversion(this.implicitConversion);
      switch (postConversionType(currentScope).id) {
        case T_long:
        case T_double:
          codeStream.pop2();
          break;
        default:
          codeStream.pop();
      }
    }
    codeStream.recordPositionsFrom(pc, this.sourceStart);

    if (this.anonymousType != null) {
      this.anonymousType.generateCode(currentScope, codeStream);
    }
  }