implements the visitor to collect calls to getAttribute/setAttribute and stores to attributes to see what have been modified without recalling
setAttribute

@param seen
the currently parsed opcode
17166
@Override
    public void sawOpcode(int seen) {
        String attributeName = null;
        boolean sawGetAttribute = false;
        try {
            stack.precomputation(this);

            if (seen == Const.INVOKEINTERFACE) {
                String clsName = getClassConstantOperand();
                if ("javax/servlet/http/HttpSession".equals(clsName)) {
                    String methodName = getNameConstantOperand();
                    if ("getAttribute".equals(methodName)) {
                        if (stack.getStackDepth() > 0) {
                            OpcodeStack.Item item = stack.getStackItem(0);
                            Object con = item.getConstant();
                            if (con instanceof String) {
                                attributeName = (String) con;
                                sawGetAttribute = true;
                            }
                        }
                    } else if ("setAttribute".equals(methodName) && (stack.getStackDepth() > 1)) {
                        OpcodeStack.Item item = stack.getStackItem(1);
                        Object con = item.getConstant();
                        if (con instanceof String) {
                            attributeName = (String) con;
                            changedAttributes.remove(attributeName);
                        }
                    }
                }
            } else if (OpcodeUtils.isALoad(seen)) {
                int reg = RegisterUtils.getALoadReg(this, seen);
                attributeName = savedAttributes.get(Integer.valueOf(reg));
                sawGetAttribute = attributeName != null;
            } else if ((((seen >= Const.ASTORE_0) && (seen <= Const.ASTORE_3)) || (seen == Const.ASTORE)) && (stack.getStackDepth() > 0)) {
                OpcodeStack.Item item = stack.getStackItem(0);
                attributeName = (String) item.getUserValue();
                int reg = RegisterUtils.getAStoreReg(this, seen);
                savedAttributes.put(Integer.valueOf(reg), attributeName);
            }

            if ((seen == Const.INVOKEINTERFACE) || (seen == Const.INVOKEVIRTUAL)) {
                String methodName = getNameConstantOperand();
                Matcher m = modifyingNames.matcher(methodName);
                if (m.matches()) {
                    String signature = getSigConstantOperand();
                    int numArgs = SignatureUtils.getNumParameters(signature);
                    if (stack.getStackDepth() > numArgs) {
                        OpcodeStack.Item item = stack.getStackItem(numArgs);
                        attributeName = (String) item.getUserValue();
                        if (attributeName != null) {
                            changedAttributes.put(attributeName, Integer.valueOf(getPC()));
                        }
                    }
                }
            } else if ((seen >= Const.IASTORE) && (seen <= Const.SASTORE) && (stack.getStackDepth() > 2)) {
                OpcodeStack.Item item = stack.getStackItem(2);
                attributeName = (String) item.getUserValue();
                if (attributeName != null) {
                    changedAttributes.put(attributeName, Integer.valueOf(getPC()));
                }
            }
        } finally {
            TernaryPatcher.pre(stack, seen);
            stack.sawOpcode(this, seen);
            TernaryPatcher.post(stack, seen);
            if (sawGetAttribute && (stack.getStackDepth() > 0)) {
                OpcodeStack.Item item = stack.getStackItem(0);
                item.setUserValue(attributeName);
            }
        }
    }
952969
@Override
    protected void updateVisibility(boolean visible, boolean activated) {
        super.updateVisibility(visible, activated);

        if (registeredComponents != null) {
            for (BaseUIComponent component : registeredComponents) {
                if (!visible) {
                    component.setAttribute(Constants.ATTR_VISIBLE, component.isVisible());
                    component.setVisible(false);
                } else {
                    component.setVisible((Boolean) component.getAttribute(Constants.ATTR_VISIBLE));
                }
            }
        }

        if (visible) {
            checkBusy();
        }

    }
