All Downloads are FREE. Search and download functionalities are using the official Maven repository.

name.remal.org.objectweb.asm.tree.MethodNode-generated.kt Maven / Gradle / Ivy

The newest version!
package name.remal
import org.objectweb.asm.tree.*
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings

@SuppressFBWarnings("RCN_REDUNDANT_NULLCHECK_OF_NONNULL_VALUE", "UJM_UNJITABLE_METHOD")
fun  MethodNode.replaceInstructions(filter1: InstructionNodeFilter, instructionsGenerator: (node1: T1) -> InsnList): Boolean {
    val instructions = this.instructions ?: return false
    if (instructions.size() < 1) return false

    val unusedLabelNodes = this.unusedLabelNodes
    if (instructions.size() - unusedLabelNodes.size < 1) return false

    fun canBeUsed(node: AbstractInsnNode) = node !is LineNumberNode && node !in unusedLabelNodes

    var node1: T1? = null

    fun reset() {
        node1 = null
    }

    var curNode: AbstractInsnNode? = instructions.first ?: return false
    var isSomethingChanged = false
    while (curNode != null) {
        val node: AbstractInsnNode = curNode
        var nextNode: AbstractInsnNode? = node.next
        run {
            if (!canBeUsed(node)) return@run
            if (null == node1) {
                if (!filter1.nodeType.isInstance(node)) return@run reset()
                filter1.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node1 = node.uncheckedCast()

                nextNode = node1!!.next
                val newInstructions = instructionsGenerator(node1!!)
                if (1 <= newInstructions.size()) {
                    if (newInstructions.contains(node1)) throw IllegalStateException("New instructions contain node #1")
                    instructions.insert(node1, newInstructions)
                }
                var nodeToDelete: AbstractInsnNode = node1!!
                while (true) {
                    val next = nodeToDelete.next ?: break
                    instructions.remove(nodeToDelete)
                    if (nodeToDelete === node1) break
                    nodeToDelete = next
                }
                isSomethingChanged = true
                reset()
            }
        }
        curNode = nextNode
    }
    return isSomethingChanged
}

fun  MethodNode.replaceInstructions(nodeType1: Class, instructionsGenerator: (node1: T1) -> InsnList) = replaceInstructions(nodeType1.toInstructionNodeFilter(), instructionsGenerator)


@SuppressFBWarnings("RCN_REDUNDANT_NULLCHECK_OF_NONNULL_VALUE", "UJM_UNJITABLE_METHOD")
fun  MethodNode.replaceInstructions(filter1: InstructionNodeFilter, filter2: InstructionNodeFilter, instructionsGenerator: (node1: T1, node2: T2) -> InsnList): Boolean {
    val instructions = this.instructions ?: return false
    if (instructions.size() < 2) return false

    val unusedLabelNodes = this.unusedLabelNodes
    if (instructions.size() - unusedLabelNodes.size < 2) return false

    fun canBeUsed(node: AbstractInsnNode) = node !is LineNumberNode && node !in unusedLabelNodes

    var node1: T1? = null
    var node2: T2? = null

    fun reset() {
        node1 = null
        node2 = null
    }

    var curNode: AbstractInsnNode? = instructions.first ?: return false
    var isSomethingChanged = false
    while (curNode != null) {
        val node: AbstractInsnNode = curNode
        var nextNode: AbstractInsnNode? = node.next
        run {
            if (!canBeUsed(node)) return@run
            if (null == node1) {
                if (!filter1.nodeType.isInstance(node)) return@run reset()
                filter1.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node1 = node.uncheckedCast()
            } else if (null == node2) {
                if (!filter2.nodeType.isInstance(node)) return@run reset()
                filter2.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node2 = node.uncheckedCast()

                nextNode = node2!!.next
                val newInstructions = instructionsGenerator(node1!!, node2!!)
                if (1 <= newInstructions.size()) {
                    if (newInstructions.contains(node1)) throw IllegalStateException("New instructions contain node #1")
                    if (newInstructions.contains(node2)) throw IllegalStateException("New instructions contain node #2")
                    instructions.insert(node2, newInstructions)
                }
                var nodeToDelete: AbstractInsnNode = node1!!
                while (true) {
                    val next = nodeToDelete.next ?: break
                    instructions.remove(nodeToDelete)
                    if (nodeToDelete === node2) break
                    nodeToDelete = next
                }
                isSomethingChanged = true
                reset()
            }
        }
        curNode = nextNode
    }
    return isSomethingChanged
}

fun  MethodNode.replaceInstructions(nodeType1: Class, nodeType2: Class, instructionsGenerator: (node1: T1, node2: T2) -> InsnList) = replaceInstructions(nodeType1.toInstructionNodeFilter(), nodeType2.toInstructionNodeFilter(), instructionsGenerator)


@SuppressFBWarnings("RCN_REDUNDANT_NULLCHECK_OF_NONNULL_VALUE", "UJM_UNJITABLE_METHOD")
fun  MethodNode.replaceInstructions(filter1: InstructionNodeFilter, filter2: InstructionNodeFilter, filter3: InstructionNodeFilter, instructionsGenerator: (node1: T1, node2: T2, node3: T3) -> InsnList): Boolean {
    val instructions = this.instructions ?: return false
    if (instructions.size() < 3) return false

    val unusedLabelNodes = this.unusedLabelNodes
    if (instructions.size() - unusedLabelNodes.size < 3) return false

    fun canBeUsed(node: AbstractInsnNode) = node !is LineNumberNode && node !in unusedLabelNodes

    var node1: T1? = null
    var node2: T2? = null
    var node3: T3? = null

    fun reset() {
        node1 = null
        node2 = null
        node3 = null
    }

    var curNode: AbstractInsnNode? = instructions.first ?: return false
    var isSomethingChanged = false
    while (curNode != null) {
        val node: AbstractInsnNode = curNode
        var nextNode: AbstractInsnNode? = node.next
        run {
            if (!canBeUsed(node)) return@run
            if (null == node1) {
                if (!filter1.nodeType.isInstance(node)) return@run reset()
                filter1.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node1 = node.uncheckedCast()
            } else if (null == node2) {
                if (!filter2.nodeType.isInstance(node)) return@run reset()
                filter2.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node2 = node.uncheckedCast()
            } else if (null == node3) {
                if (!filter3.nodeType.isInstance(node)) return@run reset()
                filter3.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node3 = node.uncheckedCast()

                nextNode = node3!!.next
                val newInstructions = instructionsGenerator(node1!!, node2!!, node3!!)
                if (1 <= newInstructions.size()) {
                    if (newInstructions.contains(node1)) throw IllegalStateException("New instructions contain node #1")
                    if (newInstructions.contains(node2)) throw IllegalStateException("New instructions contain node #2")
                    if (newInstructions.contains(node3)) throw IllegalStateException("New instructions contain node #3")
                    instructions.insert(node3, newInstructions)
                }
                var nodeToDelete: AbstractInsnNode = node1!!
                while (true) {
                    val next = nodeToDelete.next ?: break
                    instructions.remove(nodeToDelete)
                    if (nodeToDelete === node3) break
                    nodeToDelete = next
                }
                isSomethingChanged = true
                reset()
            }
        }
        curNode = nextNode
    }
    return isSomethingChanged
}

fun  MethodNode.replaceInstructions(nodeType1: Class, nodeType2: Class, nodeType3: Class, instructionsGenerator: (node1: T1, node2: T2, node3: T3) -> InsnList) = replaceInstructions(nodeType1.toInstructionNodeFilter(), nodeType2.toInstructionNodeFilter(), nodeType3.toInstructionNodeFilter(), instructionsGenerator)


@SuppressFBWarnings("RCN_REDUNDANT_NULLCHECK_OF_NONNULL_VALUE", "UJM_UNJITABLE_METHOD")
fun  MethodNode.replaceInstructions(filter1: InstructionNodeFilter, filter2: InstructionNodeFilter, filter3: InstructionNodeFilter, filter4: InstructionNodeFilter, instructionsGenerator: (node1: T1, node2: T2, node3: T3, node4: T4) -> InsnList): Boolean {
    val instructions = this.instructions ?: return false
    if (instructions.size() < 4) return false

    val unusedLabelNodes = this.unusedLabelNodes
    if (instructions.size() - unusedLabelNodes.size < 4) return false

    fun canBeUsed(node: AbstractInsnNode) = node !is LineNumberNode && node !in unusedLabelNodes

    var node1: T1? = null
    var node2: T2? = null
    var node3: T3? = null
    var node4: T4? = null

    fun reset() {
        node1 = null
        node2 = null
        node3 = null
        node4 = null
    }

    var curNode: AbstractInsnNode? = instructions.first ?: return false
    var isSomethingChanged = false
    while (curNode != null) {
        val node: AbstractInsnNode = curNode
        var nextNode: AbstractInsnNode? = node.next
        run {
            if (!canBeUsed(node)) return@run
            if (null == node1) {
                if (!filter1.nodeType.isInstance(node)) return@run reset()
                filter1.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node1 = node.uncheckedCast()
            } else if (null == node2) {
                if (!filter2.nodeType.isInstance(node)) return@run reset()
                filter2.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node2 = node.uncheckedCast()
            } else if (null == node3) {
                if (!filter3.nodeType.isInstance(node)) return@run reset()
                filter3.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node3 = node.uncheckedCast()
            } else if (null == node4) {
                if (!filter4.nodeType.isInstance(node)) return@run reset()
                filter4.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node4 = node.uncheckedCast()

                nextNode = node4!!.next
                val newInstructions = instructionsGenerator(node1!!, node2!!, node3!!, node4!!)
                if (1 <= newInstructions.size()) {
                    if (newInstructions.contains(node1)) throw IllegalStateException("New instructions contain node #1")
                    if (newInstructions.contains(node2)) throw IllegalStateException("New instructions contain node #2")
                    if (newInstructions.contains(node3)) throw IllegalStateException("New instructions contain node #3")
                    if (newInstructions.contains(node4)) throw IllegalStateException("New instructions contain node #4")
                    instructions.insert(node4, newInstructions)
                }
                var nodeToDelete: AbstractInsnNode = node1!!
                while (true) {
                    val next = nodeToDelete.next ?: break
                    instructions.remove(nodeToDelete)
                    if (nodeToDelete === node4) break
                    nodeToDelete = next
                }
                isSomethingChanged = true
                reset()
            }
        }
        curNode = nextNode
    }
    return isSomethingChanged
}

fun  MethodNode.replaceInstructions(nodeType1: Class, nodeType2: Class, nodeType3: Class, nodeType4: Class, instructionsGenerator: (node1: T1, node2: T2, node3: T3, node4: T4) -> InsnList) = replaceInstructions(nodeType1.toInstructionNodeFilter(), nodeType2.toInstructionNodeFilter(), nodeType3.toInstructionNodeFilter(), nodeType4.toInstructionNodeFilter(), instructionsGenerator)


@SuppressFBWarnings("RCN_REDUNDANT_NULLCHECK_OF_NONNULL_VALUE", "UJM_UNJITABLE_METHOD")
fun  MethodNode.replaceInstructions(filter1: InstructionNodeFilter, filter2: InstructionNodeFilter, filter3: InstructionNodeFilter, filter4: InstructionNodeFilter, filter5: InstructionNodeFilter, instructionsGenerator: (node1: T1, node2: T2, node3: T3, node4: T4, node5: T5) -> InsnList): Boolean {
    val instructions = this.instructions ?: return false
    if (instructions.size() < 5) return false

    val unusedLabelNodes = this.unusedLabelNodes
    if (instructions.size() - unusedLabelNodes.size < 5) return false

    fun canBeUsed(node: AbstractInsnNode) = node !is LineNumberNode && node !in unusedLabelNodes

    var node1: T1? = null
    var node2: T2? = null
    var node3: T3? = null
    var node4: T4? = null
    var node5: T5? = null

    fun reset() {
        node1 = null
        node2 = null
        node3 = null
        node4 = null
        node5 = null
    }

    var curNode: AbstractInsnNode? = instructions.first ?: return false
    var isSomethingChanged = false
    while (curNode != null) {
        val node: AbstractInsnNode = curNode
        var nextNode: AbstractInsnNode? = node.next
        run {
            if (!canBeUsed(node)) return@run
            if (null == node1) {
                if (!filter1.nodeType.isInstance(node)) return@run reset()
                filter1.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node1 = node.uncheckedCast()
            } else if (null == node2) {
                if (!filter2.nodeType.isInstance(node)) return@run reset()
                filter2.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node2 = node.uncheckedCast()
            } else if (null == node3) {
                if (!filter3.nodeType.isInstance(node)) return@run reset()
                filter3.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node3 = node.uncheckedCast()
            } else if (null == node4) {
                if (!filter4.nodeType.isInstance(node)) return@run reset()
                filter4.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node4 = node.uncheckedCast()
            } else if (null == node5) {
                if (!filter5.nodeType.isInstance(node)) return@run reset()
                filter5.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node5 = node.uncheckedCast()

                nextNode = node5!!.next
                val newInstructions = instructionsGenerator(node1!!, node2!!, node3!!, node4!!, node5!!)
                if (1 <= newInstructions.size()) {
                    if (newInstructions.contains(node1)) throw IllegalStateException("New instructions contain node #1")
                    if (newInstructions.contains(node2)) throw IllegalStateException("New instructions contain node #2")
                    if (newInstructions.contains(node3)) throw IllegalStateException("New instructions contain node #3")
                    if (newInstructions.contains(node4)) throw IllegalStateException("New instructions contain node #4")
                    if (newInstructions.contains(node5)) throw IllegalStateException("New instructions contain node #5")
                    instructions.insert(node5, newInstructions)
                }
                var nodeToDelete: AbstractInsnNode = node1!!
                while (true) {
                    val next = nodeToDelete.next ?: break
                    instructions.remove(nodeToDelete)
                    if (nodeToDelete === node5) break
                    nodeToDelete = next
                }
                isSomethingChanged = true
                reset()
            }
        }
        curNode = nextNode
    }
    return isSomethingChanged
}

fun  MethodNode.replaceInstructions(nodeType1: Class, nodeType2: Class, nodeType3: Class, nodeType4: Class, nodeType5: Class, instructionsGenerator: (node1: T1, node2: T2, node3: T3, node4: T4, node5: T5) -> InsnList) = replaceInstructions(nodeType1.toInstructionNodeFilter(), nodeType2.toInstructionNodeFilter(), nodeType3.toInstructionNodeFilter(), nodeType4.toInstructionNodeFilter(), nodeType5.toInstructionNodeFilter(), instructionsGenerator)


