LinkedList<ObjectType> work = new LinkedList<ObjectType>(); work.add(subtype);
boolean answer = false;
	public boolean isSubtype(ObjectType subtype, ObjectType supertype) throws ClassNotFoundException {		if (Debug.VERIFY_INTEGRITY) {			if (!inheritanceGraph.containsVertex(subtype))				throw new IllegalStateException("Inheritance graph does not contain node " + subtype.getSignature());			if (!inheritanceGraph.containsVertex(supertype))				throw new IllegalStateException("Inheritance graph does not contain node " + supertype.getSignature());		}		// TODO: precompute subtypes and store in a table of bit vectors		// based on type ids.  That would be really fast.		// For now, we do a slow traversal of the inheritance graph.		if (!supertype.isInterface()) {			// Check superclasses: this works for both class instance			// and array types.			while (true) {				if (subtype.equals(supertype))					return true;/*				if (subtype.getState() == )					// FIME: dynamic lookup to find the supertypes					throw new ClassNotFoundException("Unknown superclass for class " + subtype.getSignature());*/				// Ensure supertypes for the class are known				resolveObjectType(subtype);				ObjectType directSuperclass = getSuperclass(subtype);				if (directSuperclass == null) {					// No superclass: we must have reached java.lang.Object,					// which terminates the search.					if (Debug.CHECK_ASSERTIONS && !subtype.getSignature().equals("Ljava/lang/Object;"))						throw new IllegalStateException("Class " + subtype.getSignature() +							" has no supertypes, but is not java.lang.Object");					return false;				}				subtype = directSuperclass;			}		} else {			// Breadth first search through superinterfaces			// and interfaces implemented by superclasses			// TODO: cache the result as a bit vector of type ids.			LinkedList<ObjectType> work = new LinkedList<ObjectType>();			work.add(subtype);			HashSet<ObjectType> visited = new HashSet<ObjectType>();			LinkedList<String> missingClassList = new LinkedList<String>();			boolean answer = false;			while (!work.isEmpty()) {				ObjectType type = work.removeFirst();				if (visited.add(type))					continue;				if (type.equals(supertype)) {					answer = true;					break;				}				try {					// Resolve the type so we know its supertypes.					resolveObjectType(type);					// Add all supertypes to work queue.					for (Iterator<ObjectType> i = inheritanceGraph.successorIterator(type); i.hasNext(); )						work.add(i.next());				} catch (ClassNotFoundException e) {					String missingClassName = ClassNotFoundExceptionParser.getMissingClassName(e);					if (missingClassName == null)						missingClassName = "<unknown class>";					missingClassList.add(missingClassName);				}			}			// Search terminated without finding the superinterface.			// If no part of the class hierarchy was unknown,			// then we have a definitive answer.  Otherwise,			// throw an exception.			if (missingClassList.isEmpty()) {				// TODO: cache bit vector of known supertypes				return answer;			} else				throw new ClassNotFoundException("Class not found: " + missingClassList);		}	}