878926
@Override
    public void sawOpcode(int seen) {
        try {
            stack.precomputation(this);

            int sDepth = stack.getStackDepth();
            Iterator<PopInfo> it = popStack.iterator();

            while (it.hasNext()) {
                if (sDepth < it.next().popDepth) {
                    it.remove();
                }
            }

            if ((seen == Const.INVOKESTATIC) && !popStack.isEmpty()) {
                String method = getNameConstantOperand();
                if (method.indexOf(Values.SYNTHETIC_MEMBER_CHAR) < 0) {
                    PopInfo pInfo = popStack.get(0);
                    int numArguments = SignatureUtils.getNumParameters(getSigConstantOperand());
                    if (((numArguments > 0) || (pInfo.popPC == (getPC() - 1))) && (numArguments == (stack.getStackDepth() - pInfo.popDepth))
                            && classDefinesStaticMethod(SignatureUtils.stripSignature(pInfo.popSignature))) {
                        int lineNumber = -1;
                        if (lineNumberTable != null) {
                            lineNumber = lineNumberTable.getSourceLine(getPC());
                        }
                        if (pInfo.popLineNum == lineNumber) {
                            bugReporter.reportBug(new BugInstance(this, BugType.SMII_STATIC_METHOD_INSTANCE_INVOCATION.name(), NORMAL_PRIORITY).addClass(this)
                                    .addMethod(this).addSourceLine(this));
                        }
                        popStack.clear();
                    }
                }
            }

            if ((seen == Const.PUTFIELD) || (seen == Const.ATHROW) || (seen == Const.GOTO) || (seen == Const.GOTO_W)
                    || ((seen >= Const.IFEQ) && (seen <= Const.IF_ACMPNE)) || OpcodeUtils.isAStore(seen)) {
                popStack.clear();
            } else if ((seen == Const.INVOKESPECIAL) || (seen == Const.INVOKEINTERFACE) || (seen == Const.INVOKEVIRTUAL) || (seen == Const.INVOKESTATIC)) {
                if (Values.SIG_VOID.equals(SignatureUtils.getReturnSignature(getSigConstantOperand()))) {
                    popStack.clear();
                }
            }

            if ((seen == Const.POP) && (stack.getStackDepth() > 0)) {
                OpcodeStack.Item itm = stack.getStackItem(0);
                String popSig = itm.getSignature();
                if (popSig.startsWith(Values.SIG_QUALIFIED_CLASS_PREFIX)) {
                    int lineNumber = -1;
                    if (lineNumberTable != null) {
                        lineNumber = lineNumberTable.getSourceLine(getPC());
                    }
                    popStack.add(new PopInfo(getPC(), lineNumber, popSig, sDepth - 1));
                }
            }
        } catch (ClassNotFoundException cnfe) {
            bugReporter.reportMissingClass(cnfe);
            popStack.clear();
        } finally {
            stack.sawOpcode(this, seen);
        }
    }
517443
@Override
    public void sawOpcode(int seen) {
        try {
            stack.precomputation(this);

            if (seen == Const.INVOKEVIRTUAL) {
                checkForTailRecursion();
            }
        } finally {
            stack.sawOpcode(this, seen);
        }
    }
42718
@Override
    public void sawOpcode(int seen) {
        try {
            stack.precomputation(this);

            if (seen == Const.INVOKEVIRTUAL) {
                String clsName = getClassConstantOperand();
                if ("java/io/ObjectOutputStream".equals(clsName)) {
                    String name = getNameConstantOperand();
                    if ("writeObject".equals(name) && (stack.getStackDepth() > 0)) {
                        OpcodeStack.Item item = stack.getStackItem(0);
                        JavaClass cls = item.getJavaClass();

                        if ((cls != null) && (cls.getClassName().indexOf(Values.INNER_CLASS_SEPARATOR) >= 0) && hasOuterClassSyntheticReference(cls)) {
                            bugReporter.reportBug(new BugInstance(this, BugType.PUS_POSSIBLE_UNSUSPECTED_SERIALIZATION.name(), NORMAL_PRIORITY).addClass(this)
                                    .addMethod(this).addSourceLine(this));
                        }
                    }
                }
            }
        } catch (ClassNotFoundException cnfe) {
            bugReporter.reportMissingClass(cnfe);
        } finally {
            stack.sawOpcode(this, seen);
        }
    }