@SuppressFBWarnings("RCN_REDUNDANT_NULLCHECK_OF_NONNULL_VALUE", "UJM_UNJITABLE_METHOD")
fun  MethodNode.replaceInstructions(filter1: InstructionNodeFilter, filter2: InstructionNodeFilter, filter3: InstructionNodeFilter, filter4: InstructionNodeFilter, filter5: InstructionNodeFilter, filter6: InstructionNodeFilter, instructionsGenerator: (node1: T1, node2: T2, node3: T3, node4: T4, node5: T5, node6: T6) -> InsnList): Boolean {
    val instructions = this.instructions ?: return false
    if (instructions.size() < 6) return false

    val unusedLabelNodes = this.unusedLabelNodes
    if (instructions.size() - unusedLabelNodes.size < 6) return false

    fun canBeUsed(node: AbstractInsnNode) = node !is LineNumberNode && node !in unusedLabelNodes

    var node1: T1? = null
    var node2: T2? = null
    var node3: T3? = null
    var node4: T4? = null
    var node5: T5? = null
    var node6: T6? = null

    fun reset() {
        node1 = null
        node2 = null
        node3 = null
        node4 = null
        node5 = null
        node6 = null
    }

    var curNode: AbstractInsnNode? = instructions.first ?: return false
    var isSomethingChanged = false
    while (curNode != null) {
        val node: AbstractInsnNode = curNode
        var nextNode: AbstractInsnNode? = node.next
        run {
            if (!canBeUsed(node)) return@run
            if (null == node1) {
                if (!filter1.nodeType.isInstance(node)) return@run reset()
                filter1.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node1 = node.uncheckedCast()
            } else if (null == node2) {
                if (!filter2.nodeType.isInstance(node)) return@run reset()
                filter2.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node2 = node.uncheckedCast()
            } else if (null == node3) {
                if (!filter3.nodeType.isInstance(node)) return@run reset()
                filter3.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node3 = node.uncheckedCast()
            } else if (null == node4) {
                if (!filter4.nodeType.isInstance(node)) return@run reset()
                filter4.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node4 = node.uncheckedCast()
            } else if (null == node5) {
                if (!filter5.nodeType.isInstance(node)) return@run reset()
                filter5.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node5 = node.uncheckedCast()
            } else if (null == node6) {
                if (!filter6.nodeType.isInstance(node)) return@run reset()
                filter6.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node6 = node.uncheckedCast()

                nextNode = node6!!.next
                val newInstructions = instructionsGenerator(node1!!, node2!!, node3!!, node4!!, node5!!, node6!!)
                if (1 <= newInstructions.size()) {
                    if (newInstructions.contains(node1)) throw IllegalStateException("New instructions contain node #1")
                    if (newInstructions.contains(node2)) throw IllegalStateException("New instructions contain node #2")
                    if (newInstructions.contains(node3)) throw IllegalStateException("New instructions contain node #3")
                    if (newInstructions.contains(node4)) throw IllegalStateException("New instructions contain node #4")
                    if (newInstructions.contains(node5)) throw IllegalStateException("New instructions contain node #5")
                    if (newInstructions.contains(node6)) throw IllegalStateException("New instructions contain node #6")
                    instructions.insert(node6, newInstructions)
                }
                var nodeToDelete: AbstractInsnNode = node1!!
                while (true) {
                    val next = nodeToDelete.next ?: break
                    instructions.remove(nodeToDelete)
                    if (nodeToDelete === node6) break
                    nodeToDelete = next
                }
                isSomethingChanged = true
                reset()
            }
        }
        curNode = nextNode
    }
    return isSomethingChanged
}

fun  MethodNode.replaceInstructions(nodeType1: Class, nodeType2: Class, nodeType3: Class, nodeType4: Class, nodeType5: Class, nodeType6: Class, instructionsGenerator: (node1: T1, node2: T2, node3: T3, node4: T4, node5: T5, node6: T6) -> InsnList) = replaceInstructions(nodeType1.toInstructionNodeFilter(), nodeType2.toInstructionNodeFilter(), nodeType3.toInstructionNodeFilter(), nodeType4.toInstructionNodeFilter(), nodeType5.toInstructionNodeFilter(), nodeType6.toInstructionNodeFilter(), instructionsGenerator)


@SuppressFBWarnings("RCN_REDUNDANT_NULLCHECK_OF_NONNULL_VALUE", "UJM_UNJITABLE_METHOD")
fun  MethodNode.replaceInstructions(filter1: InstructionNodeFilter, filter2: InstructionNodeFilter, filter3: InstructionNodeFilter, filter4: InstructionNodeFilter, filter5: InstructionNodeFilter, filter6: InstructionNodeFilter, filter7: InstructionNodeFilter, instructionsGenerator: (node1: T1, node2: T2, node3: T3, node4: T4, node5: T5, node6: T6, node7: T7) -> InsnList): Boolean {
    val instructions = this.instructions ?: return false
    if (instructions.size() < 7) return false

    val unusedLabelNodes = this.unusedLabelNodes
    if (instructions.size() - unusedLabelNodes.size < 7) return false

    fun canBeUsed(node: AbstractInsnNode) = node !is LineNumberNode && node !in unusedLabelNodes

    var node1: T1? = null
    var node2: T2? = null
    var node3: T3? = null
    var node4: T4? = null
    var node5: T5? = null
    var node6: T6? = null
    var node7: T7? = null

    fun reset() {
        node1 = null
        node2 = null
        node3 = null
        node4 = null
        node5 = null
        node6 = null
        node7 = null
    }

    var curNode: AbstractInsnNode? = instructions.first ?: return false
    var isSomethingChanged = false
    while (curNode != null) {
        val node: AbstractInsnNode = curNode
        var nextNode: AbstractInsnNode? = node.next
        run {
            if (!canBeUsed(node)) return@run
            if (null == node1) {
                if (!filter1.nodeType.isInstance(node)) return@run reset()
                filter1.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node1 = node.uncheckedCast()
            } else if (null == node2) {
                if (!filter2.nodeType.isInstance(node)) return@run reset()
                filter2.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node2 = node.uncheckedCast()
            } else if (null == node3) {
                if (!filter3.nodeType.isInstance(node)) return@run reset()
                filter3.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node3 = node.uncheckedCast()
            } else if (null == node4) {
                if (!filter4.nodeType.isInstance(node)) return@run reset()
                filter4.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node4 = node.uncheckedCast()
            } else if (null == node5) {
                if (!filter5.nodeType.isInstance(node)) return@run reset()
                filter5.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node5 = node.uncheckedCast()
            } else if (null == node6) {
                if (!filter6.nodeType.isInstance(node)) return@run reset()
                filter6.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node6 = node.uncheckedCast()
            } else if (null == node7) {
                if (!filter7.nodeType.isInstance(node)) return@run reset()
                filter7.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node7 = node.uncheckedCast()

                nextNode = node7!!.next
                val newInstructions = instructionsGenerator(node1!!, node2!!, node3!!, node4!!, node5!!, node6!!, node7!!)
                if (1 <= newInstructions.size()) {
                    if (newInstructions.contains(node1)) throw IllegalStateException("New instructions contain node #1")
                    if (newInstructions.contains(node2)) throw IllegalStateException("New instructions contain node #2")
                    if (newInstructions.contains(node3)) throw IllegalStateException("New instructions contain node #3")
                    if (newInstructions.contains(node4)) throw IllegalStateException("New instructions contain node #4")
                    if (newInstructions.contains(node5)) throw IllegalStateException("New instructions contain node #5")
                    if (newInstructions.contains(node6)) throw IllegalStateException("New instructions contain node #6")
                    if (newInstructions.contains(node7)) throw IllegalStateException("New instructions contain node #7")
                    instructions.insert(node7, newInstructions)
                }
                var nodeToDelete: AbstractInsnNode = node1!!
                while (true) {
                    val next = nodeToDelete.next ?: break
                    instructions.remove(nodeToDelete)
                    if (nodeToDelete === node7) break
                    nodeToDelete = next
                }
                isSomethingChanged = true
                reset()
            }
        }
        curNode = nextNode
    }
    return isSomethingChanged
}

fun  MethodNode.replaceInstructions(nodeType1: Class, nodeType2: Class, nodeType3: Class, nodeType4: Class, nodeType5: Class, nodeType6: Class, nodeType7: Class, instructionsGenerator: (node1: T1, node2: T2, node3: T3, node4: T4, node5: T5, node6: T6, node7: T7) -> InsnList) = replaceInstructions(nodeType1.toInstructionNodeFilter(), nodeType2.toInstructionNodeFilter(), nodeType3.toInstructionNodeFilter(), nodeType4.toInstructionNodeFilter(), nodeType5.toInstructionNodeFilter(), nodeType6.toInstructionNodeFilter(), nodeType7.toInstructionNodeFilter(), instructionsGenerator)


@SuppressFBWarnings("RCN_REDUNDANT_NULLCHECK_OF_NONNULL_VALUE", "UJM_UNJITABLE_METHOD")
fun  MethodNode.replaceInstructions(filter1: InstructionNodeFilter, filter2: InstructionNodeFilter, filter3: InstructionNodeFilter, filter4: InstructionNodeFilter, filter5: InstructionNodeFilter, filter6: InstructionNodeFilter, filter7: InstructionNodeFilter, filter8: InstructionNodeFilter, instructionsGenerator: (node1: T1, node2: T2, node3: T3, node4: T4, node5: T5, node6: T6, node7: T7, node8: T8) -> InsnList): Boolean {
    val instructions = this.instructions ?: return false
    if (instructions.size() < 8) return false

    val unusedLabelNodes = this.unusedLabelNodes
    if (instructions.size() - unusedLabelNodes.size < 8) return false

    fun canBeUsed(node: AbstractInsnNode) = node !is LineNumberNode && node !in unusedLabelNodes

    var node1: T1? = null
    var node2: T2? = null
    var node3: T3? = null
    var node4: T4? = null
    var node5: T5? = null
    var node6: T6? = null
    var node7: T7? = null
    var node8: T8? = null

    fun reset() {
        node1 = null
        node2 = null
        node3 = null
        node4 = null
        node5 = null
        node6 = null
        node7 = null
        node8 = null
    }

    var curNode: AbstractInsnNode? = instructions.first ?: return false
    var isSomethingChanged = false
    while (curNode != null) {
        val node: AbstractInsnNode = curNode
        var nextNode: AbstractInsnNode? = node.next
        run {
            if (!canBeUsed(node)) return@run
            if (null == node1) {
                if (!filter1.nodeType.isInstance(node)) return@run reset()
                filter1.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node1 = node.uncheckedCast()
            } else if (null == node2) {
                if (!filter2.nodeType.isInstance(node)) return@run reset()
                filter2.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node2 = node.uncheckedCast()
            } else if (null == node3) {
                if (!filter3.nodeType.isInstance(node)) return@run reset()
                filter3.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node3 = node.uncheckedCast()
            } else if (null == node4) {
                if (!filter4.nodeType.isInstance(node)) return@run reset()
                filter4.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node4 = node.uncheckedCast()
            } else if (null == node5) {
                if (!filter5.nodeType.isInstance(node)) return@run reset()
                filter5.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node5 = node.uncheckedCast()
            } else if (null == node6) {
                if (!filter6.nodeType.isInstance(node)) return@run reset()
                filter6.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node6 = node.uncheckedCast()
            } else if (null == node7) {
                if (!filter7.nodeType.isInstance(node)) return@run reset()
                filter7.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node7 = node.uncheckedCast()
            } else if (null == node8) {
                if (!filter8.nodeType.isInstance(node)) return@run reset()
                filter8.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node8 = node.uncheckedCast()

                nextNode = node8!!.next
                val newInstructions = instructionsGenerator(node1!!, node2!!, node3!!, node4!!, node5!!, node6!!, node7!!, node8!!)
                if (1 <= newInstructions.size()) {
                    if (newInstructions.contains(node1)) throw IllegalStateException("New instructions contain node #1")
                    if (newInstructions.contains(node2)) throw IllegalStateException("New instructions contain node #2")
                    if (newInstructions.contains(node3)) throw IllegalStateException("New instructions contain node #3")
                    if (newInstructions.contains(node4)) throw IllegalStateException("New instructions contain node #4")
                    if (newInstructions.contains(node5)) throw IllegalStateException("New instructions contain node #5")
                    if (newInstructions.contains(node6)) throw IllegalStateException("New instructions contain node #6")
                    if (newInstructions.contains(node7)) throw IllegalStateException("New instructions contain node #7")
                    if (newInstructions.contains(node8)) throw IllegalStateException("New instructions contain node #8")
                    instructions.insert(node8, newInstructions)
                }
                var nodeToDelete: AbstractInsnNode = node1!!
                while (true) {
                    val next = nodeToDelete.next ?: break
                    instructions.remove(nodeToDelete)
                    if (nodeToDelete === node8) break
                    nodeToDelete = next
                }
                isSomethingChanged = true
                reset()
            }
        }
        curNode = nextNode
    }
    return isSomethingChanged
}

fun  MethodNode.replaceInstructions(nodeType1: Class, nodeType2: Class, nodeType3: Class, nodeType4: Class, nodeType5: Class, nodeType6: Class, nodeType7: Class, nodeType8: Class, instructionsGenerator: (node1: T1, node2: T2, node3: T3, node4: T4, node5: T5, node6: T6, node7: T7, node8: T8) -> InsnList) = replaceInstructions(nodeType1.toInstructionNodeFilter(), nodeType2.toInstructionNodeFilter(), nodeType3.toInstructionNodeFilter(), nodeType4.toInstructionNodeFilter(), nodeType5.toInstructionNodeFilter(), nodeType6.toInstructionNodeFilter(), nodeType7.toInstructionNodeFilter(), nodeType8.toInstructionNodeFilter(), instructionsGenerator)


@SuppressFBWarnings("RCN_REDUNDANT_NULLCHECK_OF_NONNULL_VALUE", "UJM_UNJITABLE_METHOD")
fun  MethodNode.replaceInstructions(filter1: InstructionNodeFilter, filter2: InstructionNodeFilter, filter3: InstructionNodeFilter, filter4: InstructionNodeFilter, filter5: InstructionNodeFilter, filter6: InstructionNodeFilter, filter7: InstructionNodeFilter, filter8: InstructionNodeFilter, filter9: InstructionNodeFilter, instructionsGenerator: (node1: T1, node2: T2, node3: T3, node4: T4, node5: T5, node6: T6, node7: T7, node8: T8, node9: T9) -> InsnList): Boolean {
    val instructions = this.instructions ?: return false
    if (instructions.size() < 9) return false

    val unusedLabelNodes = this.unusedLabelNodes
    if (instructions.size() - unusedLabelNodes.size < 9) return false

    fun canBeUsed(node: AbstractInsnNode) = node !is LineNumberNode && node !in unusedLabelNodes

    var node1: T1? = null
    var node2: T2? = null
    var node3: T3? = null
    var node4: T4? = null
    var node5: T5? = null
    var node6: T6? = null
    var node7: T7? = null
    var node8: T8? = null
    var node9: T9? = null

    fun reset() {
        node1 = null
        node2 = null
        node3 = null
        node4 = null
        node5 = null
        node6 = null
        node7 = null
        node8 = null
        node9 = null
    }

    var curNode: AbstractInsnNode? = instructions.first ?: return false
    var isSomethingChanged = false
    while (curNode != null) {
        val node: AbstractInsnNode = curNode
        var nextNode: AbstractInsnNode? = node.next
        run {
            if (!canBeUsed(node)) return@run
            if (null == node1) {
                if (!filter1.nodeType.isInstance(node)) return@run reset()
                filter1.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node1 = node.uncheckedCast()
            } else if (null == node2) {
                if (!filter2.nodeType.isInstance(node)) return@run reset()
                filter2.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node2 = node.uncheckedCast()
            } else if (null == node3) {
                if (!filter3.nodeType.isInstance(node)) return@run reset()
                filter3.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node3 = node.uncheckedCast()
            } else if (null == node4) {
                if (!filter4.nodeType.isInstance(node)) return@run reset()
                filter4.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node4 = node.uncheckedCast()
            } else if (null == node5) {
                if (!filter5.nodeType.isInstance(node)) return@run reset()
                filter5.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node5 = node.uncheckedCast()
            } else if (null == node6) {
                if (!filter6.nodeType.isInstance(node)) return@run reset()
                filter6.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node6 = node.uncheckedCast()
            } else if (null == node7) {
                if (!filter7.nodeType.isInstance(node)) return@run reset()
                filter7.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node7 = node.uncheckedCast()
            } else if (null == node8) {
                if (!filter8.nodeType.isInstance(node)) return@run reset()
                filter8.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node8 = node.uncheckedCast()
            } else if (null == node9) {
                if (!filter9.nodeType.isInstance(node)) return@run reset()
                filter9.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node9 = node.uncheckedCast()

                nextNode = node9!!.next
                val newInstructions = instructionsGenerator(node1!!, node2!!, node3!!, node4!!, node5!!, node6!!, node7!!, node8!!, node9!!)
                if (1 <= newInstructions.size()) {
                    if (newInstructions.contains(node1)) throw IllegalStateException("New instructions contain node #1")
                    if (newInstructions.contains(node2)) throw IllegalStateException("New instructions contain node #2")
                    if (newInstructions.contains(node3)) throw IllegalStateException("New instructions contain node #3")
                    if (newInstructions.contains(node4)) throw IllegalStateException("New instructions contain node #4")
                    if (newInstructions.contains(node5)) throw IllegalStateException("New instructions contain node #5")
                    if (newInstructions.contains(node6)) throw IllegalStateException("New instructions contain node #6")
                    if (newInstructions.contains(node7)) throw IllegalStateException("New instructions contain node #7")
                    if (newInstructions.contains(node8)) throw IllegalStateException("New instructions contain node #8")
                    if (newInstructions.contains(node9)) throw IllegalStateException("New instructions contain node #9")
                    instructions.insert(node9, newInstructions)
                }
                var nodeToDelete: AbstractInsnNode = node1!!
                while (true) {
                    val next = nodeToDelete.next ?: break
                    instructions.remove(nodeToDelete)
                    if (nodeToDelete === node9) break
                    nodeToDelete = next
                }
                isSomethingChanged = true
                reset()
            }
        }
        curNode = nextNode
    }
    return isSomethingChanged
}

