if (isSynthetic(method)) return;
	private void analyzeMethod(ClassContext classContext, Method method)			throws CFGBuilderException, DataflowAnalysisException {		CFG cfg = classContext.getCFG(method);		TypeDataflow typeDataflow = classContext.getTypeDataflow(method);		ValueNumberDataflow vnaDataflow = classContext				.getValueNumberDataflow(method);		// get the ValueNumberFrame at entry to a method:		ValueNumberFrame vnaFrameAtEntry = vnaDataflow.getStartFact(cfg				.getEntry());		// get Set of parameter values		Set<ValueNumber> paramValueNumberSet = new HashSet<ValueNumber>();		int firstParam = method.isStatic() ? 0 : 1;		for (int i = firstParam; i < vnaFrameAtEntry.getNumLocals(); ++i) {			paramValueNumberSet.add(vnaFrameAtEntry.getValue(i));		}		ConstantPoolGen cpg = classContext.getConstantPoolGen();		MethodGen methodGen = classContext.getMethodGen(method);		String methodName = methodGen.getClassName() + "."				+ methodGen.getName();		String sourceFile = classContext.getJavaClass().getSourceFileName();		if (DEBUG) {			System.out.println("Checking " + methodName);		}		Set<SourceLineAnnotation> haveInstanceOf = new HashSet<SourceLineAnnotation>();		Set<SourceLineAnnotation> haveCast = new HashSet<SourceLineAnnotation>();		Set<SourceLineAnnotation> haveMultipleInstanceOf = new HashSet<SourceLineAnnotation>();		Set<SourceLineAnnotation> haveMultipleCast = new HashSet<SourceLineAnnotation>();		for (Iterator<Location> i = cfg.locationIterator(); i.hasNext();) {			Location location = i.next();			InstructionHandle handle = location.getHandle();			Instruction ins = handle.getInstruction();			if (!(ins instanceof CHECKCAST) && !(ins instanceof INSTANCEOF))				continue;			SourceLineAnnotation sourceLineAnnotation = SourceLineAnnotation					.fromVisitedInstruction(classContext, methodGen, sourceFile, handle);			if (ins instanceof CHECKCAST) {				if (!haveCast.add(sourceLineAnnotation))					haveMultipleCast.add(sourceLineAnnotation);			} else {				if (!haveInstanceOf.add(sourceLineAnnotation))					haveMultipleInstanceOf.add(sourceLineAnnotation);			}		}		for (Iterator<Location> i = cfg.locationIterator(); i.hasNext();) {			Location location = i.next();			InstructionHandle handle = location.getHandle();			int pc = handle.getPosition();			Instruction ins = handle.getInstruction();			if (!(ins instanceof CHECKCAST) && !(ins instanceof INSTANCEOF))				continue;			boolean isCast = ins instanceof CHECKCAST;			String kind = isCast ? "checkedCast" : "instanceof";			int occurrences = cfg.getLocationsContainingInstructionWithOffset(					pc).size();			boolean split = occurrences > 1;			if (DEBUG) {				System.out						.println(kind + " at pc: " + pc + " in " + methodName);				System.out.println(" occurrences: " + occurrences);			}			if (split && !isCast) {				// don't report this case; it might be infeasible due to inlining				continue;			}			TypeFrame frame = typeDataflow.getFactAtLocation(location);			if (!frame.isValid()) {				// This basic block is probably dead				continue;			}			Type operandType = frame.getTopValue();			if (operandType.equals(TopType.instance())) {				// unreachable				continue;			}			if (!(operandType instanceof ReferenceType)) {				// Shouldn't happen - illegal bytecode				continue;			}			ReferenceType refType = (ReferenceType) operandType;			Type castType = ((TypedInstruction) ins).getType(cpg);			if (!(castType instanceof ReferenceType)) {				// This shouldn't happen either				continue;			}			if (refType.equals(castType)) {				// System.out.println("self-cast to " + castType.getSignature());				continue;			}			if (refType.equals(NullType.instance())) {				// Value is a literal null				System.out.println("cast of null value to "						+ castType.getSignature() + " in " + methodName);				continue;			}			String castSig = castType.getSignature();			String refSig = refType.getSignature();			String castSig2 = castSig;			String refSig2 = refSig;			while (castSig2.charAt(0) == '[' && refSig2.charAt(0) == '[') {				castSig2 = castSig2.substring(1);				refSig2 = refSig2.substring(1);			}			if (refSig2.equals("Ljava/lang/Object;")) {				// System.out.println("cast of object value to " + castType.getSignature());				continue;			}			if (refSig2.charAt(0) != 'L' || castSig2.charAt(0) != 'L') {				// cast involving primative arrays				continue;			}			SourceLineAnnotation sourceLineAnnotation = SourceLineAnnotation					.fromVisitedInstruction(classContext, methodGen, sourceFile, handle);			if (isCast && haveMultipleCast.contains(sourceLineAnnotation)					|| !isCast					&& haveMultipleInstanceOf.contains(sourceLineAnnotation)) {				// skip; might be due to JSR inlining				continue;			}			String castName = castSig2.substring(1, castSig2.length() - 1)					.replace('/', '.');			String refName = refSig2.substring(1, refSig2.length() - 1)					.replace('/', '.');			ValueNumberFrame vFrame = vnaDataflow.getFactAtLocation(location);			boolean isParameter = paramValueNumberSet.contains(vFrame					.getTopValue());			try {				JavaClass castJavaClass = Repository.lookupClass(castName);				JavaClass refJavaClass = Repository.lookupClass(refName);				boolean upcast = Repository.instanceOf(refJavaClass,						castJavaClass);				if (upcast) {					if (!isCast)						bugReporter.reportBug(new BugInstance(this,								"BC_VACUOUS_INSTANCEOF", NORMAL_PRIORITY)								.addClassAndMethod(methodGen, sourceFile)								.addSourceLine(sourceLineAnnotation).addClass(										refName.replace('/', '.')).addClass(										castName.replace('/', '.')));				} else {					boolean downcast = Repository.instanceOf(castJavaClass,							refJavaClass);					double rank = Analyze.deepInstanceOf(refJavaClass,							castJavaClass);					boolean castToConcreteCollection = concreteCollectionClasses.contains(castName)								&& abstractCollectionClasses.contains(refName);					boolean castToAbstractCollection = 							abstractCollectionClasses.contains(castName)							&& veryAbstractCollectionClasses.contains(refName);					if (castToConcreteCollection						&& rank > 0.6)					  rank = (rank + 0.6) /2;					else if (castToAbstractCollection						&& rank > 0.3)					  rank = (rank + 0.3) /2;											if (false)						System.out.println("Rank:\t" + rank + "\t" + refName								+ "\t" + castName);					boolean completeInformation = (!castJavaClass.isInterface() && !refJavaClass							.isInterface())							|| refJavaClass.isFinal()							|| castJavaClass.isFinal();					if (DEBUG) {						System.out.println("cast from " + refName + " to "								+ castName);						System.out.println("  is downcast: " + downcast);						System.out.println("  complete information: "								+ completeInformation);						System.out.println("  isParameter: "								+ vFrame.getTopValue());						System.out.println("  score: " + rank);					}					if (!downcast && completeInformation)						bugReporter.reportBug(new BugInstance(this,								isCast ? "BC_IMPOSSIBLE_CAST"										: "BC_IMPOSSIBLE_INSTANCEOF",								isCast ? HIGH_PRIORITY : NORMAL_PRIORITY)								.addClassAndMethod(methodGen, sourceFile)								.addSourceLine(sourceLineAnnotation).addClass(										refName.replace('/', '.')).addClass(										castName.replace('/', '.')));					else if (isCast && rank < 0.9) {						int priority = NORMAL_PRIORITY;						if (rank > 0.75)							priority += 2;						else if (rank > 0.5)							priority += 1;						else if (rank > 0.25)							priority += 0;						else							priority--;						if (DEBUG)							System.out.println(" priority a: " + priority);						if (methodGen.getClassName().startsWith(refName)								|| methodGen.getClassName().startsWith(castName))							priority += 1;						if (DEBUG)							System.out.println(" priority b: " + priority);						if (castJavaClass.isInterface() && !castToAbstractCollection)							priority++;						if (DEBUG)							System.out.println(" priority c: " + priority);						if (castToConcreteCollection							&& veryAbstractCollectionClasses.contains(refName))							priority--;						if (DEBUG)							System.out.println(" priority d: " + priority);						if (priority <= LOW_PRIORITY 								&& !castToAbstractCollection								&& !castToConcreteCollection								&& (refJavaClass.isInterface() || refJavaClass										.isAbstract()))							priority++;						if (DEBUG)							System.out.println(" priority e: " + priority);						if (DEBUG)							System.out.println(" ref name: " + refName);						if (methodGen.getName().equals("compareTo"))							priority++;						else if (methodGen.isPublic() && isParameter)							priority--;						if (DEBUG)							System.out.println(" priority h: " + priority);						if (priority < HIGH_PRIORITY)							priority = HIGH_PRIORITY;						if (priority <= LOW_PRIORITY) {							String bug = "BC_UNCONFIRMED_CAST";							if (castToConcreteCollection)								bug = "BC_BAD_CAST_TO_CONCRETE_COLLECTION";							else if (castToAbstractCollection)								bug = "BC_BAD_CAST_TO_ABSTRACT_COLLECTION";							bugReporter.reportBug(new BugInstance(this, bug,									priority).addClassAndMethod(methodGen,									sourceFile).addSourceLine(									sourceLineAnnotation).addClass(									refName.replace('/', '.')).addClass(									castName.replace('/', '.')));						}					}				}			} catch (ClassNotFoundException e) {			}		}	}