286775
@Override
    public void sawOpcode(int seen) {
        Integer userValue = null;
        try {
            stack.precomputation(this);

            switch (seen) {
                case Const.NEWARRAY:
                case Const.ANEWARRAY: {
                    if (stack.getStackDepth() > 0) {
                        OpcodeStack.Item itm = stack.getStackItem(0);
                        Integer size = (Integer) itm.getConstant();
                        if ((size != null) && (size.intValue() == 1)) {
                            userValue = Values.NEGATIVE_ONE;
                        }
                    }
                }
                break;

                case Const.IASTORE:
                case Const.LASTORE:
                case Const.FASTORE:
                case Const.DASTORE:
                case Const.AASTORE:
                case Const.BASTORE:
                case Const.CASTORE:
                case Const.SASTORE: {
                    userValue = processArrayElementStore();
                }
                break;

                case Const.ASTORE:
                case Const.ASTORE_0:
                case Const.ASTORE_1:
                case Const.ASTORE_2:
                case Const.ASTORE_3: {
                    processLocalStore(seen);
                }
                break;

                case Const.INVOKEVIRTUAL:
                case Const.INVOKEINTERFACE:
                case Const.INVOKESPECIAL:
                case Const.INVOKESTATIC: {
                    processMethodCall();
                }
                break;

                case Const.IALOAD:
                case Const.LALOAD:
                case Const.FALOAD:
                case Const.DALOAD:
                case Const.AALOAD:
                case Const.BALOAD:
                case Const.CALOAD:
                case Const.SALOAD: {
                    if (stack.getStackDepth() >= 2) {
                        OpcodeStack.Item arItm = stack.getStackItem(1);
                        int arReg = arItm.getRegisterNumber();
                        WrapperInfo wi = wrappers.get(Integer.valueOf(arReg));
                        if ((wi != null) && wi.wasArg) {
                            userValue = Integer.valueOf(wi.wrappedReg);
                        }
                    }
                }
                break;

                case Const.ALOAD:
                case Const.ALOAD_0:
                case Const.ALOAD_1:
                case Const.ALOAD_2:
                case Const.ALOAD_3: {
                    int reg = RegisterUtils.getALoadReg(this, seen);
                    WrapperInfo wi = wrappers.get(Integer.valueOf(reg));
                    if (wi != null) {
                        userValue = Integer.valueOf(wi.wrappedReg);
                    }
                }
                break;

                case Const.ISTORE:
                case Const.ISTORE_0:
                case Const.ISTORE_1:
                case Const.ISTORE_2:
                case Const.ISTORE_3:
                case Const.LSTORE:
                case Const.LSTORE_0:
                case Const.LSTORE_1:
                case Const.LSTORE_2:
                case Const.LSTORE_3:
                case Const.DSTORE:
                case Const.DSTORE_0:
                case Const.DSTORE_1:
                case Const.DSTORE_2:
                case Const.DSTORE_3:
                case Const.FSTORE:
                case Const.FSTORE_0:
                case Const.FSTORE_1:
                case Const.FSTORE_2:
                case Const.FSTORE_3: {
                    if (stack.getStackDepth() == 0) {
                        break;
                    }
                    OpcodeStack.Item itm = stack.getStackItem(0);
                    Integer elReg = (Integer) itm.getUserValue();
                    if (elReg == null) {
                        break;
                    }
                    int reg = RegisterUtils.getStoreReg(this, seen);
                    if (elReg.intValue() == reg) {
                        bugReporter.reportBug(new BugInstance(this, BugType.AWCBR_ARRAY_WRAPPED_CALL_BY_REFERENCE.name(), NORMAL_PRIORITY).addClass(this)
                                .addMethod(this).addSourceLine(this));
                    }
                }
                break;

                default:
                break;
            }
        } finally {
            TernaryPatcher.pre(stack, seen);
            stack.sawOpcode(this, seen);
            TernaryPatcher.post(stack, seen);
            if ((userValue != null) && (stack.getStackDepth() > 0)) {
                OpcodeStack.Item itm = stack.getStackItem(0);
                itm.setUserValue(userValue);
            }
        }
    }
