private static void process(@NotNull TransformationContext context, @NotNull PairConsumer<? super PsiClass, ? super PsiSubstitutor> consumer) {
    Deque<Pair<PsiClass, PsiSubstitutor>> stack = new ArrayDeque<>();

    for (PsiClassType superType : context.getSuperTypes()) {
      ClassResolveResult result = superType.resolveGenerics();
      PsiClass superClass = result.getElement();
      if (superClass == null) continue;
      stack.push(Pair.create(superClass, result.getSubstitutor()));
    }

    Set<PsiClass> visited = new HashSet<>();

    while (!stack.isEmpty()) {
      Pair<PsiClass, PsiSubstitutor> current = stack.pop();
      PsiClass currentClass = current.first;
      if (currentClass == context.getCodeClass()) {
        continue;
      }
      PsiSubstitutor currentSubstitutor = current.second;
      if (!visited.add(currentClass)) continue;
      if (GrTraitUtil.isTrait(currentClass)) {
        consumer.consume(currentClass, currentSubstitutor);
      }
      for (PsiClass superClass : currentClass.getSupers()) {
        PsiSubstitutor superSubstitutor = TypeConversionUtil.getSuperClassSubstitutor(superClass, currentClass, currentSubstitutor);
        stack.push(Pair.create(superClass, superSubstitutor));
      }
    }
  }
private static void process(@NotNull TransformationContext context, @NotNull PairConsumer<? super PsiClass, ? super PsiSubstitutor> consumer)