fun  MethodNode.replaceInstructions(nodeType1: Class, nodeType2: Class, nodeType3: Class, nodeType4: Class, nodeType5: Class, nodeType6: Class, nodeType7: Class, nodeType8: Class, nodeType9: Class, instructionsGenerator: (node1: T1, node2: T2, node3: T3, node4: T4, node5: T5, node6: T6, node7: T7, node8: T8, node9: T9) -> InsnList) = replaceInstructions(nodeType1.toInstructionNodeFilter(), nodeType2.toInstructionNodeFilter(), nodeType3.toInstructionNodeFilter(), nodeType4.toInstructionNodeFilter(), nodeType5.toInstructionNodeFilter(), nodeType6.toInstructionNodeFilter(), nodeType7.toInstructionNodeFilter(), nodeType8.toInstructionNodeFilter(), nodeType9.toInstructionNodeFilter(), instructionsGenerator)


@SuppressFBWarnings("RCN_REDUNDANT_NULLCHECK_OF_NONNULL_VALUE", "UJM_UNJITABLE_METHOD")
fun  MethodNode.replaceInstructions(filter1: InstructionNodeFilter, filter2: InstructionNodeFilter, filter3: InstructionNodeFilter, filter4: InstructionNodeFilter, filter5: InstructionNodeFilter, filter6: InstructionNodeFilter, filter7: InstructionNodeFilter, filter8: InstructionNodeFilter, filter9: InstructionNodeFilter, filter10: InstructionNodeFilter, instructionsGenerator: (node1: T1, node2: T2, node3: T3, node4: T4, node5: T5, node6: T6, node7: T7, node8: T8, node9: T9, node10: T10) -> InsnList): Boolean {
    val instructions = this.instructions ?: return false
    if (instructions.size() < 10) return false

    val unusedLabelNodes = this.unusedLabelNodes
    if (instructions.size() - unusedLabelNodes.size < 10) return false

    fun canBeUsed(node: AbstractInsnNode) = node !is LineNumberNode && node !in unusedLabelNodes

    var node1: T1? = null
    var node2: T2? = null
    var node3: T3? = null
    var node4: T4? = null
    var node5: T5? = null
    var node6: T6? = null
    var node7: T7? = null
    var node8: T8? = null
    var node9: T9? = null
    var node10: T10? = null

    fun reset() {
        node1 = null
        node2 = null
        node3 = null
        node4 = null
        node5 = null
        node6 = null
        node7 = null
        node8 = null
        node9 = null
        node10 = null
    }

    var curNode: AbstractInsnNode? = instructions.first ?: return false
    var isSomethingChanged = false
    while (curNode != null) {
        val node: AbstractInsnNode = curNode
        var nextNode: AbstractInsnNode? = node.next
        run {
            if (!canBeUsed(node)) return@run
            if (null == node1) {
                if (!filter1.nodeType.isInstance(node)) return@run reset()
                filter1.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node1 = node.uncheckedCast()
            } else if (null == node2) {
                if (!filter2.nodeType.isInstance(node)) return@run reset()
                filter2.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node2 = node.uncheckedCast()
            } else if (null == node3) {
                if (!filter3.nodeType.isInstance(node)) return@run reset()
                filter3.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node3 = node.uncheckedCast()
            } else if (null == node4) {
                if (!filter4.nodeType.isInstance(node)) return@run reset()
                filter4.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node4 = node.uncheckedCast()
            } else if (null == node5) {
                if (!filter5.nodeType.isInstance(node)) return@run reset()
                filter5.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node5 = node.uncheckedCast()
            } else if (null == node6) {
                if (!filter6.nodeType.isInstance(node)) return@run reset()
                filter6.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node6 = node.uncheckedCast()
            } else if (null == node7) {
                if (!filter7.nodeType.isInstance(node)) return@run reset()
                filter7.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node7 = node.uncheckedCast()
            } else if (null == node8) {
                if (!filter8.nodeType.isInstance(node)) return@run reset()
                filter8.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node8 = node.uncheckedCast()
            } else if (null == node9) {
                if (!filter9.nodeType.isInstance(node)) return@run reset()
                filter9.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node9 = node.uncheckedCast()
            } else if (null == node10) {
                if (!filter10.nodeType.isInstance(node)) return@run reset()
                filter10.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node10 = node.uncheckedCast()

                nextNode = node10!!.next
                val newInstructions = instructionsGenerator(node1!!, node2!!, node3!!, node4!!, node5!!, node6!!, node7!!, node8!!, node9!!, node10!!)
                if (1 <= newInstructions.size()) {
                    if (newInstructions.contains(node1)) throw IllegalStateException("New instructions contain node #1")
                    if (newInstructions.contains(node2)) throw IllegalStateException("New instructions contain node #2")
                    if (newInstructions.contains(node3)) throw IllegalStateException("New instructions contain node #3")
                    if (newInstructions.contains(node4)) throw IllegalStateException("New instructions contain node #4")
                    if (newInstructions.contains(node5)) throw IllegalStateException("New instructions contain node #5")
                    if (newInstructions.contains(node6)) throw IllegalStateException("New instructions contain node #6")
                    if (newInstructions.contains(node7)) throw IllegalStateException("New instructions contain node #7")
                    if (newInstructions.contains(node8)) throw IllegalStateException("New instructions contain node #8")
                    if (newInstructions.contains(node9)) throw IllegalStateException("New instructions contain node #9")
                    if (newInstructions.contains(node10)) throw IllegalStateException("New instructions contain node #10")
                    instructions.insert(node10, newInstructions)
                }
                var nodeToDelete: AbstractInsnNode = node1!!
                while (true) {
                    val next = nodeToDelete.next ?: break
                    instructions.remove(nodeToDelete)
                    if (nodeToDelete === node10) break
                    nodeToDelete = next
                }
                isSomethingChanged = true
                reset()
            }
        }
        curNode = nextNode
    }
    return isSomethingChanged
}

fun  MethodNode.replaceInstructions(nodeType1: Class, nodeType2: Class, nodeType3: Class, nodeType4: Class, nodeType5: Class, nodeType6: Class, nodeType7: Class, nodeType8: Class, nodeType9: Class, nodeType10: Class, instructionsGenerator: (node1: T1, node2: T2, node3: T3, node4: T4, node5: T5, node6: T6, node7: T7, node8: T8, node9: T9, node10: T10) -> InsnList) = replaceInstructions(nodeType1.toInstructionNodeFilter(), nodeType2.toInstructionNodeFilter(), nodeType3.toInstructionNodeFilter(), nodeType4.toInstructionNodeFilter(), nodeType5.toInstructionNodeFilter(), nodeType6.toInstructionNodeFilter(), nodeType7.toInstructionNodeFilter(), nodeType8.toInstructionNodeFilter(), nodeType9.toInstructionNodeFilter(), nodeType10.toInstructionNodeFilter(), instructionsGenerator)


@SuppressFBWarnings("RCN_REDUNDANT_NULLCHECK_OF_NONNULL_VALUE", "UJM_UNJITABLE_METHOD")
fun  MethodNode.replaceInstructions(filter1: InstructionNodeFilter, filter2: InstructionNodeFilter, filter3: InstructionNodeFilter, filter4: InstructionNodeFilter, filter5: InstructionNodeFilter, filter6: InstructionNodeFilter, filter7: InstructionNodeFilter, filter8: InstructionNodeFilter, filter9: InstructionNodeFilter, filter10: InstructionNodeFilter, filter11: InstructionNodeFilter, instructionsGenerator: (node1: T1, node2: T2, node3: T3, node4: T4, node5: T5, node6: T6, node7: T7, node8: T8, node9: T9, node10: T10, node11: T11) -> InsnList): Boolean {
    val instructions = this.instructions ?: return false
    if (instructions.size() < 11) return false

    val unusedLabelNodes = this.unusedLabelNodes
    if (instructions.size() - unusedLabelNodes.size < 11) return false

    fun canBeUsed(node: AbstractInsnNode) = node !is LineNumberNode && node !in unusedLabelNodes

    var node1: T1? = null
    var node2: T2? = null
    var node3: T3? = null
    var node4: T4? = null
    var node5: T5? = null
    var node6: T6? = null
    var node7: T7? = null
    var node8: T8? = null
    var node9: T9? = null
    var node10: T10? = null
    var node11: T11? = null

    fun reset() {
        node1 = null
        node2 = null
        node3 = null
        node4 = null
        node5 = null
        node6 = null
        node7 = null
        node8 = null
        node9 = null
        node10 = null
        node11 = null
    }

    var curNode: AbstractInsnNode? = instructions.first ?: return false
    var isSomethingChanged = false
    while (curNode != null) {
        val node: AbstractInsnNode = curNode
        var nextNode: AbstractInsnNode? = node.next
        run {
            if (!canBeUsed(node)) return@run
            if (null == node1) {
                if (!filter1.nodeType.isInstance(node)) return@run reset()
                filter1.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node1 = node.uncheckedCast()
            } else if (null == node2) {
                if (!filter2.nodeType.isInstance(node)) return@run reset()
                filter2.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node2 = node.uncheckedCast()
            } else if (null == node3) {
                if (!filter3.nodeType.isInstance(node)) return@run reset()
                filter3.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node3 = node.uncheckedCast()
            } else if (null == node4) {
                if (!filter4.nodeType.isInstance(node)) return@run reset()
                filter4.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node4 = node.uncheckedCast()
            } else if (null == node5) {
                if (!filter5.nodeType.isInstance(node)) return@run reset()
                filter5.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node5 = node.uncheckedCast()
            } else if (null == node6) {
                if (!filter6.nodeType.isInstance(node)) return@run reset()
                filter6.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node6 = node.uncheckedCast()
            } else if (null == node7) {
                if (!filter7.nodeType.isInstance(node)) return@run reset()
                filter7.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node7 = node.uncheckedCast()
            } else if (null == node8) {
                if (!filter8.nodeType.isInstance(node)) return@run reset()
                filter8.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node8 = node.uncheckedCast()
            } else if (null == node9) {
                if (!filter9.nodeType.isInstance(node)) return@run reset()
                filter9.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node9 = node.uncheckedCast()
            } else if (null == node10) {
                if (!filter10.nodeType.isInstance(node)) return@run reset()
                filter10.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node10 = node.uncheckedCast()
            } else if (null == node11) {
                if (!filter11.nodeType.isInstance(node)) return@run reset()
                filter11.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node11 = node.uncheckedCast()

                nextNode = node11!!.next
                val newInstructions = instructionsGenerator(node1!!, node2!!, node3!!, node4!!, node5!!, node6!!, node7!!, node8!!, node9!!, node10!!, node11!!)
                if (1 <= newInstructions.size()) {
                    if (newInstructions.contains(node1)) throw IllegalStateException("New instructions contain node #1")
                    if (newInstructions.contains(node2)) throw IllegalStateException("New instructions contain node #2")
                    if (newInstructions.contains(node3)) throw IllegalStateException("New instructions contain node #3")
                    if (newInstructions.contains(node4)) throw IllegalStateException("New instructions contain node #4")
                    if (newInstructions.contains(node5)) throw IllegalStateException("New instructions contain node #5")
                    if (newInstructions.contains(node6)) throw IllegalStateException("New instructions contain node #6")
                    if (newInstructions.contains(node7)) throw IllegalStateException("New instructions contain node #7")
                    if (newInstructions.contains(node8)) throw IllegalStateException("New instructions contain node #8")
                    if (newInstructions.contains(node9)) throw IllegalStateException("New instructions contain node #9")
                    if (newInstructions.contains(node10)) throw IllegalStateException("New instructions contain node #10")
                    if (newInstructions.contains(node11)) throw IllegalStateException("New instructions contain node #11")
                    instructions.insert(node11, newInstructions)
                }
                var nodeToDelete: AbstractInsnNode = node1!!
                while (true) {
                    val next = nodeToDelete.next ?: break
                    instructions.remove(nodeToDelete)
                    if (nodeToDelete === node11) break
                    nodeToDelete = next
                }
                isSomethingChanged = true
                reset()
            }
        }
        curNode = nextNode
    }
    return isSomethingChanged
}

fun  MethodNode.replaceInstructions(nodeType1: Class, nodeType2: Class, nodeType3: Class, nodeType4: Class, nodeType5: Class, nodeType6: Class, nodeType7: Class, nodeType8: Class, nodeType9: Class, nodeType10: Class, nodeType11: Class, instructionsGenerator: (node1: T1, node2: T2, node3: T3, node4: T4, node5: T5, node6: T6, node7: T7, node8: T8, node9: T9, node10: T10, node11: T11) -> InsnList) = replaceInstructions(nodeType1.toInstructionNodeFilter(), nodeType2.toInstructionNodeFilter(), nodeType3.toInstructionNodeFilter(), nodeType4.toInstructionNodeFilter(), nodeType5.toInstructionNodeFilter(), nodeType6.toInstructionNodeFilter(), nodeType7.toInstructionNodeFilter(), nodeType8.toInstructionNodeFilter(), nodeType9.toInstructionNodeFilter(), nodeType10.toInstructionNodeFilter(), nodeType11.toInstructionNodeFilter(), instructionsGenerator)


