// Path: parboiled-java/src/test/java/org/parboiled/transform/AsmTestUtils.java
// public static String getMethodInstructionList(MethodNode methodNode) {
//     checkArgNotNull(methodNode, "methodNode");
//     Printer printer = new NonMaxTextifier();
//     TraceMethodVisitor traceMethodVisitor = new TraceMethodVisitor(printer);
//     methodNode.accept(traceMethodVisitor);
//     StringWriter stringWriter = new StringWriter();
//     PrintWriter printWriter = new PrintWriter(stringWriter);
//     printer.print(printWriter);
//     printWriter.flush();
//     String[] lines = stringWriter.toString().split("\n");
//     int lineNr = 0;
//     for (int i = 0; i < lines.length; i++) {
//         if (!lines[i].startsWith("  @")) {
//             lines[i] = String.format("%2d %s", lineNr++, lines[i]);
//         }
//     }
//     return "Method '" + methodNode.name + "':\n" + StringUtils.join(lines, "\n") + '\n';
// }
// 
// Path: parboiled-java/src/test/java/org/parboiled/transform/AsmTestUtils.java
// public static void verifyIntegrity(String classInternalName, byte[] classCode) {
//     checkArgNotNull(classCode, "classCode");
//     ClassNode generatedClassNode = new ClassNode(ASMSettings.ASM_API);
//     ClassReader classReader = new ClassReader(classCode);
//     classReader.accept(generatedClassNode, 0);
// 
//     for (Object methodObj : generatedClassNode.methods) {
//         verifyMethodIntegrity(classInternalName, (MethodNode) methodObj);
//     }
// }


import org.parboiled.BaseParser;
import org.parboiled.Rule;
import org.parboiled.annotations.BuildParseTree;
import org.parboiled.annotations.MemoMismatches;
import org.testng.annotations.Test;
import static org.parboiled.transform.AsmTestUtils.getMethodInstructionList;
import static org.parboiled.transform.AsmTestUtils.verifyIntegrity;
import static org.testng.Assert.assertEquals;
                "Method 'A':\n" +
                " 0     ALOAD 0\n" +
                " 1     GETFIELD org/parboiled/transform/ParserHierarchyTest$Parser3$$parboiled.cache$A : Lorg/parboiled/Rule;\n" +
                " 2     DUP\n" +
                " 3     IFNULL L0\n" +
                " 4     ARETURN\n" +
                " 5    L0\n" +
                " 6     POP\n" +
                " 7     NEW org/parboiled/matchers/ProxyMatcher\n" +
                " 8     DUP\n" +
                " 9     INVOKESPECIAL org/parboiled/matchers/ProxyMatcher.<init> ()V\n" +
                "10     DUP\n" +
                "11     ALOAD 0\n" +
                "12     SWAP\n" +
                "13     PUTFIELD org/parboiled/transform/ParserHierarchyTest$Parser3$$parboiled.cache$A : Lorg/parboiled/Rule;\n" +
                "14     ALOAD 0\n" +
                "15     ALOAD 0\n" +
                "16     INVOKESPECIAL org/parboiled/transform/ParserHierarchyTest$Parser1.A ()Lorg/parboiled/Rule;\n" +
                "17     BIPUSH 65\n" +
                "18     INVOKESTATIC java/lang/Character.valueOf (C)Ljava/lang/Character;\n" +
                "19     ICONST_0\n" +
                "20     ANEWARRAY java/lang/Object\n" +
                "21     INVOKEVIRTUAL org/parboiled/transform/ParserHierarchyTest$Parser2.Sequence (Ljava/lang/Object;Ljava/lang/Object;[Ljava/lang/Object;)Lorg/parboiled/Rule;\n" +
                "22     DUP\n" +
                "23     IFNULL L1\n" +
                "24     LDC \"A\"\n" +
                "25     INVOKEINTERFACE org/parboiled/Rule.label (Ljava/lang/String;)Lorg/parboiled/Rule; (itf)\n" +
                "26    L1\n" +
                "27     DUP_X1\n" +
                "28     CHECKCAST org/parboiled/matchers/Matcher\n" +
