// ASM: a very small and fast Java bytecode manipulation framework
// Copyright (c) 2000-2011 INRIA, France Telecom
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 1. Redistributions of source code must retain the above copyright
//    notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
//    notice, this list of conditions and the following disclaimer in the
//    documentation and/or other materials provided with the distribution.
// 3. Neither the name of the copyright holders nor the names of its
//    contributors may be used to endorse or promote products derived from
//    this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
// THE POSSIBILITY OF SUCH DAMAGE.
package org.apache.tapestry5.internal.plastic.asm.util;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.tapestry5.internal.plastic.asm.AnnotationVisitor;
import org.apache.tapestry5.internal.plastic.asm.Attribute;
import org.apache.tapestry5.internal.plastic.asm.ConstantDynamic;
import org.apache.tapestry5.internal.plastic.asm.Handle;
import org.apache.tapestry5.internal.plastic.asm.Label;
import org.apache.tapestry5.internal.plastic.asm.MethodVisitor;
import org.apache.tapestry5.internal.plastic.asm.Opcodes;
import org.apache.tapestry5.internal.plastic.asm.Type;
import org.apache.tapestry5.internal.plastic.asm.TypePath;
import org.apache.tapestry5.internal.plastic.asm.TypeReference;
import org.apache.tapestry5.internal.plastic.asm.tree.MethodNode;
import org.apache.tapestry5.internal.plastic.asm.tree.analysis.Analyzer;
import org.apache.tapestry5.internal.plastic.asm.tree.analysis.AnalyzerException;
import org.apache.tapestry5.internal.plastic.asm.tree.analysis.BasicValue;
import org.apache.tapestry5.internal.plastic.asm.tree.analysis.BasicVerifier;

/**
 * A {@link MethodVisitor} that checks that its methods are properly used. More precisely this
 * method adapter checks each instruction individually, i.e., each visit method checks some
 * preconditions based <i>only</i> on its arguments - such as the fact that the given opcode is
 * correct for a given visit method. This adapter can also perform some basic data flow checks (more
 * precisely those that can be performed without the full class hierarchy - see {@link
 * org.apache.tapestry5.internal.plastic.asm.tree.analysis.BasicVerifier}). For instance in a method whose signature is
 * {@code void m ()}, the invalid instruction IRETURN, or the invalid sequence IADD L2I will be
 * detected if the data flow checks are enabled. These checks are enabled by using the {@link
 * #CheckMethodAdapter(int,String,String,MethodVisitor,Map)} constructor. They are not performed if
 * any other constructor is used.
 *
 * @author Eric Bruneton
 */
public class CheckMethodAdapter extends MethodVisitor {

  /** The 'generic' instruction visit methods (i.e. those that take an opcode argument). */
  private enum Method {
    VISIT_INSN,
    VISIT_INT_INSN,
    VISIT_VAR_INSN,
    VISIT_TYPE_INSN,
    VISIT_FIELD_INSN,
    VISIT_METHOD_INSN,
    VISIT_JUMP_INSN
  }

