implements the visitor to make sure the class is at least java 1.4 and to reset the opcode stack
481095
@Override
    public void visitClassContext(ClassContext classContext) {
        try {
            JavaClass cls = classContext.getJavaClass();
            if (cls.getMajor() >= Const.MAJOR_1_4) {
                stack = new OpcodeStack();
                regValueType = new HashMap<Integer, State>();
                super.visitClassContext(classContext);
            }
        } finally {
            stack = null;
            regValueType = null;
        }
    }
710005
@Override
    public void visitClassContext(ClassContext classContext) {
        try {
            stack = new OpcodeStack();
            registerConstants = new HashMap<>();
            overloadedMethods = collectOverloadedMethods(classContext.getJavaClass());
            super.visitClassContext(classContext);
        } finally {
            stack = null;
            registerConstants = null;
            overloadedMethods = null;
        }
    }
626451
@Override
    public void visitCode(Code obj) {
        Method m = getMethod();

        if (m.isSynthetic()) {
            return;
        }

        String signature = m.getSignature();
        if (!signature.endsWith(")Ljava/lang/Object;")) {
            return;
        }
        stack.resetForMethodEntry(this);
        returnTypes.clear();
        super.visitCode(obj);
        if (returnTypes.size() <= 1) {
            return;
        }
        String methodName = m.getName();
        try {
            boolean isInherited = SignatureUtils.isInheritedMethod(currentClass, methodName, signature);

            int priority = NORMAL_PRIORITY;
            for (JavaClass cls : returnTypes.keySet()) {
                if ((cls != null) && Values.DOTTED_JAVA_LANG_OBJECT.equals(cls.getClassName())) {
                    priority = LOW_PRIORITY;
                    break;
                }
            }

            JavaClass cls = findCommonType(returnTypes.keySet());
            BugInstance bug;
            if (isInherited) {
                bug = new BugInstance(this, BugType.URV_INHERITED_METHOD_WITH_RELATED_TYPES.name(), priority).addClass(this).addMethod(this);
                if (cls != null) {
                    bug.addString(cls.getClassName());
                }
            } else if (cls == null) {
                bug = new BugInstance(this, BugType.URV_UNRELATED_RETURN_VALUES.name(), priority).addClass(this).addMethod(this);
            } else {
                bug = new BugInstance(this, BugType.URV_CHANGE_RETURN_TYPE.name(), priority).addClass(this).addMethod(this);
                bug.addString(cls.getClassName());
            }
            for (Integer pc : returnTypes.values()) {
                bug.addSourceLine(this, pc.intValue());
            }
            bugReporter.reportBug(bug);
        } catch (ClassNotFoundException cnfe) {
            bugReporter.reportMissingClass(cnfe);
        }
    }
