private void reduceCyclicVariables() {
    final Set<PsiTypeVariable> nodes = new HashSet<>();
    final Set<Constraint> candidates = new HashSet<>();

    final Map<PsiTypeVariable, Set<PsiTypeVariable>> ins = new HashMap<>();
    final Map<PsiTypeVariable, Set<PsiTypeVariable>> outs = new HashMap<>();

    for (final Constraint constraint : myConstraints) {
      final PsiType left = constraint.getLeft();
      final PsiType right = constraint.getRight();

      if (left instanceof PsiTypeVariable leftVar && right instanceof PsiTypeVariable rightVar) {
        candidates.add(constraint);

        nodes.add(leftVar);
        nodes.add(rightVar);

        Set<PsiTypeVariable> in = ins.get(leftVar);
        Set<PsiTypeVariable> out = outs.get(rightVar);

        if (in == null) {
          final Set<PsiTypeVariable> newIn = new HashSet<>();

          newIn.add(rightVar);

          ins.put(leftVar, newIn);
        }
        else {
          in.add(rightVar);
        }

        if (out == null) {
          final Set<PsiTypeVariable> newOut = new HashSet<>();

          newOut.add(leftVar);

          outs.put(rightVar, newOut);
        }
        else {
          out.add(leftVar);
        }
      }
    }

    final DFSTBuilder<PsiTypeVariable> dfstBuilder = new DFSTBuilder<>(new Graph<>() {
      @NotNull
      @Override
      public Collection<PsiTypeVariable> getNodes() {
        return nodes;
      }

      @NotNull
      @Override
      public Iterator<PsiTypeVariable> getIn(final PsiTypeVariable n) {
        final Set<PsiTypeVariable> in = ins.get(n);

        if (in == null) {
          return Collections.emptyIterator();
        }

        return in.iterator();
      }

      @NotNull
      @Override
      public Iterator<PsiTypeVariable> getOut(final PsiTypeVariable n) {
        final Set<PsiTypeVariable> out = outs.get(n);

        if (out == null) {
          return Collections.emptyIterator();
        }

        return out.iterator();
      }
    });

    IntList sccs = dfstBuilder.getSCCs();
    Object2IntMap<PsiTypeVariable> index = new Object2IntOpenHashMap<>();
    int tNumber = 0;
    for (IntListIterator iterator = sccs.iterator(); iterator.hasNext(); ) {
      int size = iterator.nextInt();
      for (int j = 0; j < size; j++) {
        index.put(dfstBuilder.getNodeByTNumber(tNumber + j), tNumber);
      }
      tNumber += size;
    }

    for (Constraint constraint : candidates) {
      if (index.getInt(constraint.getLeft()) == index.getInt(constraint.getRight())) {
        myConstraints.remove(constraint);
      }
    }

    Binding binding = myBindingFactory.create();

    for (PsiTypeVariable fromVar : index.keySet()) {
      PsiTypeVariable toVar = dfstBuilder.getNodeByNNumber(index.getInt(fromVar));
      if (!fromVar.equals(toVar)) {
        binding = binding.compose(myBindingFactory.create(fromVar, toVar));

        if (binding == null) {
          break;
        }
      }
    }

    if (binding != null && binding.nonEmpty()) {
      myCurrentBinding = myCurrentBinding.compose(binding);
      myConstraints = apply(binding);
    }
  }
private void reduceCyclicVariables()