Example usage for org.objectweb.asm.tree InsnList iterator

List of usage examples for org.objectweb.asm.tree InsnList iterator

Introduction

In this page you can find the example usage for org.objectweb.asm.tree InsnList iterator.

Prototype

@Override
public ListIterator<AbstractInsnNode> iterator() 

Source Link

Document

Returns an iterator over the instructions in this list.

Usage

From source file:org.brutusin.instrumentation.Instrumentator.java

License:Apache License

private void addTraceThrow() {

    InsnList il = this.mn.instructions;

    Iterator<AbstractInsnNode> it = il.iterator();
    while (it.hasNext()) {
        AbstractInsnNode abstractInsnNode = it.next();

        switch (abstractInsnNode.getOpcode()) {
        case Opcodes.ATHROW:
            il.insertBefore(abstractInsnNode, getThrowTraceInstructions());
            break;
        }//from   w  w  w .j a  v a  2 s. com
    }

}

From source file:org.coldswap.asm.field.PrivateStaticFieldReplacer.java

License:Open Source License

/**
 * Removes any initializing reference of the field.
 *
 * @param classNode containing the old class.
 * @param fieldNode containing the old field.
 * @return the initializing list of instructions.
 *///w  w  w.  ja  v a  2 s  .c o m
@SuppressWarnings("unchecked")
private InsnList cleanClInit(ClassNode classNode, FieldNode fieldNode) {
    List<MethodNode> methodNodes = classNode.methods;
    AbstractInsnNode firstInst = null;
    int counter = 0;
    for (MethodNode methodNode : methodNodes) {
        if (methodNode.name.equals("<clinit>")) {
            // search for PUTSTATIC
            InsnList insnList = methodNode.instructions;
            Iterator iterator1 = insnList.iterator();
            while (iterator1.hasNext()) {
                AbstractInsnNode ins2 = (AbstractInsnNode) iterator1.next();
                // if a initializing has been found, then copy everything from
                // the corresponding label to the PUTSTATIC
                if (ins2.getOpcode() == Opcodes.PUTSTATIC) {
                    final Boolean[] fieldFound = { false };
                    final FieldNode fNode = fieldNode;
                    ins2.accept(new MethodVisitor(Opcodes.ASM5) {
                        @Override
                        public void visitFieldInsn(int i, String s, String s2, String s3) {
                            if (s2.equals(fNode.name)) {
                                fieldFound[0] = true;
                            }
                            super.visitFieldInsn(i, s, s2, s3);
                        }
                    });
                    if (fieldFound[0]) {
                        // find the first PUTSTATIC before this one.
                        boolean staticFound = false;
                        while (!staticFound) {
                            AbstractInsnNode tmpInst = ins2.getPrevious();
                            if (tmpInst != null) {
                                if (tmpInst.getOpcode() != Opcodes.F_NEW) {
                                    if (tmpInst.getOpcode() == Opcodes.PUTSTATIC) {
                                        staticFound = true;
                                    } else {
                                        firstInst = tmpInst;
                                        counter++;
                                    }
                                }
                            } else {
                                staticFound = true;
                            }
                            ins2 = tmpInst;
                        }

                        break;
                    }
                }
            }

            if (firstInst != null) {
                InsnList iList = new InsnList();
                iList.add(firstInst.clone(null));
                counter--;
                while (counter > 0) {
                    AbstractInsnNode ain = firstInst.getNext();
                    iList.add(ain.clone(null));
                    counter--;
                    insnList.remove(firstInst);
                    firstInst = ain;
                }
                // remove last instruction and the putstatic instruction
                AbstractInsnNode putStatic = firstInst.getNext();
                insnList.remove(firstInst);
                insnList.remove(putStatic);
                return iList;
            }
        }
    }
    return null;
}

From source file:org.coldswap.asm.field.PrivateStaticFieldReplacer.java

License:Open Source License

/**
 * Replaces any GETSTATIC/PUTSTATIC call of the field in the old class with the field
 * introduced in the new class./*from w  ww  . j a  v a  2s .  co  m*/
 *
 * @param classNode containing the old class.
 * @param fieldNode containing the old field.
 */
