public boolean addInjectedBlocks(List<? super Block> result, final ASTNode injectionHost, Wrap wrap, Alignment alignment, Indent indent) {
    Ref<Integer> lastInjectionEndOffset = new Ref<>(0);

    final PsiLanguageInjectionHost.InjectedPsiVisitor injectedPsiVisitor = (injectedPsi, places) -> {
      if (places.isEmpty() || (places.size() != 1 && !supportsMultipleFragments())) {
        return;
      }
      PsiLanguageInjectionHost.Shred firstShred = places.get(0);
      PsiLanguageInjectionHost.Shred lastShred = places.get(places.size() - 1);
      PsiLanguageInjectionHost shredHost = firstShred.getHost();
      if (shredHost == null) {
        return;
      }

      for (PsiLanguageInjectionHost.Shred place : places) {
        if (place.getHost() != shredHost) return;
      }

      TextRange injectionRange = new TextRange(firstShred.getRangeInsideHost().getStartOffset(),
                                               lastShred.getRangeInsideHost().getEndOffset());
      ASTNode node = shredHost.getNode();
      if (node == null || !injectionHost.getTextRange().contains(injectionRange.shiftRight(node.getStartOffset()))) {
        return;
      }
      if (node != injectionHost) {
        int shift = 0;
        boolean canProcess = false;
        for (ASTNode n = injectionHost.getTreeParent(), prev = injectionHost; n != null; prev = n, n = n.getTreeParent()) {
          shift += n.getStartOffset() - prev.getStartOffset();
          if (n == node) {
            injectionRange = injectionRange.shiftRight(shift);
            canProcess = true;
            break;
          }
        }
        if (!canProcess) {
          return;
        }
      }

      String childText;
      if (injectionHost.getTextLength() == injectionRange.getEndOffset() && injectionRange.getStartOffset() == 0 ||
          canProcessFragment((childText = injectionHost.getText()).substring(0, injectionRange.getStartOffset()), injectionHost) &&
          canProcessFragment(childText.substring(injectionRange.getEndOffset()), injectionHost)) {

        // inject language block

        final Language childLanguage = injectedPsi.getLanguage();
        final FormattingModelBuilder builder = LanguageFormatting.INSTANCE.forContext(childLanguage, injectionHost.getPsi());

        if (builder != null) {
          final int startOffset = injectionRange.getStartOffset();
          final int endOffset = injectionRange.getEndOffset();
          TextRange range = injectionHost.getTextRange();
          final int prefixLength = firstShred.getPrefix().length();
          final int suffixLength = lastShred.getSuffix().length();

          int childOffset = range.getStartOffset();
          if (lastInjectionEndOffset.get() < startOffset) {
            result.add(createBlock(injectionHost, wrap, alignment, indent, new TextRange(lastInjectionEndOffset.get(), startOffset)));
          }

          addInjectedLanguageBlocks(result, injectedPsi, indent, childOffset + startOffset,
                                    new TextRange(prefixLength, injectedPsi.getTextLength() - suffixLength), places);

          lastInjectionEndOffset.set(endOffset);
        }
      }
    };
    final PsiElement injectionHostPsi = injectionHost.getPsi();
    PsiFile containingFile = injectionHostPsi.getContainingFile();
    InjectedLanguageManager.getInstance(containingFile.getProject())
      .enumerateEx(injectionHostPsi, containingFile, true, injectedPsiVisitor);

    if (lastInjectionEndOffset.get() > 0) {
      if (lastInjectionEndOffset.get() < injectionHost.getTextLength()) {
        result.add(createBlock(injectionHost, wrap, alignment, indent,
                               new TextRange(lastInjectionEndOffset.get(), injectionHost.getTextLength())));
      }
      return true;
    }
    return false;
  }
public boolean addInjectedBlocks(List<? super Block> result, final ASTNode injectionHost, Wrap wrap, Alignment alignment, Indent indent)