Binding (final PsiType x, final PsiType y, final Set<? super Constraint> constraints) { final Binding binding = balance(x, y, new Balancer() { @Override public Binding varType(final PsiTypeVariable x, final PsiType y) { if (y instanceof Bottom) { return create(); } if (y == null || y instanceof PsiWildcardType) { return null; } final PsiTypeVariable var = myFactory.create(); final Binding binding = create(x, PsiWildcardType.createSuper(PsiManager.getInstance(myProject), var)); binding.addTypeVariable(var); constraints.add(new Subtype(var, y)); return binding; } @Override public Binding varVar(final PsiTypeVariable x, final PsiTypeVariable y) { final int xi = x.getIndex(); final int yi = y.getIndex(); if (xi == yi) return create (); return create (y, PsiWildcardType.createExtends(PsiManager.getInstance(myProject), x)); /* if (xi < yi) { return create(x, y); } else if (yi < xi) { return create(y, x); } else { return create(); } */ } @Override public Binding typeVar(final PsiType x, final PsiTypeVariable y) { if (x == null) { return create(y, Bottom.BOTTOM); } if (x instanceof PsiWildcardType) { return null; } final PsiTypeVariable var = myFactory.create(); final Binding binding = create(y, PsiWildcardType.createExtends(PsiManager.getInstance(myProject), var)); binding.addTypeVariable(var); constraints.add(new Subtype(x, var)); return binding; } }, constraints); return binding != null ? binding.reduceRecursive() : null; }