966689
@Override
    public void visitCode(Code obj) {
        Method method = getMethod();

        if (method.isSynthetic()) {
            return;
        }

        declaredCheckedExceptions.clear();
        stack.resetForMethodEntry(this);

        ExceptionTable et = method.getExceptionTable();
        if (et != null) {
            if (classIsFinal || classIsAnonymous || method.isStatic() || method.isPrivate() || method.isFinal()
                    || ((Values.CONSTRUCTOR.equals(method.getName()) && !isAnonymousInnerCtor(method, getThisClass())))) {
                String[] exNames = et.getExceptionNames();
                for (String exName : exNames) {
                    try {
                        JavaClass exCls = Repository.lookupClass(exName);
                        if (!exCls.instanceOf(runtimeExceptionClass)) {
                            declaredCheckedExceptions.add(exName);
                        }
                    } catch (ClassNotFoundException cnfe) {
                        bugReporter.reportMissingClass(cnfe);
                    }
                }
                if (!declaredCheckedExceptions.isEmpty()) {
                    try {
                        super.visitCode(obj);
                        if (!declaredCheckedExceptions.isEmpty()) {
                            BugInstance bi = new BugInstance(this, BugType.BED_BOGUS_EXCEPTION_DECLARATION.name(), NORMAL_PRIORITY).addClass(this)
                                    .addMethod(this).addSourceLine(this, 0);
                            for (String ex : declaredCheckedExceptions) {
                                bi.addString(ex.replaceAll("/", "."));
                            }
                            bugReporter.reportBug(bi);
                        }
                    } catch (StopOpcodeParsingException e) {
                        // no exceptions left
                    }
                }
            }

            String[] exNames = et.getExceptionNames();
            for (int i = 0; i < (exNames.length - 1); i++) {
                try {
                    JavaClass exCls1 = Repository.lookupClass(exNames[i]);
                    for (int j = i + 1; j < exNames.length; j++) {
                        JavaClass exCls2 = Repository.lookupClass(exNames[j]);
                        JavaClass childEx;
                        JavaClass parentEx;
                        if (exCls1.instanceOf(exCls2)) {
                            childEx = exCls1;
                            parentEx = exCls2;
                        } else if (exCls2.instanceOf(exCls1)) {
                            childEx = exCls2;
                            parentEx = exCls1;
                        } else {
                            continue;
                        }

                        if (!parentEx.equals(exceptionClass)) {
                            bugReporter.reportBug(new BugInstance(this, BugType.BED_HIERARCHICAL_EXCEPTION_DECLARATION.name(), NORMAL_PRIORITY).addClass(this)
                                    .addMethod(this).addString(childEx.getClassName() + " derives from " + parentEx.getClassName()));
                            return;
                        }

                    }
                } catch (ClassNotFoundException cnfe) {
                    bugReporter.reportMissingClass(cnfe);
                }
            }
        }
    }
152718
@Override
    public void sawOpcode(int seen) {
        try {

            stack.precomputation(this);

            if ((seen == Const.ARETURN) && (stack.getStackDepth() > 0)) {
                OpcodeStack.Item item = stack.getStackItem(0);
                if (item.isNull()) {
                    bugReporter.reportBug(new BugInstance(this, BugType.TBP_TRISTATE_BOOLEAN_PATTERN.name(), NORMAL_PRIORITY).addClass(this).addMethod(this)
                            .addSourceLine(this));
                    throw new StopOpcodeParsingException();
                }
            }
        } finally {
            stack.sawOpcode(this, seen);
        }
    }
41101
@Override
    public void visitCode(Code obj) {
        try {
            stack.resetForMethodEntry(this);
            reportedType = ImmutabilityType.UNKNOWN;
            super.visitCode(obj);
        } catch (StopOpcodeParsingException e) {
            // report type is immutable
        }
    }
228851
@Override
    public void visitClassContext(ClassContext classContext) {
        try {
            stack = new OpcodeStack();
            possibleForLoops = new HashSet<>();
            super.visitClassContext(classContext);
        } finally {
            stack = null;
            possibleForLoops = null;
        }
    }
551276
@Override
    public void visitCode(Code obj) {

        stack.resetForMethodEntry(this);
        localSpecialObjects.clear();
        sawTernary = false;
        super.visitCode(obj);

        for (Integer pc : localSpecialObjects.values()) {
            bugReporter.reportBug(
                    makeLocalBugInstance().addClass(this).addMethod(this).addSourceLine(this, pc.intValue()));
        }
    }
