private static Map<DocumentReference, Map<Integer, MutableActionChangeRange>> decompose(@NotNull UndoableGroup group, boolean isRedo) {
    Map<DocumentReference, Map<Integer, MutableActionChangeRange>> reference2Ranges = new HashMap<>();
    for (UndoableAction action : group.getActions()) {
      if (!(action instanceof AdjustableUndoableAction adjustable)) {
        continue;
      }
      DocumentReference[] affected = adjustable.getAffectedDocuments();
      if (affected == null) {
        continue;
      }
      for (DocumentReference reference : affected) {
        Map<Integer, MutableActionChangeRange> savedChangeRanges = reference2Ranges.computeIfAbsent(reference, r -> new HashMap<>());
        for (MutableActionChangeRange changeRange : adjustable.getChangeRanges(reference)) {
          MutableActionChangeRange range = isRedo ? changeRange.asInverted() : changeRange;
          savedChangeRanges.put(range.getId(), range);
        }
      }
    }
    return reference2Ranges;
  }
private static Map<DocumentReference, Map<Integer, MutableActionChangeRange>> decompose(@NotNull UndoableGroup group, boolean isRedo)