@SuppressFBWarnings("RCN_REDUNDANT_NULLCHECK_OF_NONNULL_VALUE", "UJM_UNJITABLE_METHOD")
fun  MethodNode.replaceInstructions(filter1: InstructionNodeFilter, filter2: InstructionNodeFilter, filter3: InstructionNodeFilter, filter4: InstructionNodeFilter, filter5: InstructionNodeFilter, filter6: InstructionNodeFilter, filter7: InstructionNodeFilter, filter8: InstructionNodeFilter, filter9: InstructionNodeFilter, filter10: InstructionNodeFilter, filter11: InstructionNodeFilter, filter12: InstructionNodeFilter, instructionsGenerator: (node1: T1, node2: T2, node3: T3, node4: T4, node5: T5, node6: T6, node7: T7, node8: T8, node9: T9, node10: T10, node11: T11, node12: T12) -> InsnList): Boolean {
    val instructions = this.instructions ?: return false
    if (instructions.size() < 12) return false

    val unusedLabelNodes = this.unusedLabelNodes
    if (instructions.size() - unusedLabelNodes.size < 12) return false

    fun canBeUsed(node: AbstractInsnNode) = node !is LineNumberNode && node !in unusedLabelNodes

    var node1: T1? = null
    var node2: T2? = null
    var node3: T3? = null
    var node4: T4? = null
    var node5: T5? = null
    var node6: T6? = null
    var node7: T7? = null
    var node8: T8? = null
    var node9: T9? = null
    var node10: T10? = null
    var node11: T11? = null
    var node12: T12? = null

    fun reset() {
        node1 = null
        node2 = null
        node3 = null
        node4 = null
        node5 = null
        node6 = null
        node7 = null
        node8 = null
        node9 = null
        node10 = null
        node11 = null
        node12 = null
    }

    var curNode: AbstractInsnNode? = instructions.first ?: return false
    var isSomethingChanged = false
    while (curNode != null) {
        val node: AbstractInsnNode = curNode
        var nextNode: AbstractInsnNode? = node.next
        run {
            if (!canBeUsed(node)) return@run
            if (null == node1) {
                if (!filter1.nodeType.isInstance(node)) return@run reset()
                filter1.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node1 = node.uncheckedCast()
            } else if (null == node2) {
                if (!filter2.nodeType.isInstance(node)) return@run reset()
                filter2.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node2 = node.uncheckedCast()
            } else if (null == node3) {
                if (!filter3.nodeType.isInstance(node)) return@run reset()
                filter3.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node3 = node.uncheckedCast()
            } else if (null == node4) {
                if (!filter4.nodeType.isInstance(node)) return@run reset()
                filter4.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node4 = node.uncheckedCast()
            } else if (null == node5) {
                if (!filter5.nodeType.isInstance(node)) return@run reset()
                filter5.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node5 = node.uncheckedCast()
            } else if (null == node6) {
                if (!filter6.nodeType.isInstance(node)) return@run reset()
                filter6.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node6 = node.uncheckedCast()
            } else if (null == node7) {
                if (!filter7.nodeType.isInstance(node)) return@run reset()
                filter7.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node7 = node.uncheckedCast()
            } else if (null == node8) {
                if (!filter8.nodeType.isInstance(node)) return@run reset()
                filter8.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node8 = node.uncheckedCast()
            } else if (null == node9) {
                if (!filter9.nodeType.isInstance(node)) return@run reset()
                filter9.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node9 = node.uncheckedCast()
            } else if (null == node10) {
                if (!filter10.nodeType.isInstance(node)) return@run reset()
                filter10.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node10 = node.uncheckedCast()
            } else if (null == node11) {
                if (!filter11.nodeType.isInstance(node)) return@run reset()
                filter11.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node11 = node.uncheckedCast()
            } else if (null == node12) {
                if (!filter12.nodeType.isInstance(node)) return@run reset()
                filter12.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node12 = node.uncheckedCast()

                nextNode = node12!!.next
                val newInstructions = instructionsGenerator(node1!!, node2!!, node3!!, node4!!, node5!!, node6!!, node7!!, node8!!, node9!!, node10!!, node11!!, node12!!)
                if (1 <= newInstructions.size()) {
                    if (newInstructions.contains(node1)) throw IllegalStateException("New instructions contain node #1")
                    if (newInstructions.contains(node2)) throw IllegalStateException("New instructions contain node #2")
                    if (newInstructions.contains(node3)) throw IllegalStateException("New instructions contain node #3")
                    if (newInstructions.contains(node4)) throw IllegalStateException("New instructions contain node #4")
                    if (newInstructions.contains(node5)) throw IllegalStateException("New instructions contain node #5")
                    if (newInstructions.contains(node6)) throw IllegalStateException("New instructions contain node #6")
                    if (newInstructions.contains(node7)) throw IllegalStateException("New instructions contain node #7")
                    if (newInstructions.contains(node8)) throw IllegalStateException("New instructions contain node #8")
                    if (newInstructions.contains(node9)) throw IllegalStateException("New instructions contain node #9")
                    if (newInstructions.contains(node10)) throw IllegalStateException("New instructions contain node #10")
                    if (newInstructions.contains(node11)) throw IllegalStateException("New instructions contain node #11")
                    if (newInstructions.contains(node12)) throw IllegalStateException("New instructions contain node #12")
                    instructions.insert(node12, newInstructions)
                }
                var nodeToDelete: AbstractInsnNode = node1!!
                while (true) {
                    val next = nodeToDelete.next ?: break
                    instructions.remove(nodeToDelete)
                    if (nodeToDelete === node12) break
                    nodeToDelete = next
                }
                isSomethingChanged = true
                reset()
            }
        }
        curNode = nextNode
    }
    return isSomethingChanged
}

fun  MethodNode.replaceInstructions(nodeType1: Class, nodeType2: Class, nodeType3: Class, nodeType4: Class, nodeType5: Class, nodeType6: Class, nodeType7: Class, nodeType8: Class, nodeType9: Class, nodeType10: Class, nodeType11: Class, nodeType12: Class, instructionsGenerator: (node1: T1, node2: T2, node3: T3, node4: T4, node5: T5, node6: T6, node7: T7, node8: T8, node9: T9, node10: T10, node11: T11, node12: T12) -> InsnList) = replaceInstructions(nodeType1.toInstructionNodeFilter(), nodeType2.toInstructionNodeFilter(), nodeType3.toInstructionNodeFilter(), nodeType4.toInstructionNodeFilter(), nodeType5.toInstructionNodeFilter(), nodeType6.toInstructionNodeFilter(), nodeType7.toInstructionNodeFilter(), nodeType8.toInstructionNodeFilter(), nodeType9.toInstructionNodeFilter(), nodeType10.toInstructionNodeFilter(), nodeType11.toInstructionNodeFilter(), nodeType12.toInstructionNodeFilter(), instructionsGenerator)


@SuppressFBWarnings("RCN_REDUNDANT_NULLCHECK_OF_NONNULL_VALUE", "UJM_UNJITABLE_METHOD")
fun  MethodNode.replaceInstructions(filter1: InstructionNodeFilter, filter2: InstructionNodeFilter, filter3: InstructionNodeFilter, filter4: InstructionNodeFilter, filter5: InstructionNodeFilter, filter6: InstructionNodeFilter, filter7: InstructionNodeFilter, filter8: InstructionNodeFilter, filter9: InstructionNodeFilter, filter10: InstructionNodeFilter, filter11: InstructionNodeFilter, filter12: InstructionNodeFilter, filter13: InstructionNodeFilter, instructionsGenerator: (node1: T1, node2: T2, node3: T3, node4: T4, node5: T5, node6: T6, node7: T7, node8: T8, node9: T9, node10: T10, node11: T11, node12: T12, node13: T13) -> InsnList): Boolean {
    val instructions = this.instructions ?: return false
    if (instructions.size() < 13) return false

    val unusedLabelNodes = this.unusedLabelNodes
    if (instructions.size() - unusedLabelNodes.size < 13) return false

    fun canBeUsed(node: AbstractInsnNode) = node !is LineNumberNode && node !in unusedLabelNodes

    var node1: T1? = null
    var node2: T2? = null
    var node3: T3? = null
    var node4: T4? = null
    var node5: T5? = null
    var node6: T6? = null
    var node7: T7? = null
    var node8: T8? = null
    var node9: T9? = null
    var node10: T10? = null
    var node11: T11? = null
    var node12: T12? = null
    var node13: T13? = null

    fun reset() {
        node1 = null
        node2 = null
        node3 = null
        node4 = null
        node5 = null
        node6 = null
        node7 = null
        node8 = null
        node9 = null
        node10 = null
        node11 = null
        node12 = null
        node13 = null
    }

    var curNode: AbstractInsnNode? = instructions.first ?: return false
    var isSomethingChanged = false
    while (curNode != null) {
        val node: AbstractInsnNode = curNode
        var nextNode: AbstractInsnNode? = node.next
        run {
            if (!canBeUsed(node)) return@run
            if (null == node1) {
                if (!filter1.nodeType.isInstance(node)) return@run reset()
                filter1.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node1 = node.uncheckedCast()
            } else if (null == node2) {
                if (!filter2.nodeType.isInstance(node)) return@run reset()
                filter2.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node2 = node.uncheckedCast()
            } else if (null == node3) {
                if (!filter3.nodeType.isInstance(node)) return@run reset()
                filter3.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node3 = node.uncheckedCast()
            } else if (null == node4) {
                if (!filter4.nodeType.isInstance(node)) return@run reset()
                filter4.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node4 = node.uncheckedCast()
            } else if (null == node5) {
                if (!filter5.nodeType.isInstance(node)) return@run reset()
                filter5.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node5 = node.uncheckedCast()
            } else if (null == node6) {
                if (!filter6.nodeType.isInstance(node)) return@run reset()
                filter6.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node6 = node.uncheckedCast()
            } else if (null == node7) {
                if (!filter7.nodeType.isInstance(node)) return@run reset()
                filter7.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node7 = node.uncheckedCast()
            } else if (null == node8) {
                if (!filter8.nodeType.isInstance(node)) return@run reset()
                filter8.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node8 = node.uncheckedCast()
            } else if (null == node9) {
                if (!filter9.nodeType.isInstance(node)) return@run reset()
                filter9.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node9 = node.uncheckedCast()
            } else if (null == node10) {
                if (!filter10.nodeType.isInstance(node)) return@run reset()
                filter10.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node10 = node.uncheckedCast()
            } else if (null == node11) {
                if (!filter11.nodeType.isInstance(node)) return@run reset()
                filter11.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node11 = node.uncheckedCast()
            } else if (null == node12) {
                if (!filter12.nodeType.isInstance(node)) return@run reset()
                filter12.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node12 = node.uncheckedCast()
            } else if (null == node13) {
                if (!filter13.nodeType.isInstance(node)) return@run reset()
                filter13.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node13 = node.uncheckedCast()

                nextNode = node13!!.next
                val newInstructions = instructionsGenerator(node1!!, node2!!, node3!!, node4!!, node5!!, node6!!, node7!!, node8!!, node9!!, node10!!, node11!!, node12!!, node13!!)
                if (1 <= newInstructions.size()) {
                    if (newInstructions.contains(node1)) throw IllegalStateException("New instructions contain node #1")
                    if (newInstructions.contains(node2)) throw IllegalStateException("New instructions contain node #2")
                    if (newInstructions.contains(node3)) throw IllegalStateException("New instructions contain node #3")
                    if (newInstructions.contains(node4)) throw IllegalStateException("New instructions contain node #4")
                    if (newInstructions.contains(node5)) throw IllegalStateException("New instructions contain node #5")
                    if (newInstructions.contains(node6)) throw IllegalStateException("New instructions contain node #6")
                    if (newInstructions.contains(node7)) throw IllegalStateException("New instructions contain node #7")
                    if (newInstructions.contains(node8)) throw IllegalStateException("New instructions contain node #8")
                    if (newInstructions.contains(node9)) throw IllegalStateException("New instructions contain node #9")
                    if (newInstructions.contains(node10)) throw IllegalStateException("New instructions contain node #10")
                    if (newInstructions.contains(node11)) throw IllegalStateException("New instructions contain node #11")
                    if (newInstructions.contains(node12)) throw IllegalStateException("New instructions contain node #12")
                    if (newInstructions.contains(node13)) throw IllegalStateException("New instructions contain node #13")
                    instructions.insert(node13, newInstructions)
                }
                var nodeToDelete: AbstractInsnNode = node1!!
                while (true) {
                    val next = nodeToDelete.next ?: break
                    instructions.remove(nodeToDelete)
                    if (nodeToDelete === node13) break
                    nodeToDelete = next
                }
                isSomethingChanged = true
                reset()
            }
        }
        curNode = nextNode
    }
    return isSomethingChanged
}

fun  MethodNode.replaceInstructions(nodeType1: Class, nodeType2: Class, nodeType3: Class, nodeType4: Class, nodeType5: Class, nodeType6: Class, nodeType7: Class, nodeType8: Class, nodeType9: Class, nodeType10: Class, nodeType11: Class, nodeType12: Class, nodeType13: Class, instructionsGenerator: (node1: T1, node2: T2, node3: T3, node4: T4, node5: T5, node6: T6, node7: T7, node8: T8, node9: T9, node10: T10, node11: T11, node12: T12, node13: T13) -> InsnList) = replaceInstructions(nodeType1.toInstructionNodeFilter(), nodeType2.toInstructionNodeFilter(), nodeType3.toInstructionNodeFilter(), nodeType4.toInstructionNodeFilter(), nodeType5.toInstructionNodeFilter(), nodeType6.toInstructionNodeFilter(), nodeType7.toInstructionNodeFilter(), nodeType8.toInstructionNodeFilter(), nodeType9.toInstructionNodeFilter(), nodeType10.toInstructionNodeFilter(), nodeType11.toInstructionNodeFilter(), nodeType12.toInstructionNodeFilter(), nodeType13.toInstructionNodeFilter(), instructionsGenerator)