@SuppressWarnings("unchecked")
private void replaceReferences(ClassNode classNode, FieldNode fieldNode) {
    List<MethodNode> methodNodes = classNode.methods;
    String contClass = classNode.name.substring(classNode.name.lastIndexOf("/") + 1);
    final String className = classPackage
            + TransformerNameGenerator.getPrivateStaticFieldClassName(contClass, fieldNode.name);
    for (MethodNode method : methodNodes) {
        InsnList inst = method.instructions;
        Iterator iter = inst.iterator();
        while (iter.hasNext()) {
            AbstractInsnNode absIns = (AbstractInsnNode) iter.next();
            int opcode = absIns.getOpcode();
            // check if instruction is GETSTATIC or PUTSTATIC
            if (opcode == Opcodes.GETSTATIC) {
                // get type
                if (absIns.getType() == AbstractInsnNode.FIELD_INSN) {
                    final Boolean[] foundField = { false };
                    final ClassNode cNode = classNode;
                    final FieldNode fNode = fieldNode;
                    absIns.accept(new MethodVisitor(Opcodes.ASM5) {
                        @Override
                        public void visitFieldInsn(int i, String s, String s2, String s3) {
                            if (cNode.name.equals(s) && fNode.name.equals(s2)) {
                                foundField[0] = true;
                            }
                            super.visitFieldInsn(i, s, s2, s3);
                        }
                    });
                    if (foundField[0]) {
                        inst.set(absIns, new FieldInsnNode(Opcodes.GETSTATIC, className, fieldNode.name,
                                fieldNode.desc));
                    }
                }
            } else if (opcode == Opcodes.PUTSTATIC) {
                if (absIns.getType() == AbstractInsnNode.FIELD_INSN) {
                    final Boolean[] foundField = { false };
                    final ClassNode cNode = classNode;
                    final FieldNode fNode = fieldNode;
                    absIns.accept(new MethodVisitor(Opcodes.ASM5) {
                        @Override
                        public void visitFieldInsn(int i, String s, String s2, String s3) {
                            if (cNode.name.equals(s) && fNode.name.equals(s2)) {
                                foundField[0] = true;
                            }
                            super.visitFieldInsn(i, s, s2, s3);
                        }
                    });
                    if (foundField[0]) {
                        inst.set(absIns, new FieldInsnNode(Opcodes.PUTSTATIC, className, fieldNode.name,
                                fieldNode.desc));
                    }
                }
            }
        }
    }
}

From source file:org.coldswap.asm.field.ProtectedStaticFieldReferenceReplacer.java

License:Open Source License

@SuppressWarnings("uncheked")
@Override// ww w. jav  a  2  s  .co m
public int findAndReplace(ClassNode classNode) {
    int counter = 0;
    if (classNode.superName.equals(supperClass)) {
        List<MethodNode> methodNodes = classNode.methods;
        for (MethodNode method : methodNodes) {
            InsnList inst = method.instructions;
            Iterator iter = inst.iterator();
            while (iter.hasNext()) {
                AbstractInsnNode absIns = (AbstractInsnNode) iter.next();
                int opcode = absIns.getOpcode();
                // check if instruction is GETSTATIC or PUTSTATIC
                if (opcode == Opcodes.GETSTATIC) {
                    // get type
                    if (absIns.getType() == AbstractInsnNode.FIELD_INSN) {
                        final Boolean[] foundField = { false };
                        absIns.accept(new MethodVisitor(Opcodes.ASM5) {
                            @Override
                            public void visitFieldInsn(int i, String s, String s2, String s3) {
                                if (oldClass.equals(s) && fieldToReplace.name.equals(s2)) {
                                    foundField[0] = true;
                                }
                                super.visitFieldInsn(i, s, s2, s3);
                            }
                        });
                        if (foundField[0]) {
                            inst.set(absIns, new FieldInsnNode(Opcodes.GETSTATIC, newClass, fieldToReplace.name,
                                    fieldToReplace.desc));
                            counter++;
                        }
                    }
                } else if (opcode == Opcodes.PUTSTATIC) {
                    if (absIns.getType() == AbstractInsnNode.FIELD_INSN) {
                        final Boolean[] foundField = { false };
                        absIns.accept(new MethodVisitor(Opcodes.ASM5) {
                            @Override
                            public void visitFieldInsn(int i, String s, String s2, String s3) {
                                if (oldClass.equals(s) && fieldToReplace.name.equals(s2)) {
                                    foundField[0] = true;
                                }
                                super.visitFieldInsn(i, s, s2, s3);
                            }
                        });
                        if (foundField[0]) {
                            inst.set(absIns, new FieldInsnNode(Opcodes.PUTSTATIC, newClass, fieldToReplace.name,
                                    fieldToReplace.desc));
                            counter++;
                        }
                    }
                }
            }
        }
    }
    return counter;
}