268364
@Override
    public void sawOpcode(final int seen) {
        if (stage == Stage.FIND_LOOP_STAGE) {
            sawOpcodeLoop(seen);
        } else {
            sawOpcodeBug(seen);
        }
    }
1350037
private void sawMethodOpcode(int seen) {
        boolean isSyncCollection = false;
        try {
            stack.mergeJumps(this);
            isSyncCollection = isSyncCollectionCreation(seen);

            switch (seen) {
                case Const.INVOKEVIRTUAL:
                case Const.INVOKEINTERFACE:
                    String methodName = getNameConstantOperand();
                    if (modifyingMethods.contains(methodName)) {
                        String signature = getSigConstantOperand();
                        int parmCount = SignatureUtils.getNumParameters(signature);
                        if (stack.getStackDepth() > parmCount) {
                            OpcodeStack.Item item = stack.getStackItem(parmCount);
                            XField field = item.getXField();
                            if (field != null) {
                                collectionFields.remove(field.getName());
                            } else {
                                int reg = item.getRegisterNumber();
                                if (reg >= 0) {
                                    Integer register = Integer.valueOf(reg);
                                    String fName = aliases.get(register);
                                    if (fName != null) {
                                        collectionFields.remove(fName);
                                        aliases.remove(register);
                                    }
                                }
                            }
                        }
                    }
                    removeCollectionParameters();
                break;

                case Const.INVOKESTATIC:
                    removeCollectionParameters();
                break;

                case Const.ARETURN:
                    if (stack.getStackDepth() > 0) {
                        OpcodeStack.Item item = stack.getStackItem(0);
                        XField field = item.getXField();
                        if (field != null) {
                            collectionFields.remove(field.getName());
                        }
                    }
                break;

                case Const.PUTFIELD:
                case Const.PUTSTATIC:
                    String fieldName = getNameConstantOperand();
                    collectionFields.remove(fieldName);
                break;

                case Const.GOTO:
                case Const.GOTO_W:
                    if (stack.getStackDepth() > 0) {
                        OpcodeStack.Item item = stack.getStackItem(0);
                        XField field = item.getXField();
                        if (field != null) {
                            collectionFields.remove(field.getName());
                        }
                    }
                break;
                default:
                break;
            }
        } finally {
            TernaryPatcher.pre(stack, seen);
            stack.sawOpcode(this, seen);
            TernaryPatcher.post(stack, seen);
            if (isSyncCollection && (stack.getStackDepth() > 0)) {
                OpcodeStack.Item item = stack.getStackItem(0);
                item.setUserValue(Boolean.TRUE);
            }
        }

    }
328554
@Override
    public void sawOpcode(int seen) {
        if (seen == Const.INVOKEVIRTUAL) {
            String className = getClassConstantOperand();
            String methodName = getNameConstantOperand();
            String methodSig = getSigConstantOperand();

            FQMethod methodInfo = new FQMethod(className, methodName, methodSig);
            if (oldMethods.contains(methodInfo)) {
                bugReporter.reportBug(new BugInstance(this, BugType.NCMU_NON_COLLECTION_METHOD_USE.name(), NORMAL_PRIORITY).addClass(this).addMethod(this)
                        .addSourceLine(this));
            }
        }
    }