  /** The method to use to visit each instruction. Only generic methods are represented here. */
  private static final Method[] OPCODE_METHODS = {
    Method.VISIT_INSN, // NOP
    Method.VISIT_INSN, // ACONST_NULL
    Method.VISIT_INSN, // ICONST_M1
    Method.VISIT_INSN, // ICONST_0
    Method.VISIT_INSN, // ICONST_1
    Method.VISIT_INSN, // ICONST_2
    Method.VISIT_INSN, // ICONST_3
    Method.VISIT_INSN, // ICONST_4
    Method.VISIT_INSN, // ICONST_5
    Method.VISIT_INSN, // LCONST_0
    Method.VISIT_INSN, // LCONST_1
    Method.VISIT_INSN, // FCONST_0
    Method.VISIT_INSN, // FCONST_1
    Method.VISIT_INSN, // FCONST_2
    Method.VISIT_INSN, // DCONST_0
    Method.VISIT_INSN, // DCONST_1
    Method.VISIT_INT_INSN, // BIPUSH
    Method.VISIT_INT_INSN, // SIPUSH
    null, // LDC
    null, // LDC_W
    null, // LDC2_W
    Method.VISIT_VAR_INSN, // ILOAD
    Method.VISIT_VAR_INSN, // LLOAD
    Method.VISIT_VAR_INSN, // FLOAD
    Method.VISIT_VAR_INSN, // DLOAD
    Method.VISIT_VAR_INSN, // ALOAD
    null, // ILOAD_0
    null, // ILOAD_1
    null, // ILOAD_2
    null, // ILOAD_3
    null, // LLOAD_0
    null, // LLOAD_1
    null, // LLOAD_2
    null, // LLOAD_3
    null, // FLOAD_0
    null, // FLOAD_1
    null, // FLOAD_2
    null, // FLOAD_3
    null, // DLOAD_0
    null, // DLOAD_1
    null, // DLOAD_2
    null, // DLOAD_3
    null, // ALOAD_0
    null, // ALOAD_1
    null, // ALOAD_2
    null, // ALOAD_3
    Method.VISIT_INSN, // IALOAD
    Method.VISIT_INSN, // LALOAD
    Method.VISIT_INSN, // FALOAD
    Method.VISIT_INSN, // DALOAD
    Method.VISIT_INSN, // AALOAD
    Method.VISIT_INSN, // BALOAD
    Method.VISIT_INSN, // CALOAD
    Method.VISIT_INSN, // SALOAD
    Method.VISIT_VAR_INSN, // ISTORE
    Method.VISIT_VAR_INSN, // LSTORE
    Method.VISIT_VAR_INSN, // FSTORE
    Method.VISIT_VAR_INSN, // DSTORE
    Method.VISIT_VAR_INSN, // ASTORE
    null, // ISTORE_0
    null, // ISTORE_1
    null, // ISTORE_2
    null, // ISTORE_3
    null, // LSTORE_0
    null, // LSTORE_1
    null, // LSTORE_2
    null, // LSTORE_3
    null, // FSTORE_0
    null, // FSTORE_1
    null, // FSTORE_2
    null, // FSTORE_3
    null, // DSTORE_0
    null, // DSTORE_1
    null, // DSTORE_2
    null, // DSTORE_3
    null, // ASTORE_0
    null, // ASTORE_1
    null, // ASTORE_2
    null, // ASTORE_3
    Method.VISIT_INSN, // IASTORE
    Method.VISIT_INSN, // LASTORE
    Method.VISIT_INSN, // FASTORE
    Method.VISIT_INSN, // DASTORE
    Method.VISIT_INSN, // AASTORE
    Method.VISIT_INSN, // BASTORE
    Method.VISIT_INSN, // CASTORE
    Method.VISIT_INSN, // SASTORE
    Method.VISIT_INSN, // POP
    Method.VISIT_INSN, // POP2
    Method.VISIT_INSN, // DUP
    Method.VISIT_INSN, // DUP_X1
    Method.VISIT_INSN, // DUP_X2
    Method.VISIT_INSN, // DUP2
    Method.VISIT_INSN, // DUP2_X1
    Method.VISIT_INSN, // DUP2_X2
    Method.VISIT_INSN, // SWAP
    Method.VISIT_INSN, // IADD
    Method.VISIT_INSN, // LADD
    Method.VISIT_INSN, // FADD
    Method.VISIT_INSN, // DADD
    Method.VISIT_INSN, // ISUB
    Method.VISIT_INSN, // LSUB
    Method.VISIT_INSN, // FSUB
    Method.VISIT_INSN, // DSUB
    Method.VISIT_INSN, // IMUL
    Method.VISIT_INSN, // LMUL
    Method.VISIT_INSN, // FMUL
    Method.VISIT_INSN, // DMUL
    Method.VISIT_INSN, // IDIV
    Method.VISIT_INSN, // LDIV
    Method.VISIT_INSN, // FDIV
    Method.VISIT_INSN, // DDIV
    Method.VISIT_INSN, // IREM
    Method.VISIT_INSN, // LREM
    Method.VISIT_INSN, // FREM
    Method.VISIT_INSN, // DREM
    Method.VISIT_INSN, // INEG
    Method.VISIT_INSN, // LNEG
    Method.VISIT_INSN, // FNEG
    Method.VISIT_INSN, // DNEG
    Method.VISIT_INSN, // ISHL
    Method.VISIT_INSN, // LSHL
    Method.VISIT_INSN, // ISHR
    Method.VISIT_INSN, // LSHR
    Method.VISIT_INSN, // IUSHR
    Method.VISIT_INSN, // LUSHR
    Method.VISIT_INSN, // IAND
    Method.VISIT_INSN, // LAND
    Method.VISIT_INSN, // IOR
    Method.VISIT_INSN, // LOR
    Method.VISIT_INSN, // IXOR
    Method.VISIT_INSN, // LXOR
    null, // IINC
    Method.VISIT_INSN, // I2L
    Method.VISIT_INSN, // I2F
    Method.VISIT_INSN, // I2D
    Method.VISIT_INSN, // L2I
    Method.VISIT_INSN, // L2F
    Method.VISIT_INSN, // L2D
    Method.VISIT_INSN, // F2I
    Method.VISIT_INSN, // F2L
    Method.VISIT_INSN, // F2D
    Method.VISIT_INSN, // D2I
    Method.VISIT_INSN, // D2L
    Method.VISIT_INSN, // D2F
    Method.VISIT_INSN, // I2B
    Method.VISIT_INSN, // I2C
    Method.VISIT_INSN, // I2S
    Method.VISIT_INSN, // LCMP
    Method.VISIT_INSN, // FCMPL
    Method.VISIT_INSN, // FCMPG
    Method.VISIT_INSN, // DCMPL
    Method.VISIT_INSN, // DCMPG
    Method.VISIT_JUMP_INSN, // IFEQ
    Method.VISIT_JUMP_INSN, // IFNE
    Method.VISIT_JUMP_INSN, // IFLT
    Method.VISIT_JUMP_INSN, // IFGE
    Method.VISIT_JUMP_INSN, // IFGT
    Method.VISIT_JUMP_INSN, // IFLE
    Method.VISIT_JUMP_INSN, // IF_ICMPEQ
    Method.VISIT_JUMP_INSN, // IF_ICMPNE
    Method.VISIT_JUMP_INSN, // IF_ICMPLT
    Method.VISIT_JUMP_INSN, // IF_ICMPGE
    Method.VISIT_JUMP_INSN, // IF_ICMPGT
    Method.VISIT_JUMP_INSN, // IF_ICMPLE
    Method.VISIT_JUMP_INSN, // IF_ACMPEQ
    Method.VISIT_JUMP_INSN, // IF_ACMPNE
    Method.VISIT_JUMP_INSN, // GOTO
    Method.VISIT_JUMP_INSN, // JSR
    Method.VISIT_VAR_INSN, // RET
    null, // TABLESWITCH
    null, // LOOKUPSWITCH
    Method.VISIT_INSN, // IRETURN
    Method.VISIT_INSN, // LRETURN
    Method.VISIT_INSN, // FRETURN
    Method.VISIT_INSN, // DRETURN
    Method.VISIT_INSN, // ARETURN
    Method.VISIT_INSN, // RETURN
    Method.VISIT_FIELD_INSN, // GETSTATIC
    Method.VISIT_FIELD_INSN, // PUTSTATIC
    Method.VISIT_FIELD_INSN, // GETFIELD
    Method.VISIT_FIELD_INSN, // PUTFIELD
    Method.VISIT_METHOD_INSN, // INVOKEVIRTUAL
    Method.VISIT_METHOD_INSN, // INVOKESPECIAL
    Method.VISIT_METHOD_INSN, // INVOKESTATIC
    Method.VISIT_METHOD_INSN, // INVOKEINTERFACE
    null, // INVOKEDYNAMIC
    Method.VISIT_TYPE_INSN, // NEW
    Method.VISIT_INT_INSN, // NEWARRAY
    Method.VISIT_TYPE_INSN, // ANEWARRAY
    Method.VISIT_INSN, // ARRAYLENGTH
    Method.VISIT_INSN, // ATHROW
    Method.VISIT_TYPE_INSN, // CHECKCAST
    Method.VISIT_TYPE_INSN, // INSTANCEOF
    Method.VISIT_INSN, // MONITORENTER
    Method.VISIT_INSN, // MONITOREXIT
    null, // WIDE
    null, // MULTIANEWARRAY
    Method.VISIT_JUMP_INSN, // IFNULL
    Method.VISIT_JUMP_INSN // IFNONNULL
  };

  private static final String INVALID = "Invalid ";
  private static final String INVALID_DESCRIPTOR = "Invalid descriptor: ";
  private static final String INVALID_TYPE_REFERENCE = "Invalid type reference sort 0x";
  private static final String INVALID_LOCAL_VARIABLE_INDEX = "Invalid local variable index";
  private static final String MUST_NOT_BE_NULL_OR_EMPTY = " (must not be null or empty)";
  private static final String START_LABEL = "start label";
  private static final String END_LABEL = "end label";

  /** The class version number. */
  public int version;

  /** The access flags of the visited method. */
  private int access;

  /**
   * The number of method parameters that can have runtime visible annotations. 0 means that all the
   * parameters from the method descriptor can have annotations.
   */
  private int visibleAnnotableParameterCount;

  /**
   * The number of method parameters that can have runtime invisible annotations. 0 means that all
   * the parameters from the method descriptor can have annotations.
   */
  private int invisibleAnnotableParameterCount;

  /** Whether the {@link #visitCode} method has been called. */
  private boolean visitCodeCalled;

