Set<JavaClass> both = new HashSet<JavaClass>(xSubtypes); both.retainAll(ySubtypes); Set<JavaClass> xButNotY = new HashSet<JavaClass>(xSubtypes); xButNotY.removeAll(ySubtypes);
boolean emptyIntersection = true;  boolean concreteClassesInXButNotY = false; for(JavaClass s : xSubtypes) { if (ySubtypes.contains(s)) emptyIntersection = false; else if (!s.isInterface() && !s.isAbstract()) concreteClassesInXButNotY = true; }
	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);		Set<JavaClass> both = new HashSet<JavaClass>(xSubtypes);		both.retainAll(ySubtypes);		Set<JavaClass> xButNotY = new HashSet<JavaClass>(xSubtypes);		xButNotY.removeAll(ySubtypes);		if (false && yIsSubtypeOfX && both.isEmpty()) {			System.out.println("Strange: y is subtype of x, but no classes in both");			System.out.println("X : " + x.getClassName());			System.out.println("Immediate subtypes:");			for(JavaClass c : subtypes.getImmediateSubtypes(x))				System.out.println("  " + c.getClassName());			System.out.println("transitive subtypes:");			for(JavaClass c : xSubtypes)				System.out.println("  " + c.getClassName());			System.out.println("Y : " + y.getClassName());			System.out.println("Immediate subtypes:");			for(JavaClass c : subtypes.getImmediateSubtypes(y))				System.out.println("  " + c.getClassName());			System.out.println("transitive subtypes:");			for(JavaClass c : ySubtypes)				System.out.println("  " + c.getClassName());					}		boolean concreteClassesInXButNotY = containsConcreteClasses(xButNotY);		if (both.isEmpty()) {			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;	}