public void read(DataInput in) throws InvalidByteCodeException, IOException {

    info = new byte[attributeLength];
    in.readFully(info);

    if (debug) debug("read " + getDebugMessage());
  }
  /**
   * Factory method for creating <tt>AttributeInfo</tt> structures.
   *
   * <p>An <tt>AttributeInfo</tt> of the appropriate subtype from the <tt>attributes</tt> package is
   * created unless the type of the attribute is unknown in which case an instance of
   * <tt>AttributeInfo</tt> is returned.
   *
   * <p>
   *
   * <p>Attributes are skipped if the environment variable <tt>SYSTEM_PROPERTY_SKIP_ATTRIBUTES</tt>
   * is set to true.
   *
   * @param in the <tt>DataInput</tt> from which to read the <tt>AttributeInfo</tt> structure
   * @param classFile the parent class file of the structure to be created
   * @return the new <tt>AttributeInfo</tt> structure
   * @throws InvalidByteCodeException if the byte code is invalid
   * @throws IOException if an exception occurs with the <tt>DataInput</tt>
   */
  public static AttributeInfo createOrSkip(DataInput in, ClassFile classFile)
      throws InvalidByteCodeException, IOException {

    AttributeInfo attributeInfo = null;

    if (Boolean.getBoolean(SYSTEM_PROPERTY_SKIP_ATTRIBUTES)) {
      in.skipBytes(2);
      in.skipBytes(in.readInt());
    } else {
      int attributeNameIndex = in.readUnsignedShort();
      int attributeLength = in.readInt();

      ConstantUtf8Info cpInfoName = classFile.getConstantPoolUtf8Entry(attributeNameIndex);
      String attributeName = null;

      if (cpInfoName == null) {
        return null;
      }

      attributeName = cpInfoName.getString();

      if (ConstantValueAttribute.ATTRIBUTE_NAME.equals(attributeName)) {
        attributeInfo = new ConstantValueAttribute();

      } else if (CodeAttribute.ATTRIBUTE_NAME.equals(attributeName)) {
        attributeInfo = new CodeAttribute();

      } else if (ExceptionsAttribute.ATTRIBUTE_NAME.equals(attributeName)) {
        attributeInfo = new ExceptionsAttribute();

      } else if (InnerClassesAttribute.ATTRIBUTE_NAME.equals(attributeName)) {
        attributeInfo = new InnerClassesAttribute();

      } else if (SyntheticAttribute.ATTRIBUTE_NAME.equals(attributeName)) {
        attributeInfo = new SyntheticAttribute();

      } else if (SourceFileAttribute.ATTRIBUTE_NAME.equals(attributeName)) {
        attributeInfo = new SourceFileAttribute();

      } else if (LineNumberTableAttribute.ATTRIBUTE_NAME.equals(attributeName)) {
        attributeInfo = new LineNumberTableAttribute();

      } else if (LocalVariableTableAttribute.ATTRIBUTE_NAME.equals(attributeName)) {
        attributeInfo = new LocalVariableTableAttribute();

      } else if (DeprecatedAttribute.ATTRIBUTE_NAME.equals(attributeName)) {
        attributeInfo = new DeprecatedAttribute();

      } else if (EnclosingMethodAttribute.ATTRIBUTE_NAME.equals(attributeName)) {
        attributeInfo = new EnclosingMethodAttribute();

      } else if (SignatureAttribute.ATTRIBUTE_NAME.equals(attributeName)) {
        attributeInfo = new SignatureAttribute();

      } else if (LocalVariableTypeTableAttribute.ATTRIBUTE_NAME.equals(attributeName)) {
        attributeInfo = new LocalVariableTypeTableAttribute();

      } else if (RuntimeVisibleAnnotationsAttribute.ATTRIBUTE_NAME.equals(attributeName)) {
        attributeInfo = new RuntimeVisibleAnnotationsAttribute();

      } else if (RuntimeInvisibleAnnotationsAttribute.ATTRIBUTE_NAME.equals(attributeName)) {
        attributeInfo = new RuntimeInvisibleAnnotationsAttribute();

      } else if (AnnotationDefaultAttribute.ATTRIBUTE_NAME.equals(attributeName)) {
        attributeInfo = new AnnotationDefaultAttribute();

      } else if (BootstrapMethodsAttribute.ATTRIBUTE_NAME.equals(attributeName)) {
        attributeInfo = new BootstrapMethodsAttribute(attributeLength);

      } else {
        attributeInfo = new AttributeInfo(attributeLength);
      }
      attributeInfo.setAttributeNameIndex(attributeNameIndex);
      attributeInfo.setClassFile(classFile);
      attributeInfo.read(in);
    }

    return attributeInfo;
  }