BitSet bytecodeSet = classContext.getBytecodeSet(method); if (bytecodeSet == null) continue;
	public void execute() throws CFGBuilderException, DataflowAnalysisException {		if (AnalysisContext.currentAnalysisContext().getBoolProperty(AnalysisFeatures.CONSERVE_SPACE))			throw new IllegalStateException("This should not happen");		Set<Edge> deletedEdgeSet = new HashSet<Edge>();		if (DEBUG)			System.out.println("PruneUnconditionalExceptionThrowerEdges: examining " +			        SignatureConverter.convertMethodSignature(methodGen));		 Subtypes subtypes = AnalysisContext.currentAnalysisContext()			.getSubtypes();		for (Iterator<BasicBlock> i = cfg.blockIterator(); i.hasNext();) {			BasicBlock basicBlock = i.next();			if (!basicBlock.isExceptionThrower())				continue;			Instruction exceptionThrower = basicBlock.getExceptionThrower().getInstruction();			if (!(exceptionThrower instanceof InvokeInstruction))				continue;			InvokeInstruction inv = (InvokeInstruction) exceptionThrower;			try {				String className = inv.getClassName(cpg);				if (className.startsWith("["))					continue;				String methodSig = inv.getSignature(cpg);				if (!methodSig.endsWith("V")) 					continue;				JavaClass javaClass = Repository.lookupClass(className);				ClassContext classContext = analysisContext.getClassContext(javaClass);				if (DEBUG) System.out.println("\tlooking up method for " + basicBlock.getExceptionThrower());				JavaClassAndMethod classAndMethod = Hierarchy.findExactMethod(inv, cpg);				if (classAndMethod == null) {					if (DEBUG) System.out.println("\tNOT FOUND");					continue;				}				Method method = classAndMethod.getMethod();				XMethod xMethod = XFactory.createXMethod(javaClass, method);				if (DEBUG) System.out.println("\tFound " + xMethod);				// FIXME: for now, only allow static and private methods.				// Could also allow final methods (but would require class hierarchy				// search).				if (!(method.isStatic() || method.isPrivate() || method.isFinal() || javaClass.isFinal() || !subtypes.hasSubtypes(javaClass)))					continue;								// Ignore abstract and native methods				if (method.getCode() == null) continue;								BitSet bytecodeSet = classContext.getBytecodeSet(method);				if (bytecodeSet == null) continue;								Boolean isUnconditionalThrower = cachedResults.get(xMethod);				if (isUnconditionalThrower == null) {					if (DEBUG) System.out.println("\tChecking " + xMethod);					isUnconditionalThrower = !bytecodeSet.intersects(RETURN_OPCODE_SET);					if (DEBUG && isUnconditionalThrower) {						System.out.println("Return opcode set: " + RETURN_OPCODE_SET);						System.out.println("Code opcode set: " + bytecodeSet);																	}					cachedResults.put(xMethod, isUnconditionalThrower);				}				if (false && isUnconditionalThrower.booleanValue()) {				    MethodGen calledMethodGen = classContext.getMethodGen(method);					// Ignore abstract and native methods					if (calledMethodGen == null)						continue;					// Analyze exception paths of called method					// to see if it always throws an unhandled exception.					CFG calledCFG = classContext.getCFG(method);					ReturnPathDataflow pathDataflow = classContext							.getReturnPathDataflow(method);					ReturnPath pathValue = pathDataflow.getStartFact(calledCFG							.getExit());					isUnconditionalThrower = pathValue.getKind() != ReturnPath.RETURNS;					// System.out.println("isThrower: " + result + " " + method.getCode().getLength() + " " + method);					if (true) cachedResults.put(xMethod, isUnconditionalThrower);				}				if (isUnconditionalThrower.booleanValue()) {					// Method always throws an unhandled exception					// Remove the normal control flow edge from the CFG.					Edge fallThrough = cfg.getOutgoingEdgeWithType(basicBlock,							FALL_THROUGH_EDGE);					if (fallThrough != null) {						if (DEBUG) {							System.out.println("\tREMOVING normal return for: " + xMethod);						}						deletedEdgeSet.add(fallThrough);					}				}			} catch (ClassNotFoundException e) {				analysisContext.getLookupFailureCallback().reportMissingClass(e);			}		}		// Remove all edges marked for deletion		for (Edge edge : deletedEdgeSet) {			cfg.removeEdge(edge);		}	}