  /** Whether the {@link #visitMaxs} method has been called. */
  private boolean visitMaxCalled;

  /** Whether the {@link #visitEnd} method has been called. */
  private boolean visitEndCalled;

  /** The number of visited instructions so far. */
  private int insnCount;

  /** The index of the instruction designated by each visited label. */
  private final Map<Label, Integer> labelInsnIndices;

  /** The labels referenced by the visited method. */
  private Set<Label> referencedLabels;

  /** The index of the instruction corresponding to the last visited stack map frame. */
  private int lastFrameInsnIndex = -1;

  /** The number of visited frames in expanded form. */
  private int numExpandedFrames;

  /** The number of visited frames in compressed form. */
  private int numCompressedFrames;

  /**
   * The exception handler ranges. Each pair of list element contains the start and end labels of an
   * exception handler block.
   */
  private List<Label> handlers;

  /**
   * Constructs a new {@link CheckMethodAdapter} object. This method adapter will not perform any
   * data flow check (see {@link #CheckMethodAdapter(int,String,String,MethodVisitor,Map)}).
   * <i>Subclasses must not use this constructor</i>. Instead, they must use the {@link
   * #CheckMethodAdapter(int, MethodVisitor, Map)} version.
   *
   * @param methodvisitor the method visitor to which this adapter must delegate calls.
   */
  public CheckMethodAdapter(final MethodVisitor methodvisitor) {
    this(methodvisitor, new HashMap<Label, Integer>());
  }

  /**
   * Constructs a new {@link CheckMethodAdapter} object. This method adapter will not perform any
   * data flow check (see {@link #CheckMethodAdapter(int,String,String,MethodVisitor,Map)}).
   * <i>Subclasses must not use this constructor</i>. Instead, they must use the {@link
   * #CheckMethodAdapter(int, MethodVisitor, Map)} version.
   *
   * @param methodVisitor the method visitor to which this adapter must delegate calls.
   * @param labelInsnIndices the index of the instruction designated by each visited label so far
   *     (in other methods). This map is updated with the labels from the visited method.
   * @throws IllegalStateException If a subclass calls this constructor.
   */
  public CheckMethodAdapter(
      final MethodVisitor methodVisitor, final Map<Label, Integer> labelInsnIndices) {
    this(/* latest api = */ Opcodes.ASM8, methodVisitor, labelInsnIndices);
    if (getClass() != CheckMethodAdapter.class) {
      throw new IllegalStateException();
    }
  }

  /**
   * Constructs a new {@link CheckMethodAdapter} object. This method adapter will not perform any
   * data flow check (see {@link #CheckMethodAdapter(int,String,String,MethodVisitor,Map)}).
   *
   * @param api the ASM API version implemented by this CheckMethodAdapter. Must be one of {@link
   *     Opcodes#ASM4}, {@link Opcodes#ASM5}, {@link Opcodes#ASM6}, {@link Opcodes#ASM7} or {@link
   *     Opcodes#ASM8}.
   * @param methodVisitor the method visitor to which this adapter must delegate calls.
   * @param labelInsnIndices the index of the instruction designated by each visited label so far
   *     (in other methods). This map is updated with the labels from the visited method.
   */
  protected CheckMethodAdapter(
      final int api,
      final MethodVisitor methodVisitor,
      final Map<Label, Integer> labelInsnIndices) {
    super(api, methodVisitor);
    this.labelInsnIndices = labelInsnIndices;
    this.referencedLabels = new HashSet<>();
    this.handlers = new ArrayList<>();
  }

  /**
   * Constructs a new {@link CheckMethodAdapter} object. This method adapter will perform basic data
   * flow checks. For instance in a method whose signature is {@code void m ()}, the invalid
   * instruction IRETURN, or the invalid sequence IADD L2I will be detected. <i>Subclasses must not
   * use this constructor</i>. Instead, they must use the {@link
   * #CheckMethodAdapter(int,int,String,String,MethodVisitor,Map)} version.
   *
   * @param access the method's access flags.
   * @param name the method's name.
   * @param descriptor the method's descriptor (see {@link Type}).
   * @param methodVisitor the method visitor to which this adapter must delegate calls.
   * @param labelInsnIndices the index of the instruction designated by each visited label so far
   *     (in other methods). This map is updated with the labels from the visited method.
   */
  public CheckMethodAdapter(
      final int access,
      final String name,
      final String descriptor,
      final MethodVisitor methodVisitor,
      final Map<Label, Integer> labelInsnIndices) {
    this(
        /* latest api = */ Opcodes.ASM8, access, name, descriptor, methodVisitor, labelInsnIndices);
    if (getClass() != CheckMethodAdapter.class) {
      throw new IllegalStateException();
    }
  }

  /**
   * Constructs a new {@link CheckMethodAdapter} object. This method adapter will perform basic data
   * flow checks. For instance in a method whose signature is {@code void m ()}, the invalid
   * instruction IRETURN, or the invalid sequence IADD L2I will be detected.
   *
   * @param api the ASM API version implemented by this CheckMethodAdapter. Must be one of {@link
   *     Opcodes#ASM4}, {@link Opcodes#ASM5}, {@link Opcodes#ASM6}, {@link Opcodes#ASM7} or {@link
   *     Opcodes#ASM8}.
   * @param access the method's access flags.
   * @param name the method's name.
   * @param descriptor the method's descriptor (see {@link Type}).
   * @param methodVisitor the method visitor to which this adapter must delegate calls.
   * @param labelInsnIndices the index of the instruction designated by each visited label so far
   *     (in other methods). This map is updated with the labels from the visited method.
   */
  protected CheckMethodAdapter(
      final int api,
      final int access,
      final String name,
      final String descriptor,
      final MethodVisitor methodVisitor,
      final Map<Label, Integer> labelInsnIndices) {
    this(
        api,
        new MethodNode(api, access, name, descriptor, null, null) {
          @Override
          public void visitEnd() {
            Analyzer<BasicValue> analyzer = new Analyzer<>(new BasicVerifier());
            try {
              analyzer.analyze("dummy", this);
            } catch (IndexOutOfBoundsException e) {
              if (maxLocals == 0 && maxStack == 0) {
                throw new IllegalArgumentException(
                    "Data flow checking option requires valid, non zero maxLocals and maxStack.",
                    e);
              }
              throwError(analyzer, e);
            } catch (AnalyzerException e) {
              throwError(analyzer, e);
            }
            if (methodVisitor != null) {
              accept(methodVisitor);
            }
          }

          private void throwError(final Analyzer<BasicValue> analyzer, final Exception e) {
            StringWriter stringWriter = new StringWriter();
            PrintWriter printWriter = new PrintWriter(stringWriter, true);
            CheckClassAdapter.printAnalyzerResult(this, analyzer, printWriter);
            printWriter.close();
            throw new IllegalArgumentException(e.getMessage() + ' ' + stringWriter.toString(), e);
          }
        },
        labelInsnIndices);
    this.access = access;
  }

