implements the visitor to look for returns of constant values, and records them for being negative, zero or positive. It also records unconditional
returns of non zero values

@param seen
the currently parsed opcode
546778
@Override
    public void sawOpcode(int seen) {
        try {
            stack.precomputation(this);

            switch (seen) {
                case Const.IRETURN: {
                    processIntegerReturn();
                }
                break;

                case Const.GOTO:
                case Const.GOTO_W: {
                    if (stack.getStackDepth() > 0) {
                        throw new StopOpcodeParsingException();
                    }
                    if (furthestBranchTarget < getBranchTarget()) {
                        furthestBranchTarget = getBranchTarget();
                    }
                }
                break;

                case Const.IFEQ:
                case Const.IFNE:
                case Const.IFLT:
                case Const.IFGE:
                case Const.IFGT:
                case Const.IFLE:
                case Const.IF_ICMPEQ:
                case Const.IF_ICMPNE:
                case Const.IF_ICMPLT:
                case Const.IF_ICMPGE:
                case Const.IF_ICMPGT:
                case Const.IF_ICMPLE:
                case Const.IF_ACMPEQ:
                case Const.IF_ACMPNE:
                case Const.IFNULL:
                case Const.IFNONNULL: {
                    if (furthestBranchTarget < getBranchTarget()) {
                        furthestBranchTarget = getBranchTarget();
                    }
                }
                break;

                case Const.LOOKUPSWITCH:
                case Const.TABLESWITCH: {
                    int defTarget = getDefaultSwitchOffset() + getPC();
                    if (furthestBranchTarget > defTarget) {
                        furthestBranchTarget = defTarget;
                    }
                }
                break;

                case Const.ATHROW: {
                    if (stack.getStackDepth() > 0) {
                        OpcodeStack.Item item = stack.getStackItem(0);
                        String exSig = item.getSignature();
                        if ("Ljava/lang/UnsupportedOperationException;".equals(exSig)) {
                            throw new StopOpcodeParsingException();
                        }
                    }
                }
                break;

                /*
                 * these three opcodes are here because findbugs proper is broken, it sometimes
                 * doesn't push this constant on the stack, because of bad branch handling
                 */
                case Const.ICONST_0:
                    if (getNextOpcode() == Const.IRETURN) {
                        sawConstant = Integer.valueOf(0);
                    }
                break;

                case Const.ICONST_M1:
                    if (getNextOpcode() == Const.IRETURN) {
                        sawConstant = Integer.valueOf(-1);
                    }
                break;

                case Const.ICONST_1:
                    if (getNextOpcode() == Const.IRETURN) {
                        sawConstant = Integer.valueOf(1);
                    }
                break;

                default:
                break;

            }
        } finally {
            stack.sawOpcode(this, seen);
        }
    }
29543
@Override
    public void sawOpcode(int seen) {
        if (DEBUG) {
            System.out.println(getPC() + " " + Const.getOpcodeName(seen));
        }
        switch (seen) {
        case Const.IFNE:
        case Const.IFEQ: {
            OpcodeStack.Item top = stack.getStackItem(0);
            if (DEBUG) {
                System.out.println("Stack top: " + top);
            }
            XMethod m = top.getReturnValueOf();
            if (m != null && "java.util.concurrent.ConcurrentHashMap".equals(m.getClassName())
                    && "containsKey".equals(m.getName())) {
                lastQuestionableCheckTarget = getBranchTarget();
                if (seen == Const.IFEQ) {
                    priority = LOW_PRIORITY;
                } else if (seen == Const.IFNE) {
                    priority = NORMAL_PRIORITY;
                }
            }
            break;
        }
        case Const.IFNULL:
        case Const.IFNONNULL: {
            OpcodeStack.Item top = stack.getStackItem(0);
            if (DEBUG) {
                System.out.println("Stack top: " + top);
            }
            XMethod m = top.getReturnValueOf();
            if (DEBUG) {
                System.out.println("Found null check");
            }
            if (m != null && "java.util.concurrent.ConcurrentHashMap".equals(m.getClassName()) && "get".equals(m.getName())) {
                lastQuestionableCheckTarget = getBranchTarget();
                if (seen == Const.IFNULL) {
                    priority = LOW_PRIORITY;
                } else if (seen == Const.IFNONNULL) {
                    priority = NORMAL_PRIORITY;
                }
            }
            break;
        }
        case Const.INVOKEVIRTUAL:
        case Const.INVOKEINTERFACE: {
            if ("java.util.concurrent.ConcurrentHashMap".equals(getDottedClassConstantOperand())) {
                String methodName = getNameConstantOperand();
                XClass xClass = getXClassOperand();
                if (xClass != null && "put".equals(methodName)) {
                    if ((getPC() < lastQuestionableCheckTarget) && (lastQuestionableCheckTarget != -1)) {
                        bugReporter.reportBug(new BugInstance(this, "AT_OPERATION_SEQUENCE_ON_CONCURRENT_ABSTRACTION", priority)
                        .addClassAndMethod(this).addType(xClass.getClassDescriptor()).addCalledMethod(this)
                        .addSourceLine(this));
                    }
                }
            }
            break;
        }
        default:
            break;
        }
    }
1263647
private void sawOpcodeLoop(final int seen) {
        try {
            stack.mergeJumps(this);

            switch (state) {
                case SAW_NOTHING:
                    if ((seen == Const.IINC) && (getIntConstant() == 1)) {
                        loopReg = getRegisterOperand();
                        state = State.SAW_IINC;
                    }
                break;

                case SAW_IINC:
                    if ((seen == Const.GOTO) || (seen == Const.GOTO_W)) {
                        int branchTarget = getBranchTarget();
                        int pc = getPC();
                        if (branchTarget < pc) {
                            possibleForLoops.add(new ForLoop(branchTarget, pc, loopReg));
                        }
                    }
                    state = State.SAW_NOTHING;
                break;
            }

            if ((seen == Const.INVOKEINTERFACE) && Values.SLASHED_JAVA_UTIL_LIST.equals(getClassConstantOperand()) && "size".equals(getNameConstantOperand())
                    && SignatureBuilder.SIG_VOID_TO_INT.equals(getSigConstantOperand())) {
                sawListSize = true;
            }
        } finally {
            stack.sawOpcode(this, seen);
        }
    }
