public static ClassFile ParseClassFile(byte[] data)
        {
            ClassFile res = new ClassFile();
            int       pos = 0;

            for (int i = 0; i < 4; ++i)
            {
                res.Magic[i] = data[pos++];
            }

            res.MinorVersion = Utils.ReadUShort(data, ref pos);
            res.MajorVersion = Utils.ReadUShort(data, ref pos);

            res.ConstantPoolCount = Utils.ReadUShort(data, ref pos);
            res.ConstantPool      = new ConstantPoolDescription[res.ConstantPoolCount - 1];
            for (int i = 0; i < res.ConstantPoolCount - 1; ++i)
            {
                ConstantPoolDescription cpd = ConstantPoolDescription.ParseData(data, ref pos);
                res.ConstantPool[i] = cpd;
                res.INDEX_TO_CONST_MAP.Add(i, cpd);
                if (cpd.Tag == ConstantPoolTag.CONSTANT_Double || cpd.Tag == ConstantPoolTag.CONSTANT_Long)
                {
                    ;
                    ++i;                    // f*****g java
                }
            }

            res.AccessFlags = Utils.ReadUShort(data, ref pos);
            res.ThisClass   = Utils.ReadUShort(data, ref pos);
            res.SuperClass  = Utils.ReadUShort(data, ref pos);

            res.InterfacesCount = Utils.ReadUShort(data, ref pos);
            res.Interfaces      = new ushort[res.InterfacesCount];
            for (int i = 0; i < res.InterfacesCount; ++i)
            {
                res.Interfaces[i] = Utils.ReadUShort(data, ref pos);
            }

            res.FieldsCount = Utils.ReadUShort(data, ref pos);
            res.Fields      = new FieldInfo[res.FieldsCount];
            for (int i = 0; i < res.FieldsCount; ++i)
            {
                res.Fields[i] = FieldInfo.ParseData(res, data, ref pos);
            }

            res.MethodsCount = Utils.ReadUShort(data, ref pos);
            res.Methods      = new MethodInfo[res.MethodsCount];
            for (int i = 0; i < res.MethodsCount; ++i)
            {
                res.Methods[i] = MethodInfo.ParseData(res, data, ref pos);
            }

            res.AttributesCount = Utils.ReadUShort(data, ref pos);
            res.Attributes      = new AttributeDescription[res.AttributesCount];
            for (int i = 0; i < res.AttributesCount; ++i)
            {
                res.Attributes[i] = AttributeDescription.ParseData(data, ref pos);
            }

            res.AttributeParsers = AttributeParser.GenerateAttributeMap(res, res.Attributes);
            return(res);
        }