  @Override
  public void visitParameter(final String name, final int access) {
    if (name != null) {
      checkUnqualifiedName(version, name, "name");
    }
    CheckClassAdapter.checkAccess(
        access, Opcodes.ACC_FINAL + Opcodes.ACC_MANDATED + Opcodes.ACC_SYNTHETIC);
    super.visitParameter(name, access);
  }

  @Override
  public AnnotationVisitor visitAnnotation(final String descriptor, final boolean visible) {
    checkVisitEndNotCalled();
    checkDescriptor(version, descriptor, false);
    return new CheckAnnotationAdapter(super.visitAnnotation(descriptor, visible));
  }

  @Override
  public AnnotationVisitor visitTypeAnnotation(
      final int typeRef, final TypePath typePath, final String descriptor, final boolean visible) {
    checkVisitEndNotCalled();
    int sort = new TypeReference(typeRef).getSort();
    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 + Integer.toHexString(sort));
    }
    CheckClassAdapter.checkTypeRef(typeRef);
    CheckMethodAdapter.checkDescriptor(version, descriptor, false);
    return new CheckAnnotationAdapter(
        super.visitTypeAnnotation(typeRef, typePath, descriptor, visible));
  }

  @Override
  public AnnotationVisitor visitAnnotationDefault() {
    checkVisitEndNotCalled();
    return new CheckAnnotationAdapter(super.visitAnnotationDefault(), false);
  }

  @Override
  public void visitAnnotableParameterCount(final int parameterCount, final boolean visible) {
    checkVisitEndNotCalled();
    if (visible) {
      visibleAnnotableParameterCount = parameterCount;
    } else {
      invisibleAnnotableParameterCount = parameterCount;
    }
    super.visitAnnotableParameterCount(parameterCount, visible);
  }

  @Override
  public AnnotationVisitor visitParameterAnnotation(
      final int parameter, final String descriptor, final boolean visible) {
    checkVisitEndNotCalled();
    if ((visible
            && visibleAnnotableParameterCount > 0
            && parameter >= visibleAnnotableParameterCount)
        || (!visible
            && invisibleAnnotableParameterCount > 0
            && parameter >= invisibleAnnotableParameterCount)) {
      throw new IllegalArgumentException("Invalid parameter index");
    }
    checkDescriptor(version, descriptor, false);
    return new CheckAnnotationAdapter(
        super.visitParameterAnnotation(parameter, descriptor, visible));
  }

  @Override
  public void visitAttribute(final Attribute attribute) {
    checkVisitEndNotCalled();
    if (attribute == null) {
      throw new IllegalArgumentException("Invalid attribute (must not be null)");
    }
    super.visitAttribute(attribute);
  }

  @Override
  public void visitCode() {
    if ((access & Opcodes.ACC_ABSTRACT) != 0) {
      throw new UnsupportedOperationException("Abstract methods cannot have code");
    }
    visitCodeCalled = true;
    super.visitCode();
  }

  @Override
  public void visitFrame(
      final int type,
      final int numLocal,
      final Object[] local,
      final int numStack,
      final Object[] stack) {
    if (insnCount == lastFrameInsnIndex) {
      throw new IllegalStateException("At most one frame can be visited at a given code location.");
    }
    lastFrameInsnIndex = insnCount;
    int maxNumLocal;
    int maxNumStack;
    switch (type) {
      case Opcodes.F_NEW:
      case Opcodes.F_FULL:
        maxNumLocal = Integer.MAX_VALUE;
        maxNumStack = Integer.MAX_VALUE;
        break;

      case Opcodes.F_SAME:
        maxNumLocal = 0;
        maxNumStack = 0;
        break;

      case Opcodes.F_SAME1:
        maxNumLocal = 0;
        maxNumStack = 1;
        break;

      case Opcodes.F_APPEND:
      case Opcodes.F_CHOP:
        maxNumLocal = 3;
        maxNumStack = 0;
        break;

      default:
        throw new IllegalArgumentException("Invalid frame type " + type);
    }

    if (numLocal > maxNumLocal) {
      throw new IllegalArgumentException(
          "Invalid numLocal=" + numLocal + " for frame type " + type);
    }
    if (numStack > maxNumStack) {
      throw new IllegalArgumentException(
          "Invalid numStack=" + numStack + " for frame type " + type);
    }

    if (type != Opcodes.F_CHOP) {
      if (numLocal > 0 && (local == null || local.length < numLocal)) {
        throw new IllegalArgumentException("Array local[] is shorter than numLocal");
      }
      for (int i = 0; i < numLocal; ++i) {
        checkFrameValue(local[i]);
      }
    }
    if (numStack > 0 && (stack == null || stack.length < numStack)) {
      throw new IllegalArgumentException("Array stack[] is shorter than numStack");
    }
    for (int i = 0; i < numStack; ++i) {
      checkFrameValue(stack[i]);
    }
    if (type == Opcodes.F_NEW) {
      ++numExpandedFrames;
    } else {
      ++numCompressedFrames;
    }
    if (numExpandedFrames > 0 && numCompressedFrames > 0) {
      throw new IllegalArgumentException("Expanded and compressed frames must not be mixed.");
    }
    super.visitFrame(type, numLocal, local, numStack, stack);
  }

  @Override
  public void visitInsn(final int opcode) {
    checkVisitCodeCalled();
    checkVisitMaxsNotCalled();
    checkOpcodeMethod(opcode, Method.VISIT_INSN);
    super.visitInsn(opcode);
    ++insnCount;
  }

  @Override
  public void visitIntInsn(final int opcode, final int operand) {
    checkVisitCodeCalled();
    checkVisitMaxsNotCalled();
    checkOpcodeMethod(opcode, Method.VISIT_INT_INSN);
    switch (opcode) {
      case Opcodes.BIPUSH:
        checkSignedByte(operand, "Invalid operand");
        break;
      case Opcodes.SIPUSH:
        checkSignedShort(operand, "Invalid operand");
        break;
      case Opcodes.NEWARRAY:
        if (operand < Opcodes.T_BOOLEAN || operand > Opcodes.T_LONG) {
          throw new IllegalArgumentException(
              "Invalid operand (must be an array type code T_...): " + operand);
        }
        break;
      default:
        throw new AssertionError();
    }
    super.visitIntInsn(opcode, operand);
    ++insnCount;
  }

  @Override
  public void visitVarInsn(final int opcode, final int var) {
    checkVisitCodeCalled();
    checkVisitMaxsNotCalled();
    checkOpcodeMethod(opcode, Method.VISIT_VAR_INSN);
    checkUnsignedShort(var, INVALID_LOCAL_VARIABLE_INDEX);
    super.visitVarInsn(opcode, var);
    ++insnCount;
  }

  @Override
  public void visitTypeInsn(final int opcode, final String type) {
    checkVisitCodeCalled();
    checkVisitMaxsNotCalled();
    checkOpcodeMethod(opcode, Method.VISIT_TYPE_INSN);
    checkInternalName(version, type, "type");
    if (opcode == Opcodes.NEW && type.charAt(0) == '[') {
      throw new IllegalArgumentException("NEW cannot be used to create arrays: " + type);
    }
    super.visitTypeInsn(opcode, type);
    ++insnCount;
  }

  @Override
  public void visitFieldInsn(
      final int opcode, final String owner, final String name, final String descriptor) {
    checkVisitCodeCalled();
    checkVisitMaxsNotCalled();
    checkOpcodeMethod(opcode, Method.VISIT_FIELD_INSN);
    checkInternalName(version, owner, "owner");
    checkUnqualifiedName(version, name, "name");
    checkDescriptor(version, descriptor, false);
    super.visitFieldInsn(opcode, owner, name, descriptor);
    ++insnCount;
  }

  @Override
  public void visitMethodInsn(
      final int opcodeAndSource,
      final String owner,
      final String name,
      final String descriptor,
      final boolean isInterface) {
    if (api < Opcodes.ASM5 && (opcodeAndSource & Opcodes.SOURCE_DEPRECATED) == 0) {
      // Redirect the call to the deprecated version of this method.
      super.visitMethodInsn(opcodeAndSource, owner, name, descriptor, isInterface);
      return;
    }
    int opcode = opcodeAndSource & ~Opcodes.SOURCE_MASK;

    checkVisitCodeCalled();
    checkVisitMaxsNotCalled();
    checkOpcodeMethod(opcode, Method.VISIT_METHOD_INSN);
    if (opcode != Opcodes.INVOKESPECIAL || !"<init>".equals(name)) {
      checkMethodIdentifier(version, name, "name");
    }
    checkInternalName(version, owner, "owner");
    checkMethodDescriptor(version, descriptor);
    if (opcode == Opcodes.INVOKEVIRTUAL && isInterface) {
      throw new IllegalArgumentException("INVOKEVIRTUAL can't be used with interfaces");
    }
    if (opcode == Opcodes.INVOKEINTERFACE && !isInterface) {
      throw new IllegalArgumentException("INVOKEINTERFACE can't be used with classes");
    }
    if (opcode == Opcodes.INVOKESPECIAL && isInterface && (version & 0xFFFF) < Opcodes.V1_8) {
      throw new IllegalArgumentException(
          "INVOKESPECIAL can't be used with interfaces prior to Java 8");
    }
    super.visitMethodInsn(opcodeAndSource, owner, name, descriptor, isInterface);
    ++insnCount;
  }

  @Override
  public void visitInvokeDynamicInsn(
      final String name,
      final String descriptor,
      final Handle bootstrapMethodHandle,
      final Object... bootstrapMethodArguments) {
    checkVisitCodeCalled();
    checkVisitMaxsNotCalled();
    checkMethodIdentifier(version, name, "name");
    checkMethodDescriptor(version, descriptor);
    if (bootstrapMethodHandle.getTag() != Opcodes.H_INVOKESTATIC
        && bootstrapMethodHandle.getTag() != Opcodes.H_NEWINVOKESPECIAL) {
      throw new IllegalArgumentException("invalid handle tag " + bootstrapMethodHandle.getTag());
    }
    for (Object bootstrapMethodArgument : bootstrapMethodArguments) {
      checkLdcConstant(bootstrapMethodArgument);
    }
    super.visitInvokeDynamicInsn(name, descriptor, bootstrapMethodHandle, bootstrapMethodArguments);
    ++insnCount;
  }

  @Override
  public void visitJumpInsn(final int opcode, final Label label) {
    checkVisitCodeCalled();
    checkVisitMaxsNotCalled();
    checkOpcodeMethod(opcode, Method.VISIT_JUMP_INSN);
    checkLabel(label, false, "label");
    super.visitJumpInsn(opcode, label);
    referencedLabels.add(label);
    ++insnCount;
  }

  @Override
  public void visitLabel(final Label label) {
    checkVisitCodeCalled();
    checkVisitMaxsNotCalled();
    checkLabel(label, false, "label");
    if (labelInsnIndices.get(label) != null) {
      throw new IllegalArgumentException("Already visited label");
    }
    labelInsnIndices.put(label, insnCount);
    super.visitLabel(label);
  }

  @Override
  public void visitLdcInsn(final Object value) {
    checkVisitCodeCalled();
    checkVisitMaxsNotCalled();
    checkLdcConstant(value);
    super.visitLdcInsn(value);
    ++insnCount;
  }

  @Override
  public void visitIincInsn(final int var, final int increment) {
    checkVisitCodeCalled();
    checkVisitMaxsNotCalled();
    checkUnsignedShort(var, INVALID_LOCAL_VARIABLE_INDEX);
    checkSignedShort(increment, "Invalid increment");
    super.visitIincInsn(var, increment);
    ++insnCount;
  }

  @Override
  public void visitTableSwitchInsn(
      final int min, final int max, final Label dflt, final Label... labels) {
    checkVisitCodeCalled();
    checkVisitMaxsNotCalled();
    if (max < min) {
      throw new IllegalArgumentException(
          "Max = " + max + " must be greater than or equal to min = " + min);
    }
    checkLabel(dflt, false, "default label");
    if (labels == null || labels.length != max - min + 1) {
      throw new IllegalArgumentException("There must be max - min + 1 labels");
    }
    for (int i = 0; i < labels.length; ++i) {
      checkLabel(labels[i], false, "label at index " + i);
    }
    super.visitTableSwitchInsn(min, max, dflt, labels);
    Collections.addAll(referencedLabels, labels);
    ++insnCount;
  }

  @Override
  public void visitLookupSwitchInsn(final Label dflt, final int[] keys, final Label[] labels) {
    checkVisitMaxsNotCalled();
    checkVisitCodeCalled();
    checkLabel(dflt, false, "default label");
    if (keys == null || labels == null || keys.length != labels.length) {
      throw new IllegalArgumentException("There must be the same number of keys and labels");
    }
    for (int i = 0; i < labels.length; ++i) {
      checkLabel(labels[i], false, "label at index " + i);
    }
    super.visitLookupSwitchInsn(dflt, keys, labels);
    referencedLabels.add(dflt);
    Collections.addAll(referencedLabels, labels);
    ++insnCount;
  }

  @Override
  public void visitMultiANewArrayInsn(final String descriptor, final int numDimensions) {
    checkVisitCodeCalled();
    checkVisitMaxsNotCalled();
    checkDescriptor(version, descriptor, false);
    if (descriptor.charAt(0) != '[') {
      throw new IllegalArgumentException(
          "Invalid descriptor (must be an array type descriptor): " + descriptor);
    }
    if (numDimensions < 1) {
      throw new IllegalArgumentException(
          "Invalid dimensions (must be greater than 0): " + numDimensions);
    }
    if (numDimensions > descriptor.lastIndexOf('[') + 1) {
      throw new IllegalArgumentException(
          "Invalid dimensions (must not be greater than numDimensions(descriptor)): "
              + numDimensions);
    }
    super.visitMultiANewArrayInsn(descriptor, numDimensions);
    ++insnCount;
  }

  @Override
  public AnnotationVisitor visitInsnAnnotation(
      final int typeRef, final TypePath typePath, final String descriptor, final boolean visible) {
    checkVisitCodeCalled();
    checkVisitMaxsNotCalled();
    int sort = new TypeReference(typeRef).getSort();
    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 + Integer.toHexString(sort));
    }
    CheckClassAdapter.checkTypeRef(typeRef);
    CheckMethodAdapter.checkDescriptor(version, descriptor, false);
    return new CheckAnnotationAdapter(
        super.visitInsnAnnotation(typeRef, typePath, descriptor, visible));
  }

  @Override
  public void visitTryCatchBlock(
      final Label start, final Label end, final Label handler, final String type) {
    checkVisitCodeCalled();
    checkVisitMaxsNotCalled();
    checkLabel(start, false, START_LABEL);
    checkLabel(end, false, END_LABEL);
    checkLabel(handler, false, "handler label");
    if (labelInsnIndices.get(start) != null
        || labelInsnIndices.get(end) != null
        || labelInsnIndices.get(handler) != null) {
      throw new IllegalStateException("Try catch blocks must be visited before their labels");
    }
    if (type != null) {
      checkInternalName(version, type, "type");
    }
    super.visitTryCatchBlock(start, end, handler, type);
    handlers.add(start);
    handlers.add(end);
  }

  @Override
  public AnnotationVisitor visitTryCatchAnnotation(
      final int typeRef, final TypePath typePath, final String descriptor, final boolean visible) {
    checkVisitCodeCalled();
    checkVisitMaxsNotCalled();
    int sort = new TypeReference(typeRef).getSort();
    if (sort != TypeReference.EXCEPTION_PARAMETER) {
      throw new IllegalArgumentException(INVALID_TYPE_REFERENCE + Integer.toHexString(sort));
    }
    CheckClassAdapter.checkTypeRef(typeRef);
    CheckMethodAdapter.checkDescriptor(version, descriptor, false);
    return new CheckAnnotationAdapter(
        super.visitTryCatchAnnotation(typeRef, typePath, descriptor, visible));
  }

  @Override
  public void visitLocalVariable(
      final String name,
      final String descriptor,
      final String signature,
      final Label start,
      final Label end,
      final int index) {
    checkVisitCodeCalled();
    checkVisitMaxsNotCalled();
    checkUnqualifiedName(version, name, "name");
    checkDescriptor(version, descriptor, false);
    if (signature != null) {
      CheckClassAdapter.checkFieldSignature(signature);
    }
    checkLabel(start, true, START_LABEL);
    checkLabel(end, true, END_LABEL);
    checkUnsignedShort(index, INVALID_LOCAL_VARIABLE_INDEX);
    int startInsnIndex = labelInsnIndices.get(start).intValue();
    int endInsnIndex = labelInsnIndices.get(end).intValue();
    if (endInsnIndex < startInsnIndex) {
      throw new IllegalArgumentException(
          "Invalid start and end labels (end must be greater than start)");
    }
    super.visitLocalVariable(name, descriptor, signature, start, end, index);
  }

  @Override
  public AnnotationVisitor visitLocalVariableAnnotation(
      final int typeRef,
      final TypePath typePath,
      final Label[] start,
      final Label[] end,
      final int[] index,
      final String descriptor,
      final boolean visible) {
    checkVisitCodeCalled();
    checkVisitMaxsNotCalled();
    int sort = new TypeReference(typeRef).getSort();
    if (sort != TypeReference.LOCAL_VARIABLE && sort != TypeReference.RESOURCE_VARIABLE) {
      throw new IllegalArgumentException(INVALID_TYPE_REFERENCE + Integer.toHexString(sort));
    }
    CheckClassAdapter.checkTypeRef(typeRef);
    checkDescriptor(version, descriptor, 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_LOCAL_VARIABLE_INDEX);
      int startInsnIndex = labelInsnIndices.get(start[i]).intValue();
      int endInsnIndex = labelInsnIndices.get(end[i]).intValue();
      if (endInsnIndex < startInsnIndex) {
        throw new IllegalArgumentException(
            "Invalid start and end labels (end must be greater than start)");
      }
    }
    return super.visitLocalVariableAnnotation(
        typeRef, typePath, start, end, index, descriptor, visible);
  }

  @Override
  public void visitLineNumber(final int line, final Label start) {
    checkVisitCodeCalled();
    checkVisitMaxsNotCalled();
    checkUnsignedShort(line, "Invalid line number");
    checkLabel(start, true, START_LABEL);
    super.visitLineNumber(line, start);
  }

  @Override
  public void visitMaxs(final int maxStack, final int maxLocals) {
    checkVisitCodeCalled();
    checkVisitMaxsNotCalled();
    visitMaxCalled = true;
    for (Label l : referencedLabels) {
      if (labelInsnIndices.get(l) == null) {
        throw new IllegalStateException("Undefined label used");
      }
    }
    for (int i = 0; i < handlers.size(); i += 2) {
      Integer startInsnIndex = labelInsnIndices.get(handlers.get(i));
      Integer endInsnIndex = labelInsnIndices.get(handlers.get(i + 1));
      if (startInsnIndex == null || endInsnIndex == null) {
        throw new IllegalStateException("Undefined try catch block labels");
      }
      if (endInsnIndex.intValue() <= startInsnIndex.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 void visitEnd() {
    checkVisitEndNotCalled();
    visitEndCalled = true;
    super.visitEnd();
  }

  // -----------------------------------------------------------------------------------------------
  // Utility methods
  // -----------------------------------------------------------------------------------------------

  /** Checks that the {@link #visitCode} method has been called. */
  private void checkVisitCodeCalled() {
    if (!visitCodeCalled) {
      throw new IllegalStateException(
          "Cannot visit instructions before visitCode has been called.");
    }
  }

  /** Checks that the {@link #visitMaxs} method has not been called. */
  private void checkVisitMaxsNotCalled() {
    if (visitMaxCalled) {
      throw new IllegalStateException("Cannot visit instructions after visitMaxs has been called.");
    }
  }

  /** Checks that the {@link #visitEnd} method has not been called. */
  private void checkVisitEndNotCalled() {
    if (visitEndCalled) {
      throw new IllegalStateException("Cannot visit elements after visitEnd has been called.");
    }
  }

  /**
   * Checks a stack frame value.
   *
   * @param value the value to be checked.
   */
  private void checkFrameValue(final Object value) {
    if (value == Opcodes.TOP
        || value == Opcodes.INTEGER
        || value == Opcodes.FLOAT
        || value == Opcodes.LONG
        || value == Opcodes.DOUBLE
        || value == Opcodes.NULL
        || value == Opcodes.UNINITIALIZED_THIS) {
      return;
    }
    if (value instanceof String) {
      checkInternalName(version, (String) value, "Invalid stack frame value");
    } else if (value instanceof Label) {
      referencedLabels.add((Label) value);
    } else {
      throw new IllegalArgumentException("Invalid stack frame value: " + value);
    }
  }

  /**
   * Checks that the method to visit the given opcode is equal to the given method.
   *
   * @param opcode the opcode to be checked.
   * @param method the expected visit method.
   */
  private static void checkOpcodeMethod(final int opcode, final Method method) {
    if (opcode < Opcodes.NOP || opcode > Opcodes.IFNONNULL || OPCODE_METHODS[opcode] != method) {
      throw new IllegalArgumentException("Invalid opcode: " + opcode);
    }
  }

  /**
   * Checks that the given value is a signed byte.
   *
   * @param value the value to be checked.
   * @param message the message to use in case of error.
   */
  private static void checkSignedByte(final int value, final String message) {
    if (value < Byte.MIN_VALUE || value > Byte.MAX_VALUE) {
      throw new IllegalArgumentException(message + " (must be a signed byte): " + value);
    }
  }

  /**
   * Checks that the given value is a signed short.
   *
   * @param value the value to be checked.
   * @param message the message to use in case of error.
   */
  private static void checkSignedShort(final int value, final String message) {
    if (value < Short.MIN_VALUE || value > Short.MAX_VALUE) {
      throw new IllegalArgumentException(message + " (must be a signed short): " + value);
    }
  }

  /**
   * Checks that the given value is an unsigned short.
   *
   * @param value the value to be checked.
   * @param message the message to use in case of error.
   */
  private static void checkUnsignedShort(final int value, final String message) {
    if (value < 0 || value > 65535) {
      throw new IllegalArgumentException(message + " (must be an unsigned short): " + value);
    }
  }

  /**
   * Checks that the given value is an {@link Integer}, {@link Float}, {@link Long}, {@link Double}
   * or {@link String} value.
   *
   * @param value the value to be checked.
   */
  static void checkConstant(final Object value) {
    if (!(value instanceof Integer)
        && !(value instanceof Float)
        && !(value instanceof Long)
        && !(value instanceof Double)
        && !(value instanceof String)) {
      throw new IllegalArgumentException("Invalid constant: " + value);
    }
  }

  /**
   * Checks that the given value is a valid operand for the LDC instruction.
   *
   * @param value the value to be checked.
   */
  private void checkLdcConstant(final Object value) {
    if (value instanceof Type) {
      int sort = ((Type) value).getSort();
      if (sort != Type.OBJECT && sort != Type.ARRAY && sort != Type.METHOD) {
        throw new IllegalArgumentException("Illegal LDC constant value");
      }
      if (sort != Type.METHOD && (version & 0xFFFF) < Opcodes.V1_5) {
        throw new IllegalArgumentException("ldc of a constant class requires at least version 1.5");
      }
      if (sort == Type.METHOD && (version & 0xFFFF) < Opcodes.V1_7) {
        throw new IllegalArgumentException("ldc of a method type requires at least version 1.7");
      }
    } else if (value instanceof Handle) {
      if ((version & 0xFFFF) < Opcodes.V1_7) {
        throw new IllegalArgumentException("ldc of a Handle requires at least version 1.7");
      }
      Handle handle = (Handle) value;
      int tag = handle.getTag();
      if (tag < Opcodes.H_GETFIELD || tag > Opcodes.H_INVOKEINTERFACE) {
        throw new IllegalArgumentException("invalid handle tag " + tag);
      }
      checkInternalName(this.version, handle.getOwner(), "handle owner");
      if (tag <= Opcodes.H_PUTSTATIC) {
        checkDescriptor(this.version, handle.getDesc(), false);
      } else {
        checkMethodDescriptor(this.version, handle.getDesc());
      }
      String handleName = handle.getName();
      if (!("<init>".equals(handleName) && tag == Opcodes.H_NEWINVOKESPECIAL)) {
        checkMethodIdentifier(this.version, handleName, "handle name");
      }
    } else if (value instanceof ConstantDynamic) {
      if ((version & 0xFFFF) < Opcodes.V11) {
        throw new IllegalArgumentException("ldc of a ConstantDynamic requires at least version 11");
      }
      ConstantDynamic constantDynamic = (ConstantDynamic) value;
      checkMethodIdentifier(this.version, constantDynamic.getName(), "constant dynamic name");
      checkDescriptor(this.version, constantDynamic.getDescriptor(), false);
      checkLdcConstant(constantDynamic.getBootstrapMethod());
      int bootstrapMethodArgumentCount = constantDynamic.getBootstrapMethodArgumentCount();
      for (int i = 0; i < bootstrapMethodArgumentCount; ++i) {
        checkLdcConstant(constantDynamic.getBootstrapMethodArgument(i));
      }
    } else {
      checkConstant(value);
    }
  }

  /**
   * Checks that the given string is a valid unqualified name.
   *
   * @param version the class version.
   * @param name the string to be checked.
   * @param message the message to use in case of error.
   */
  static void checkUnqualifiedName(final int version, final String name, final String message) {
    checkIdentifier(version, name, 0, -1, message);
  }

  /**
   * Checks that the given substring is a valid Java identifier.
   *
   * @param version the class version.
   * @param name the string to be checked.
   * @param startPos the index of the first character of the identifier (inclusive).
   * @param endPos the index of the last character of the identifier (exclusive). -1 is equivalent
   *     to {@code name.length()} if name is not {@literal null}.
   * @param message the message to use in case of error.
   */
  static void checkIdentifier(
      final int version,
      final String name,
      final int startPos,
      final int endPos,
      final String message) {
    if (name == null || (endPos == -1 ? name.length() <= startPos : endPos <= startPos)) {
      throw new IllegalArgumentException(INVALID + message + MUST_NOT_BE_NULL_OR_EMPTY);
    }
    int max = endPos == -1 ? name.length() : endPos;
    if ((version & 0xFFFF) >= Opcodes.V1_5) {
      for (int i = startPos; i < max; i = name.offsetByCodePoints(i, 1)) {
        if (".;[/".indexOf(name.codePointAt(i)) != -1) {
          throw new IllegalArgumentException(
              INVALID + message + " (must not contain . ; [ or /): " + name);
        }
      }
      return;
    }
    for (int i = startPos; i < max; i = name.offsetByCodePoints(i, 1)) {
      if (i == startPos
          ? !Character.isJavaIdentifierStart(name.codePointAt(i))
          : !Character.isJavaIdentifierPart(name.codePointAt(i))) {
        throw new IllegalArgumentException(
            INVALID + message + " (must be a valid Java identifier): " + name);
      }
    }
  }

  /**
   * Checks that the given string is a valid Java identifier.
   *
   * @param version the class version.
   * @param name the string to be checked.
   * @param message the message to use in case of error.
   */
  static void checkMethodIdentifier(final int version, final String name, final String message) {
    if (name == null || name.length() == 0) {
      throw new IllegalArgumentException(INVALID + message + MUST_NOT_BE_NULL_OR_EMPTY);
    }
    if ((version & 0xFFFF) >= Opcodes.V1_5) {
      for (int i = 0; i < name.length(); i = name.offsetByCodePoints(i, 1)) {
        if (".;[/<>".indexOf(name.codePointAt(i)) != -1) {
          throw new IllegalArgumentException(
              INVALID + message + " (must be a valid unqualified name): " + name);
        }
      }
      return;
    }
    for (int i = 0; i < name.length(); i = name.offsetByCodePoints(i, 1)) {
      if (i == 0
          ? !Character.isJavaIdentifierStart(name.codePointAt(i))
          : !Character.isJavaIdentifierPart(name.codePointAt(i))) {
        throw new IllegalArgumentException(
            INVALID
                + message
                + " (must be a '<init>', '<clinit>' or a valid Java identifier): "
                + name);
      }
    }
  }

  /**
   * Checks that the given string is a valid internal class name or array type descriptor.
   *
   * @param version the class version.
   * @param name the string to be checked.
   * @param message the message to use in case of error.
   */
  static void checkInternalName(final int version, final String name, final String message) {
    if (name == null || name.length() == 0) {
      throw new IllegalArgumentException(INVALID + message + MUST_NOT_BE_NULL_OR_EMPTY);
    }
    if (name.charAt(0) == '[') {
      checkDescriptor(version, name, false);
    } else {
      checkInternalClassName(version, name, message);
    }
  }

  /**
   * Checks that the given string is a valid internal class name.
   *
   * @param version the class version.
   * @param name the string to be checked.
   * @param message the message to use in case of error.
   */
  private static void checkInternalClassName(
      final int version, final String name, final String message) {
    try {
      int startIndex = 0;
      int slashIndex;
      while ((slashIndex = name.indexOf('/', startIndex + 1)) != -1) {
        checkIdentifier(version, name, startIndex, slashIndex, null);
        startIndex = slashIndex + 1;
      }
      checkIdentifier(version, name, startIndex, name.length(), null);
    } catch (IllegalArgumentException e) {
      throw new IllegalArgumentException(
          INVALID + message + " (must be an internal class name): " + name, e);
    }
  }

  /**
   * Checks that the given string is a valid type descriptor.
   *
   * @param version the class version.
   * @param descriptor the string to be checked.
   * @param canBeVoid {@literal true} if {@code V} can be considered valid.
   */
  static void checkDescriptor(final int version, final String descriptor, final boolean canBeVoid) {
    int endPos = checkDescriptor(version, descriptor, 0, canBeVoid);
    if (endPos != descriptor.length()) {
      throw new IllegalArgumentException(INVALID_DESCRIPTOR + descriptor);
    }
  }

  /**
   * Checks that a the given substring is a valid type descriptor.
   *
   * @param version the class version.
   * @param descriptor the string to be checked.
   * @param startPos the index of the first character of the type descriptor (inclusive).
   * @param canBeVoid whether {@code V} can be considered valid.
   * @return the index of the last character of the type descriptor, plus one.
   */
  private static int checkDescriptor(
      final int version, final String descriptor, final int startPos, final boolean canBeVoid) {
    if (descriptor == null || startPos >= descriptor.length()) {
      throw new IllegalArgumentException("Invalid type descriptor (must not be null or empty)");
    }
    switch (descriptor.charAt(startPos)) {
      case 'V':
        if (canBeVoid) {
          return startPos + 1;
        } else {
          throw new IllegalArgumentException(INVALID_DESCRIPTOR + descriptor);
        }
      case 'Z':
      case 'C':
      case 'B':
      case 'S':
      case 'I':
      case 'F':
      case 'J':
      case 'D':
        return startPos + 1;
      case '[':
        int pos = startPos + 1;
        while (pos < descriptor.length() && descriptor.charAt(pos) == '[') {
          ++pos;
        }
        if (pos < descriptor.length()) {
          return checkDescriptor(version, descriptor, pos, false);
        } else {
          throw new IllegalArgumentException(INVALID_DESCRIPTOR + descriptor);
        }
      case 'L':
        int endPos = descriptor.indexOf(';', startPos);
        if (startPos == -1 || endPos - startPos < 2) {
          throw new IllegalArgumentException(INVALID_DESCRIPTOR + descriptor);
        }
        try {
          checkInternalClassName(version, descriptor.substring(startPos + 1, endPos), null);
        } catch (IllegalArgumentException e) {
          throw new IllegalArgumentException(INVALID_DESCRIPTOR + descriptor, e);
        }
        return endPos + 1;
      default:
        throw new IllegalArgumentException(INVALID_DESCRIPTOR + descriptor);
    }
  }

  /**
   * Checks that the given string is a valid method descriptor.
   *
   * @param version the class version.
   * @param descriptor the string to be checked.
   */
  static void checkMethodDescriptor(final int version, final String descriptor) {
    if (descriptor == null || descriptor.length() == 0) {
      throw new IllegalArgumentException("Invalid method descriptor (must not be null or empty)");
    }
    if (descriptor.charAt(0) != '(' || descriptor.length() < 3) {
      throw new IllegalArgumentException(INVALID_DESCRIPTOR + descriptor);
    }
    int pos = 1;
    if (descriptor.charAt(pos) != ')') {
      do {
        if (descriptor.charAt(pos) == 'V') {
          throw new IllegalArgumentException(INVALID_DESCRIPTOR + descriptor);
        }
        pos = checkDescriptor(version, descriptor, pos, false);
      } while (pos < descriptor.length() && descriptor.charAt(pos) != ')');
    }
    pos = checkDescriptor(version, descriptor, pos + 1, true);
    if (pos != descriptor.length()) {
      throw new IllegalArgumentException(INVALID_DESCRIPTOR + descriptor);
    }
  }

  /**
   * Checks that the given label is not null. This method can also check that the label has been
   * visited.
   *
   * @param label the label to be checked.
   * @param checkVisited whether to check that the label has been visited.
   * @param message the message to use in case of error.
   */
  private void checkLabel(final Label label, final boolean checkVisited, final String message) {
    if (label == null) {
      throw new IllegalArgumentException(INVALID + message + " (must not be null)");
    }
    if (checkVisited && labelInsnIndices.get(label) == null) {
      throw new IllegalArgumentException(INVALID + message + " (must be visited first)");
    }
  }
}