735711
@Override
    public void sawOpcode(int seen) {
        if (seen == Const.INVOKEVIRTUAL) {
            if ("equals".equals(getNameConstantOperand()) && "(Ljava/lang/Object;)Z".equals(getSigConstantOperand())) {
                OpcodeStack.Item item = stack.getStackItem(1);
                ClassDescriptor c = DescriptorFactory.createClassDescriptorFromSignature(item.getSignature());
                check(c);

            } else if ("java/lang/Class".equals(getClassConstantOperand())
                    && ("isInstance".equals(getNameConstantOperand()) || "cast".equals(getNameConstantOperand()))) {
                OpcodeStack.Item item = stack.getStackItem(1);
                if ("Ljava/lang/Class;".equals(item.getSignature())) {
                    Object value = item.getConstant();
                    if (value instanceof String) {
                        ClassDescriptor c = DescriptorFactory.createClassDescriptor((String) value);
                        check(c);
                    }
                }

            }

        } else if (seen == Const.INSTANCEOF || seen == Const.CHECKCAST) {
            check(getClassDescriptorOperand());
        }

    }
206541
private void sawInitOpcode(int seen) {
        boolean isSyncCollection = false;
        try {
            stack.mergeJumps(this);
            isSyncCollection = isSyncCollectionCreation(seen);
            if (seen == Const.PUTFIELD) {
                processCollectionStore();
            }
        } finally {
            stack.sawOpcode(this, seen);
            if (isSyncCollection && (stack.getStackDepth() > 0)) {
                OpcodeStack.Item item = stack.getStackItem(0);
                item.setUserValue(Boolean.TRUE);
            }
        }
    }
715349
@Override
    public void sawOpcode(int seen) {
        switch (state) {
            case SEEN_NOTHING:
                if ((seen == Const.INVOKEINTERFACE) || (seen == Const.INVOKEVIRTUAL)) {
                    String sig = getSigConstantOperand();
                    String returnSig = SignatureUtils.getReturnSignature(sig);
                    if (returnSig.startsWith(Values.SIG_QUALIFIED_CLASS_PREFIX)) {
                        String clsName = getClassConstantOperand();
                        if (!Values.SLASHED_JAVA_LANG_OBJECT.equals(clsName) && !Values.SLASHED_JAVA_LANG_CLASS.equals(clsName)) {
                            returnType = SignatureUtils.trimSignature(returnSig);
                            invokePC = getPC();
                            state = State.SEEN_INVOKE;
                        }
                    }
                }
            break;

            case SEEN_INVOKE:
                if (seen == Const.POP) {
                    state = State.SEEN_POP;
                } else {
                    state = State.SEEN_NOTHING;
                    returnType = null;
                }
            break;

            case SEEN_POP:
                if (((seen >= Const.ACONST_NULL) && (seen <= Const.DCONST_1)) || (seen == Const.GETFIELD)) {
                    state = State.SEEN_POP;
                } else if ((seen == Const.INVOKESTATIC) || (seen == Const.GETSTATIC)) {
                    if (getClassConstantOperand().equals(returnType) && (lnTable.getSourceLine(invokePC) == lnTable.getSourceLine(getPC()))) {
                        bugReporter.reportBug(new BugInstance(this, BugType.NIR_NEEDLESS_INSTANCE_RETRIEVAL.name(), NORMAL_PRIORITY).addClass(this)
                                .addMethod(this).addSourceLine(this));
                    }
                    state = State.SEEN_NOTHING;
                    returnType = null;
                } else {
                    state = State.SEEN_NOTHING;
                    returnType = null;
                }
            break;

            default:
                state = State.SEEN_NOTHING;
                returnType = null;
            break;
        }
    }
129885
@Override
    public void sawOpcode(int seen) {
        if ((seen == Const.GETFIELD) || (seen == Const.PUTFIELD)) {
            String fieldName = getNameConstantOperand();
            FieldInfo fi = localizableFields.get(fieldName);
            if (fi != null) {
                SourceLineAnnotation sla = SourceLineAnnotation.fromVisitedInstruction(this);
                fi.setSrcLineAnnotation(sla);
            }
        }
    }
