@Override
 public AnnotationVisitor visitParameterAnnotation(
     final int parameter, final String desc, final boolean visible) {
   checkEndMethod();
   checkDesc(desc, false);
   return new CheckAnnotationAdapter(super.visitParameterAnnotation(parameter, desc, visible));
 }
 /**
  * Checks that the given string is a valid internal class name.
  *
  * @param name the string to be checked.
  * @param msg a message to be used in case of error.
  */
 static void checkInternalName(final String name, final String msg) {
   if (name == null || name.length() == 0) {
     throw new IllegalArgumentException("Invalid " + msg + " (must not be null or empty)");
   }
   if (name.charAt(0) == '[') {
     checkDesc(name, false);
   } else {
     checkInternalName(name, 0, -1, msg);
   }
 }
 @Override
 public void visitFieldInsn(
     final int opcode, final String owner, final String name, final String desc) {
   checkStartCode();
   checkEndCode();
   checkOpcode(opcode, 4);
   checkInternalName(owner, "owner");
   checkUnqualifiedName(version, name, "name");
   checkDesc(desc, false);
   super.visitFieldInsn(opcode, owner, name, desc);
   ++insnCount;
 }
 @Override
 public AnnotationVisitor visitTypeAnnotation(
     final int typeRef, final TypePath typePath, final String desc, final boolean visible) {
   checkEnd();
   int sort = typeRef >>> 24;
   if (sort != TypeReference.FIELD) {
     throw new IllegalArgumentException(
         "Invalid type reference sort 0x" + Integer.toHexString(sort));
   }
   CheckClassAdapter.checkTypeRefAndPath(typeRef, typePath);
   CheckMethodAdapter.checkDesc(desc, false);
   return new CheckAnnotationAdapter(super.visitTypeAnnotation(typeRef, typePath, desc, visible));
 }
 @Override
 public AnnotationVisitor visitTypeAnnotation(
     final int typeRef, final TypePath typePath, final String desc, final boolean visible) {
   checkEndMethod();
   int sort = typeRef >>> 24;
   if (sort != TypeReference.METHOD_TYPE_PARAMETER
       && sort != TypeReference.METHOD_TYPE_PARAMETER_BOUND
       && sort != TypeReference.METHOD_RETURN
       && sort != TypeReference.METHOD_RECEIVER
       && sort != TypeReference.METHOD_FORMAL_PARAMETER
       && sort != TypeReference.THROWS) {
     throw new IllegalArgumentException(
         "Invalid type reference sort 0x" + Integer.toHexString(sort));
   }
   CheckClassAdapter.checkTypeRefAndPath(typeRef, typePath);
   CheckMethodAdapter.checkDesc(desc, false);
   return new CheckAnnotationAdapter(super.visitTypeAnnotation(typeRef, typePath, desc, visible));
 }
 @Override
 public void visitMultiANewArrayInsn(final String desc, final int dims) {
   checkStartCode();
   checkEndCode();
   checkDesc(desc, false);
   if (desc.charAt(0) != '[') {
     throw new IllegalArgumentException(
         "Invalid descriptor (must be an array type descriptor): " + desc);
   }
   if (dims < 1) {
     throw new IllegalArgumentException("Invalid dimensions (must be greater than 0): " + dims);
   }
   if (dims > desc.lastIndexOf('[') + 1) {
     throw new IllegalArgumentException(
         "Invalid dimensions (must not be greater than dims(desc)): " + dims);
   }
   super.visitMultiANewArrayInsn(desc, dims);
   ++insnCount;
 }
 @Override
 public AnnotationVisitor visitLocalVariableAnnotation(
     int typeRef,
     TypePath typePath,
     Label[] start,
     Label[] end,
     int[] index,
     String desc,
     boolean visible) {
   checkStartCode();
   checkEndCode();
   int sort = typeRef >>> 24;
   if (sort != TypeReference.LOCAL_VARIABLE && sort != TypeReference.RESOURCE_VARIABLE) {
     throw new IllegalArgumentException(
         "Invalid type reference sort 0x" + Integer.toHexString(sort));
   }
   CheckClassAdapter.checkTypeRefAndPath(typeRef, typePath);
   checkDesc(desc, false);
   if (start == null
       || end == null
       || index == null
       || end.length != start.length
       || index.length != start.length) {
     throw new IllegalArgumentException(
         "Invalid start, end and index arrays (must be non null and of identical length");
   }
   for (int i = 0; i < start.length; ++i) {
     checkLabel(start[i], true, "start label");
     checkLabel(end[i], true, "end label");
     checkUnsignedShort(index[i], "Invalid variable index");
     int s = labels.get(start[i]).intValue();
     int e = labels.get(end[i]).intValue();
     if (e < s) {
       throw new IllegalArgumentException(
           "Invalid start and end labels (end must be greater than start)");
     }
   }
   return super.visitLocalVariableAnnotation(typeRef, typePath, start, end, index, desc, visible);
 }
 @Override
 public AnnotationVisitor visitInsnAnnotation(
     final int typeRef, final TypePath typePath, final String desc, final boolean visible) {
   checkStartCode();
   checkEndCode();
   int sort = typeRef >>> 24;
   if (sort != TypeReference.INSTANCEOF
       && sort != TypeReference.NEW
       && sort != TypeReference.CONSTRUCTOR_REFERENCE
       && sort != TypeReference.METHOD_REFERENCE
       && sort != TypeReference.CAST
       && sort != TypeReference.CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT
       && sort != TypeReference.METHOD_INVOCATION_TYPE_ARGUMENT
       && sort != TypeReference.CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT
       && sort != TypeReference.METHOD_REFERENCE_TYPE_ARGUMENT) {
     throw new IllegalArgumentException(
         "Invalid type reference sort 0x" + Integer.toHexString(sort));
   }
   CheckClassAdapter.checkTypeRefAndPath(typeRef, typePath);
   CheckMethodAdapter.checkDesc(desc, false);
   return new CheckAnnotationAdapter(super.visitInsnAnnotation(typeRef, typePath, desc, visible));
 }
 @Override
 public void visitLocalVariable(
     final String name,
     final String desc,
     final String signature,
     final Label start,
     final Label end,
     final int index) {
   checkStartCode();
   checkEndCode();
   checkUnqualifiedName(version, name, "name");
   checkDesc(desc, false);
   checkLabel(start, true, "start label");
   checkLabel(end, true, "end label");
   checkUnsignedShort(index, "Invalid variable index");
   int s = labels.get(start).intValue();
   int e = labels.get(end).intValue();
   if (e < s) {
     throw new IllegalArgumentException(
         "Invalid start and end labels (end must be greater than start)");
   }
   super.visitLocalVariable(name, desc, signature, start, end, index);
 }
 @Override
 public AnnotationVisitor visitAnnotation(final String desc, final boolean visible) {
   checkEnd();
   CheckMethodAdapter.checkDesc(desc, false);
   return new CheckAnnotationAdapter(super.visitAnnotation(desc, visible));
 }