@SuppressFBWarnings("RCN_REDUNDANT_NULLCHECK_OF_NONNULL_VALUE", "UJM_UNJITABLE_METHOD")
fun  MethodNode.replaceInstructions(filter1: InstructionNodeFilter, filter2: InstructionNodeFilter, filter3: InstructionNodeFilter, filter4: InstructionNodeFilter, filter5: InstructionNodeFilter, filter6: InstructionNodeFilter, filter7: InstructionNodeFilter, filter8: InstructionNodeFilter, filter9: InstructionNodeFilter, filter10: InstructionNodeFilter, filter11: InstructionNodeFilter, filter12: InstructionNodeFilter, filter13: InstructionNodeFilter, filter14: InstructionNodeFilter, instructionsGenerator: (node1: T1, node2: T2, node3: T3, node4: T4, node5: T5, node6: T6, node7: T7, node8: T8, node9: T9, node10: T10, node11: T11, node12: T12, node13: T13, node14: T14) -> InsnList): Boolean {
    val instructions = this.instructions ?: return false
    if (instructions.size() < 14) return false

    val unusedLabelNodes = this.unusedLabelNodes
    if (instructions.size() - unusedLabelNodes.size < 14) return false

    fun canBeUsed(node: AbstractInsnNode) = node !is LineNumberNode && node !in unusedLabelNodes

    var node1: T1? = null
    var node2: T2? = null
    var node3: T3? = null
    var node4: T4? = null
    var node5: T5? = null
    var node6: T6? = null
    var node7: T7? = null
    var node8: T8? = null
    var node9: T9? = null
    var node10: T10? = null
    var node11: T11? = null
    var node12: T12? = null
    var node13: T13? = null
    var node14: T14? = null

    fun reset() {
        node1 = null
        node2 = null
        node3 = null
        node4 = null
        node5 = null
        node6 = null
        node7 = null
        node8 = null
        node9 = null
        node10 = null
        node11 = null
        node12 = null
        node13 = null
        node14 = null
    }

    var curNode: AbstractInsnNode? = instructions.first ?: return false
    var isSomethingChanged = false
    while (curNode != null) {
        val node: AbstractInsnNode = curNode
        var nextNode: AbstractInsnNode? = node.next
        run {
            if (!canBeUsed(node)) return@run
            if (null == node1) {
                if (!filter1.nodeType.isInstance(node)) return@run reset()
                filter1.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node1 = node.uncheckedCast()
            } else if (null == node2) {
                if (!filter2.nodeType.isInstance(node)) return@run reset()
                filter2.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node2 = node.uncheckedCast()
            } else if (null == node3) {
                if (!filter3.nodeType.isInstance(node)) return@run reset()
                filter3.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node3 = node.uncheckedCast()
            } else if (null == node4) {
                if (!filter4.nodeType.isInstance(node)) return@run reset()
                filter4.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node4 = node.uncheckedCast()
            } else if (null == node5) {
                if (!filter5.nodeType.isInstance(node)) return@run reset()
                filter5.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node5 = node.uncheckedCast()
            } else if (null == node6) {
                if (!filter6.nodeType.isInstance(node)) return@run reset()
                filter6.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node6 = node.uncheckedCast()
            } else if (null == node7) {
                if (!filter7.nodeType.isInstance(node)) return@run reset()
                filter7.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node7 = node.uncheckedCast()
            } else if (null == node8) {
                if (!filter8.nodeType.isInstance(node)) return@run reset()
                filter8.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node8 = node.uncheckedCast()
            } else if (null == node9) {
                if (!filter9.nodeType.isInstance(node)) return@run reset()
                filter9.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node9 = node.uncheckedCast()
            } else if (null == node10) {
                if (!filter10.nodeType.isInstance(node)) return@run reset()
                filter10.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node10 = node.uncheckedCast()
            } else if (null == node11) {
                if (!filter11.nodeType.isInstance(node)) return@run reset()
                filter11.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node11 = node.uncheckedCast()
            } else if (null == node12) {
                if (!filter12.nodeType.isInstance(node)) return@run reset()
                filter12.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node12 = node.uncheckedCast()
            } else if (null == node13) {
                if (!filter13.nodeType.isInstance(node)) return@run reset()
                filter13.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node13 = node.uncheckedCast()
            } else if (null == node14) {
                if (!filter14.nodeType.isInstance(node)) return@run reset()
                filter14.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node14 = node.uncheckedCast()

                nextNode = node14!!.next
                val newInstructions = instructionsGenerator(node1!!, node2!!, node3!!, node4!!, node5!!, node6!!, node7!!, node8!!, node9!!, node10!!, node11!!, node12!!, node13!!, node14!!)
                if (1 <= newInstructions.size()) {
                    if (newInstructions.contains(node1)) throw IllegalStateException("New instructions contain node #1")
                    if (newInstructions.contains(node2)) throw IllegalStateException("New instructions contain node #2")
                    if (newInstructions.contains(node3)) throw IllegalStateException("New instructions contain node #3")
                    if (newInstructions.contains(node4)) throw IllegalStateException("New instructions contain node #4")
                    if (newInstructions.contains(node5)) throw IllegalStateException("New instructions contain node #5")
                    if (newInstructions.contains(node6)) throw IllegalStateException("New instructions contain node #6")
                    if (newInstructions.contains(node7)) throw IllegalStateException("New instructions contain node #7")
                    if (newInstructions.contains(node8)) throw IllegalStateException("New instructions contain node #8")
                    if (newInstructions.contains(node9)) throw IllegalStateException("New instructions contain node #9")
                    if (newInstructions.contains(node10)) throw IllegalStateException("New instructions contain node #10")
                    if (newInstructions.contains(node11)) throw IllegalStateException("New instructions contain node #11")
                    if (newInstructions.contains(node12)) throw IllegalStateException("New instructions contain node #12")
                    if (newInstructions.contains(node13)) throw IllegalStateException("New instructions contain node #13")
                    if (newInstructions.contains(node14)) throw IllegalStateException("New instructions contain node #14")
                    instructions.insert(node14, newInstructions)
                }
                var nodeToDelete: AbstractInsnNode = node1!!
                while (true) {
                    val next = nodeToDelete.next ?: break
                    instructions.remove(nodeToDelete)
                    if (nodeToDelete === node14) break
                    nodeToDelete = next
                }
                isSomethingChanged = true
                reset()
            }
        }
        curNode = nextNode
    }
    return isSomethingChanged
}

fun  MethodNode.replaceInstructions(nodeType1: Class, nodeType2: Class, nodeType3: Class, nodeType4: Class, nodeType5: Class, nodeType6: Class, nodeType7: Class, nodeType8: Class, nodeType9: Class, nodeType10: Class, nodeType11: Class, nodeType12: Class, nodeType13: Class, nodeType14: Class, instructionsGenerator: (node1: T1, node2: T2, node3: T3, node4: T4, node5: T5, node6: T6, node7: T7, node8: T8, node9: T9, node10: T10, node11: T11, node12: T12, node13: T13, node14: T14) -> InsnList) = replaceInstructions(nodeType1.toInstructionNodeFilter(), nodeType2.toInstructionNodeFilter(), nodeType3.toInstructionNodeFilter(), nodeType4.toInstructionNodeFilter(), nodeType5.toInstructionNodeFilter(), nodeType6.toInstructionNodeFilter(), nodeType7.toInstructionNodeFilter(), nodeType8.toInstructionNodeFilter(), nodeType9.toInstructionNodeFilter(), nodeType10.toInstructionNodeFilter(), nodeType11.toInstructionNodeFilter(), nodeType12.toInstructionNodeFilter(), nodeType13.toInstructionNodeFilter(), nodeType14.toInstructionNodeFilter(), instructionsGenerator)


@SuppressFBWarnings("RCN_REDUNDANT_NULLCHECK_OF_NONNULL_VALUE", "UJM_UNJITABLE_METHOD")
fun  MethodNode.replaceInstructions(filter1: InstructionNodeFilter, filter2: InstructionNodeFilter, filter3: InstructionNodeFilter, filter4: InstructionNodeFilter, filter5: InstructionNodeFilter, filter6: InstructionNodeFilter, filter7: InstructionNodeFilter, filter8: InstructionNodeFilter, filter9: InstructionNodeFilter, filter10: InstructionNodeFilter, filter11: InstructionNodeFilter, filter12: InstructionNodeFilter, filter13: InstructionNodeFilter, filter14: InstructionNodeFilter, filter15: InstructionNodeFilter, instructionsGenerator: (node1: T1, node2: T2, node3: T3, node4: T4, node5: T5, node6: T6, node7: T7, node8: T8, node9: T9, node10: T10, node11: T11, node12: T12, node13: T13, node14: T14, node15: T15) -> InsnList): Boolean {
    val instructions = this.instructions ?: return false
    if (instructions.size() < 15) return false

    val unusedLabelNodes = this.unusedLabelNodes
    if (instructions.size() - unusedLabelNodes.size < 15) return false

    fun canBeUsed(node: AbstractInsnNode) = node !is LineNumberNode && node !in unusedLabelNodes

    var node1: T1? = null
    var node2: T2? = null
    var node3: T3? = null
    var node4: T4? = null
    var node5: T5? = null
    var node6: T6? = null
    var node7: T7? = null
    var node8: T8? = null
    var node9: T9? = null
    var node10: T10? = null
    var node11: T11? = null
    var node12: T12? = null
    var node13: T13? = null
    var node14: T14? = null
    var node15: T15? = null

    fun reset() {
        node1 = null
        node2 = null
        node3 = null
        node4 = null
        node5 = null
        node6 = null
        node7 = null
        node8 = null
        node9 = null
        node10 = null
        node11 = null
        node12 = null
        node13 = null
        node14 = null
        node15 = null
    }

    var curNode: AbstractInsnNode? = instructions.first ?: return false
    var isSomethingChanged = false
    while (curNode != null) {
        val node: AbstractInsnNode = curNode
        var nextNode: AbstractInsnNode? = node.next
        run {
            if (!canBeUsed(node)) return@run
            if (null == node1) {
                if (!filter1.nodeType.isInstance(node)) return@run reset()
                filter1.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node1 = node.uncheckedCast()
            } else if (null == node2) {
                if (!filter2.nodeType.isInstance(node)) return@run reset()
                filter2.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node2 = node.uncheckedCast()
            } else if (null == node3) {
                if (!filter3.nodeType.isInstance(node)) return@run reset()
                filter3.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node3 = node.uncheckedCast()
            } else if (null == node4) {
                if (!filter4.nodeType.isInstance(node)) return@run reset()
                filter4.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node4 = node.uncheckedCast()
            } else if (null == node5) {
                if (!filter5.nodeType.isInstance(node)) return@run reset()
                filter5.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node5 = node.uncheckedCast()
            } else if (null == node6) {
                if (!filter6.nodeType.isInstance(node)) return@run reset()
                filter6.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node6 = node.uncheckedCast()
            } else if (null == node7) {
                if (!filter7.nodeType.isInstance(node)) return@run reset()
                filter7.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node7 = node.uncheckedCast()
            } else if (null == node8) {
                if (!filter8.nodeType.isInstance(node)) return@run reset()
                filter8.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node8 = node.uncheckedCast()
            } else if (null == node9) {
                if (!filter9.nodeType.isInstance(node)) return@run reset()
                filter9.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node9 = node.uncheckedCast()
            } else if (null == node10) {
                if (!filter10.nodeType.isInstance(node)) return@run reset()
                filter10.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node10 = node.uncheckedCast()
            } else if (null == node11) {
                if (!filter11.nodeType.isInstance(node)) return@run reset()
                filter11.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node11 = node.uncheckedCast()
            } else if (null == node12) {
                if (!filter12.nodeType.isInstance(node)) return@run reset()
                filter12.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node12 = node.uncheckedCast()
            } else if (null == node13) {
                if (!filter13.nodeType.isInstance(node)) return@run reset()
                filter13.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node13 = node.uncheckedCast()
            } else if (null == node14) {
                if (!filter14.nodeType.isInstance(node)) return@run reset()
                filter14.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node14 = node.uncheckedCast()
            } else if (null == node15) {
                if (!filter15.nodeType.isInstance(node)) return@run reset()
                filter15.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node15 = node.uncheckedCast()

                nextNode = node15!!.next
                val newInstructions = instructionsGenerator(node1!!, node2!!, node3!!, node4!!, node5!!, node6!!, node7!!, node8!!, node9!!, node10!!, node11!!, node12!!, node13!!, node14!!, node15!!)
                if (1 <= newInstructions.size()) {
                    if (newInstructions.contains(node1)) throw IllegalStateException("New instructions contain node #1")
                    if (newInstructions.contains(node2)) throw IllegalStateException("New instructions contain node #2")
                    if (newInstructions.contains(node3)) throw IllegalStateException("New instructions contain node #3")
                    if (newInstructions.contains(node4)) throw IllegalStateException("New instructions contain node #4")
                    if (newInstructions.contains(node5)) throw IllegalStateException("New instructions contain node #5")
                    if (newInstructions.contains(node6)) throw IllegalStateException("New instructions contain node #6")
                    if (newInstructions.contains(node7)) throw IllegalStateException("New instructions contain node #7")
                    if (newInstructions.contains(node8)) throw IllegalStateException("New instructions contain node #8")
                    if (newInstructions.contains(node9)) throw IllegalStateException("New instructions contain node #9")
                    if (newInstructions.contains(node10)) throw IllegalStateException("New instructions contain node #10")
                    if (newInstructions.contains(node11)) throw IllegalStateException("New instructions contain node #11")
                    if (newInstructions.contains(node12)) throw IllegalStateException("New instructions contain node #12")
                    if (newInstructions.contains(node13)) throw IllegalStateException("New instructions contain node #13")
                    if (newInstructions.contains(node14)) throw IllegalStateException("New instructions contain node #14")
                    if (newInstructions.contains(node15)) throw IllegalStateException("New instructions contain node #15")
                    instructions.insert(node15, newInstructions)
                }
                var nodeToDelete: AbstractInsnNode = node1!!
                while (true) {
                    val next = nodeToDelete.next ?: break
                    instructions.remove(nodeToDelete)
                    if (nodeToDelete === node15) break
                    nodeToDelete = next
                }
                isSomethingChanged = true
                reset()
            }
        }
        curNode = nextNode
    }
    return isSomethingChanged
}

fun  MethodNode.replaceInstructions(nodeType1: Class, nodeType2: Class, nodeType3: Class, nodeType4: Class, nodeType5: Class, nodeType6: Class, nodeType7: Class, nodeType8: Class, nodeType9: Class, nodeType10: Class, nodeType11: Class, nodeType12: Class, nodeType13: Class, nodeType14: Class, nodeType15: Class, instructionsGenerator: (node1: T1, node2: T2, node3: T3, node4: T4, node5: T5, node6: T6, node7: T7, node8: T8, node9: T9, node10: T10, node11: T11, node12: T12, node13: T13, node14: T14, node15: T15) -> InsnList) = replaceInstructions(nodeType1.toInstructionNodeFilter(), nodeType2.toInstructionNodeFilter(), nodeType3.toInstructionNodeFilter(), nodeType4.toInstructionNodeFilter(), nodeType5.toInstructionNodeFilter(), nodeType6.toInstructionNodeFilter(), nodeType7.toInstructionNodeFilter(), nodeType8.toInstructionNodeFilter(), nodeType9.toInstructionNodeFilter(), nodeType10.toInstructionNodeFilter(), nodeType11.toInstructionNodeFilter(), nodeType12.toInstructionNodeFilter(), nodeType13.toInstructionNodeFilter(), nodeType14.toInstructionNodeFilter(), nodeType15.toInstructionNodeFilter(), instructionsGenerator)