// Path: parboiled-java/src/test/java/org/parboiled/transform/AsmTestUtils.java
// public static String getMethodInstructionList(MethodNode methodNode) {
//     checkArgNotNull(methodNode, "methodNode");
//     Printer printer = new NonMaxTextifier();
//     TraceMethodVisitor traceMethodVisitor = new TraceMethodVisitor(printer);
//     methodNode.accept(traceMethodVisitor);
//     StringWriter stringWriter = new StringWriter();
//     PrintWriter printWriter = new PrintWriter(stringWriter);
//     printer.print(printWriter);
//     printWriter.flush();
//     String[] lines = stringWriter.toString().split("\n");
//     int lineNr = 0;
//     for (int i = 0; i < lines.length; i++) {
//         if (!lines[i].startsWith("  @")) {
//             lines[i] = String.format("%2d %s", lineNr++, lines[i]);
//         }
//     }
//     return "Method '" + methodNode.name + "':\n" + StringUtils.join(lines, "\n") + '\n';
// }
// 
// Path: parboiled-java/src/test/java/org/parboiled/transform/AsmTestUtils.java
// public static void verifyIntegrity(String classInternalName, byte[] classCode) {
//     checkArgNotNull(classCode, "classCode");
//     ClassNode generatedClassNode = new ClassNode(ASMSettings.ASM_API);
//     ClassReader classReader = new ClassReader(classCode);
//     classReader.accept(generatedClassNode, 0);
// 
//     for (Object methodObj : generatedClassNode.methods) {
//         verifyMethodIntegrity(classInternalName, (MethodNode) methodObj);
//     }
// }


// Path: parboiled-java/src/test/java/org/parboiled/transform/ParserHierarchyTest.java
import org.parboiled.BaseParser;
import org.parboiled.Rule;
import org.parboiled.annotations.BuildParseTree;
import org.parboiled.annotations.MemoMismatches;
import org.testng.annotations.Test;
import static org.parboiled.transform.AsmTestUtils.getMethodInstructionList;
import static org.parboiled.transform.AsmTestUtils.verifyIntegrity;
import static org.testng.Assert.assertEquals;

                "Method 'A':\n" +
                " 0     ALOAD 0\n" +
                " 1     GETFIELD org/parboiled/transform/ParserHierarchyTest$Parser3$$parboiled.cache$A : Lorg/parboiled/Rule;\n" +
                " 2     DUP\n" +
                " 3     IFNULL L0\n" +
                " 4     ARETURN\n" +
                " 5    L0\n" +
                " 6     POP\n" +
                " 7     NEW org/parboiled/matchers/ProxyMatcher\n" +
                " 8     DUP\n" +
                " 9     INVOKESPECIAL org/parboiled/matchers/ProxyMatcher.<init> ()V\n" +
                "10     DUP\n" +
                "11     ALOAD 0\n" +
                "12     SWAP\n" +
                "13     PUTFIELD org/parboiled/transform/ParserHierarchyTest$Parser3$$parboiled.cache$A : Lorg/parboiled/Rule;\n" +
                "14     ALOAD 0\n" +
                "15     ALOAD 0\n" +
                "16     INVOKESPECIAL org/parboiled/transform/ParserHierarchyTest$Parser1.A ()Lorg/parboiled/Rule;\n" +
                "17     BIPUSH 65\n" +
                "18     INVOKESTATIC java/lang/Character.valueOf (C)Ljava/lang/Character;\n" +
                "19     ICONST_0\n" +
                "20     ANEWARRAY java/lang/Object\n" +
                "21     INVOKEVIRTUAL org/parboiled/transform/ParserHierarchyTest$Parser2.Sequence (Ljava/lang/Object;Ljava/lang/Object;[Ljava/lang/Object;)Lorg/parboiled/Rule;\n" +
                "22     DUP\n" +
                "23     IFNULL L1\n" +
                "24     LDC \"A\"\n" +
                "25     INVOKEINTERFACE org/parboiled/Rule.label (Ljava/lang/String;)Lorg/parboiled/Rule; (itf)\n" +
                "26    L1\n" +
                "27     DUP_X1\n" +
                "28     CHECKCAST org/parboiled/matchers/Matcher\n" +
                "29     INVOKEVIRTUAL org/parboiled/matchers/ProxyMatcher.arm (Lorg/parboiled/matchers/Matcher;)V\n" +