484232
@Override
    public void sawOpcode(int seen) {
        boolean markAsValid = false;

        try {
            stack.precomputation(this);

            int pc = getPC();
            for (CodeException ex : exceptions) {
                if (pc == ex.getEndPC()) {
                    if (OpcodeUtils.isReturn(seen)) {
                        addCatchBlock(ex.getHandlerPC(), Integer.MAX_VALUE);
                    } else if ((seen == Const.GOTO) || (seen == Const.GOTO_W)) {
                        addCatchBlock(ex.getHandlerPC(), this.getBranchTarget());
                    } else {
                        addCatchBlock(ex.getHandlerPC(), Integer.MAX_VALUE);
                    }
                } else if (pc == ex.getHandlerPC()) {
                    removePreviousHandlers(pc);
                }
            }

            Iterator<CatchInfo> it = catchInfos.iterator();
            while (it.hasNext()) {
                try {
                    CatchInfo catchInfo = it.next();
                    if (pc == catchInfo.getStart()) {
                        if (!updateExceptionRegister(catchInfo, seen, pc)) {
                            it.remove();
                        }
                        break;
                    } else if (pc > catchInfo.getFinish()) {
                        it.remove();
                        break;
                    } else if ((pc > catchInfo.getStart()) && (pc <= catchInfo.getFinish())) {
                        if (seen == Const.INVOKESPECIAL) {
                            if (Values.CONSTRUCTOR.equals(getNameConstantOperand())) {
                                String className = getClassConstantOperand();
                                JavaClass exClass = Repository.lookupClass(className);
                                if (exClass.instanceOf(throwableClass)) {
                                    String sig = getSigConstantOperand();
                                    if ((sig.indexOf("Exception") >= 0) || (sig.indexOf("Throwable") >= 0) || (sig.indexOf("Error") >= 0)) {
                                        markAsValid = true;
                                        break;
                                    }
                                    if (exClass.instanceOf(assertionClass)) {
                                        // just ignore LEST for AssertionErrors
                                        markAsValid = true;
                                        break;
                                    }
                                }
                            } else if (isPossibleExBuilder(catchInfo.getRegister())) {
                                markAsValid = true;
                            }
                        } else if (seen == Const.INVOKEVIRTUAL) {
                            String methodName = getNameConstantOperand();
                            if ("initCause".equals(methodName) || "addSuppressed".equals(methodName)) {
                                if (stack.getStackDepth() > 1) {
                                    String className = getClassConstantOperand();
                                    JavaClass exClass = Repository.lookupClass(className);
                                    if (exClass.instanceOf(throwableClass)) {
                                        OpcodeStack.Item itm = stack.getStackItem(1);
                                        int reg = itm.getRegisterNumber();
                                        if (reg >= 0) {
                                            exReg.put(Integer.valueOf(reg), Boolean.TRUE);
                                        }
                                        markAsValid = true; // Fixes javac generated code
                                    }
                                }
                            } else if ((("getTargetException".equals(methodName) || "getCause".equals(methodName))
                                    && "java/lang/reflect/InvocationTargetException".equals(getClassConstantOperand()))
                                    || "java/io/UncheckedIOException".equals(getClassConstantOperand())) {
                                markAsValid = true;
                            } else if (isPossibleExBuilder(catchInfo.getRegister())) {
                                markAsValid = true;
                            }
                        } else if ((seen == Const.INVOKEINTERFACE) || (seen == Const.INVOKESTATIC)) {
                            if (isPossibleExBuilder(catchInfo.getRegister())) {
                                markAsValid = true;
                            }
                        } else if (seen == Const.ATHROW) {
                            if (stack.getStackDepth() > 0) {
                                OpcodeStack.Item itm = stack.getStackItem(0);
                                if ((itm.getRegisterNumber() != catchInfo.getRegister()) && (itm.getUserValue() == null)) {
                                    if (!isPre14Class(itm.getJavaClass())) {
                                        int priority = getPrevOpcode(1) == Const.MONITOREXIT ? LOW_PRIORITY : NORMAL_PRIORITY;
                                        bugReporter.reportBug(new BugInstance(this, BugType.LEST_LOST_EXCEPTION_STACK_TRACE.name(), priority).addClass(this)
                                                .addMethod(this).addSourceLine(this));
                                    }
                                    it.remove();
                                    break;
                                }
                            }
                            if (catchInfo.getFinish() == Integer.MAX_VALUE) {
                                catchInfo.setFinish(pc);
                            }

                        } else if (OpcodeUtils.isAStore(seen)) {
                            if (lastWasExitPoint) {
                                // crazy jdk6 finally block injection -- shut
                                // off detection
                                catchInfos.clear();
                                break;
                            }

                            if (stack.getStackDepth() > 0) {
                                OpcodeStack.Item itm = stack.getStackItem(0);
                                int reg = RegisterUtils.getAStoreReg(this, seen);
                                exReg.put(Integer.valueOf(reg), (Boolean) itm.getUserValue());
                                if ((reg == catchInfo.getRegister()) && (catchInfo.getFinish() == Integer.MAX_VALUE)) {
                                    it.remove();
                                }
                            }
                        } else if (OpcodeUtils.isALoad(seen)) {
                            Boolean valid = exReg.get(Integer.valueOf(RegisterUtils.getALoadReg(this, seen)));
                            if (valid != null) {
                                markAsValid = valid.booleanValue();
                            }
                        } else if (OpcodeUtils.isReturn(seen)) {
                            removeIndeterminateHandlers(pc);
                            break;
                        }
                    }
                } catch (ClassNotFoundException cnfe) {
                    bugReporter.reportMissingClass(cnfe);
                    it.remove();
                }
            }

            lastWasExitPoint = (seen == Const.GOTO) || (seen == Const.GOTO_W) || (seen == Const.ATHROW) || OpcodeUtils.isReturn(seen);
        } finally {
            TernaryPatcher.pre(stack, seen);
            stack.sawOpcode(this, seen);
            TernaryPatcher.post(stack, seen);
            if (markAsValid && (stack.getStackDepth() > 0)) {
                OpcodeStack.Item itm = stack.getStackItem(0);
                itm.setUserValue(Boolean.TRUE);
            }
        }
    }
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);
            }
        }
    }