@SuppressFBWarnings("RCN_REDUNDANT_NULLCHECK_OF_NONNULL_VALUE", "UJM_UNJITABLE_METHOD")
fun  MethodNode.replaceInstructions(filter1: InstructionNodeFilter, filter2: InstructionNodeFilter, filter3: InstructionNodeFilter, filter4: InstructionNodeFilter, filter5: InstructionNodeFilter, filter6: InstructionNodeFilter, filter7: InstructionNodeFilter, filter8: InstructionNodeFilter, filter9: InstructionNodeFilter, filter10: InstructionNodeFilter, filter11: InstructionNodeFilter, filter12: InstructionNodeFilter, filter13: InstructionNodeFilter, filter14: InstructionNodeFilter, filter15: InstructionNodeFilter, filter16: InstructionNodeFilter, instructionsGenerator: (node1: T1, node2: T2, node3: T3, node4: T4, node5: T5, node6: T6, node7: T7, node8: T8, node9: T9, node10: T10, node11: T11, node12: T12, node13: T13, node14: T14, node15: T15, node16: T16) -> InsnList): Boolean {
    val instructions = this.instructions ?: return false
    if (instructions.size() < 16) return false

    val unusedLabelNodes = this.unusedLabelNodes
    if (instructions.size() - unusedLabelNodes.size < 16) return false

    fun canBeUsed(node: AbstractInsnNode) = node !is LineNumberNode && node !in unusedLabelNodes

    var node1: T1? = null
    var node2: T2? = null
    var node3: T3? = null
    var node4: T4? = null
    var node5: T5? = null
    var node6: T6? = null
    var node7: T7? = null
    var node8: T8? = null
    var node9: T9? = null
    var node10: T10? = null
    var node11: T11? = null
    var node12: T12? = null
    var node13: T13? = null
    var node14: T14? = null
    var node15: T15? = null
    var node16: T16? = null

    fun reset() {
        node1 = null
        node2 = null
        node3 = null
        node4 = null
        node5 = null
        node6 = null
        node7 = null
        node8 = null
        node9 = null
        node10 = null
        node11 = null
        node12 = null
        node13 = null
        node14 = null
        node15 = null
        node16 = null
    }

    var curNode: AbstractInsnNode? = instructions.first ?: return false
    var isSomethingChanged = false
    while (curNode != null) {
        val node: AbstractInsnNode = curNode
        var nextNode: AbstractInsnNode? = node.next
        run {
            if (!canBeUsed(node)) return@run
            if (null == node1) {
                if (!filter1.nodeType.isInstance(node)) return@run reset()
                filter1.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node1 = node.uncheckedCast()
            } else if (null == node2) {
                if (!filter2.nodeType.isInstance(node)) return@run reset()
                filter2.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node2 = node.uncheckedCast()
            } else if (null == node3) {
                if (!filter3.nodeType.isInstance(node)) return@run reset()
                filter3.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node3 = node.uncheckedCast()
            } else if (null == node4) {
                if (!filter4.nodeType.isInstance(node)) return@run reset()
                filter4.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node4 = node.uncheckedCast()
            } else if (null == node5) {
                if (!filter5.nodeType.isInstance(node)) return@run reset()
                filter5.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node5 = node.uncheckedCast()
            } else if (null == node6) {
                if (!filter6.nodeType.isInstance(node)) return@run reset()
                filter6.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node6 = node.uncheckedCast()
            } else if (null == node7) {
                if (!filter7.nodeType.isInstance(node)) return@run reset()
                filter7.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node7 = node.uncheckedCast()
            } else if (null == node8) {
                if (!filter8.nodeType.isInstance(node)) return@run reset()
                filter8.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node8 = node.uncheckedCast()
            } else if (null == node9) {
                if (!filter9.nodeType.isInstance(node)) return@run reset()
                filter9.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node9 = node.uncheckedCast()
            } else if (null == node10) {
                if (!filter10.nodeType.isInstance(node)) return@run reset()
                filter10.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node10 = node.uncheckedCast()
            } else if (null == node11) {
                if (!filter11.nodeType.isInstance(node)) return@run reset()
                filter11.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node11 = node.uncheckedCast()
            } else if (null == node12) {
                if (!filter12.nodeType.isInstance(node)) return@run reset()
                filter12.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node12 = node.uncheckedCast()
            } else if (null == node13) {
                if (!filter13.nodeType.isInstance(node)) return@run reset()
                filter13.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node13 = node.uncheckedCast()
            } else if (null == node14) {
                if (!filter14.nodeType.isInstance(node)) return@run reset()
                filter14.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node14 = node.uncheckedCast()
            } else if (null == node15) {
                if (!filter15.nodeType.isInstance(node)) return@run reset()
                filter15.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node15 = node.uncheckedCast()
            } else if (null == node16) {
                if (!filter16.nodeType.isInstance(node)) return@run reset()
                filter16.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node16 = node.uncheckedCast()

                nextNode = node16!!.next
                val newInstructions = instructionsGenerator(node1!!, node2!!, node3!!, node4!!, node5!!, node6!!, node7!!, node8!!, node9!!, node10!!, node11!!, node12!!, node13!!, node14!!, node15!!, node16!!)
                if (1 <= newInstructions.size()) {
                    if (newInstructions.contains(node1)) throw IllegalStateException("New instructions contain node #1")
                    if (newInstructions.contains(node2)) throw IllegalStateException("New instructions contain node #2")
                    if (newInstructions.contains(node3)) throw IllegalStateException("New instructions contain node #3")
                    if (newInstructions.contains(node4)) throw IllegalStateException("New instructions contain node #4")
                    if (newInstructions.contains(node5)) throw IllegalStateException("New instructions contain node #5")
                    if (newInstructions.contains(node6)) throw IllegalStateException("New instructions contain node #6")
                    if (newInstructions.contains(node7)) throw IllegalStateException("New instructions contain node #7")
                    if (newInstructions.contains(node8)) throw IllegalStateException("New instructions contain node #8")
                    if (newInstructions.contains(node9)) throw IllegalStateException("New instructions contain node #9")
                    if (newInstructions.contains(node10)) throw IllegalStateException("New instructions contain node #10")
                    if (newInstructions.contains(node11)) throw IllegalStateException("New instructions contain node #11")
                    if (newInstructions.contains(node12)) throw IllegalStateException("New instructions contain node #12")
                    if (newInstructions.contains(node13)) throw IllegalStateException("New instructions contain node #13")
                    if (newInstructions.contains(node14)) throw IllegalStateException("New instructions contain node #14")
                    if (newInstructions.contains(node15)) throw IllegalStateException("New instructions contain node #15")
                    if (newInstructions.contains(node16)) throw IllegalStateException("New instructions contain node #16")
                    instructions.insert(node16, newInstructions)
                }
                var nodeToDelete: AbstractInsnNode = node1!!
                while (true) {
                    val next = nodeToDelete.next ?: break
                    instructions.remove(nodeToDelete)
                    if (nodeToDelete === node16) break
                    nodeToDelete = next
                }
                isSomethingChanged = true
                reset()
            }
        }
        curNode = nextNode
    }
    return isSomethingChanged
}

fun  MethodNode.replaceInstructions(nodeType1: Class, nodeType2: Class, nodeType3: Class, nodeType4: Class, nodeType5: Class, nodeType6: Class, nodeType7: Class, nodeType8: Class, nodeType9: Class, nodeType10: Class, nodeType11: Class, nodeType12: Class, nodeType13: Class, nodeType14: Class, nodeType15: Class, nodeType16: Class, instructionsGenerator: (node1: T1, node2: T2, node3: T3, node4: T4, node5: T5, node6: T6, node7: T7, node8: T8, node9: T9, node10: T10, node11: T11, node12: T12, node13: T13, node14: T14, node15: T15, node16: T16) -> InsnList) = replaceInstructions(nodeType1.toInstructionNodeFilter(), nodeType2.toInstructionNodeFilter(), nodeType3.toInstructionNodeFilter(), nodeType4.toInstructionNodeFilter(), nodeType5.toInstructionNodeFilter(), nodeType6.toInstructionNodeFilter(), nodeType7.toInstructionNodeFilter(), nodeType8.toInstructionNodeFilter(), nodeType9.toInstructionNodeFilter(), nodeType10.toInstructionNodeFilter(), nodeType11.toInstructionNodeFilter(), nodeType12.toInstructionNodeFilter(), nodeType13.toInstructionNodeFilter(), nodeType14.toInstructionNodeFilter(), nodeType15.toInstructionNodeFilter(), nodeType16.toInstructionNodeFilter(), instructionsGenerator)


@SuppressFBWarnings("RCN_REDUNDANT_NULLCHECK_OF_NONNULL_VALUE", "UJM_UNJITABLE_METHOD")
fun  MethodNode.replaceInstructions(filter1: InstructionNodeFilter, filter2: InstructionNodeFilter, filter3: InstructionNodeFilter, filter4: InstructionNodeFilter, filter5: InstructionNodeFilter, filter6: InstructionNodeFilter, filter7: InstructionNodeFilter, filter8: InstructionNodeFilter, filter9: InstructionNodeFilter, filter10: InstructionNodeFilter, filter11: InstructionNodeFilter, filter12: InstructionNodeFilter, filter13: InstructionNodeFilter, filter14: InstructionNodeFilter, filter15: InstructionNodeFilter, filter16: InstructionNodeFilter, filter17: InstructionNodeFilter, instructionsGenerator: (node1: T1, node2: T2, node3: T3, node4: T4, node5: T5, node6: T6, node7: T7, node8: T8, node9: T9, node10: T10, node11: T11, node12: T12, node13: T13, node14: T14, node15: T15, node16: T16, node17: T17) -> InsnList): Boolean {
    val instructions = this.instructions ?: return false
    if (instructions.size() < 17) return false

    val unusedLabelNodes = this.unusedLabelNodes
    if (instructions.size() - unusedLabelNodes.size < 17) return false

    fun canBeUsed(node: AbstractInsnNode) = node !is LineNumberNode && node !in unusedLabelNodes

    var node1: T1? = null
    var node2: T2? = null
    var node3: T3? = null
    var node4: T4? = null
    var node5: T5? = null
    var node6: T6? = null
    var node7: T7? = null
    var node8: T8? = null
    var node9: T9? = null
    var node10: T10? = null
    var node11: T11? = null
    var node12: T12? = null
    var node13: T13? = null
    var node14: T14? = null
    var node15: T15? = null
    var node16: T16? = null
    var node17: T17? = null

    fun reset() {
        node1 = null
        node2 = null
        node3 = null
        node4 = null
        node5 = null
        node6 = null
        node7 = null
        node8 = null
        node9 = null
        node10 = null
        node11 = null
        node12 = null
        node13 = null
        node14 = null
        node15 = null
        node16 = null
        node17 = null
    }

    var curNode: AbstractInsnNode? = instructions.first ?: return false
    var isSomethingChanged = false
    while (curNode != null) {
        val node: AbstractInsnNode = curNode
        var nextNode: AbstractInsnNode? = node.next
        run {
            if (!canBeUsed(node)) return@run
            if (null == node1) {
                if (!filter1.nodeType.isInstance(node)) return@run reset()
                filter1.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node1 = node.uncheckedCast()
            } else if (null == node2) {
                if (!filter2.nodeType.isInstance(node)) return@run reset()
                filter2.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node2 = node.uncheckedCast()
            } else if (null == node3) {
                if (!filter3.nodeType.isInstance(node)) return@run reset()
                filter3.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node3 = node.uncheckedCast()
            } else if (null == node4) {
                if (!filter4.nodeType.isInstance(node)) return@run reset()
                filter4.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node4 = node.uncheckedCast()
            } else if (null == node5) {
                if (!filter5.nodeType.isInstance(node)) return@run reset()
                filter5.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node5 = node.uncheckedCast()
            } else if (null == node6) {
                if (!filter6.nodeType.isInstance(node)) return@run reset()
                filter6.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node6 = node.uncheckedCast()
            } else if (null == node7) {
                if (!filter7.nodeType.isInstance(node)) return@run reset()
                filter7.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node7 = node.uncheckedCast()
            } else if (null == node8) {
                if (!filter8.nodeType.isInstance(node)) return@run reset()
                filter8.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node8 = node.uncheckedCast()
            } else if (null == node9) {
                if (!filter9.nodeType.isInstance(node)) return@run reset()
                filter9.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node9 = node.uncheckedCast()
            } else if (null == node10) {
                if (!filter10.nodeType.isInstance(node)) return@run reset()
                filter10.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node10 = node.uncheckedCast()
            } else if (null == node11) {
                if (!filter11.nodeType.isInstance(node)) return@run reset()
                filter11.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node11 = node.uncheckedCast()
            } else if (null == node12) {
                if (!filter12.nodeType.isInstance(node)) return@run reset()
                filter12.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node12 = node.uncheckedCast()
            } else if (null == node13) {
                if (!filter13.nodeType.isInstance(node)) return@run reset()
                filter13.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node13 = node.uncheckedCast()
            } else if (null == node14) {
                if (!filter14.nodeType.isInstance(node)) return@run reset()
                filter14.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node14 = node.uncheckedCast()
            } else if (null == node15) {
                if (!filter15.nodeType.isInstance(node)) return@run reset()
                filter15.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node15 = node.uncheckedCast()
            } else if (null == node16) {
                if (!filter16.nodeType.isInstance(node)) return@run reset()
                filter16.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node16 = node.uncheckedCast()
            } else if (null == node17) {
                if (!filter17.nodeType.isInstance(node)) return@run reset()
                filter17.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node17 = node.uncheckedCast()

                nextNode = node17!!.next
                val newInstructions = instructionsGenerator(node1!!, node2!!, node3!!, node4!!, node5!!, node6!!, node7!!, node8!!, node9!!, node10!!, node11!!, node12!!, node13!!, node14!!, node15!!, node16!!, node17!!)
                if (1 <= newInstructions.size()) {
                    if (newInstructions.contains(node1)) throw IllegalStateException("New instructions contain node #1")
                    if (newInstructions.contains(node2)) throw IllegalStateException("New instructions contain node #2")
                    if (newInstructions.contains(node3)) throw IllegalStateException("New instructions contain node #3")
                    if (newInstructions.contains(node4)) throw IllegalStateException("New instructions contain node #4")
                    if (newInstructions.contains(node5)) throw IllegalStateException("New instructions contain node #5")
                    if (newInstructions.contains(node6)) throw IllegalStateException("New instructions contain node #6")
                    if (newInstructions.contains(node7)) throw IllegalStateException("New instructions contain node #7")
                    if (newInstructions.contains(node8)) throw IllegalStateException("New instructions contain node #8")
                    if (newInstructions.contains(node9)) throw IllegalStateException("New instructions contain node #9")
                    if (newInstructions.contains(node10)) throw IllegalStateException("New instructions contain node #10")
                    if (newInstructions.contains(node11)) throw IllegalStateException("New instructions contain node #11")
                    if (newInstructions.contains(node12)) throw IllegalStateException("New instructions contain node #12")
                    if (newInstructions.contains(node13)) throw IllegalStateException("New instructions contain node #13")
                    if (newInstructions.contains(node14)) throw IllegalStateException("New instructions contain node #14")
                    if (newInstructions.contains(node15)) throw IllegalStateException("New instructions contain node #15")
                    if (newInstructions.contains(node16)) throw IllegalStateException("New instructions contain node #16")
                    if (newInstructions.contains(node17)) throw IllegalStateException("New instructions contain node #17")
                    instructions.insert(node17, newInstructions)
                }
                var nodeToDelete: AbstractInsnNode = node1!!
                while (true) {
                    val next = nodeToDelete.next ?: break
                    instructions.remove(nodeToDelete)
                    if (nodeToDelete === node17) break
                    nodeToDelete = next
                }
                isSomethingChanged = true
                reset()
            }
        }
        curNode = nextNode
    }
    return isSomethingChanged
}