From source file:org.coldswap.asm.field.ProtectedStaticFieldReplacer.java

License:Open Source License

/**
 * Removes any initializing reference of the field.
 *
 * @param classNode containing the old class.
 * @param fieldNode containing the old field.
 * @param canRemove <code>true</code> if this method should remove the initializing code and return it
 *                  or <code>false</code> if you only want to return the init code.
 * @return the initializing list of instructions.
 *//*www.j  a va  2  s . c  o  m*/
@SuppressWarnings("unchecked")
private InsnList cleanClInit(ClassNode classNode, FieldNode fieldNode, boolean canRemove) {
    List<MethodNode> methodNodes = classNode.methods;
    AbstractInsnNode firstInst = null;
    int counter = 0;
    for (MethodNode methodNode : methodNodes) {
        if (methodNode.name.equals("<clinit>")) {
            // search for PUTSTATIC
            InsnList insnList = methodNode.instructions;
            Iterator iterator1 = insnList.iterator();
            while (iterator1.hasNext()) {
                AbstractInsnNode ins2 = (AbstractInsnNode) iterator1.next();
                // if a initializing has been found, then copy everything from
                // the coresponding label to the PUTSTATIC
                if (ins2.getOpcode() == Opcodes.PUTSTATIC) {
                    final Boolean[] fieldFound = { false };
                    final FieldNode fNode = fieldNode;
                    ins2.accept(new MethodVisitor(Opcodes.ASM5) {
                        @Override
                        public void visitFieldInsn(int i, String s, String s2, String s3) {
                            if (s2.equals(fNode.name)) {
                                fieldFound[0] = true;
                            }
                            super.visitFieldInsn(i, s, s2, s3);
                        }
                    });
                    if (fieldFound[0]) {
                        // find the first PUTSTATIC before this one.
                        boolean staticFound = false;
                        while (!staticFound) {
                            AbstractInsnNode tmpInst = ins2.getPrevious();
                            if (tmpInst != null) {
                                if (tmpInst.getOpcode() != Opcodes.F_NEW) {
                                    if (tmpInst.getOpcode() == Opcodes.PUTSTATIC) {
                                        staticFound = true;
                                    } else {
                                        firstInst = tmpInst;
                                        counter++;
                                    }
                                }
                            } else {
                                staticFound = true;
                            }
                            ins2 = tmpInst;
                        }

                        break;
                    }
                }
            }

            if (firstInst != null) {
                InsnList iList = new InsnList();
                iList.add(firstInst.clone(null));
                counter--;
                while (counter > 0) {
                    AbstractInsnNode ain = firstInst.getNext();
                    iList.add(ain.clone(null));
                    counter--;
                    if (canRemove) {
                        insnList.remove(firstInst);
                    }
                    firstInst = ain;
                }
                if (canRemove) {
                    // remove last instruction and the putstatic instruction
                    AbstractInsnNode putStatic = firstInst.getNext();
                    insnList.remove(firstInst);
                    insnList.remove(putStatic);
                }
                return iList;
            }
        }
    }
    return null;
}

From source file:org.coldswap.asm.field.ProtectedStaticFieldReplacer.java

License:Open Source License

/**
 * Replaces any GETSTATIC/PUTSTATIC call of the field in the old class with the field
 * introduced in the new class./*from w w w .j av  a2  s .c o m*/
 *
 * @param classNode containing the old class.
 * @param fieldNode containing the old field.
 */