418410
@Override
    public void sawOpcode(int seen) {
        if (seen != Const.INVOKESPECIAL) {
            sawOpenInAppendMode = false;
            return;
        }
        String calledClassName = getClassConstantOperand();
        String calledMethodName = getNameConstantOperand();
        String calledMethodSig = getSigConstantOperand();
        if (!sawOpenInAppendMode) {
            if ("java/io/ObjectOutputStream".equals(calledClassName) && Const.CONSTRUCTOR_NAME.equals(calledMethodName)
                    && "(Ljava/io/OutputStream;)V".equals(calledMethodSig)
                    && stack.getStackItem(0).getSpecialKind() == OpcodeStack.Item.FILE_OPENED_IN_APPEND_MODE) {
                bugReporter.reportBug(new BugInstance(this, "IO_APPENDING_TO_OBJECT_OUTPUT_STREAM", Priorities.HIGH_PRIORITY)
                .addClassAndMethod(this).addSourceLine(this));
            }
            return;
        }
        if ("java/io/FileOutputStream".equals(calledClassName) && Const.CONSTRUCTOR_NAME.equals(calledMethodName)
                && ("(Ljava/io/File;Z)V".equals(calledMethodSig) || "(Ljava/lang/String;Z)V".equals(calledMethodSig))) {
            OpcodeStack.Item item = stack.getStackItem(0);
            Object value = item.getConstant();
            sawOpenInAppendMode = value instanceof Integer && ((Integer) value).intValue() == 1;
        } else if ("java/io/BufferedOutputStream".equals(calledClassName) && Const.CONSTRUCTOR_NAME.equals(calledMethodName)
                && "(Ljava/io/OutputStream;)V".equals(calledMethodSig)) {
            // do nothing

        } else if ("java/io/ObjectOutputStream".equals(calledClassName) && Const.CONSTRUCTOR_NAME.equals(calledMethodName)
                && "(Ljava/io/OutputStream;)V".equals(calledMethodSig)) {
            bugReporter.reportBug(new BugInstance(this, "IO_APPENDING_TO_OBJECT_OUTPUT_STREAM", Priorities.HIGH_PRIORITY)
                .addClassAndMethod(this).addSourceLine(this));
            sawOpenInAppendMode = false;
        } else {
            sawOpenInAppendMode = false;
        }

    }
