@Override
 public void visitLineNumber(final int line, final Label start) {
   checkStartCode();
   checkEndCode();
   checkUnsignedShort(line, "Invalid line number");
   checkLabel(start, true, "start label");
   super.visitLineNumber(line, start);
 }
 @Override
 public void visitIincInsn(final int var, final int increment) {
   checkStartCode();
   checkEndCode();
   checkUnsignedShort(var, "Invalid variable index");
   checkSignedShort(increment, "Invalid increment");
   super.visitIincInsn(var, increment);
   ++insnCount;
 }
 @Override
 public void visitVarInsn(final int opcode, final int var) {
   checkStartCode();
   checkEndCode();
   checkOpcode(opcode, 2);
   checkUnsignedShort(var, "Invalid variable index");
   super.visitVarInsn(opcode, var);
   ++insnCount;
 }
 @Override
 public void visitMaxs(final int maxStack, final int maxLocals) {
   checkStartCode();
   checkEndCode();
   endCode = true;
   for (Label l : usedLabels) {
     if (labels.get(l) == null) {
       throw new IllegalStateException("Undefined label used");
     }
   }
   for (int i = 0; i < handlers.size(); ) {
     Integer start = labels.get(handlers.get(i++));
     Integer end = labels.get(handlers.get(i++));
     if (start == null || end == null) {
       throw new IllegalStateException("Undefined try catch block labels");
     }
     if (end.intValue() <= start.intValue()) {
       throw new IllegalStateException("Emty try catch block handler range");
     }
   }
   checkUnsignedShort(maxStack, "Invalid max stack");
   checkUnsignedShort(maxLocals, "Invalid max locals");
   super.visitMaxs(maxStack, maxLocals);
 }
 @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 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);
 }