fun  MethodNode.replaceInstructions(nodeType1: Class, nodeType2: Class, nodeType3: Class, nodeType4: Class, nodeType5: Class, nodeType6: Class, nodeType7: Class, nodeType8: Class, nodeType9: Class, nodeType10: Class, nodeType11: Class, nodeType12: Class, nodeType13: Class, nodeType14: Class, nodeType15: Class, nodeType16: Class, nodeType17: Class, instructionsGenerator: (node1: T1, node2: T2, node3: T3, node4: T4, node5: T5, node6: T6, node7: T7, node8: T8, node9: T9, node10: T10, node11: T11, node12: T12, node13: T13, node14: T14, node15: T15, node16: T16, node17: T17) -> InsnList) = replaceInstructions(nodeType1.toInstructionNodeFilter(), nodeType2.toInstructionNodeFilter(), nodeType3.toInstructionNodeFilter(), nodeType4.toInstructionNodeFilter(), nodeType5.toInstructionNodeFilter(), nodeType6.toInstructionNodeFilter(), nodeType7.toInstructionNodeFilter(), nodeType8.toInstructionNodeFilter(), nodeType9.toInstructionNodeFilter(), nodeType10.toInstructionNodeFilter(), nodeType11.toInstructionNodeFilter(), nodeType12.toInstructionNodeFilter(), nodeType13.toInstructionNodeFilter(), nodeType14.toInstructionNodeFilter(), nodeType15.toInstructionNodeFilter(), nodeType16.toInstructionNodeFilter(), nodeType17.toInstructionNodeFilter(), instructionsGenerator)


@SuppressFBWarnings("RCN_REDUNDANT_NULLCHECK_OF_NONNULL_VALUE", "UJM_UNJITABLE_METHOD")
fun  MethodNode.replaceInstructions(filter1: InstructionNodeFilter, filter2: InstructionNodeFilter, filter3: InstructionNodeFilter, filter4: InstructionNodeFilter, filter5: InstructionNodeFilter, filter6: InstructionNodeFilter, filter7: InstructionNodeFilter, filter8: InstructionNodeFilter, filter9: InstructionNodeFilter, filter10: InstructionNodeFilter, filter11: InstructionNodeFilter, filter12: InstructionNodeFilter, filter13: InstructionNodeFilter, filter14: InstructionNodeFilter, filter15: InstructionNodeFilter, filter16: InstructionNodeFilter, filter17: InstructionNodeFilter, filter18: InstructionNodeFilter, instructionsGenerator: (node1: T1, node2: T2, node3: T3, node4: T4, node5: T5, node6: T6, node7: T7, node8: T8, node9: T9, node10: T10, node11: T11, node12: T12, node13: T13, node14: T14, node15: T15, node16: T16, node17: T17, node18: T18) -> InsnList): Boolean {
    val instructions = this.instructions ?: return false
    if (instructions.size() < 18) return false

    val unusedLabelNodes = this.unusedLabelNodes
    if (instructions.size() - unusedLabelNodes.size < 18) return false

    fun canBeUsed(node: AbstractInsnNode) = node !is LineNumberNode && node !in unusedLabelNodes

    var node1: T1? = null
    var node2: T2? = null
    var node3: T3? = null
    var node4: T4? = null
    var node5: T5? = null
    var node6: T6? = null
    var node7: T7? = null
    var node8: T8? = null
    var node9: T9? = null
    var node10: T10? = null
    var node11: T11? = null
    var node12: T12? = null
    var node13: T13? = null
    var node14: T14? = null
    var node15: T15? = null
    var node16: T16? = null
    var node17: T17? = null
    var node18: T18? = null

    fun reset() {
        node1 = null
        node2 = null
        node3 = null
        node4 = null
        node5 = null
        node6 = null
        node7 = null
        node8 = null
        node9 = null
        node10 = null
        node11 = null
        node12 = null
        node13 = null
        node14 = null
        node15 = null
        node16 = null
        node17 = null
        node18 = null
    }

    var curNode: AbstractInsnNode? = instructions.first ?: return false
    var isSomethingChanged = false
    while (curNode != null) {
        val node: AbstractInsnNode = curNode
        var nextNode: AbstractInsnNode? = node.next
        run {
            if (!canBeUsed(node)) return@run
            if (null == node1) {
                if (!filter1.nodeType.isInstance(node)) return@run reset()
                filter1.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node1 = node.uncheckedCast()
            } else if (null == node2) {
                if (!filter2.nodeType.isInstance(node)) return@run reset()
                filter2.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node2 = node.uncheckedCast()
            } else if (null == node3) {
                if (!filter3.nodeType.isInstance(node)) return@run reset()
                filter3.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node3 = node.uncheckedCast()
            } else if (null == node4) {
                if (!filter4.nodeType.isInstance(node)) return@run reset()
                filter4.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node4 = node.uncheckedCast()
            } else if (null == node5) {
                if (!filter5.nodeType.isInstance(node)) return@run reset()
                filter5.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node5 = node.uncheckedCast()
            } else if (null == node6) {
                if (!filter6.nodeType.isInstance(node)) return@run reset()
                filter6.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node6 = node.uncheckedCast()
            } else if (null == node7) {
                if (!filter7.nodeType.isInstance(node)) return@run reset()
                filter7.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node7 = node.uncheckedCast()
            } else if (null == node8) {
                if (!filter8.nodeType.isInstance(node)) return@run reset()
                filter8.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node8 = node.uncheckedCast()
            } else if (null == node9) {
                if (!filter9.nodeType.isInstance(node)) return@run reset()
                filter9.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node9 = node.uncheckedCast()
            } else if (null == node10) {
                if (!filter10.nodeType.isInstance(node)) return@run reset()
                filter10.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node10 = node.uncheckedCast()
            } else if (null == node11) {
                if (!filter11.nodeType.isInstance(node)) return@run reset()
                filter11.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node11 = node.uncheckedCast()
            } else if (null == node12) {
                if (!filter12.nodeType.isInstance(node)) return@run reset()
                filter12.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node12 = node.uncheckedCast()
            } else if (null == node13) {
                if (!filter13.nodeType.isInstance(node)) return@run reset()
                filter13.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node13 = node.uncheckedCast()
            } else if (null == node14) {
                if (!filter14.nodeType.isInstance(node)) return@run reset()
                filter14.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node14 = node.uncheckedCast()
            } else if (null == node15) {
                if (!filter15.nodeType.isInstance(node)) return@run reset()
                filter15.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node15 = node.uncheckedCast()
            } else if (null == node16) {
                if (!filter16.nodeType.isInstance(node)) return@run reset()
                filter16.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node16 = node.uncheckedCast()
            } else if (null == node17) {
                if (!filter17.nodeType.isInstance(node)) return@run reset()
                filter17.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node17 = node.uncheckedCast()
            } else if (null == node18) {
                if (!filter18.nodeType.isInstance(node)) return@run reset()
                filter18.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node18 = node.uncheckedCast()

                nextNode = node18!!.next
                val newInstructions = instructionsGenerator(node1!!, node2!!, node3!!, node4!!, node5!!, node6!!, node7!!, node8!!, node9!!, node10!!, node11!!, node12!!, node13!!, node14!!, node15!!, node16!!, node17!!, node18!!)
                if (1 <= newInstructions.size()) {
                    if (newInstructions.contains(node1)) throw IllegalStateException("New instructions contain node #1")
                    if (newInstructions.contains(node2)) throw IllegalStateException("New instructions contain node #2")
                    if (newInstructions.contains(node3)) throw IllegalStateException("New instructions contain node #3")
                    if (newInstructions.contains(node4)) throw IllegalStateException("New instructions contain node #4")
                    if (newInstructions.contains(node5)) throw IllegalStateException("New instructions contain node #5")
                    if (newInstructions.contains(node6)) throw IllegalStateException("New instructions contain node #6")
                    if (newInstructions.contains(node7)) throw IllegalStateException("New instructions contain node #7")
                    if (newInstructions.contains(node8)) throw IllegalStateException("New instructions contain node #8")
                    if (newInstructions.contains(node9)) throw IllegalStateException("New instructions contain node #9")
                    if (newInstructions.contains(node10)) throw IllegalStateException("New instructions contain node #10")
                    if (newInstructions.contains(node11)) throw IllegalStateException("New instructions contain node #11")
                    if (newInstructions.contains(node12)) throw IllegalStateException("New instructions contain node #12")
                    if (newInstructions.contains(node13)) throw IllegalStateException("New instructions contain node #13")
                    if (newInstructions.contains(node14)) throw IllegalStateException("New instructions contain node #14")
                    if (newInstructions.contains(node15)) throw IllegalStateException("New instructions contain node #15")
                    if (newInstructions.contains(node16)) throw IllegalStateException("New instructions contain node #16")
                    if (newInstructions.contains(node17)) throw IllegalStateException("New instructions contain node #17")
                    if (newInstructions.contains(node18)) throw IllegalStateException("New instructions contain node #18")
                    instructions.insert(node18, newInstructions)
                }
                var nodeToDelete: AbstractInsnNode = node1!!
                while (true) {
                    val next = nodeToDelete.next ?: break
                    instructions.remove(nodeToDelete)
                    if (nodeToDelete === node18) break
                    nodeToDelete = next
                }
                isSomethingChanged = true
                reset()
            }
        }
        curNode = nextNode
    }
    return isSomethingChanged
}

fun  MethodNode.replaceInstructions(nodeType1: Class, nodeType2: Class, nodeType3: Class, nodeType4: Class, nodeType5: Class, nodeType6: Class, nodeType7: Class, nodeType8: Class, nodeType9: Class, nodeType10: Class, nodeType11: Class, nodeType12: Class, nodeType13: Class, nodeType14: Class, nodeType15: Class, nodeType16: Class, nodeType17: Class, nodeType18: Class, instructionsGenerator: (node1: T1, node2: T2, node3: T3, node4: T4, node5: T5, node6: T6, node7: T7, node8: T8, node9: T9, node10: T10, node11: T11, node12: T12, node13: T13, node14: T14, node15: T15, node16: T16, node17: T17, node18: T18) -> InsnList) = replaceInstructions(nodeType1.toInstructionNodeFilter(), nodeType2.toInstructionNodeFilter(), nodeType3.toInstructionNodeFilter(), nodeType4.toInstructionNodeFilter(), nodeType5.toInstructionNodeFilter(), nodeType6.toInstructionNodeFilter(), nodeType7.toInstructionNodeFilter(), nodeType8.toInstructionNodeFilter(), nodeType9.toInstructionNodeFilter(), nodeType10.toInstructionNodeFilter(), nodeType11.toInstructionNodeFilter(), nodeType12.toInstructionNodeFilter(), nodeType13.toInstructionNodeFilter(), nodeType14.toInstructionNodeFilter(), nodeType15.toInstructionNodeFilter(), nodeType16.toInstructionNodeFilter(), nodeType17.toInstructionNodeFilter(), nodeType18.toInstructionNodeFilter(), instructionsGenerator)


@SuppressFBWarnings("RCN_REDUNDANT_NULLCHECK_OF_NONNULL_VALUE", "UJM_UNJITABLE_METHOD")
fun  MethodNode.replaceInstructions(filter1: InstructionNodeFilter, filter2: InstructionNodeFilter, filter3: InstructionNodeFilter, filter4: InstructionNodeFilter, filter5: InstructionNodeFilter, filter6: InstructionNodeFilter, filter7: InstructionNodeFilter, filter8: InstructionNodeFilter, filter9: InstructionNodeFilter, filter10: InstructionNodeFilter, filter11: InstructionNodeFilter, filter12: InstructionNodeFilter, filter13: InstructionNodeFilter, filter14: InstructionNodeFilter, filter15: InstructionNodeFilter, filter16: InstructionNodeFilter, filter17: InstructionNodeFilter, filter18: InstructionNodeFilter, filter19: InstructionNodeFilter, instructionsGenerator: (node1: T1, node2: T2, node3: T3, node4: T4, node5: T5, node6: T6, node7: T7, node8: T8, node9: T9, node10: T10, node11: T11, node12: T12, node13: T13, node14: T14, node15: T15, node16: T16, node17: T17, node18: T18, node19: T19) -> InsnList): Boolean {
    val instructions = this.instructions ?: return false
    if (instructions.size() < 19) return false

    val unusedLabelNodes = this.unusedLabelNodes
    if (instructions.size() - unusedLabelNodes.size < 19) return false

    fun canBeUsed(node: AbstractInsnNode) = node !is LineNumberNode && node !in unusedLabelNodes

    var node1: T1? = null
    var node2: T2? = null
    var node3: T3? = null
    var node4: T4? = null
    var node5: T5? = null
    var node6: T6? = null
    var node7: T7? = null
    var node8: T8? = null
    var node9: T9? = null
    var node10: T10? = null
    var node11: T11? = null
    var node12: T12? = null
    var node13: T13? = null
    var node14: T14? = null
    var node15: T15? = null
    var node16: T16? = null
    var node17: T17? = null
    var node18: T18? = null
    var node19: T19? = null

    fun reset() {
        node1 = null
        node2 = null
        node3 = null
        node4 = null
        node5 = null
        node6 = null
        node7 = null
        node8 = null
        node9 = null
        node10 = null
        node11 = null
        node12 = null
        node13 = null
        node14 = null
        node15 = null
        node16 = null
        node17 = null
        node18 = null
        node19 = null
    }

    var curNode: AbstractInsnNode? = instructions.first ?: return false
    var isSomethingChanged = false
    while (curNode != null) {
        val node: AbstractInsnNode = curNode
        var nextNode: AbstractInsnNode? = node.next
        run {
            if (!canBeUsed(node)) return@run
            if (null == node1) {
                if (!filter1.nodeType.isInstance(node)) return@run reset()
                filter1.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node1 = node.uncheckedCast()
            } else if (null == node2) {
                if (!filter2.nodeType.isInstance(node)) return@run reset()
                filter2.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node2 = node.uncheckedCast()
            } else if (null == node3) {
                if (!filter3.nodeType.isInstance(node)) return@run reset()
                filter3.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node3 = node.uncheckedCast()
            } else if (null == node4) {
                if (!filter4.nodeType.isInstance(node)) return@run reset()
                filter4.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node4 = node.uncheckedCast()
            } else if (null == node5) {
                if (!filter5.nodeType.isInstance(node)) return@run reset()
                filter5.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node5 = node.uncheckedCast()
            } else if (null == node6) {
                if (!filter6.nodeType.isInstance(node)) return@run reset()
                filter6.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node6 = node.uncheckedCast()
            } else if (null == node7) {
                if (!filter7.nodeType.isInstance(node)) return@run reset()
                filter7.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node7 = node.uncheckedCast()
            } else if (null == node8) {
                if (!filter8.nodeType.isInstance(node)) return@run reset()
                filter8.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node8 = node.uncheckedCast()
            } else if (null == node9) {
                if (!filter9.nodeType.isInstance(node)) return@run reset()
                filter9.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node9 = node.uncheckedCast()
            } else if (null == node10) {
                if (!filter10.nodeType.isInstance(node)) return@run reset()
                filter10.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node10 = node.uncheckedCast()
            } else if (null == node11) {
                if (!filter11.nodeType.isInstance(node)) return@run reset()
                filter11.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node11 = node.uncheckedCast()
            } else if (null == node12) {
                if (!filter12.nodeType.isInstance(node)) return@run reset()
                filter12.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node12 = node.uncheckedCast()
            } else if (null == node13) {
                if (!filter13.nodeType.isInstance(node)) return@run reset()
                filter13.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node13 = node.uncheckedCast()
            } else if (null == node14) {
                if (!filter14.nodeType.isInstance(node)) return@run reset()
                filter14.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node14 = node.uncheckedCast()
            } else if (null == node15) {
                if (!filter15.nodeType.isInstance(node)) return@run reset()
                filter15.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node15 = node.uncheckedCast()
            } else if (null == node16) {
                if (!filter16.nodeType.isInstance(node)) return@run reset()
                filter16.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node16 = node.uncheckedCast()
            } else if (null == node17) {
                if (!filter17.nodeType.isInstance(node)) return@run reset()
                filter17.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node17 = node.uncheckedCast()
            } else if (null == node18) {
                if (!filter18.nodeType.isInstance(node)) return@run reset()
                filter18.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node18 = node.uncheckedCast()
            } else if (null == node19) {
                if (!filter19.nodeType.isInstance(node)) return@run reset()
                filter19.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node19 = node.uncheckedCast()

                nextNode = node19!!.next
                val newInstructions = instructionsGenerator(node1!!, node2!!, node3!!, node4!!, node5!!, node6!!, node7!!, node8!!, node9!!, node10!!, node11!!, node12!!, node13!!, node14!!, node15!!, node16!!, node17!!, node18!!, node19!!)
                if (1 <= newInstructions.size()) {
                    if (newInstructions.contains(node1)) throw IllegalStateException("New instructions contain node #1")
                    if (newInstructions.contains(node2)) throw IllegalStateException("New instructions contain node #2")
                    if (newInstructions.contains(node3)) throw IllegalStateException("New instructions contain node #3")
                    if (newInstructions.contains(node4)) throw IllegalStateException("New instructions contain node #4")
                    if (newInstructions.contains(node5)) throw IllegalStateException("New instructions contain node #5")
                    if (newInstructions.contains(node6)) throw IllegalStateException("New instructions contain node #6")
                    if (newInstructions.contains(node7)) throw IllegalStateException("New instructions contain node #7")
                    if (newInstructions.contains(node8)) throw IllegalStateException("New instructions contain node #8")
                    if (newInstructions.contains(node9)) throw IllegalStateException("New instructions contain node #9")
                    if (newInstructions.contains(node10)) throw IllegalStateException("New instructions contain node #10")
                    if (newInstructions.contains(node11)) throw IllegalStateException("New instructions contain node #11")
                    if (newInstructions.contains(node12)) throw IllegalStateException("New instructions contain node #12")
                    if (newInstructions.contains(node13)) throw IllegalStateException("New instructions contain node #13")
                    if (newInstructions.contains(node14)) throw IllegalStateException("New instructions contain node #14")
                    if (newInstructions.contains(node15)) throw IllegalStateException("New instructions contain node #15")
                    if (newInstructions.contains(node16)) throw IllegalStateException("New instructions contain node #16")
                    if (newInstructions.contains(node17)) throw IllegalStateException("New instructions contain node #17")
                    if (newInstructions.contains(node18)) throw IllegalStateException("New instructions contain node #18")
                    if (newInstructions.contains(node19)) throw IllegalStateException("New instructions contain node #19")
                    instructions.insert(node19, newInstructions)
                }
                var nodeToDelete: AbstractInsnNode = node1!!
                while (true) {
                    val next = nodeToDelete.next ?: break
                    instructions.remove(nodeToDelete)
                    if (nodeToDelete === node19) break
                    nodeToDelete = next
                }
                isSomethingChanged = true
                reset()
            }
        }
        curNode = nextNode
    }
    return isSomethingChanged
}

