public void insertMethodCall(MethodCallReplacementMethodAdapter mv, int opcode) {
    mv.visitMethodInsn(
        Opcodes.INVOKESTATIC,
        MockFramework.class.getCanonicalName().replace('.', '/'),
        "isEnabled",
        "()Z",
        false);
    Label origCallLabel = new Label();
    Label afterOrigCallLabel = new Label();

    Label annotationStartTag = new AnnotatedLabel(true, true);
    annotationStartTag.info = Boolean.TRUE;
    mv.visitLabel(annotationStartTag);
    mv.visitJumpInsn(Opcodes.IFEQ, origCallLabel);
    Label annotationEndTag = new AnnotatedLabel(true, false);
    annotationEndTag.info = Boolean.FALSE;
    mv.visitLabel(annotationEndTag);

    if (popCallee) {
      Type[] args = Type.getArgumentTypes(desc);
      Map<Integer, Integer> to = new HashMap<Integer, Integer>();
      for (int i = args.length - 1; i >= 0; i--) {
        int loc = mv.newLocal(args[i]);
        mv.storeLocal(loc);
        to.put(i, loc);
      }

      mv.pop(); // callee
      if (popUninitialisedReference) mv.pop();

      for (int i = 0; i < args.length; i++) {
        mv.loadLocal(to.get(i));
      }
    }
    if (opcode == Opcodes.INVOKESPECIAL && MockList.shouldBeMocked(className.replace('/', '.'))) {
      insertInvokeSpecialForMockedSuperclass(mv);
    } else {
      if (opcode == Opcodes.INVOKESPECIAL) {
        logger.info(
            "Not mocking invokespecial: " + replacementMethodName + " for class " + className);
      }
      mv.visitMethodInsn(
          opcode, replacementClassName, replacementMethodName, replacementDesc, false);
    }
    mv.visitJumpInsn(Opcodes.GOTO, afterOrigCallLabel);
    mv.visitLabel(origCallLabel);
    mv.getNextVisitor()
        .visitMethodInsn(origOpcode, className, methodName, desc, false); // TODO: What is itf here?
    mv.visitLabel(afterOrigCallLabel);
  }
  public void insertConstructorCall(
      MethodCallReplacementMethodAdapter mv, MethodCallReplacement replacement, boolean isSelf) {
    Label origCallLabel = new Label();
    Label afterOrigCallLabel = new Label();

    if (!isSelf) {
      mv.visitMethodInsn(
          Opcodes.INVOKESTATIC,
          MockFramework.class.getCanonicalName().replace('.', '/'),
          "isEnabled",
          "()Z",
          false);
      Label annotationStartTag = new AnnotatedLabel(true, true);
      annotationStartTag.info = Boolean.TRUE;
      mv.visitLabel(annotationStartTag);
      mv.visitJumpInsn(Opcodes.IFEQ, origCallLabel);
      Label annotationEndTag = new AnnotatedLabel(true, false);
      annotationEndTag.info = Boolean.FALSE;
      mv.visitLabel(annotationEndTag);

      Type[] args = Type.getArgumentTypes(desc);
      Map<Integer, Integer> to = new HashMap<Integer, Integer>();
      for (int i = args.length - 1; i >= 0; i--) {
        int loc = mv.newLocal(args[i]);
        mv.storeLocal(loc);
        to.put(i, loc);
      }

      mv.pop2(); // uninitialized reference (which is duplicated)
      mv.newInstance(Type.getType(replacement.replacementClassName));
      mv.dup();

      for (int i = 0; i < args.length; i++) {
        mv.loadLocal(to.get(i));
      }
    }
    mv.visitMethodInsn(
        Opcodes.INVOKESPECIAL, replacementClassName, replacementMethodName, replacementDesc, false);
    if (!isSelf) {
      mv.visitJumpInsn(Opcodes.GOTO, afterOrigCallLabel);
      mv.visitLabel(origCallLabel);
      mv.getNextVisitor()
          .visitMethodInsn(Opcodes.INVOKESPECIAL, className, methodName, desc, false);
      mv.visitLabel(afterOrigCallLabel);
    }
  }