848492
@Override
    public void sawOpcode(int seen) {
        try {
            switch (state) {
                case SAW_NOTHING:
                    if (seen == Const.RETURN) {
                        bugReporter.reportBug(new BugInstance(this, BugType.ACEM_ABSTRACT_CLASS_EMPTY_METHODS.name(), NORMAL_PRIORITY).addClass(this)
                                .addMethod(this).addSourceLine(this));
                        state = State.SAW_DONE;
                    } else if (seen == Const.NEW) {
                        String newClass = getClassConstantOperand();
                        JavaClass exCls = Repository.lookupClass(newClass);
                        if ((exceptionClass != null) && exCls.instanceOf(exceptionClass)) {
                            state = State.SAW_NEW;
                        } else {
                            state = State.SAW_DONE;
                        }
                    } else {
                        state = State.SAW_DONE;
                    }
                break;

                case SAW_NEW:
                    if (seen == Const.DUP) {
                        state = State.SAW_DUP;
                    } else {
                        state = State.SAW_DONE;
                    }
                break;

                case SAW_DUP:
                    if (((seen == Const.LDC) || (seen == Const.LDC_W)) && (getConstantRefOperand() instanceof ConstantString)) {
                        state = State.SAW_LDC;
                    } else {
                        state = State.SAW_DONE;
                    }
                break;

                case SAW_LDC:
                    if ((seen == Const.INVOKESPECIAL) && Values.CONSTRUCTOR.equals(getNameConstantOperand())) {
                        state = State.SAW_INVOKESPECIAL;
                    } else {
                        state = State.SAW_DONE;
                    }
                break;

                case SAW_INVOKESPECIAL:
                    if (seen == Const.ATHROW) {
                        bugReporter.reportBug(new BugInstance(this, BugType.ACEM_ABSTRACT_CLASS_EMPTY_METHODS.name(), NORMAL_PRIORITY).addClass(this)
                                .addMethod(this).addSourceLine(this));
                    }
                    state = State.SAW_DONE;
                break;

                case SAW_DONE:
                break;
            }
        } catch (ClassNotFoundException cnfe) {
            bugReporter.reportMissingClass(cnfe);
            state = State.SAW_DONE;
        }
    }
1011865
@Override
    public void sawOpcode(final int seen) {
        Object hashCodedStringRef = null;
        try {
            stack.precomputation(this);

            switch (seen) {
                case Const.INVOKEVIRTUAL:
                    if (Values.SLASHED_JAVA_LANG_STRING.equals(getClassConstantOperand())) {
                        String calledMethodName = getNameConstantOperand();
                        String calledMethodSig = getSigConstantOperand();

                        if (("equals".equals(calledMethodName) && SignatureBuilder.SIG_OBJECT_TO_BOOLEAN.equals(calledMethodSig))
                                || ("compareTo".equals(calledMethodName) && SignatureBuilder.SIG_STRING_TO_INT.equals(calledMethodSig))
                                || ("equalsIgnoreCase".equals(calledMethodName) && SignatureBuilder.SIG_STRING_TO_BOOLEAN.equals(calledMethodSig))) {

                            if (stack.getStackDepth() > 0) {
                                OpcodeStack.Item itm = stack.getStackItem(0);
                                Object constant = itm.getConstant();
                                if ((constant != null) && constant.getClass().equals(String.class) && !lookupSwitchOnString()) {
                                    bugReporter.reportBug(new BugInstance(this, "LSC_LITERAL_STRING_COMPARISON", HIGH_PRIORITY) // very
                                                                                                                                // confident
                                            .addClass(this).addMethod(this).addSourceLine(this));
                                }
                            }
                        } else if (Values.HASHCODE.equals(calledMethodName) && (stack.getStackDepth() > 0)) {
                            OpcodeStack.Item item = stack.getStackItem(0);
                            int reg = item.getRegisterNumber();
                            if (reg >= 0) {
                                hashCodedStringRef = String.valueOf(reg);
                            } else {
                                XField xf = item.getXField();
                                if (xf != null) {
                                    hashCodedStringRef = xf.getName();
                                } else {
                                    XMethod xm = item.getReturnValueOf();
                                    if (xm != null) {
                                        hashCodedStringRef = xm.toString();
                                    }
                                }

                            }
                        }
                    }
                break;

                case Const.TABLESWITCH:
                case Const.LOOKUPSWITCH:
                    if (stack.getStackDepth() > 0) {
                        OpcodeStack.Item item = stack.getStackItem(0);
                        String stringRef = (String) item.getUserValue();
                        if (stringRef != null) {
                            int[] offsets = getSwitchOffsets();
                            BitSet bs = new BitSet();
                            int pc = getPC();
                            for (int offset : offsets) {
                                bs.set(pc + offset);
                            }
                            bs.set(pc + getDefaultSwitchOffset());
                            lookupSwitches.add(new LookupDetails(stringRef, bs));
                        }
                    }
                break;
                default:
                break;
            }

        } finally {
            stack.sawOpcode(this, seen);
            if ((hashCodedStringRef != null) && (stack.getStackDepth() > 0)) {
                OpcodeStack.Item item = stack.getStackItem(0);
                item.setUserValue(hashCodedStringRef);
            }

            if (!lookupSwitches.isEmpty()) {
                int innerMostSwitch = lookupSwitches.size() - 1;
                LookupDetails details = lookupSwitches.get(innerMostSwitch);
                if (details.getSwitchTargets().get(getPC()) && (stack.getStackDepth() > 0)) {
                    OpcodeStack.Item item = stack.getStackItem(0);
                    item.setUserValue(details.getStringReference());
                }

                // previousSetBit is a jdk1.7 api - gonna cheat cause findbugs
                // runs on 1.7
                if (getPC() >= details.getSwitchTargets().previousSetBit(Integer.MAX_VALUE)) {
                    lookupSwitches.remove(innerMostSwitch);
                }
            }
        }
    }
