@NotNull ASTNode applyRangeCollectorAndExpandChameleon(@NotNull ASTNode chameleon,
                                                         @NotNull Language language,
                                                         @NotNull Function<? super @NotNull CharSequence, ? extends @NotNull ASTNode> parser) {
    CharSequence chars = chameleon.getChars();
    if (myOuterAndRemoveRanges.isEmpty()) return parser.apply(chars);

    StringBuilder stringBuilder = applyOuterAndRemoveRanges(chars);

    OuterLanguageRangePatcher outerLanguageRangePatcher = OuterLanguageRangePatcher.EXTENSION.forLanguage(language);
    if (outerLanguageRangePatcher != null) {
      insertDummyStringIntoInsertionRanges(outerLanguageRangePatcher, chars, stringBuilder);
    }

    ASTNode root = parser.apply(stringBuilder.toString());
    DebugUtil.performPsiModification("lazy parseable outer elements insertion", () ->
      insertOuterElementsAndRemoveRanges((TreeElement)root, chars, SharedImplUtil.findCharTableByTree(chameleon), language));

    return root;
  }
@NotNull ASTNode applyRangeCollectorAndExpandChameleon(@NotNull ASTNode chameleon,
                                                         @NotNull Language language,
                                                         @NotNull Function<? super @NotNull CharSequence, ? extends @NotNull ASTNode> parser)