Set<JavaClass> xSubtypes = subtypes.getTransitiveSubtypes(x);
Subtypes subtypes = AnalysisContext.currentAnalysisContext() .getSubtypes();
	public static double deepInstanceOf(JavaClass x, JavaClass y)  {		try {		boolean upcast = Repository.instanceOf( x, y);		if (upcast) return 1.0;		boolean downcast = Repository.instanceOf(y, x);		if (!downcast) {			if (x.isFinal() || y.isFinal()) return 0.0;			if (!x.isInterface() && !y.isInterface()) return 0.0;			}		String xName = x.getClassName().replace('/','.');		String yName = y.getClassName().replace('/','.');		Subtypes subtypes= AnalysisContext.currentAnalysisContext().getSubtypes();		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);		boolean concreteClassesInBoth = false;		for(JavaClass v : both)			if (v.isAbstract())				concreteClassesInBoth = true;		boolean concreteClassesInXButNotY = false;		for(JavaClass v : xButNotY)			if (v.isAbstract())				concreteClassesInXButNotY = true;		if (downcast) {			if (!concreteClassesInXButNotY) return 1.0;			return 0.7;			}					if (both.isEmpty()) {			if (concreteClassesInXButNotY) {				return 0.1;				}			return 0.2;			}		if (!concreteClassesInXButNotY) {			if (concreteClassesInBoth) return 1.0;			return 0.7;			}		if (concreteClassesInBoth) return 0.5;		return 0.4;		} catch (ClassNotFoundException e) {			return 1.0;			}		}