} }      if (isPossibleIfComparison(edge)) { Obligation obligation; if ((obligation = comparesObligationTypeToNull(edge)) != null) { fact = fact.duplicate(); if (DEBUG) { System.out.println("Deleting " + obligation.toString() + " on edge from comparision " + edge.getSource().getLastInstruction()); } deleteObligation(fact, obligation, edge.getSource().getLastInstruction());
	public void meetInto(StateSet fact, Edge edge, StateSet result)			throws DataflowAnalysisException {		// If the edge is an exception thrown from a method that		// tries to discharge an obligation, then that obligation needs to		// be removed from all states in the input fact.		if (edge.isExceptionEdge() && fact.isValid()) {			BasicBlock sourceBlock = edge.getSource();			InstructionHandle handle = sourceBlock.getExceptionThrower();			Obligation obligation;			if ((obligation = deletesObligation(handle)) != null) {				fact = fact.duplicate();				deleteObligation(fact, obligation, handle);			}		}		final StateSet inputFact = fact;		// Handle easy top and bottom cases		if (inputFact.isTop() || result.isBottom()) {			// Nothing to do		} else if (inputFact.isBottom() || result.isTop()) {			copy(inputFact, result);		} else {			// Various things need to happen here			// - Match up states with equal ObligationSets			// - Paths with multiple occurences of a program point,			//   but different obligation sets on different passes			//   (i.e., obligation created inside a loop but not deleted)			//   (how do we detect this?)			// We will destructively replace the state map of the result fact			// we're building.			final Map<ObligationSet, State> updatedStateMap = result.createEmptyMap();						// Get all of the States from the input fact that don't			// have matching states.  These will be copied verbatim			// into the result fact.			for (Iterator<State> i = inputFact.stateIterator(); i.hasNext(); ) {				State otherState = i.next();				if (result.getStateWithObligationSet(otherState.getObligationSet()) == null) {					// Input fact has a State with an ObligationSet not in					// the result fact.  Add a duplicate of it.					State dup = otherState.duplicate();					updatedStateMap.put(dup.getObligationSet(), dup);				}			}			// Find states from the input fact that have obligation sets			// which match a State in the result fact, and combine them			// into a single State.			StateSet.StateCallback callback = new StateSet.StateCallback() {				public void apply(State state) throws NonexistentObligationException {					// Find state in other fact with same obligation set (if any).					State matchingState = inputFact.getStateWithObligationSet(state.getObligationSet());					if (matchingState != null) {						// Combine the states by using the shorter of the two paths.						if (state.getPath().getLength() > matchingState.getPath().getLength()) {							state.getPath().copyFrom(matchingState.getPath());						}					}					updatedStateMap.put(state.getObligationSet(), state);				}			};						try {				result.applyToAllStatesAndUpdateMap(callback, updatedStateMap);			} catch (NonexistentObligationException e) {				// This can't happen, since we're not removing an obligation.				// But we'll propagate the exception just to be cautious.				throw new DataflowAnalysisException("This shouldn't happen", e);			}		}	}