public boolean match() {
        int matchIndex = 0;
        boolean anyMatches = false;

        AbstractInsnNode currentNode = nodes.getFirst();
        while (currentNode != null) {
            if (matchIndex == opcodes.length) {
                //found a fully matching pattern, add a new index to the list and keep searching
                matches.add(new AbstractInsnNode[opcodes.length]);
                anyMatches = true;
                matchIndex = 0;
            }
            if (currentNode.getOpcode() == opcodes[matchIndex]) {
                //match, proceed to keep matching
                matches.get(size() - 1)[matchIndex] = currentNode;
                matchIndex++;
            } else {
                //an instruction broke the pattern, reset
                if (matchIndex > highestBreakpoint) {
                    highestBreakpoint = matchIndex;
                    highestBreakpointOpcode = currentNode.getOpcode();
                }
                clear();
                matchIndex = 0;
            }
            if (matchIndex > 0 && currentNode instanceof JumpInsnNode && jumps <= maxJumps) {
                //if the current node is a goto instruction, set the next node as the jump target
                JumpInsnNode jumpInsn = (JumpInsnNode) currentNode;
                currentNode = jumpInsn.label.getNext();
                jumps++;
            } else {
                currentNode = currentNode.getNext();
            }
        }

        matches.remove(size() - 1);

        return anyMatches;
    }