private void initializeClassInfo(final byte[] classCode) {

    final ClassReader classReader = new ClassReader(classCode);
    classNode = new ClassNode(Opcodes.ASM4);
    classReader.accept(classNode, ClassReader.SKIP_DEBUG | ClassReader.EXPAND_FRAMES);

    access = classNode.access;
    name = classNode.name.replace('/', '.');

    methods = new ArrayList<MethodInfo>(classNode.methods.size());
    public_methods = new LinkedList<MethodInfo>();

    for (final MethodNode methodNode : classNode.methods) {

      final MethodInfo methodInfo = new MethodInfo(methodNode);
      methods.add(methodInfo);

      if (methodInfo.isPublic()) {
        public_methods.add(methodInfo);
      }
    }

    fields = new ArrayList<FieldInfo>(classNode.fields.size());
    public_fields = new LinkedList<FieldInfo>();

    for (final FieldNode fieldNode : classNode.fields) {

      final FieldInfo fieldInfo = new FieldInfo(fieldNode);
      fields.add(fieldInfo);

      if (fieldInfo.isPublic()) {
        public_fields.add(fieldInfo);
      }
    }

    if (getSuperclass() != null) {

      for (final MethodInfo methodInfo : getSuperclass().getMethods()) {
        public_methods.add(methodInfo);
      }

      for (final FieldInfo fieldInfo : getSuperclass().getFields()) {
        public_fields.add(fieldInfo);
      }
    }

    innerclasses = new ArrayList<String>(classNode.innerClasses.size());

    for (final InnerClassNode innerClassNode : classNode.innerClasses) {
      innerclasses.add(innerClassNode.name);
    }
  }
  @Override
  public FieldInfo getField(final String fieldName) throws NoSuchFieldException {

    for (final FieldInfo fieldInfo : fields) {
      if (fieldInfo.isPublic() && fieldInfo.getName().equals(fieldName)) {
        return fieldInfo;
      }
    }

    if (getSuperclass() == null) {
      throw new NoSuchFieldException(name + "." + fieldName);
    }

    return getSuperclass().getField(fieldName);
  }