implements the visitor to set up the stack and methodToCalledmethods map reports calls to public non final methods from methods called from constructors.

@param classContext
the context object of the currently parsed class
546362
@Override
    public void visitClassContext(final ClassContext classContext) {
        try {
            JavaClass cls = classContext.getJavaClass();
            if (!cls.isFinal()) {
                stack = new OpcodeStack();
                methodToCalledMethods = new HashMap<>();
                super.visitClassContext(classContext);

                if (!methodToCalledMethods.isEmpty()) {
                    reportChainedMethods();
                }
            }
        } finally {
            stack = null;
            methodToCalledMethods = null;
        }
    }
281578
@Override
    public void visitClassContext(ClassContext classContext) {
        try {
            JavaClass cls = classContext.getJavaClass();
            constrainingMethods = buildConstrainingMethods(cls);
            AnnotationEntry[] annotations = cls.getAnnotationEntries();
            classHasAnnotation = !CollectionUtils.isEmpty(annotations);
            stack = new OpcodeStack();
            selfCallTree = new HashMap<>();
            super.visitClassContext(classContext);

            performModifyStateClosure(classContext.getJavaClass());

        } finally {
            stack = null;
            selfCallTree = null;
            curMethod = null;
            constrainingMethods = null;
        }
    }
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;
        }
    }
487424
@Override
    public void visitClassContext(ClassContext clsContext) {

        try {
            stack = new OpcodeStack();
            clsVersion = clsContext.getJavaClass().getMajor();
            unendedZLIBs = new HashMap<>();
            super.visitClassContext(clsContext);
        } finally {
            unendedZLIBs = null;
            stack = 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;
        }
    }
940815
@Override
    public void visitClassContext(ClassContext classContext) {
        try {
            queryLocations = new ArrayList<>();
            loops = new ArrayList<>();
            super.visitClassContext(classContext);
        } finally {
            queryLocations = null;
            loops = null;
        }
    }
736867
public static void setStack(final Collection<String> stack) {
        if (stack.isEmpty() || !useStack) {
            return;
        }
        contextStack.clear();
        contextStack.addAll(stack);
    }
512733
@Override
    public void visitClassContext(ClassContext classContext) {

        if (cloneClass == null) {
            return;
        }

        try {
            cls = classContext.getJavaClass();
            if (cls.implementationOf(cloneClass)) {
                clsName = cls.getClassName();
                stack = new OpcodeStack();
                super.visitClassContext(classContext);
            }
        } catch (ClassNotFoundException cnfe) {
            bugReporter.reportMissingClass(cnfe);
        } finally {
            cls = null;
            stack = null;
        }
    }
1072874
@Override
    public void visitClassContext(ClassContext classContext) {
        JavaClass cls = classContext.getJavaClass();
        cls.accept(this);
    }
80273
@Override
    public void visitClassContext(ClassContext classContext) {
        try {
            classVersion = classContext.getJavaClass().getMajor();
            if (classVersion >= Const.MAJOR_1_4) {
                stack = new OpcodeStack();
                super.visitClassContext(classContext);
            }
        } finally {
            stack = null;
        }
    }
871233
@Override
    public void visitClassContext(ClassContext classContext) {
        try {
            if ((invocationHandlerClass != null) && classContext.getJavaClass().implementationOf(invocationHandlerClass)) {
                return;
            }
            iConst0Looped = new BitSet();
            stack = new OpcodeStack();
            super.visitClassContext(classContext);
        } catch (ClassNotFoundException cnfe) {
            bugReporter.reportMissingClass(cnfe);
        } finally {
            iConst0Looped = null;
            stack = null;
        }
    }
634096
@Override
    public void visitClassContext(ClassContext classContext) {
        try {
            stack = new OpcodeStack();
            nodeCreations = new HashMap<>();
            nodeStores = new HashMap<>();
            super.visitClassContext(classContext);
        } finally {
            stack = null;
            nodeCreations = null;
            nodeStores = null;
        }
    }
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;
    }
