bugReporter.reportBug(new BugInstance(this, "HE_EQUALS_USE_HASHCODE", priority).addClass(getDottedClassName()));
BugInstance bug = new BugInstance(this, "HE_EQUALS_USE_HASHCODE", priority).addClass(getDottedClassName()); if (equalsMethod != null) bug.addMethod(equalsMethod); bugReporter.reportBug(bug);
	public void visitAfter(JavaClass obj) {		if (!obj.isClass()) return;		if (getDottedClassName().equals("java.lang.Object")) return;		int accessFlags = obj.getAccessFlags();		if ((accessFlags & ACC_INTERFACE) != 0) return;		visibleOutsidePackage = obj.isPublic() || obj.isProtected();		String whereEqual = getDottedClassName();		boolean classThatDefinesEqualsIsAbstract = false;		boolean inheritedHashCodeIsFinal = false;		boolean inheritedEqualsIsFinal = false;		boolean inheritedEqualsIsAbstract = false;		if (!hasEqualsObject) {			JavaClass we = Lookup.findSuperImplementor(obj, "equals",			        "(Ljava/lang/Object;)Z", bugReporter);			if (we == null) {				whereEqual = "java.lang.Object";			} else {				whereEqual = we.getClassName();				classThatDefinesEqualsIsAbstract = we.isAbstract();				Method m = findMethod(we, "equals", "(Ljava/lang/Object;)Z");				if (m != null && m.isFinal()) inheritedEqualsIsFinal = true;				if (m != null && m.isAbstract()) inheritedEqualsIsAbstract = true;			}		}		boolean usesDefaultEquals = whereEqual.equals("java.lang.Object");		String whereHashCode = getDottedClassName();		if (!hasHashCode) {			JavaClass wh = Lookup.findSuperImplementor(obj, "hashCode",			        "()I", bugReporter);			if (wh == null) {				whereHashCode = "java.lang.Object";			} else {				whereHashCode = wh.getClassName();				Method m = findMethod(wh, "hashCode", "()I");				if (m != null && m.isFinal()) inheritedHashCodeIsFinal = true;			}		}		boolean usesDefaultHashCode = whereHashCode.equals("java.lang.Object");		if (false && (usesDefaultEquals || usesDefaultHashCode)) {			try {				if (Repository.implementationOf(obj, "java/util/Set")				        || Repository.implementationOf(obj, "java/util/List")				        || Repository.implementationOf(obj, "java/util/Map")) {					// System.out.println(getDottedClassName() + " uses default hashCode or equals");				}			} catch (ClassNotFoundException e) {				// e.printStackTrace();			}		}		if (!hasEqualsObject && hasEqualsSelf) {			if (usesDefaultEquals) {				int priority = HIGH_PRIORITY;				if (usesDefaultHashCode || obj.isAbstract())					priority++;				if (!visibleOutsidePackage)					priority++;				bugReporter.reportBug(new BugInstance(this, "EQ_SELF_USE_OBJECT", priority).addClass(getDottedClassName()));			} else {				int priority = NORMAL_PRIORITY;				if (hasFields)					priority--;				if (obj.isAbstract()) priority++;				bugReporter.reportBug(new BugInstance(this, "EQ_SELF_NO_OBJECT", priority).addClass(getDottedClassName()));			}		}		/*		System.out.println("Class " + betterClassName);		System.out.println("usesDefaultEquals: " + usesDefaultEquals);		System.out.println("hasHashCode: : " + hasHashCode);		System.out.println("usesDefaultHashCode: " + usesDefaultHashCode);		System.out.println("hasEquals: : " + hasEqualsObject);		*/		if (!hasCompareToObject && hasCompareToSelf) {			if (!extendsObject)				bugReporter.reportBug(new BugInstance(this, "CO_SELF_NO_OBJECT", NORMAL_PRIORITY).addClass(getDottedClassName()));		}		// if (!hasFields) return;		if (hasHashCode && !hashCodeIsAbstract && !(hasEqualsObject || hasEqualsSelf)) {			int priority = LOW_PRIORITY;			if (usesDefaultEquals)				bugReporter.reportBug(new BugInstance(this, "HE_HASHCODE_USE_OBJECT_EQUALS", priority).addClass(getDottedClassName()));			else if (!inheritedEqualsIsFinal)				bugReporter.reportBug(new BugInstance(this, "HE_HASHCODE_NO_EQUALS", priority).addClass(getDottedClassName()));		}		if (!hasHashCode		        && (hasEqualsObject && !equalsObjectIsAbstract || hasEqualsSelf)) {			if (usesDefaultHashCode) {				int priority = HIGH_PRIORITY;				if (equalsMethodIsInstanceOfEquals)					priority += 2;				else if (obj.isAbstract() || !hasEqualsObject) priority++;				if (!visibleOutsidePackage) {					priority++;				}				bugReporter.reportBug(new BugInstance(this, "HE_EQUALS_USE_HASHCODE",				        priority).addClass(getDottedClassName()));			} else if (!inheritedHashCodeIsFinal) {				int priority = LOW_PRIORITY;				if (hasEqualsObject && inheritedEqualsIsAbstract)					priority++;				if (hasFields) priority--;				if (equalsMethodIsInstanceOfEquals || !hasEqualsObject)					priority += 2;				else if (obj.isAbstract()) priority++;				bugReporter.reportBug(new BugInstance(this, "HE_EQUALS_NO_HASHCODE",				        priority)				        .addClass(getDottedClassName()));			}		}		if (!hasHashCode && !hasEqualsObject && !hasEqualsSelf		        && !usesDefaultEquals && usesDefaultHashCode		        && !obj.isAbstract() && classThatDefinesEqualsIsAbstract) {			bugReporter.reportBug(new BugInstance(this, "HE_INHERITS_EQUALS_USE_HASHCODE",			        NORMAL_PRIORITY).addClass(getDottedClassName()));		}	}