private @NotNull Map<PsiElement, TextContent> calcContents(PsiElement container) {
    if (container instanceof XmlTag && isNonText((XmlTag)container)) {
      return Collections.emptyMap();
    }

    var classifier = tagClassifier(container);
    var unknownContainer = container instanceof XmlTag && classifier.apply((XmlTag) container) == TagKind.Unknown;

    var fullContent = NotNullLazyValue.lazy(() -> TextContent.psiFragment(PLAIN_TEXT, container));

    var visitor = new PsiRecursiveElementWalkingVisitor() {
      final Map<PsiElement, TextContent> result = new HashMap<>();
      final List<PsiElement> group = new ArrayList<>();
      final Set<Integer> markupIndices = new HashSet<>();
      final Set<XmlTag> inlineTags = new HashSet<>();
      boolean unknownBefore = unknownContainer;

      @Override
      public void visitElement(@NotNull PsiElement each) {
        if (each instanceof XmlTag tag) {
          TagKind kind = classifier.apply(tag);
          if (kind != TagKind.Inline) {
            boolean unknown = kind == TagKind.Unknown;
            flushGroup(unknown);
            unknownBefore = unknown;
            return;
          } else {
            inlineTags.add(tag);
            markupIndices.add(group.size());
          }
        }
        if (each instanceof OuterLanguageElement || each instanceof XmlEntityRef) {
          flushGroup(true);
          unknownBefore = true;
        }

        if (isText(each)) {
          group.add(each);
        }
        super.visitElement(each);
      }

      @Override
      protected void elementFinished(PsiElement element) {
        super.elementFinished(element);
        if (inlineTags.contains(element)) {
          markupIndices.add(group.size());
        }
      }

      private void flushGroup(boolean unknownAfter) {
        int containerStart = container.getTextRange().getStartOffset();
        List<TextContent> components = new ArrayList<>(group.size());
        for (int i = 0; i < group.size(); i++) {
          PsiElement e = group.get(i);
          TextContent component = extractRange(fullContent.getValue(), e.getTextRange().shiftLeft(containerStart));
          if (markupIndices.contains(i)) {
            component = component.excludeRanges(List.of(new Exclusion(0, 0, ExclusionKind.markup)));
          }
          if (markupIndices.contains(i + 1)) {
            component = component.excludeRanges(List.of(new Exclusion(component.length(), component.length(), ExclusionKind.markup)));
          }
          components.add(component);
        }
        TextContent content = TextContent.join(components);
        if (content != null) {
          if (unknownBefore) content = content.markUnknown(TextRange.from(0, 0));
          if (unknownAfter) content = content.markUnknown(TextRange.from(content.length(), 0));
          content = HtmlUtilsKt.nbspToSpace(content.removeIndents(Set.of(' ', '\t')));
          if (content != null) {
            for (PsiElement e : group) {
              result.put(e, content);
            }
          }
        }
        group.clear();
      }
    };
    container.acceptChildren(visitor);
    visitor.flushGroup(unknownContainer);
    return visitor.result;
  }
private @NotNull Map<PsiElement, TextContent> calcContents(PsiElement container)