private void replaceReferences(ClassNode classNode, FieldNode fieldNode) {
    List<MethodNode> methodNodes = classNode.methods;
    String contClass = classNode.name.substring(classNode.name.lastIndexOf("/") + 1);
    final String className = classPackage
            + TransformerNameGenerator.getProtectedStaticFieldClassName(contClass, fieldNode.name);
    for (MethodNode method : methodNodes) {
        InsnList inst = method.instructions;
        Iterator iter = inst.iterator();
        while (iter.hasNext()) {
            AbstractInsnNode absIns = (AbstractInsnNode) iter.next();
            int opcode = absIns.getOpcode();
            // check if instruction is GETSTATIC or PUTSTATIC
            if (opcode == Opcodes.GETSTATIC) {
                // get type
                if (absIns.getType() == AbstractInsnNode.FIELD_INSN) {
                    final Boolean[] foundField = { false };
                    final ClassNode cNode = classNode;
                    final FieldNode fNode = fieldNode;
                    absIns.accept(new MethodVisitor(Opcodes.ASM5) {
                        @Override
                        public void visitFieldInsn(int i, String s, String s2, String s3) {
                            if (cNode.name.equals(s) && fNode.name.equals(s2)) {
                                foundField[0] = true;
                            }
                            super.visitFieldInsn(i, s, s2, s3);
                        }
                    });
                    if (foundField[0]) {
                        inst.set(absIns, new FieldInsnNode(Opcodes.GETSTATIC, className, fieldNode.name,
                                fieldNode.desc));
                    }
                }
            } else if (opcode == Opcodes.PUTSTATIC) {
                if (absIns.getType() == AbstractInsnNode.FIELD_INSN) {
                    final Boolean[] foundField = { false };
                    final ClassNode cNode = classNode;
                    final FieldNode fNode = fieldNode;
                    absIns.accept(new MethodVisitor(Opcodes.ASM5) {
                        @Override
                        public void visitFieldInsn(int i, String s, String s2, String s3) {
                            if (cNode.name.equals(s) && fNode.name.equals(s2)) {
                                foundField[0] = true;
                            }
                            super.visitFieldInsn(i, s, s2, s3);
                        }
                    });
                    if (foundField[0]) {
                        inst.set(absIns, new FieldInsnNode(Opcodes.PUTSTATIC, className, fieldNode.name,
                                fieldNode.desc));
                    }
                }
            }
        }
    }
}

From source file:org.coldswap.asm.field.PublicStaticFieldReferenceReplacer.java

License:Open Source License

@SuppressWarnings("unchecked")
@Override/*from  w  w  w .jav  a2 s  .c  o m*/
public int findAndReplace(ClassNode classNode) {
    int counter = 0;
    List<MethodNode> methodNodes = classNode.methods;
    for (MethodNode method : methodNodes) {
        InsnList inst = method.instructions;
        Iterator iter = inst.iterator();
        while (iter.hasNext()) {
            AbstractInsnNode absIns = (AbstractInsnNode) iter.next();
            int opcode = absIns.getOpcode();
            // check if instruction is GETSTATIC or PUTSTATIC
            if (opcode == Opcodes.GETSTATIC) {
                // get type
                if (absIns.getType() == AbstractInsnNode.FIELD_INSN) {
                    final Boolean[] foundField = { false };
                    absIns.accept(new MethodVisitor(Opcodes.ASM5) {
                        @Override
                        public void visitFieldInsn(int i, String s, String s2, String s3) {
                            if (oldClass.equals(s) && fieldToReplace.name.equals(s2)) {
                                foundField[0] = true;
                            }
                            super.visitFieldInsn(i, s, s2, s3);
                        }
                    });
                    if (foundField[0]) {
                        inst.set(absIns, new FieldInsnNode(Opcodes.GETSTATIC, newClass, fieldToReplace.name,
                                fieldToReplace.desc));
                        counter++;
                    }
                }
            } else if (opcode == Opcodes.PUTSTATIC) {
                if (absIns.getType() == AbstractInsnNode.FIELD_INSN) {
                    final Boolean[] foundField = { false };
                    absIns.accept(new MethodVisitor(Opcodes.ASM5) {
                        @Override
                        public void visitFieldInsn(int i, String s, String s2, String s3) {
                            if (oldClass.equals(s) && fieldToReplace.name.equals(s2)) {
                                foundField[0] = true;
                            }
                            super.visitFieldInsn(i, s, s2, s3);
                        }
                    });
                    if (foundField[0]) {
                        inst.set(absIns, new FieldInsnNode(Opcodes.PUTSTATIC, newClass, fieldToReplace.name,
                                fieldToReplace.desc));
                        counter++;
                    }
                }
            }
        }
    }
    return counter;
}

From source file:org.coldswap.asm.field.PublicStaticFieldReplacer.java

