@NotNull
  private static ReduceResult unwrapSealedTypes(@NotNull Set<? extends PatternDescription> existedPatterns,
                                                @NotNull ReduceCache cache) {
    Set<PatternDescription> result = new HashSet<>(existedPatterns);
    if (existedPatterns.isEmpty()) return new ReduceResult(result, false);
    List<PatternDeconstructionDescription> deconstructionExistedPatterns =
      ContainerUtil.filterIsInstance(existedPatterns, PatternDeconstructionDescription.class);
    if (deconstructionExistedPatterns.isEmpty()) return new ReduceResult(result, false);
    ReduceUnwrapContext cacheContext = new ReduceUnwrapContext(new HashSet<>(deconstructionExistedPatterns));
    ReduceResult cachedResult = cache.unwrapCache().get(cacheContext);
    if (cachedResult != null) {
      return new ReduceResult(cachedResult.patterns(), cachedResult.patterns().size() != existedPatterns.size());
    }

    Map<PsiType, Set<PatternDeconstructionDescription>> deconstructionPatternsByType =
      StreamEx.of(deconstructionExistedPatterns)
        .groupingBy(t -> t.type(), Collectors.toSet());

    for (Set<PatternDeconstructionDescription> deconstructionExistedPatternWithTheSameType : deconstructionPatternsByType.values()) {
      for (PatternDeconstructionDescription basePattern : deconstructionExistedPatternWithTheSameType) {
        List<? extends PatternDescription> patternDescriptions = basePattern.list();
        for (int i = 0; i < patternDescriptions.size(); i++) {
          PatternDescription baseDescription = patternDescriptions.get(i);
          if (!(baseDescription instanceof PatternTypeTestDescription baseTypeDescription)) continue;
          if (baseTypeDescription.myPsiClass == null) continue;
          if (!PatternsInSwitchBlockHighlightingModel.isAbstractSealed(baseTypeDescription.myPsiClass)) continue;
          for (PatternDeconstructionDescription comparedPattern : deconstructionExistedPatternWithTheSameType) {
            if (comparedPattern == basePattern) continue;
            if (!comparedPattern.type().equals(basePattern.type())) continue;
            if (comparedPattern.list().size() != patternDescriptions.size()) continue;
            PatternDescription comparedDescription = comparedPattern.list().get(i);
            if (!(comparedDescription instanceof PatternTypeTestDescription comparedTypeDescription)) continue;
            if (comparedTypeDescription.myPsiClass == null) continue;
            if (baseTypeDescription.myPsiClass.getManager()
              .areElementsEquivalent(baseTypeDescription.myPsiClass, comparedTypeDescription.myPsiClass)) {
              continue;
            }
            if (!baseTypeDescription.type.isAssignableFrom(comparedTypeDescription.type)) continue;
            if (!isDirectSealedPath(comparedTypeDescription.myPsiClass, baseTypeDescription.myPsiClass, cache, new HashSet<>())) {
              continue;
            }
            result.addAll(createPatternsFrom(i, Set.of(comparedDescription), basePattern));
          }
        }
      }
    }
    ReduceResult reduceResult = new ReduceResult(result, result.size() != existedPatterns.size());
    cache.unwrapCache().put(cacheContext, reduceResult);
    ReduceUnwrapContext newContext =
      new ReduceUnwrapContext(StreamEx.of(reduceResult.patterns()).select(PatternDeconstructionDescription.class).toSet());
    cache.unwrapCache().put(newContext, reduceResult);
    return reduceResult;
  }
@NotNull
  private static ReduceResult unwrapSealedTypes(@NotNull Set<? extends PatternDescription> existedPatterns,
                                                @NotNull ReduceCache cache)