931751
@Override
    public void sawOpcode(int seen) {
        try {
            stack.precomputation(this);

            if ((seen == Const.INVOKEVIRTUAL) || (seen == Const.INVOKEINTERFACE)) {
                String clsName = getClassConstantOperand();
                String methodName = getNameConstantOperand();
                String signature = getSigConstantOperand();

                if ("add".equals(methodName) && SignatureBuilder.SIG_OBJECT_TO_BOOLEAN.equals(signature) && isImplementationOf(clsName, setCls)) {
                    if (stack.getStackDepth() > 1) {
                        OpcodeStack.Item item = stack.getStackItem(0);
                        JavaClass entryCls = item.getJavaClass();
                        if (isImplementationOf(entryCls, collectionCls)) {
                            bugReporter.reportBug(new BugInstance(this, BugType.DSOC_DUBIOUS_SET_OF_COLLECTIONS.name(), NORMAL_PRIORITY).addClass(this)
                                    .addMethod(this).addSourceLine(this));
                        }
                    }
                } else if ("put".equals(methodName) && SignatureBuilder.SIG_TWO_OBJECTS_TO_OBJECT.equals(signature) && isImplementationOf(clsName, setCls)
                        && (stack.getStackDepth() > 2)) {
                    OpcodeStack.Item item = stack.getStackItem(1);
                    JavaClass entryCls = item.getJavaClass();
                    if (isImplementationOf(entryCls, collectionCls)) {
                        bugReporter.reportBug(new BugInstance(this, BugType.DSOC_DUBIOUS_SET_OF_COLLECTIONS.name(), NORMAL_PRIORITY).addClass(this)
                                .addMethod(this).addSourceLine(this));
                    }
                }
            }
        } catch (ClassNotFoundException cnfe) {
            bugReporter.reportMissingClass(cnfe);
        } finally {
            stack.sawOpcode(this, seen);
        }
    }
581120
@Override
    public void visitClassContext(ClassContext classContext) {
        try {
            unusedParms = new BitSet();
            regToParm = new HashMap<>();
            stack = new OpcodeStack();
            super.visitClassContext(classContext);
        } finally {
            stack = null;
            regToParm = null;
            unusedParms.clear();
        }
    }
298936
@Override
    public void visitCode(Code obj) {
        if (prescreen(getMethod())) {
            ifBlocks.clear();
            loadedRegs.clear();
            loopLocations.clear();
            stack.resetForMethodEntry(this);
            state = State.SAW_NOTHING;
            super.visitCode(obj);
        }
    }
1264293
@Override
    public void visitCode(Code obj) {
        Method method = getMethod();
        if (!method.isSynthetic() && prescreen(method)) {
            stack.resetForMethodEntry(this);
            super.visitCode(obj);
        }
    }
428871
@Override
    public void visitClassContext(ClassContext classContext) {
        currentClass = classContext.getJavaClass();

        if (currentClass.getMajor() >= Const.MAJOR_1_8) {
            try {
                stack = new OpcodeStack();
                activeStackOps = new ArrayDeque<>();
                super.visitClassContext(classContext);
            } finally {
                activeStackOps = null;
                stack = null;
            }
        }
        currentClass = null;
    }
1113436
@Override
    public final void visitClass(@Nullable JavaTypeElement oldType, @Nullable JavaTypeElement newType) {
        depth++;
        doVisitClass(oldType, newType);
    }
1319440
@Override
    public void visitCode(Code obj) {
        try {
            Method m = getMethod();
            Type retType = m.getReturnType();
            if ("Ljava/lang/Boolean;".equals(retType.getSignature())) {
                stack.resetForMethodEntry(this);
                super.visitCode(obj);
            }
        } catch (StopOpcodeParsingException e) {
            // if the method was already reported
        }
    }
1320847
@Override
    public void visitClassContext(ClassContext classContext) {
        try {
            ignoreRegs = new BitSet();
            tryBlocks = new BitSet();
            catchHandlers = new BitSet();
            switchTargets = new BitSet();
            monitorSyncPCs = new ArrayList<>(5);
            stack = new OpcodeStack();
            super.visitClassContext(classContext);
        } finally {
            ignoreRegs = null;
            tryBlocks = null;
            catchHandlers = null;
            switchTargets = null;
            monitorSyncPCs = null;
            stack = null;
        }
    }
587520
@Override
    public void visitMethod(Method obj) {
        stack.resetForMethodEntry(this);
        enumRegs.clear();
        super.visitMethod(obj);
    }