public static double deepInstanceOf(JavaClass x, JavaClass y) throws ClassNotFoundException {  if (x.equals(y)) return 1.0; boolean xIsSubtypeOfY = Repository.instanceOf(x, y); if (xIsSubtypeOfY) return 1.0; boolean yIsSubtypeOfX = Repository.instanceOf(y, x); if (!yIsSubtypeOfX) { if (x.isFinal() || y.isFinal()) return 0.0; if (!x.isInterface() && !y.isInterface()) return 0.0; }  Subtypes subtypes = AnalysisContext.currentAnalysisContext() .getSubtypes(); subtypes.addClass(x); subtypes.addClass(y);  Set<JavaClass> xSubtypes = subtypes.getTransitiveSubtypes(x);  Set<JavaClass> ySubtypes = subtypes.getTransitiveSubtypes(y);  boolean emptyIntersection = true;  boolean concreteClassesInXButNotY = false; for(JavaClass s : xSubtypes) { if (ySubtypes.contains(s)) emptyIntersection = false; else if (!s.isInterface() && !s.isAbstract()) concreteClassesInXButNotY = true; }   if (emptyIntersection) { if (concreteClassesInXButNotY) { if (x.isAbstract() || x.isInterface()) return 0.2; return 0.1; } return 0.3; }    if (!concreteClassesInXButNotY) {  return 0.99; }   return 0.7;
public static double deepInstanceOf(String x, String y) throws ClassNotFoundException { return deepInstanceOf(AnalysisContext.currentAnalysisContext().lookupClass(x), AnalysisContext.currentAnalysisContext().lookupClass(y));
	public static double deepInstanceOf(JavaClass x, JavaClass y)			throws ClassNotFoundException {		if (x.equals(y))			return 1.0;		boolean xIsSubtypeOfY = Repository.instanceOf(x, y);		if (xIsSubtypeOfY)			return 1.0;		boolean yIsSubtypeOfX = Repository.instanceOf(y, x);		if (!yIsSubtypeOfX) {			if (x.isFinal() || y.isFinal())				return 0.0;			if (!x.isInterface() && !y.isInterface())				return 0.0;		}		Subtypes subtypes = AnalysisContext.currentAnalysisContext()				.getSubtypes();		subtypes.addClass(x);		subtypes.addClass(y);		Set<JavaClass> xSubtypes = subtypes.getTransitiveSubtypes(x);		Set<JavaClass> ySubtypes = subtypes.getTransitiveSubtypes(y);		boolean emptyIntersection = true;				boolean concreteClassesInXButNotY = false;		for(JavaClass s : xSubtypes) {			if (ySubtypes.contains(s)) emptyIntersection = false;			else if (!s.isInterface() && !s.isAbstract())				concreteClassesInXButNotY = true;		}				if (emptyIntersection) {			if (concreteClassesInXButNotY) {				if (x.isAbstract() || x.isInterface()) return 0.2;				return 0.1;			}			return 0.3;		}		// exist classes that are both X and Y		if (!concreteClassesInXButNotY) {			// only abstract/interfaces that are X but not Y			return 0.99;		}		// Concrete classes in X but not Y		return 0.7;	}