505589
@Override
    @SuppressWarnings("unchecked")
    public void sawOpcode(int seen) {
        String ldcClassName = null;
        String seenMethodName = null;
        boolean seenToString = false;
        boolean seenFormatterLogger = false;
        int exMessageReg = -1;
        Integer arraySize = null;
        boolean simpleFormat = false;

        try {
            stack.precomputation(this);

            if ((seen == Const.LDC) || (seen == Const.LDC_W)) {
                Constant c = getConstantRefOperand();
                if (c instanceof ConstantClass) {
                    ConstantPool pool = getConstantPool();
                    ldcClassName = ((ConstantUtf8) pool.getConstant(((ConstantClass) c).getNameIndex())).getBytes();
                }
            } else if (seen == Const.INVOKESTATIC) {
                lookForSuspectClasses();

                String clsName = getClassConstantOperand();
                String methodName = getNameConstantOperand();
                if (Values.SLASHED_JAVA_LANG_STRING.equals(clsName) && "format".equals(methodName) && (stack.getStackDepth() >= 2)) {
                    String format = (String) stack.getStackItem(1).getConstant();
                    if (format != null) {
                        Matcher m = NON_SIMPLE_FORMAT.matcher(format);
                        if (!m.matches()) {
                            simpleFormat = true;
                        }
                    }
                } else if ("getFormatterLogger".equals(methodName) && LOG4J2_LOGMANAGER.equals(clsName)) {
                    seenFormatterLogger = true;
                }
            } else if (((seen == Const.INVOKEVIRTUAL) || (seen == Const.INVOKEINTERFACE)) && (throwableClass != null)) {
                String mthName = getNameConstantOperand();
                if ("getName".equals(mthName)) {
                    if (stack.getStackDepth() >= 1) {
                        // Foo.class.getName() is being called, so we pass the
                        // name of the class to the current top of the stack
                        // (the name of the class is currently on the top of the
                        // stack, but won't be on the stack at all next opcode)
                        Item stackItem = stack.getStackItem(0);
                        LOUserValue<String> uv = (LOUserValue<String>) stackItem.getUserValue();
                        if ((uv != null) && (uv.getType() == LOUserValue.LOType.CLASS_NAME)) {
                            ldcClassName = uv.getValue();
                        }
                    }
                } else if ("getMessage".equals(mthName)) {
                    String callingClsName = getClassConstantOperand();
                    JavaClass cls = Repository.lookupClass(callingClsName);
                    if (cls.instanceOf(throwableClass) && (stack.getStackDepth() > 0)) {
                        OpcodeStack.Item exItem = stack.getStackItem(0);
                        exMessageReg = exItem.getRegisterNumber();
                    }
                } else if (LOGGER_METHODS.contains(mthName)) {
                    checkForProblemsWithLoggerMethods();
                } else if (Values.TOSTRING.equals(mthName) && SignatureBuilder.SIG_VOID_TO_STRING.equals(getSigConstantOperand())) {
                    String callingClsName = getClassConstantOperand();
                    if (SignatureUtils.isPlainStringConvertableClass(callingClsName) && (stack.getStackDepth() > 0)) {
                        OpcodeStack.Item item = stack.getStackItem(0);
                        // if the stringbuilder was previously stored, don't report it
                        if (item.getRegisterNumber() < 0) {
                            seenMethodName = mthName;
                        }
                    }

                    if (seenMethodName == null) {
                        seenToString = true;
                    }
                }
            } else if (seen == Const.INVOKESPECIAL) {
                checkForLoggerParam();
            } else if (seen == Const.ANEWARRAY) {
                if (stack.getStackDepth() > 0) {
                    OpcodeStack.Item sizeItem = stack.getStackItem(0);
                    Object con = sizeItem.getConstant();
                    if (con instanceof Integer) {
                        arraySize = (Integer) con;
                    }
                }
            } else if (seen == Const.AASTORE) {
                if (stack.getStackDepth() >= 3) {
                    OpcodeStack.Item arrayItem = stack.getStackItem(2);
                    LOUserValue<Integer> uv = (LOUserValue<Integer>) arrayItem.getUserValue();
                    if ((uv != null) && (uv.getType() == LOUserValue.LOType.ARRAY_SIZE)) {
                        Integer size = uv.getValue();
                        if ((size != null) && (size.intValue() > 0) && hasExceptionOnStack()) {
                            arrayItem.setUserValue(new LOUserValue<>(LOUserValue.LOType.ARRAY_SIZE, Integer.valueOf(-size.intValue())));
                        }
                    }
                }
            } else if (seen == Const.PUTSTATIC) {
                OpcodeStack.Item itm = stack.getStackItem(0);
                if (isStaticInitializer && isNonPrivateLogField(getClassConstantOperand(), getNameConstantOperand(), getSigConstantOperand())) {
                    XMethod m = itm.getReturnValueOf();
                    if ((m != null) && isLoggerWithClassParm(m)) {
                        bugReporter.reportBug(new BugInstance(this, BugType.LO_NON_PRIVATE_STATIC_LOGGER.name(), NORMAL_PRIORITY).addClass(this).addMethod(this)
                                .addSourceLine(this));
                    }
                }

                LOUserValue<Void> loggerUV = (LOUserValue<Void>) itm.getUserValue();
                if ((loggerUV != null) && (loggerUV.getType() == LOUserValue.LOType.FORMATTER_LOGGER)) {
                    formatterLoggers.add(getNameConstantOperand());
                }
            } else if (seen == Const.GETSTATIC) {
                if (formatterLoggers.contains(getNameConstantOperand())) {
                    seenFormatterLogger = true;
                }
            } else if (OpcodeUtils.isAStore(seen) && (stack.getStackDepth() > 0)) {
                OpcodeStack.Item item = stack.getStackItem(0);
                LOUserValue<String> uv = (LOUserValue<String>) item.getUserValue();
                if (uv != null) {
                    if (((uv.getType() == LOUserValue.LOType.METHOD_NAME) && Values.TOSTRING.equals(uv.getValue()))
                            || (uv.getType() == LOUserValue.LOType.SIMPLE_FORMAT) || (uv.getType() == LOUserValue.LOType.TOSTRING)) {
                        item.setUserValue(new LOUserValue<>(LOUserValue.LOType.NULL, null));
                    }
                }
            }
        } catch (ClassNotFoundException cnfe) {
            bugReporter.reportMissingClass(cnfe);
        } finally {
            TernaryPatcher.pre(stack, seen);
            stack.sawOpcode(this, seen);
            TernaryPatcher.post(stack, seen);

            if (stack.getStackDepth() > 0) {
                OpcodeStack.Item item = stack.getStackItem(0);
                if (ldcClassName != null) {
                    item.setUserValue(new LOUserValue<>(LOUserValue.LOType.CLASS_NAME, ldcClassName));
                } else if (seenMethodName != null) {
                    item.setUserValue(new LOUserValue<>(LOUserValue.LOType.METHOD_NAME, seenMethodName));
                } else if (exMessageReg >= 0) {
                    item.setUserValue(new LOUserValue<>(LOUserValue.LOType.MESSAGE_REG, Integer.valueOf(exMessageReg)));
                } else if (arraySize != null) {
                    item.setUserValue(new LOUserValue<>(LOUserValue.LOType.ARRAY_SIZE, arraySize));
                } else if (simpleFormat) {
                    item.setUserValue(new LOUserValue<>(LOUserValue.LOType.SIMPLE_FORMAT, Boolean.TRUE));
                } else if (seenToString) {
                    item.setUserValue(new LOUserValue<>(LOUserValue.LOType.TOSTRING, null));
                } else if (seenFormatterLogger) {
                    item.setUserValue(new LOUserValue<>(LOUserValue.LOType.FORMATTER_LOGGER, null));
                }
            }
        }
    }
