private void put(ClassFormatOutput out) throws IOException {

    /* Write out the header */
    out.putU4(VMDescriptor.JAVA_CLASS_FORMAT_MAGIC);
    out.putU2(minor_version);
    out.putU2(major_version);

    // special case checking that the number of constant
    // pool entries does not exceed the limit of 65535
    // (as it is stored as a U2).
    // Special case to allow somewhat easier debugging
    // of the resulting failure.
    out.putU2("constant_pool", cptEntries.size());
    cptPut(out);

    out.putU2(access_flags);
    out.putU2(this_class);
    out.putU2(super_class);

    if (interfaces != null) {
      int ilen = interfaces.length;
      out.putU2(ilen);
      for (int i = 0; i < ilen; i++) {
        out.putU2(interfaces[i]);
      }
    } else {
      out.putU2(0);
    }

    if (field_info != null) {
      out.putU2(field_info.size());
      field_info.put(out);
    } else {
      out.putU2(0);
    }

    if (method_info != null) {
      out.putU2(method_info.size());
      method_info.put(out);
    } else {
      out.putU2(0);
    }

    if (attribute_info != null) {
      out.putU2(attribute_info.size());
      attribute_info.put(out);
    } else {
      out.putU2(0);
    }
  }
  // remove all atttributes that are not essential
  public void removeAttributes() throws IOException {

    // Class level attributes
    if (attribute_info != null) {
      for (int i = attribute_info.size() - 1; i >= 0; i--) {

        AttributeEntry ae = (AttributeEntry) attribute_info.elementAt(i);
        String name = nameIndexToString(ae.getNameIndex());
        if (name.equals("SourceFile")) attribute_info.removeElementAt(i);
        else if (name.equals("InnerClasses")) ; // leave in
        else System.err.println("WARNING - Unknown Class File attribute " + name);
      }

      if (attribute_info.size() == 0) attribute_info = null;
    }
    attribute_info = null;

    // fields
    for (Enumeration e = getFields(); e.hasMoreElements(); ) {
      ClassMember member = (ClassMember) e.nextElement();

      Attributes attrs = member.attribute_info;

      if (attrs != null) {

        for (int i = attrs.size() - 1; i >= 0; i--) {

          AttributeEntry ae = (AttributeEntry) attrs.elementAt(i);
          String name = nameIndexToString(ae.getNameIndex());
          if (name.equals("ConstantValue")) ; // leave in
          else if (name.equals("Synthetic")) ; // leave in
          else System.err.println("WARNING - Unknown Field attribute " + name);
        }

        if (attrs.size() == 0) member.attribute_info = null;
      }
    }

    // methods
    for (Enumeration e = getMethods(); e.hasMoreElements(); ) {
      ClassMember member = (ClassMember) e.nextElement();

      Attributes attrs = member.attribute_info;

      if (attrs != null) {

        for (int i = attrs.size() - 1; i >= 0; i--) {

          AttributeEntry ae = (AttributeEntry) attrs.elementAt(i);
          String name = nameIndexToString(ae.getNameIndex());
          if (name.equals("Code")) processCodeAttribute(member, ae);
          else if (name.equals("Exceptions")) ; // leave in
          else if (name.equals("Deprecated")) ; // leave in
          else if (name.equals("Synthetic")) ; // leave in
          else System.err.println("WARNING - Unknown method attribute " + name);
        }

        if (attrs.size() == 0) member.attribute_info = null;
      }
    }
  }