221478
private void sawOpcodeBug(final int seen) {
        try {
            stack.precomputation(this);

            Iterator<ForLoop> it = possibleForLoops.iterator();
            while (it.hasNext()) {
                ForLoop fl = it.next();
                switch (fl.getLoopState()) {
                    case LOOP_NOT_STARTED:
                        if (getPC() == fl.getLoopStart()) {
                            if (OpcodeUtils.isILoad(seen) && (RegisterUtils.getLoadReg(this, seen) == fl.getLoopReg())) {
                                fl.setLoopState(LoopState.LOOP_INDEX_LOADED_FOR_TEST);
                                continue;
                            }

                            it.remove();
                        }
                    break;

                    case LOOP_INDEX_LOADED_FOR_TEST:
                        if (getPC() >= fl.getLoopEnd()) {
                            it.remove();
                            continue;
                        }
                        if (seen == Const.IF_ICMPGE) {
                            if (stack.getStackDepth() > 1) {
                                OpcodeStack.Item itm = stack.getStackItem(0);
                                if (itm.getConstant() != null) {
                                    it.remove();
                                    continue;
                                }
                                XMethod constantSource = itm.getReturnValueOf();
                                if (constantSource != null) {
                                    if (!"size".equals(constantSource.getMethodDescriptor().getName())) {
                                        it.remove();
                                        continue;
                                    }
                                } else if (getPrevOpcode(1) != Const.ARRAYLENGTH) {
                                    it.remove();
                                    continue;
                                }
                            }
                            int branchTarget = getBranchTarget();
                            if ((branchTarget >= (fl.getLoopEnd() + 3)) && (branchTarget <= (fl.getLoopEnd() + 5))) {
                                fl.setLoopState(LoopState.LOOP_IN_BODY);
                                continue;
                            }
                        }
                    break;

                    case LOOP_IN_BODY:
                    case LOOP_IN_BODY_WITH_GET:
                        if ((getPC() == fl.getLoopEnd()) && (fl.getLoopState() == LoopState.LOOP_IN_BODY_WITH_GET)) {
                            bugReporter.reportBug(new BugInstance(this, "LII_LIST_INDEXED_ITERATING", NORMAL_PRIORITY).addClass(this).addMethod(this)
                                    .addSourceLineRange(this, fl.getLoopStart(), fl.getLoopEnd()));
                            it.remove();
                        }
                        if (getPC() > fl.getLoopEnd()) {
                            it.remove();
                        }

                        if (OpcodeUtils.isILoad(seen)) {
                            loopReg = RegisterUtils.getLoadReg(this, seen);
                            if (loopReg == fl.getLoopReg()) {
                                fl.setLoopRegLoaded(true);
                            }
                        } else if (fl.getLoopRegLoaded()) {
                            boolean sawGet = ((seen == Const.INVOKEINTERFACE) && Values.SLASHED_JAVA_UTIL_LIST.equals(getClassConstantOperand())
                                    && "get".equals(getNameConstantOperand()) && SignatureBuilder.SIG_INT_TO_OBJECT.equals(getSigConstantOperand()));
                            if (!sawGet) {
                                it.remove();
                            } else {
                                fl.setLoopState(LoopState.LOOP_IN_BODY_WITH_GET);
                                if (stack.getStackDepth() > 1) {
                                    OpcodeStack.Item itm = stack.getStackItem(0);
                                    if (!itm.couldBeZero()) {
                                        it.remove();
                                    } else {
                                        itm = stack.getStackItem(1);
                                        if (fl.isSecondItem(itm)) {
                                            it.remove();
                                        }
                                    }
                                }
                                fl.setLoopRegLoaded(false);
                            }
                        }
                    break;
                }
            }

        } finally {
            stack.sawOpcode(this, seen);
        }
    }