946952
@Override
	public void visitClassContext(ClassContext classContext) {
		JavaClass cls = classContext.getJavaClass();
		fieldStatus = FieldStatus.NONE;

		String packageName = cls.getPackageName();
		if (packageName.isEmpty()) {
			bugReporter.reportBug(
					new BugInstance(this, BugType.IMC_IMMATURE_CLASS_NO_PACKAGE.name(), LOW_PRIORITY).addClass(cls));
		}

		if (!packageName.equals(packageName.toLowerCase(Locale.ENGLISH))) {
			bugReporter.reportBug(
					new BugInstance(this, BugType.IMC_IMMATURE_CLASS_UPPER_PACKAGE.name(), LOW_PRIORITY).addClass(cls));
		}

		String simpleClassName = cls.getClassName();
		int dotPos = simpleClassName.lastIndexOf('.');
		if (dotPos >= 0) {
			simpleClassName = simpleClassName.substring(dotPos + 1);
		}
		if (!Character.isUpperCase(simpleClassName.charAt(0))
				&& (simpleClassName.indexOf(Values.INNER_CLASS_SEPARATOR) < 0)
				&& !PACKAGE_INFO.equals(simpleClassName)) {
			bugReporter.reportBug(
					new BugInstance(this, BugType.IMC_IMMATURE_CLASS_LOWER_CLASS.name(), LOW_PRIORITY).addClass(cls));
		}

		if ((!cls.isAbstract()) && (!cls.isEnum()) && (cls.getClassName().indexOf(Values.INNER_CLASS_SEPARATOR) < 0)
				&& !isTestClass(cls)) {

			try {
				boolean clsHasRuntimeAnnotation = classHasRuntimeVisibleAnnotation(cls);
				if (clsHasRuntimeAnnotation) {
					classIsJPAEntity = classIsJPAEntity(cls);
				} else {
					classIsJPAEntity = false;
				}
				HEStatus heStatus = HEStatus.UNKNOWN;

				checkIDEGeneratedParmNames(cls);

				for (Field f : cls.getFields()) {
					if (!f.isStatic() && !f.isSynthetic()) {

						boolean fieldHasRuntimeAnnotation = fieldHasRuntimeVisibleAnnotation(f);
						if (!fieldHasRuntimeAnnotation) {
							/* only report one of these, so as not to flood the report */
							if (!classIsJPAEntity && !hasMethodInHierarchy(cls, Values.TOSTRING,
									SignatureBuilder.SIG_VOID_TO_STRING)) {
								bugReporter.reportBug(new BugInstance(this,
										BugType.IMC_IMMATURE_CLASS_NO_TOSTRING.name(), LOW_PRIORITY).addClass(cls));
								heStatus = HEStatus.NOT_NEEDED;
								break;
							}
							if (heStatus != HEStatus.NOT_NEEDED) {
								String fieldSig = f.getSignature();
								if (fieldSig.startsWith(Values.SIG_QUALIFIED_CLASS_PREFIX)) {
									if (!fieldSig.startsWith("Ljava")) {
										JavaClass fieldClass = Repository
												.lookupClass(SignatureUtils.trimSignature(fieldSig));
										if (!hasMethodInHierarchy(fieldClass, "equals",
												SignatureBuilder.SIG_OBJECT_TO_BOOLEAN)) {
											heStatus = HEStatus.NOT_NEEDED;
										}
									} else if (!fieldSig.startsWith("Ljava/lang/")
											&& !fieldSig.startsWith("Ljava/util/")) {
										heStatus = HEStatus.NOT_NEEDED;
									}
								} else if (!fieldSig.startsWith(Values.SIG_ARRAY_PREFIX)) {
									heStatus = HEStatus.NEEDED;
								}
							}
						} else {
							heStatus = HEStatus.NOT_NEEDED;
						}
					}
				}

				if (!clsHasRuntimeAnnotation && (heStatus == HEStatus.NEEDED)) {
					if (!hasMethodInHierarchy(cls, "equals", SignatureBuilder.SIG_OBJECT_TO_BOOLEAN)) {
						bugReporter.reportBug(
								new BugInstance(this, BugType.IMC_IMMATURE_CLASS_NO_EQUALS.name(), LOW_PRIORITY)
										.addClass(cls));
					} else if (!hasMethodInHierarchy(cls, Values.HASHCODE, SignatureBuilder.SIG_VOID_TO_INT)) {
						bugReporter.reportBug(
								new BugInstance(this, BugType.IMC_IMMATURE_CLASS_NO_HASHCODE.name(), LOW_PRIORITY)
										.addClass(cls));
					}
				}

			} catch (ClassNotFoundException cnfe) {
				bugReporter.reportMissingClass(cnfe);
			}
		}

		super.visitClassContext(classContext);
	}
703281
@Override
  public Object invoke(final ELContext context, final Object base, final Object method,
      Class<?>[] paramTypes, final Object[] params) {
    if ((base == null) || (method == null)) {
      return null;
    }

    final MethodDescriptor[] methodDescriptors = getMethodDescriptors(context, base);

    if (methodDescriptors != null) {
      final Method m =
          findMethodOrThrow(method.toString(), paramTypes, params, false, methodDescriptors);
      paramTypes = m.getParameterTypes();
    }

    return super.invoke(context, base, method, paramTypes, params);
  }
10700
@Override
    public void visitClassContext(ClassContext classContext) {
        try {
            JavaClass cls = classContext.getJavaClass();
            for (CompareSpec entry : compareClasses) {
                if (cls.implementationOf(entry.getCompareClass())) {
                    methodInfo = entry.getMethodInfo();
                    stack = new OpcodeStack();
                    super.visitClassContext(classContext);
                    break;
                }
            }
        } catch (ClassNotFoundException cnfe) {
            bugReporter.reportMissingClass(cnfe);
        } finally {
            methodInfo = null;
            stack = null;
        }
    }
393538
@Override
    public void visitClassContext(ClassContext classContext) {
        try {
            stack = new OpcodeStack();
            nameOfThisClass = SignatureUtils.getNonAnonymousPortion(classContext.getJavaClass().getClassName());
            formatterLoggers = new HashSet<>();
            super.visitClassContext(classContext);
        } finally {
            formatterLoggers = null;
            stack = null;
        }
    }