478600
@Override
    public void sawOpcode(int seen) {
        int groupId = -1;

        try {
            stack.precomputation(this);

            if (seen == Const.INVOKEINTERFACE) {
                String className = getClassConstantOperand();
                String methodName = getNameConstantOperand();
                String signature = getSigConstantOperand();
                QMethod methodInfo = new QMethod(methodName, signature);

                if (isCollection(className)) {
                    if (collectionMethods.contains(methodInfo) || ITERATOR.equals(methodInfo)) {
                        if (stack.getStackDepth() > 0) {
                            OpcodeStack.Item itm = stack.getStackItem(0);
                            groupId = findCollectionGroup(itm, true);
                        }
                    } else if (REMOVE.equals(methodInfo)) {
                        if (stack.getStackDepth() > 1) {
                            OpcodeStack.Item itm = stack.getStackItem(1);
                            int id = findCollectionGroup(itm, true);
                            if ((id >= 0) && collectionGroups.get(id).isStandardCollection()) {
                                Integer it = groupToIterator.get(Integer.valueOf(id));
                                Loop loop = loops.get(it);
                                if (loop != null) {
                                    int pc = getPC();
                                    if (loop.hasPC(pc)) {
                                        boolean needPop = !Values.SIG_VOID.equals(SignatureUtils.getReturnSignature(signature));

                                        if (!breakFollows(loop, needPop) && !returnFollows(needPop)) {
                                            bugReporter.reportBug(new BugInstance(this, BugType.DWI_DELETING_WHILE_ITERATING.name(), NORMAL_PRIORITY)
                                                    .addClass(this).addMethod(this).addSourceLine(this));
                                        }
                                    }
                                }
                            }
                        }
                    } else {
                        Integer numArgs = modifyingMethods.get(methodInfo);
                        if ((numArgs != null) && (stack.getStackDepth() > numArgs.intValue())) {
                            OpcodeStack.Item itm = stack.getStackItem(numArgs.intValue());
                            int id = findCollectionGroup(itm, true);
                            if (id >= 0) {
                                Integer it = groupToIterator.get(Integer.valueOf(id));
                                if (it != null) {
                                    Loop loop = loops.get(it);
                                    if (loop != null) {
                                        int pc = getPC();
                                        if (loop.hasPC(pc)) {
                                            boolean needPop = !Values.SIG_VOID.equals(SignatureUtils.getReturnSignature(signature));
                                            boolean breakFollows = breakFollows(loop, needPop);
                                            boolean returnFollows = !breakFollows && returnFollows(needPop);

                                            if (!breakFollows && !returnFollows) {
                                                bugReporter.reportBug(new BugInstance(this, BugType.DWI_MODIFYING_WHILE_ITERATING.name(), NORMAL_PRIORITY)
                                                        .addClass(this).addMethod(this).addSourceLine(this));
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                } else if ("java/util/Iterator".equals(className) && HASNEXT.equals(methodInfo) && (stack.getStackDepth() > 0)) {
                    OpcodeStack.Item itm = stack.getStackItem(0);
                    Integer id = (Integer) itm.getUserValue();
                    if (id != null) {
                        groupId = id.intValue();
                    }
                }
            } else if ((seen == Const.PUTFIELD) || (seen == Const.PUTSTATIC)) {
                if (stack.getStackDepth() > 1) {
                    OpcodeStack.Item itm = stack.getStackItem(0);

                    Integer id = (Integer) itm.getUserValue();
                    if (id == null) {
                        FieldAnnotation fa = FieldAnnotation
                                .fromFieldDescriptor(new FieldDescriptor(getClassConstantOperand(), getNameConstantOperand(), getSigConstantOperand(), false));
                        itm = new OpcodeStack.Item(itm.getSignature(), fa, stack.getStackItem(1).getRegisterNumber());
                        removeFromCollectionGroup(itm);
                        groupId = findCollectionGroup(itm, true);
                    }
                }
            } else if (OpcodeUtils.isAStore(seen)) {
                if (stack.getStackDepth() > 0) {
                    OpcodeStack.Item itm = stack.getStackItem(0);
                    Integer id = (Integer) itm.getUserValue();
                    if (id != null) {
                        int reg = RegisterUtils.getAStoreReg(this, seen);

                        try {
                            JavaClass cls = itm.getJavaClass();
                            if ((cls != null) && cls.implementationOf(iteratorClass)) {
                                Integer regIt = Integer.valueOf(reg);
                                Iterator<Integer> curIt = groupToIterator.values().iterator();
                                while (curIt.hasNext()) {
                                    if (curIt.next().equals(regIt)) {
                                        curIt.remove();
                                    }
                                }
                                groupToIterator.put(id, regIt);
                            }

                            GroupPair pair = collectionGroups.get(id.intValue());
                            if (pair != null) {
                                pair.addMember(Integer.valueOf(reg));
                            }
                        } catch (ClassNotFoundException cnfe) {
                            bugReporter.reportMissingClass(cnfe);
                        }
                    } else {
                        String cls = itm.getSignature();
                        if ((cls != null) && cls.startsWith(Values.SIG_QUALIFIED_CLASS_PREFIX)) {
                            cls = SignatureUtils.trimSignature(cls);
                            if (isCollection(cls) || "java/util/Iterator".equals(cls)) {
                                int reg = RegisterUtils.getAStoreReg(this, seen);
                                removeFromCollectionGroup(new OpcodeStack.Item(itm, reg));
                                Iterator<Integer> it = groupToIterator.values().iterator();
                                while (it.hasNext()) {
                                    if (it.next().intValue() == reg) {
                                        it.remove();
                                        break;
                                    }
                                }
                            }
                        }
                    }
                }
            } else if (OpcodeUtils.isALoad(seen)) {
                int reg = RegisterUtils.getALoadReg(this, seen);
                OpcodeStack.Item itm = new OpcodeStack.Item(new OpcodeStack.Item(), reg);
                groupId = findCollectionGroup(itm, false);
            } else if ((seen == Const.IFEQ) && (stack.getStackDepth() > 0)) {
                OpcodeStack.Item itm = stack.getStackItem(0);
                Integer id = (Integer) itm.getUserValue();
                if (id != null) {
                    int target = getBranchTarget();
                    int gotoAddr = target - 3;
                    int ins = getCode().getCode()[gotoAddr];
                    if (ins < 0) {
                        ins = 256 + ins;
                    }
                    if ((ins == Const.GOTO) || (ins == Const.GOTO_W)) {
                        Integer reg = groupToIterator.get(id);
                        if (reg != null) {
                            loops.put(reg, new Loop(getPC(), gotoAddr));
                        }
                    }
                }
            }
        } finally {
            TernaryPatcher.pre(stack, seen);
            stack.sawOpcode(this, seen);
            TernaryPatcher.post(stack, seen);
            if ((groupId >= 0) && (stack.getStackDepth() > 0)) {
                OpcodeStack.Item itm = stack.getStackItem(0);
                itm.setUserValue(Integer.valueOf(groupId));
            }

            processEndOfScopes(Integer.valueOf(getPC()));
        }
    }
23344
@Override
    public void sawOpcode(int seen) {
        if (!forLoops.isEmpty()) {
            Iterator<FloatForLoop> ffl = forLoops.iterator();
            while (ffl.hasNext()) {
                if (!ffl.next().sawOpcode(seen)) {
                    ffl.remove();
                }
            }
        }

        if (OpcodeUtils.isFLoad(seen) || OpcodeUtils.isDLoad(seen)) {
            forLoops.add(new FloatForLoop(RegisterUtils.getLoadReg(this, seen), getPC()));
        }
    }
1217657
@Override
    public void sawOpcode(int seen) {
        switch (state) {
            case IN_CLINIT:
                sawCLInitOpcode(seen);
            break;

            case IN_INIT:
                sawInitOpcode(seen);
            break;

            case IN_METHOD:
                sawMethodOpcode(seen);
            break;
        }
    }
928085
@Override
    public void sawOpcode(int seen) {
        boolean allConstantStrings = false;
        boolean sawConstant = false;
        try {
            stack.precomputation(this);

            if (seen == Const.ATHROW) {
                checkForWEM();
            } else if ((seen == Const.LDC) || (seen == Const.LDC_W)) {
                if (getConstantRefOperand() instanceof ConstantString) {
                    sawConstant = true;
                }
            } else if ((seen == Const.INVOKESPECIAL) && Values.CONSTRUCTOR.equals(getNameConstantOperand())) {
                String clsName = getClassConstantOperand();
                if (clsName.indexOf("Exception") < 0) {
                    return;
                }
                JavaClass exCls = Repository.lookupClass(clsName);
                if (!exCls.instanceOf(exceptionClass)) {
                    return;
                }
                String sig = getSigConstantOperand();
                List<String> argTypes = SignatureUtils.getParameterSignatures(sig);
                int stringParms = 0;
                for (int t = 0; t < argTypes.size(); t++) {
                    if (!Values.SIG_JAVA_LANG_STRING.equals(argTypes.get(t))) {
                        continue;
                    }
                    stringParms++;
                    int stackOffset = argTypes.size() - t - 1;
                    if ((stack.getStackDepth() > stackOffset) && (stack.getStackItem(stackOffset).getUserValue() == null)) {
                        return;
                    }
                }
                if (Values.SLASHED_JAVA_LANG_EXCEPTION.equals(clsName) && SignatureBuilder.SIG_THROWABLE_TO_VOID.equals(getSigConstantOperand())) {
                    bugReporter.reportBug(
                            new BugInstance(this, BugType.WEM_OBSCURING_EXCEPTION.name(), LOW_PRIORITY).addClass(this).addMethod(this).addSourceLine(this));
                }
                allConstantStrings = stringParms > 0;
            }
        } catch (ClassNotFoundException cnfe) {
            bugReporter.reportMissingClass(cnfe);
        } finally {
            TernaryPatcher.pre(stack, seen);
            stack.sawOpcode(this, seen);
            TernaryPatcher.post(stack, seen);
            if ((sawConstant || allConstantStrings) && (stack.getStackDepth() > 0)) {
                OpcodeStack.Item item = stack.getStackItem(0);
                item.setUserValue(Boolean.TRUE);
            }
        }
    }
1165918
@Override
    public void sawOpcode(int seen) {
        boolean srcField = false;
        try {
            stack.precomputation(this);

            switch (seen) {
                case Const.ALOAD_0:
                    srcField = true;
                break;

                case Const.DUP:
                    if (stack.getStackDepth() > 0) {
                        OpcodeStack.Item item = stack.getStackItem(0);
                        if (item.getUserValue() != null) {
                            srcField = true;
                        }
                    }
                break;

                case Const.GETFIELD:
                    if (stack.getStackDepth() > 0) {
                        OpcodeStack.Item item = stack.getStackItem(0);
                        if (item.getRegisterNumber() == 0) {
                            srcField = true;
                        }
                    }
                break;

                case Const.PUTFIELD:
                    if (stack.getStackDepth() >= 2) {
                        OpcodeStack.Item item = stack.getStackItem(1);
                        if ((item.getRegisterNumber() == 0) || (item.getUserValue() != null)) {
                            bugReporter.reportBug(new BugInstance(this, BugType.SCA_SUSPICIOUS_CLONE_ALGORITHM.name(), NORMAL_PRIORITY).addClass(this)
                                    .addMethod(this).addSourceLine(this));
                        }
                    }

                break;

                case Const.INVOKEINTERFACE:
                case Const.INVOKEVIRTUAL:
                    String sig = getSigConstantOperand();
                    int numArgs = SignatureUtils.getNumParameters(sig);
                    if (stack.getStackDepth() > numArgs) {
                        OpcodeStack.Item item = stack.getStackItem(numArgs);
                        if ((item.getRegisterNumber() == 0) || (item.getUserValue() != null)) {
                            String name = getNameConstantOperand();
                            Integer priority = changingMethods.get(name);
                            if (priority != null) {
                                bugReporter.reportBug(new BugInstance(this, BugType.SCA_SUSPICIOUS_CLONE_ALGORITHM.name(), priority.intValue()).addClass(this)
                                        .addMethod(this).addSourceLine(this));
                            }
                        }
                    }
                break;

                default:
                break;
            }
        } finally {
            TernaryPatcher.pre(stack, seen);
            stack.sawOpcode(this, seen);
            TernaryPatcher.post(stack, seen);
            if (srcField && (stack.getStackDepth() > 0)) {
                OpcodeStack.Item item = stack.getStackItem(0);
                item.setUserValue(Boolean.TRUE);
            }
        }
    }
1215066
@Override
    public void sawOpcode(final int seen) {

        try {
            stack.precomputation(this);

            if (OpcodeUtils.isInvoke(seen)) {
                String methodSig = getSigConstantOperand();
                List<String> parmTypes = SignatureUtils.getParameterSignatures(methodSig);
                int stackDepth = stack.getStackDepth();
                if (stackDepth >= parmTypes.size()) {
                    for (int i = 0; i < parmTypes.size(); i++) {
                        OpcodeStack.Item itm = stack.getStackItem(i);
                        int reg = itm.getRegisterNumber();
                        removeUselessDefiners(parmTypes.get(parmTypes.size() - i - 1), reg);
                    }
                }

                if ((seen != Const.INVOKESPECIAL) && (seen != Const.INVOKESTATIC)) {
                    if (stackDepth > parmTypes.size()) {
                        OpcodeStack.Item itm = stack.getStackItem(parmTypes.size());
                        int reg = itm.getRegisterNumber();
                        int parm = reg;
                        if (!methodIsStatic) {
                            parm--;
                        }
                        if ((parm >= 0) && (parm < parmCount)) {
                            removeUselessDefiners(reg);
                        }
                    } else {
                        parameterDefiners.clear();
                    }
                }
            } else if ((seen == Const.PUTFIELD) || (seen == Const.GETFIELD) || (seen == Const.PUTSTATIC)
                    || (seen == Const.GETSTATIC) || OpcodeUtils.isAStore(seen)) {
                // Don't check parameters that are aliased
                if (stack.getStackDepth() > 0) {
                    OpcodeStack.Item itm = stack.getStackItem(0);
                    int reg = itm.getRegisterNumber();
                    int parm = reg;
                    if (!methodIsStatic) {
                        parm--;
                    }
                    if ((parm >= 0) && (parm < parmCount)) {
                        parameterDefiners.remove(Integer.valueOf(reg));
                    }
                } else {
                    parameterDefiners.clear();
                }

                if ((seen == Const.GETFIELD) || (seen == Const.PUTFIELD)) {
                    if (stack.getStackDepth() > 1) {
                        OpcodeStack.Item itm = stack.getStackItem(1);
                        int reg = itm.getRegisterNumber();
                        int parm = reg;
                        if (!methodIsStatic) {
                            parm--;
                        }
                        if ((parm >= 0) && (parm < parmCount)) {
                            parameterDefiners.remove(Integer.valueOf(reg));
                        }
                    } else {
                        parameterDefiners.clear();
                    }
                }

            } else if (OpcodeUtils.isALoad(seen)) {
                int reg = RegisterUtils.getALoadReg(this, seen);

                int parm = reg;
                if (!methodIsStatic) {
                    parm--;
                }
                if ((parm >= 0) && (parm < parmCount)) {
                    usedParameters.set(reg);
                }
            } else if (seen == Const.AASTORE) {
                // Don't check parameters that are stored in
                if (stack.getStackDepth() >= 3) {
                    OpcodeStack.Item itm = stack.getStackItem(0);
                    int reg = itm.getRegisterNumber();
                    int parm = reg;
                    if (!methodIsStatic) {
                        parm--;
                    }
                    if ((parm >= 0) && (parm < parmCount)) {
                        parameterDefiners.remove(Integer.valueOf(reg));
                    }
                } else {
                    parameterDefiners.clear();
                }
            } else if (seen == Const.ARETURN) {
                if (stack.getStackDepth() >= 1) {
                    OpcodeStack.Item item = stack.getStackItem(0);
                    int reg = item.getRegisterNumber();
                    int parm = reg;
                    if (!methodIsStatic) {
                        parm--;
                    }

                    if ((parm >= 0) && (parm < parmCount)) {
                        parameterDefiners.remove(Integer.valueOf(reg));
                    }
                } else {
                    parameterDefiners.clear();
                }
            }

            if (parameterDefiners.isEmpty()) {
                throw new StopOpcodeParsingException();
            }
        } finally {
            stack.sawOpcode(this, seen);
        }
    }
1230602
@Override
    public void sawOpcode(int seen) {
        Units unit = null;
        try {
            stack.precomputation(this);

            switch (seen) {
                case Const.INVOKEVIRTUAL:
                case Const.INVOKEINTERFACE:
                case Const.INVOKESTATIC:
                    unit = processInvoke();
                break;

                case Const.GETSTATIC:
                    String clsName = getClassConstantOperand();
                    if ("java/util/concurrent/TimeUnit".equals(clsName) || "edu/emory/matchcs/backport/java/util/concurrent/TimeUnit".equals(clsName)) {
                        unit = TIMEUNIT_TO_UNITS.get(getNameConstantOperand());
                    }
                break;

                case Const.L2I:
                case Const.I2L:
                    if (stack.getStackDepth() > 0) {
                        OpcodeStack.Item item = stack.getStackItem(0);
                        unit = (Units) item.getUserValue();
                    }
                break;

                case Const.IADD:
                case Const.ISUB:
                case Const.IMUL:
                case Const.IDIV:
                case Const.IREM:
                case Const.LADD:
                case Const.LSUB:
                case Const.LMUL:
                case Const.LDIV:
                case Const.LREM:
                    processArithmetic();
                break;

                default:
                break;
            }
        } finally {
            stack.sawOpcode(this, seen);
            if ((unit != null) && (stack.getStackDepth() > 0)) {
                OpcodeStack.Item item = stack.getStackItem(0);
                item.setUserValue(unit);
            }
        }
    }
291812
@Override
    public void sawOpcode(int seen) {
        XField userValue = null;
        try {
            stack.precomputation(this);

            if ((seen == Const.INVOKEVIRTUAL) || (seen == Const.INVOKEINTERFACE) || (seen == Const.INVOKEDYNAMIC)) {
                String sig = getSigConstantOperand();
                int argCount = SignatureUtils.getNumParameters(sig);
                if (stack.getStackDepth() > argCount) {
                    OpcodeStack.Item itm = stack.getStackItem(argCount);
                    XField field = itm.getXField();
                    if ((field != null) && bloatableCandidates.containsKey(field)) {
                        checkMethodAsDecreasingOrIncreasing(field);
                    }
                    String calledMethod = getNameConstantOperand();
                    if ("iterator".equals(calledMethod)) {
                        userValue = (XField) itm.getUserValue();
                        if (userValue == null) {
                            userValue = field;
                        }
                    } else {
                        if (field == null) {
                            field = (XField) itm.getUserValue();
                        }
                        if (field != null) {
                            if (mapSubsets.contains(calledMethod)) {
                                userValue = field;
                            } else if ("remove".equals(calledMethod) && "java/util/Iterator".equals(getClassConstantOperand())) {
                                bloatableCandidates.remove(field);
                                bloatableFields.remove(field);
                            }
                        }
                    }
                    
                    for (int i = 0; i < argCount; i++) {
                    	itm = stack.getStackItem(i);
                    	jaxbContextRegs.remove(itm.getRegisterNumber());
                    }
                }
            } else if (seen == Const.PUTFIELD) {
                if (stack.getStackDepth() > 0) {
                	OpcodeStack.Item item = stack.getStackItem(0);
	                jaxbContextRegs.remove(item.getRegisterNumber());
                }
            } else if (seen == Const.PUTSTATIC) {
                if (stack.getStackDepth() > 0) {
                    OpcodeStack.Item item = stack.getStackItem(0);
                    if (nonBloatableSigs.contains(item.getSignature())) {
                        XField field = item.getXField();
                        bloatableFields.remove(field);
                    }
                    
                    jaxbContextRegs.remove(item.getRegisterNumber());
                }
            }
            // Should not include private methods
            else if (seen == Const.ARETURN) {
                removeFieldsThatGetReturned();
            } else if (OpcodeUtils.isALoad(seen)) {
                userValue = userValues.get(RegisterUtils.getALoadReg(this, seen));
            } else if (OpcodeUtils.isAStore(seen)) {
                if (stack.getStackDepth() > 0) {
                    OpcodeStack.Item itm = stack.getStackItem(0);
                    userValues.put(RegisterUtils.getAStoreReg(this, seen), (XField) itm.getUserValue());
                    
            		XMethod xm = itm.getReturnValueOf();
            		if (xm != null) {
            			FQMethod calledMethod = new FQMethod(xm.getClassName().replace('.', '/'), xm.getName(), xm.getSignature());
                    	if (jaxbNewInstance.equals(calledMethod)) {
                    		jaxbContextRegs.put(RegisterUtils.getAStoreReg(this, seen), getPC());
                    	}
            		}
                }
            }
        } finally {
            stack.sawOpcode(this, seen);
            if ((userValue != null) && (stack.getStackDepth() > 0)) {
                OpcodeStack.Item itm = stack.getStackItem(0);
                itm.setUserValue(userValue);
            }
        }
    }
283703
@Override
    public void sawOpcode(int seen) {
        switch (state) {
            case SAW_NOTHING:
                if ((seen == Const.IF_ICMPGE) || (seen == Const.IF_ICMPGT)) {
                    state = State.SAW_ICMP;
                }
            break;

            case SAW_ICMP:
                if (OpcodeUtils.isALoad(seen)) {
                    state = State.SAW_ARRAY1_LOAD;
                }
            break;

            case SAW_ARRAY1_LOAD:
                if (seen == Const.ILOAD) {
                    arrayIndexReg = getRegisterOperand();
                    state = State.SAW_ARRAY1_INDEX;
                } else if ((seen >= Const.ILOAD_0) && (seen <= Const.ILOAD_3)) {
                    arrayIndexReg = seen - Const.ILOAD_0;
                    state = State.SAW_ARRAY1_INDEX;
                } else {
                    state = State.SAW_NOTHING;
                }
            break;

            case SAW_ARRAY1_INDEX:
                if (OpcodeUtils.isALoad(seen)) {
                    state = State.SAW_ARRAY2_LOAD;
                } else {
                    state = State.SAW_NOTHING;
                }
            break;

            case SAW_ARRAY2_LOAD:
                if (seen == Const.ILOAD) {
                    if (arrayIndexReg == this.getRegisterOperand()) {
                        state = State.SAW_ARRAY2_INDEX;
                    } else {
                        state = State.SAW_NOTHING;
                    }
                } else if ((seen >= Const.ILOAD_0) && (seen <= Const.ILOAD_3)) {
                    if (arrayIndexReg == (seen - Const.ILOAD_0)) {
                        state = State.SAW_ARRAY2_INDEX;
                    } else {
                        state = State.SAW_NOTHING;
                    }
                } else {
                    state = State.SAW_NOTHING;
                }
            break;

            case SAW_ARRAY2_INDEX:
                if ((seen == Const.AALOAD) || (seen == Const.BALOAD) || (seen == Const.CALOAD) || (seen == Const.SALOAD) || (seen == Const.IALOAD)
                        || (seen == Const.LALOAD) || (seen == Const.DALOAD) || (seen == Const.FALOAD)) {
                    loadInstruction = seen;
                    state = State.SAW_ELEM_LOAD;
                } else {
                    state = State.SAW_NOTHING;
                }
            break;

            case SAW_ELEM_LOAD:
                if ((seen == Const.AASTORE) || (seen == Const.BASTORE) || (seen == Const.CASTORE) || (seen == Const.SASTORE) || (seen == Const.IASTORE)
                        || (seen == Const.LASTORE) || (seen == Const.DASTORE) || (seen == Const.FASTORE)) {
                    if (similarArrayInstructions(loadInstruction, seen)) {
                        state = State.SAW_ELEM_STORE;
                    } else {
                        state = State.SAW_NOTHING;
                    }
                } else {
                    state = State.SAW_NOTHING;
                }
            break;

            case SAW_ELEM_STORE:
                if (seen == Const.IINC) {
                    bugReporter.reportBug(new BugInstance(this, "MAC_MANUAL_ARRAY_COPY", NORMAL_PRIORITY).addClass(this).addMethod(this).addSourceLine(this));
                }
                state = State.SAW_NOTHING;
            break;
        }
    }
753132
@Override
    public void sawOpcode(int seen) {
        if (downwardBranchTarget == -1) {
            switch (state) {
                case SAW_NOTHING:
                    sawOpcodeAfterNothing(seen);
                break;

                case SAW_LOAD:
                    sawOpcodeAfterLoad(seen);
                break;

                case SAW_CHECKCAST:
                    sawOpcodeAfterCheckCast(seen);
                break;
            }

            int insTarget = -1;
            if (((seen >= Const.IFEQ) && (seen <= Const.IF_ACMPNE)) || (seen == Const.GOTO) || (seen == Const.GOTO_W)) {
                insTarget = getBranchTarget();
                if (insTarget < getPC()) {
                    insTarget = -1;
                }
            } else if ((seen == Const.LOOKUPSWITCH) || (seen == Const.TABLESWITCH)) {
                insTarget = this.getDefaultSwitchOffset() + getPC();
            }

            if (insTarget > downwardBranchTarget) {
                downwardBranchTarget = insTarget;
            }
        } else {
            state = State.SAW_NOTHING;
            if (getPC() >= downwardBranchTarget) {
                downwardBranchTarget = -1;
            }
        }
    }
1230272
@Override
    public void sawOpcode(int seen) {
        ImmutabilityType imType = null;

        try {
            stack.precomputation(this);

            switch (seen) {
                case Const.INVOKESTATIC:
                case Const.INVOKEINTERFACE:
                case Const.INVOKESPECIAL:
                case Const.INVOKEVIRTUAL: {
                    String className = getClassConstantOperand();
                    String methodName = getNameConstantOperand();
                    String signature = getSigConstantOperand();

                    MethodInfo mi = Statistics.getStatistics().getMethodStatistics(className, methodName, signature);
                    imType = mi.getImmutabilityType();

                    if (seen == Const.INVOKEINTERFACE) {
                        Integer collectionOffset = MODIFYING_METHODS.get(new QMethod(methodName, signature));
                        if ((collectionOffset != null) && CollectionUtils.isListSetMap(className) && (stack.getStackDepth() > collectionOffset.intValue())) {
                            OpcodeStack.Item item = stack.getStackItem(collectionOffset.intValue());
                            ImmutabilityType type = (ImmutabilityType) item.getUserValue();

                            if ((type == ImmutabilityType.IMMUTABLE)
                                    || ((type == ImmutabilityType.POSSIBLY_IMMUTABLE) && (reportedType != ImmutabilityType.POSSIBLY_IMMUTABLE))) {
                                bugReporter.reportBug(new BugInstance(this, BugType.MUC_MODIFYING_UNMODIFIABLE_COLLECTION.name(),
                                        (type == ImmutabilityType.IMMUTABLE) ? HIGH_PRIORITY : NORMAL_PRIORITY).addClass(this).addMethod(this)
                                                .addSourceLine(this));
                                if (type == ImmutabilityType.IMMUTABLE) {
                                    throw new StopOpcodeParsingException();
                                }

                                reportedType = type;
                            }
                        }
                    }
                }
                break;
                default:
                break;
            }
        } catch (ClassNotFoundException cnfe) {
            bugReporter.reportMissingClass(cnfe);
        } finally {
            stack.sawOpcode(this, seen);
            if ((imType != null) && (stack.getStackDepth() > 0)) {
                OpcodeStack.Item item = stack.getStackItem(0);
                item.setUserValue(imType);
            }

        }
    }