void (final Constraint left, final Constraint right) { final PsiType leftType = left.getLeft(); final PsiType rightType = right.getRight(); final PsiTypeVariable var = (PsiTypeVariable)left.getRight(); if (leftType.equals(rightType)) { final Binding binding = myBindingFactory.create(var, leftType); myConstraints.remove(left); myConstraints.remove(right); mySons = new ResolverTree[]{applyRule(binding)}; return; } Binding riseBinding = myBindingFactory.rise(leftType, rightType, null); Binding sinkBinding = myBindingFactory.sink(leftType, rightType, null); int indicator = (riseBinding == null ? 0 : 1) + (sinkBinding == null ? 0 : 1); if (indicator == 0) { return; } else if ((indicator == 2 && riseBinding.equals(sinkBinding)) || canBePruned(riseBinding)) { indicator = 1; sinkBinding = null; } PsiType[] riseRange = PsiType.EMPTY_ARRAY; PsiType[] sinkRange = PsiType.EMPTY_ARRAY; if (riseBinding != null) { riseRange = getTypeRange(riseBinding.apply(rightType), riseBinding.apply(leftType)); } if (sinkBinding != null) { sinkRange = getTypeRange(sinkBinding.apply(rightType), sinkBinding.apply(leftType)); } if (riseRange.length + sinkRange.length > 0) { myConstraints.remove(left); myConstraints.remove(right); } mySons = new ResolverTree[riseRange.length + sinkRange.length]; for (int i = 0; i < riseRange.length; i++) { final PsiType type = riseRange[i]; mySons[i] = applyRule(riseBinding.compose(myBindingFactory.create(var, type))); } for (int i = 0; i < sinkRange.length; i++) { final PsiType type = sinkRange[i]; mySons[i + riseRange.length] = applyRule(sinkBinding.compose(myBindingFactory.create(var, type))); } }