if (refSig2.equals("Ljava/io/Serializable;")) continue;
	private void analyzeMethod(ClassContext classContext, Method method)			throws CFGBuilderException, DataflowAnalysisException {		if (isSynthetic(method) || !prescreen(classContext, method))			return;		BugAccumulator accumulator = new BugAccumulator(bugReporter);						CFG cfg = classContext.getCFG(method);		TypeDataflow typeDataflow = classContext.getTypeDataflow(method);		IsNullValueDataflow isNullDataflow = classContext.getIsNullValueDataflow(method);		Set<ValueNumber> paramValueNumberSet = null;				ValueNumberDataflow vnaDataflow = null;		ConstantPoolGen cpg = classContext.getConstantPoolGen();		MethodGen methodGen = classContext.getMethodGen(method);		if (methodGen == null) return;		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;			if (handle.getNext() == null) continue;			Instruction nextIns = handle.getNext().getInstruction();			boolean isCast = ins instanceof CHECKCAST;			String kind = isCast ? "checkedCast" : "instanceof";			int occurrences = cfg.getLocationsContainingInstructionWithOffset(					pc).size();			boolean split = occurrences > 1;			IsNullValueFrame nullFrame = isNullDataflow.getFactAtLocation(location);			IsNullValue operandNullness = nullFrame.getTopValue();			if (DEBUG) {				System.out						.println(kind + " at pc: " + pc + " in " + methodName);				System.out.println(" occurrences: " + occurrences);				System.out.println("XXX: " + operandNullness);							}			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;			}			Type castType = ((TypedInstruction) ins).getType(cpg);			if (!(castType instanceof ReferenceType)) {				// This shouldn't happen either				continue;			}			String castSig = castType.getSignature();						if (operandType.equals(NullType.instance()) || operandNullness.isDefinitelyNull()) {				SourceLineAnnotation sourceLineAnnotation = SourceLineAnnotation				.fromVisitedInstruction(classContext, methodGen, sourceFile, handle);				String castName = castSig.substring(1, castSig.length() - 1)				.replace('/', '.');				if (!isCast) accumulator.accumulateBug(new BugInstance(this,						"NP_NULL_INSTANCEOF", NORMAL_PRIORITY)						.addClassAndMethod(methodGen, sourceFile)						.addClass(castName), sourceLineAnnotation);				continue;			}			if (!(operandType instanceof ReferenceType)) {				// Shouldn't happen - illegal bytecode				continue;			}			ReferenceType refType = (ReferenceType) operandType;					if (refType.equals(castType)) {				// System.out.println("self-cast to " + castType.getSignature());				continue;			}						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;") && !(nextIns instanceof InvokeInstruction)) {				// System.out.println("cast of object value to " + castType.getSignature());				continue;			}			SourceLineAnnotation sourceLineAnnotation = SourceLineAnnotation			.fromVisitedInstruction(classContext, methodGen, sourceFile, handle);			if (refSig2.charAt(0) != 'L' || castSig2.charAt(0) != 'L') {				bugReporter.reportBug(						new BugInstance(this,						"BC_IMPOSSIBLE_CAST_PRIMITIVE_ARRAY", HIGH_PRIORITY )						.addClassAndMethod(methodGen, sourceFile)						.addSourceLine(sourceLineAnnotation));				continue;			}						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('/', '.');			if (vnaDataflow == null)				vnaDataflow = classContext				.getValueNumberDataflow(method);			ValueNumberFrame vFrame = vnaDataflow.getFactAtLocation(location);			if (paramValueNumberSet == null) 				paramValueNumberSet = getParameterValueNumbers(classContext, method, cfg);			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)						accumulator.accumulateBug(new BugInstance(this,								"BC_VACUOUS_INSTANCEOF", NORMAL_PRIORITY)								.addClassAndMethod(methodGen, sourceFile)															.addClass(refName.replace('/', '.'))								.addClass(castName.replace('/', '.'))								,sourceLineAnnotation);				} else {					boolean downcast = Repository.instanceOf(castJavaClass,							refJavaClass);					if (false && downcast && refName.equals("java.lang.Object") && nextIns instanceof InvokeInstruction) {						InvokeInstruction nextInvokeIns =  (InvokeInstruction) nextIns;						Type []  argTypes = nextInvokeIns.getArgumentTypes(cpg);						String mName =  nextInvokeIns.getMethodName(cpg);						if (argTypes.length > 0 && !mName.equals("add")) {							Type lastArg = argTypes[argTypes.length - 1];							if (lastArg instanceof ObjectType) {								String name = ((ObjectType)lastArg).getClassName();								if (refName.equals(name))								System.out.println("Cast from " + refName + " to " + castName + " for argument of type " + name	+ " of " + mName										+ " in " + sourceFile + " : " + methodName);							}						}					}					if (refName.equals("java.lang.Object")) continue;					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)																.addClass(refName.replace('/', '.'))								.addClass(castName.replace('/', '.'))								.addSourceLine(sourceLineAnnotation));					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";							accumulator.accumulateBug(new BugInstance(this, bug, priority)									.addClassAndMethod(methodGen, sourceFile)									.addClass(refName.replace('/', '.'))									.addClass(castName.replace('/', '.')),									sourceLineAnnotation									);						}					}				}			} catch (ClassNotFoundException e) {			}		}		accumulator.reportAccumulatedBugs();	}