@Override
    public Binding compose(final Binding b) {
      LOG.assertTrue(b instanceof BindingImpl);

      final BindingImpl b1 = this;
      final BindingImpl b2 = (BindingImpl)b;

      final BindingImpl b3 = new BindingImpl();

      for (PsiTypeVariable boundVariable : myBoundVariables) {
        final int i = boundVariable.getIndex();

        final PsiType b1i = b1.myBindings.get(i);
        final PsiType b2i = b2.myBindings.get(i);

        final int flag = (b1i == null ? 0 : 1) + (b2i == null ? 0 : 2);

        switch (flag) {
          case 0 -> {}
          case 1 -> /* b1(i)\b2(i) */
          {
            final PsiType type = b2.apply(b1i);

            if (type == null) {
              return null;
            }

            if (type != PsiTypes.nullType()) {
              b3.myBindings.put(i, type);
              b3.myCyclic = type instanceof PsiTypeVariable;
            }
          }
          case 2 -> /* b2(i)\b1(i) */
          {
            final PsiType type = b1.apply(b2i);

            if (type == null) {
              return null;
            }

            if (type != PsiTypes.nullType()) {
              b3.myBindings.put(i, type);
              b3.myCyclic = type instanceof PsiTypeVariable;
            }
          }
          case 3 ->  /* b2(i) \cap b1(i) */
          {
            final Binding common = rise(b1i, b2i, null);

            if (common == null) {
              return null;
            }

            final PsiType type = common.apply(b1i);
            if (type == null) {
              return null;
            }

            if (type != PsiTypes.nullType()) {
              b3.myBindings.put(i, type);
              b3.myCyclic = type instanceof PsiTypeVariable;
            }
          }
        }
      }

      return b3;
    }
@Override
    public Binding compose(final Binding b)