@NotNull
    private ReduceResult reduceRecordPatterns(@NotNull PsiElement context, @NotNull ReduceCache cache) {
      boolean changed = false;
      Map<PsiType, Set<PatternDeconstructionDescription>> byType = StreamEx.of(patterns)
        .select(PatternDeconstructionDescription.class)
        .groupingBy(t -> t.type(), Collectors.toSet());
      Set<PatternDescription> toRemove = new HashSet<>();
      Set<PatternDescription> toAdd = new HashSet<>();
      Map<PsiType, List<PsiType>> componentCaches = new HashMap<>();
      for (Map.Entry<PsiType, Set<PatternDeconstructionDescription>> entry : byType.entrySet()) {
        Set<PatternDeconstructionDescription> descriptions = entry.getValue();
        if (descriptions.isEmpty()) {
          continue;
        }
        PatternDeconstructionDescription first = descriptions.iterator().next();
        for (int i = 0; i < first.list().size(); i++) {
          MultiMap<List<PatternDescription>, PatternDeconstructionDescription> groupWithoutOneComponent =
            getGroupWithoutOneComponent(descriptions, i);

          for (Map.Entry<List<PatternDescription>, Collection<PatternDeconstructionDescription>> value : groupWithoutOneComponent.entrySet()) {
            Collection<PatternDeconstructionDescription> setWithOneDifferentElement = value.getValue();
            if (setWithOneDifferentElement.isEmpty()) {
              continue;
            }
            int finalI = i;
            Set<PatternDescription> nestedDescriptions = setWithOneDifferentElement.stream()
              .map(t -> t.list().get(finalI))
              .collect(Collectors.toSet());
            PsiType recordType = entry.getKey();
            List<PsiType> componentTypes = componentCaches.get(recordType);
            if (componentTypes == null) {
              componentTypes = getComponentTypes(context, recordType);
              componentCaches.put(recordType, componentTypes);
            }
            if (componentTypes == null || componentTypes.size() <= i) {
              continue;
            }
            LoopReduceResult result = reduceInLoop(componentTypes.get(i), context, nestedDescriptions, (set, type) -> false, cache, true);
            if (result.changed()) {
              changed = true;
              toRemove.addAll(setWithOneDifferentElement);
              toAdd.addAll(createPatternsFrom(i, result.patterns(), setWithOneDifferentElement.iterator().next()));
            }
          }
        }
      }
      if (!changed) {
        return new ReduceResult(patterns, changed());
      }
      return new ReduceResult(combineResult(patterns, toRemove, toAdd), true);
    }
@NotNull
    private ReduceResult reduceRecordPatterns(@NotNull PsiElement context, @NotNull ReduceCache cache)