TypeConstraint (@NotNull Constrained other) { Set<Exact> notTypes = new HashSet<>(this.myNotInstanceOf); notTypes.retainAll(other.myNotInstanceOf); Set<Exact> instanceOfTypes; if (this.myInstanceOf.containsAll(other.myInstanceOf)) { instanceOfTypes = other.myInstanceOf; } else if (other.myInstanceOf.containsAll(this.myInstanceOf)) { instanceOfTypes = this.myInstanceOf; } else { instanceOfTypes = withSuper(this.myInstanceOf); instanceOfTypes.retainAll(withSuper(other.myInstanceOf)); } TypeConstraint constraint = TOP; for (Exact type: instanceOfTypes) { constraint = constraint.meet(type.instanceOf()); } for (Exact type: notTypes) { constraint = constraint.meet(type.notInstanceOf()); } return constraint; }