fun  MethodNode.replaceInstructions(nodeType1: Class, nodeType2: Class, nodeType3: Class, nodeType4: Class, nodeType5: Class, nodeType6: Class, nodeType7: Class, nodeType8: Class, nodeType9: Class, nodeType10: Class, nodeType11: Class, nodeType12: Class, nodeType13: Class, nodeType14: Class, nodeType15: Class, nodeType16: Class, nodeType17: Class, nodeType18: Class, nodeType19: Class, instructionsGenerator: (node1: T1, node2: T2, node3: T3, node4: T4, node5: T5, node6: T6, node7: T7, node8: T8, node9: T9, node10: T10, node11: T11, node12: T12, node13: T13, node14: T14, node15: T15, node16: T16, node17: T17, node18: T18, node19: T19) -> InsnList) = replaceInstructions(nodeType1.toInstructionNodeFilter(), nodeType2.toInstructionNodeFilter(), nodeType3.toInstructionNodeFilter(), nodeType4.toInstructionNodeFilter(), nodeType5.toInstructionNodeFilter(), nodeType6.toInstructionNodeFilter(), nodeType7.toInstructionNodeFilter(), nodeType8.toInstructionNodeFilter(), nodeType9.toInstructionNodeFilter(), nodeType10.toInstructionNodeFilter(), nodeType11.toInstructionNodeFilter(), nodeType12.toInstructionNodeFilter(), nodeType13.toInstructionNodeFilter(), nodeType14.toInstructionNodeFilter(), nodeType15.toInstructionNodeFilter(), nodeType16.toInstructionNodeFilter(), nodeType17.toInstructionNodeFilter(), nodeType18.toInstructionNodeFilter(), nodeType19.toInstructionNodeFilter(), instructionsGenerator)


@SuppressFBWarnings("RCN_REDUNDANT_NULLCHECK_OF_NONNULL_VALUE", "UJM_UNJITABLE_METHOD")
fun  MethodNode.replaceInstructions(filter1: InstructionNodeFilter, filter2: InstructionNodeFilter, filter3: InstructionNodeFilter, filter4: InstructionNodeFilter, filter5: InstructionNodeFilter, filter6: InstructionNodeFilter, filter7: InstructionNodeFilter, filter8: InstructionNodeFilter, filter9: InstructionNodeFilter, filter10: InstructionNodeFilter, filter11: InstructionNodeFilter, filter12: InstructionNodeFilter, filter13: InstructionNodeFilter, filter14: InstructionNodeFilter, filter15: InstructionNodeFilter, filter16: InstructionNodeFilter, filter17: InstructionNodeFilter, filter18: InstructionNodeFilter, filter19: InstructionNodeFilter, filter20: InstructionNodeFilter, instructionsGenerator: (node1: T1, node2: T2, node3: T3, node4: T4, node5: T5, node6: T6, node7: T7, node8: T8, node9: T9, node10: T10, node11: T11, node12: T12, node13: T13, node14: T14, node15: T15, node16: T16, node17: T17, node18: T18, node19: T19, node20: T20) -> InsnList): Boolean {
    val instructions = this.instructions ?: return false
    if (instructions.size() < 20) return false

    val unusedLabelNodes = this.unusedLabelNodes
    if (instructions.size() - unusedLabelNodes.size < 20) return false

    fun canBeUsed(node: AbstractInsnNode) = node !is LineNumberNode && node !in unusedLabelNodes

    var node1: T1? = null
    var node2: T2? = null
    var node3: T3? = null
    var node4: T4? = null
    var node5: T5? = null
    var node6: T6? = null
    var node7: T7? = null
    var node8: T8? = null
    var node9: T9? = null
    var node10: T10? = null
    var node11: T11? = null
    var node12: T12? = null
    var node13: T13? = null
    var node14: T14? = null
    var node15: T15? = null
    var node16: T16? = null
    var node17: T17? = null
    var node18: T18? = null
    var node19: T19? = null
    var node20: T20? = null

    fun reset() {
        node1 = null
        node2 = null
        node3 = null
        node4 = null
        node5 = null
        node6 = null
        node7 = null
        node8 = null
        node9 = null
        node10 = null
        node11 = null
        node12 = null
        node13 = null
        node14 = null
        node15 = null
        node16 = null
        node17 = null
        node18 = null
        node19 = null
        node20 = null
    }

    var curNode: AbstractInsnNode? = instructions.first ?: return false
    var isSomethingChanged = false
    while (curNode != null) {
        val node: AbstractInsnNode = curNode
        var nextNode: AbstractInsnNode? = node.next
        run {
            if (!canBeUsed(node)) return@run
            if (null == node1) {
                if (!filter1.nodeType.isInstance(node)) return@run reset()
                filter1.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node1 = node.uncheckedCast()
            } else if (null == node2) {
                if (!filter2.nodeType.isInstance(node)) return@run reset()
                filter2.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node2 = node.uncheckedCast()
            } else if (null == node3) {
                if (!filter3.nodeType.isInstance(node)) return@run reset()
                filter3.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node3 = node.uncheckedCast()
            } else if (null == node4) {
                if (!filter4.nodeType.isInstance(node)) return@run reset()
                filter4.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node4 = node.uncheckedCast()
            } else if (null == node5) {
                if (!filter5.nodeType.isInstance(node)) return@run reset()
                filter5.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node5 = node.uncheckedCast()
            } else if (null == node6) {
                if (!filter6.nodeType.isInstance(node)) return@run reset()
                filter6.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node6 = node.uncheckedCast()
            } else if (null == node7) {
                if (!filter7.nodeType.isInstance(node)) return@run reset()
                filter7.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node7 = node.uncheckedCast()
            } else if (null == node8) {
                if (!filter8.nodeType.isInstance(node)) return@run reset()
                filter8.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node8 = node.uncheckedCast()
            } else if (null == node9) {
                if (!filter9.nodeType.isInstance(node)) return@run reset()
                filter9.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node9 = node.uncheckedCast()
            } else if (null == node10) {
                if (!filter10.nodeType.isInstance(node)) return@run reset()
                filter10.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node10 = node.uncheckedCast()
            } else if (null == node11) {
                if (!filter11.nodeType.isInstance(node)) return@run reset()
                filter11.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node11 = node.uncheckedCast()
            } else if (null == node12) {
                if (!filter12.nodeType.isInstance(node)) return@run reset()
                filter12.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node12 = node.uncheckedCast()
            } else if (null == node13) {
                if (!filter13.nodeType.isInstance(node)) return@run reset()
                filter13.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node13 = node.uncheckedCast()
            } else if (null == node14) {
                if (!filter14.nodeType.isInstance(node)) return@run reset()
                filter14.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node14 = node.uncheckedCast()
            } else if (null == node15) {
                if (!filter15.nodeType.isInstance(node)) return@run reset()
                filter15.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node15 = node.uncheckedCast()
            } else if (null == node16) {
                if (!filter16.nodeType.isInstance(node)) return@run reset()
                filter16.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node16 = node.uncheckedCast()
            } else if (null == node17) {
                if (!filter17.nodeType.isInstance(node)) return@run reset()
                filter17.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node17 = node.uncheckedCast()
            } else if (null == node18) {
                if (!filter18.nodeType.isInstance(node)) return@run reset()
                filter18.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node18 = node.uncheckedCast()
            } else if (null == node19) {
                if (!filter19.nodeType.isInstance(node)) return@run reset()
                filter19.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node19 = node.uncheckedCast()
            } else if (null == node20) {
                if (!filter20.nodeType.isInstance(node)) return@run reset()
                filter20.predicate.let { if (it != null && !it(InstructionNodeContext(node.uncheckedCast(), node.getPrevious(::canBeUsed), node.getNext(::canBeUsed)))) return@run reset() }
                node20 = node.uncheckedCast()

                nextNode = node20!!.next
                val newInstructions = instructionsGenerator(node1!!, node2!!, node3!!, node4!!, node5!!, node6!!, node7!!, node8!!, node9!!, node10!!, node11!!, node12!!, node13!!, node14!!, node15!!, node16!!, node17!!, node18!!, node19!!, node20!!)
                if (1 <= newInstructions.size()) {
                    if (newInstructions.contains(node1)) throw IllegalStateException("New instructions contain node #1")
                    if (newInstructions.contains(node2)) throw IllegalStateException("New instructions contain node #2")
                    if (newInstructions.contains(node3)) throw IllegalStateException("New instructions contain node #3")
                    if (newInstructions.contains(node4)) throw IllegalStateException("New instructions contain node #4")
                    if (newInstructions.contains(node5)) throw IllegalStateException("New instructions contain node #5")
                    if (newInstructions.contains(node6)) throw IllegalStateException("New instructions contain node #6")
                    if (newInstructions.contains(node7)) throw IllegalStateException("New instructions contain node #7")
                    if (newInstructions.contains(node8)) throw IllegalStateException("New instructions contain node #8")
                    if (newInstructions.contains(node9)) throw IllegalStateException("New instructions contain node #9")
                    if (newInstructions.contains(node10)) throw IllegalStateException("New instructions contain node #10")
                    if (newInstructions.contains(node11)) throw IllegalStateException("New instructions contain node #11")
                    if (newInstructions.contains(node12)) throw IllegalStateException("New instructions contain node #12")
                    if (newInstructions.contains(node13)) throw IllegalStateException("New instructions contain node #13")
                    if (newInstructions.contains(node14)) throw IllegalStateException("New instructions contain node #14")
                    if (newInstructions.contains(node15)) throw IllegalStateException("New instructions contain node #15")
                    if (newInstructions.contains(node16)) throw IllegalStateException("New instructions contain node #16")
                    if (newInstructions.contains(node17)) throw IllegalStateException("New instructions contain node #17")
                    if (newInstructions.contains(node18)) throw IllegalStateException("New instructions contain node #18")
                    if (newInstructions.contains(node19)) throw IllegalStateException("New instructions contain node #19")
                    if (newInstructions.contains(node20)) throw IllegalStateException("New instructions contain node #20")
                    instructions.insert(node20, newInstructions)
                }
                var nodeToDelete: AbstractInsnNode = node1!!
                while (true) {
                    val next = nodeToDelete.next ?: break
                    instructions.remove(nodeToDelete)
                    if (nodeToDelete === node20) break
                    nodeToDelete = next
                }
                isSomethingChanged = true
                reset()
            }
        }
        curNode = nextNode
    }
    return isSomethingChanged
}

fun  MethodNode.replaceInstructions(nodeType1: Class, nodeType2: Class, nodeType3: Class, nodeType4: Class, nodeType5: Class, nodeType6: Class, nodeType7: Class, nodeType8: Class, nodeType9: Class, nodeType10: Class, nodeType11: Class, nodeType12: Class, nodeType13: Class, nodeType14: Class, nodeType15: Class, nodeType16: Class, nodeType17: Class, nodeType18: Class, nodeType19: Class, nodeType20: Class, instructionsGenerator: (node1: T1, node2: T2, node3: T3, node4: T4, node5: T5, node6: T6, node7: T7, node8: T8, node9: T9, node10: T10, node11: T11, node12: T12, node13: T13, node14: T14, node15: T15, node16: T16, node17: T17, node18: T18, node19: T19, node20: T20) -> InsnList) = replaceInstructions(nodeType1.toInstructionNodeFilter(), nodeType2.toInstructionNodeFilter(), nodeType3.toInstructionNodeFilter(), nodeType4.toInstructionNodeFilter(), nodeType5.toInstructionNodeFilter(), nodeType6.toInstructionNodeFilter(), nodeType7.toInstructionNodeFilter(), nodeType8.toInstructionNodeFilter(), nodeType9.toInstructionNodeFilter(), nodeType10.toInstructionNodeFilter(), nodeType11.toInstructionNodeFilter(), nodeType12.toInstructionNodeFilter(), nodeType13.toInstructionNodeFilter(), nodeType14.toInstructionNodeFilter(), nodeType15.toInstructionNodeFilter(), nodeType16.toInstructionNodeFilter(), nodeType17.toInstructionNodeFilter(), nodeType18.toInstructionNodeFilter(), nodeType19.toInstructionNodeFilter(), nodeType20.toInstructionNodeFilter(), instructionsGenerator)





© 2015 - 2025 Weber Informatics LLC | Privacy Policy