License:Open Source License

/**
 * Replaces any GETSTATIC/PUTSTATIC call of the field in the old class with the field
 * introduced in the new class./*from   w w w.j  ava 2s.c o m*/
 *
 * @param classNode containing the old class.
 * @param fieldNode containing the old field.
 */
private void replaceReferences(ClassNode classNode, FieldNode fieldNode) {
    List<MethodNode> methodNodes = classNode.methods;
    String contClass = classNode.name.substring(classNode.name.lastIndexOf("/") + 1);
    final String className = classPackage
            + TransformerNameGenerator.getPublicStaticFieldClassName(contClass, fieldNode.name);
    for (MethodNode method : methodNodes) {
        InsnList inst = method.instructions;
        Iterator iter = inst.iterator();
        while (iter.hasNext()) {
            AbstractInsnNode absIns = (AbstractInsnNode) iter.next();
            int opcode = absIns.getOpcode();
            // check if instruction is GETSTATIC or PUTSTATIC
            if (opcode == Opcodes.GETSTATIC) {
                // get type
                if (absIns.getType() == AbstractInsnNode.FIELD_INSN) {
                    final Boolean[] foundField = { false };
                    final ClassNode cNode = classNode;
                    final FieldNode fNode = fieldNode;
                    absIns.accept(new MethodVisitor(Opcodes.ASM5) {
                        @Override
                        public void visitFieldInsn(int i, String s, String s2, String s3) {
                            if (cNode.name.equals(s) && fNode.name.equals(s2)) {
                                foundField[0] = true;
                            }
                            super.visitFieldInsn(i, s, s2, s3);
                        }
                    });
                    if (foundField[0]) {
                        inst.set(absIns, new FieldInsnNode(Opcodes.GETSTATIC, className, fieldNode.name,
                                fieldNode.desc));
                    }
                }
            } else if (opcode == Opcodes.PUTSTATIC) {
                if (absIns.getType() == AbstractInsnNode.FIELD_INSN) {
                    final Boolean[] foundField = { false };
                    final ClassNode cNode = classNode;
                    final FieldNode fNode = fieldNode;
                    absIns.accept(new MethodVisitor(Opcodes.ASM5) {
                        @Override
                        public void visitFieldInsn(int i, String s, String s2, String s3) {
                            if (cNode.name.equals(s) && fNode.name.equals(s2)) {
                                foundField[0] = true;
                            }
                            super.visitFieldInsn(i, s, s2, s3);
                        }
                    });
                    if (foundField[0]) {
                        inst.set(absIns, new FieldInsnNode(Opcodes.PUTSTATIC, className, fieldNode.name,
                                fieldNode.desc));
                    }
                }
            }
        }
    }
}

From source file:org.coldswap.asm.VirtualMethodReplacer.java

License:Open Source License

@Override
public MethodNode replaceInvoke(MethodNode methodNode) {
    InsnList instructions = methodNode.instructions;
    Iterator it = instructions.iterator();
    while (it.hasNext()) {
        AbstractInsnNode code = (AbstractInsnNode) it.next();
        if (code.getOpcode() == Opcodes.INVOKEVIRTUAL) {
            // check if methodToReplace is called
            final boolean[] callFounded = new boolean[] { false };
            code.accept(new MethodVisitor(Opcodes.ASM5) {
                @Override/*from  ww w.  java 2s. co  m*/
                public void visitMethodInsn(int i, String s, String s2, String s3) {
                    if (s.equals(classContainer) && s2.equals(methodName)) {
                        callFounded[0] = true;
                    }
                    super.visitMethodInsn(i, s, s2, s3);
                }
            });

            if (callFounded[0]) {
                // if the return type is primitive and the value is not discarded, unbox
                if (AutoBoxing.isPrimitive(retType.getDescriptor())) {
                    AbstractInsnNode codeNext = code.getNext();
                    boolean discarded = false;
                    // if returning primitive double or long and it is discarded with a pop2 than discard with
                    // simple pop, because we use an Object as return value.
                    if (codeNext.getOpcode() == Opcodes.POP2
                            && (retType.getDescriptor().equals("D") || retType.getDescriptor().equals("J"))) {
                        instructions.set(codeNext, new InsnNode(Opcodes.POP));

                    }
                    if (codeNext.getOpcode() == Opcodes.POP || codeNext.getOpcode() == Opcodes.POP2) {
                        discarded = true;
                    }
                    if (!discarded) {
                        instructions.insert(code, AutoBoxing.unbox(retType));
                    }
                }

                // replace call with a custom call
                String newMethodName;
                AbstractInsnNode newInvoke = null;
                if (Constants.VAROBJECT.equals(methodType)) {
                    newMethodName = TransformerNameGenerator.getObjectMethodNameWithCounter(classContainer,
                            methodNumber);
                    newInvoke = new MethodInsnNode(Opcodes.INVOKEVIRTUAL, classContainer, newMethodName,
                            "([Ljava/lang/Object;)Ljava/lang/Object;");
                } else if (Constants.INT.equals(methodType)) {
                    newMethodName = TransformerNameGenerator.getIntMethodNameWithCounter(classContainer,
                            methodNumber);
                    newInvoke = new MethodInsnNode(Opcodes.INVOKEVIRTUAL, classContainer, newMethodName,
                            "(I)Ljava/lang/Object;");
                } else if (Constants.FLOAT.equals(methodType)) {
                    newMethodName = TransformerNameGenerator.getFloatMethodNameWithCounter(classContainer,
                            methodNumber);
                    newInvoke = new MethodInsnNode(Opcodes.INVOKEVIRTUAL, classContainer, newMethodName,
                            "(F)Ljava/lang/Object;");
                } else if (Constants.STRING.equals(methodType)) {
                    newMethodName = TransformerNameGenerator.getStringMethodNameWithCounter(classContainer,
                            methodNumber);
                    newInvoke = new MethodInsnNode(Opcodes.INVOKEVIRTUAL, classContainer, newMethodName,
                            "(Ljava/lang/String;)Ljava/lang/Object;");
                } else if (Constants.LONG.equals(methodType)) {
                    newMethodName = TransformerNameGenerator.getLongMethodNameWithCounter(classContainer,
                            methodNumber);
                    newInvoke = new MethodInsnNode(Opcodes.INVOKEVIRTUAL, classContainer, newMethodName,
                            "(J)Ljava/lang/Object;");
                }
                if (newInvoke != null) {
                    instructions.set(code, newInvoke);
                }
            }
        }
    }
    return methodNode;
}

From source file:org.eclipse.objectteams.otredyn.bytecode.asm.AbstractTransformableClassNode.java

License:Open Source License

/**
 * Adds a new Label to an existing switch statement
 * @param instructions the instructions, in which the switch statement is defined
 * @param newInstructions the instructions of the new label
 * @param labelIndex the index of the label
 *//*from ww w.  j  a v a 2 s . c  o m*/
@SuppressWarnings("unchecked")
protected void addNewLabelToSwitch(InsnList instructions, InsnList newInstructions, int labelIndex) {
    ListIterator<AbstractInsnNode> iter = instructions.iterator();
    LookupSwitchInsnNode lSwitch = null;
    while (iter.hasNext()) {
        AbstractInsnNode node = (AbstractInsnNode) iter.next();
        if (node.getType() == AbstractInsnNode.LOOKUPSWITCH_INSN) {
            lSwitch = (LookupSwitchInsnNode) node;
            LabelNode label = new LabelNode();
            boolean labelAdded = false;
            for (int i = 0; i < lSwitch.keys.size(); i++) {
                Integer key = (Integer) lSwitch.keys.get(i);
                if (key >= labelIndex) {
                    lSwitch.keys.add(i, labelIndex);
                    lSwitch.labels.add(i, label);
                    labelAdded = true;
                    break;
                }
            }
            if (!labelAdded) {
                lSwitch.labels.add(label);
                lSwitch.keys.add(labelIndex);
            }
            boolean foundDefLabel = false;
            AbstractInsnNode prevNode = node;
            while (iter.hasNext()) {
                node = (AbstractInsnNode) iter.next();
                if (node.getType() == AbstractInsnNode.LABEL) {
                    if (!foundDefLabel) {
                        foundDefLabel = true;
                    } else {
                        break;
                    }
                }
                prevNode = node;
            }
            instructions.insert(prevNode, label);
            instructions.insert(label, newInstructions);
        }
    }
    if (lSwitch == null) {
        throw new RuntimeException("No switch statement found.");
    }
}