void getInjectedLanguage(final PsiElement place,
                           final Ref<? super Boolean> unparsableRef,
                           final PairProcessor<? super Language, ? super List<InjectionInfo>> processor) {
    if (place instanceof XmlTag xmlTag) {

      List<BaseInjection> injections = getConfiguration().getInjections(XmlLanguageInjectionSupport.XML_SUPPORT_ID);
      for (int i = 0, injectionsSize = injections.size(); i < injectionsSize; i++) {
        final BaseInjection injection = injections.get(i);
        if (injection.acceptsPsiElement(xmlTag)) {
          final Language language = InjectedLanguage.findLanguageById(injection.getInjectedLanguageId());
          if (language == null) continue;
          final boolean separateFiles = !injection.isSingleFile() && StringUtil.isNotEmpty(injection.getValuePattern());

          final List<InjectionInfo> result = new ArrayList<>();

          xmlTag.acceptChildren(new PsiElementVisitor() {
            @Override
            public void visitElement(@NotNull PsiElement element) {
              if (element instanceof XmlText) {
                if (!(element instanceof PsiLanguageInjectionHost) || element.getTextLength() == 0) return;

                if (!injection.shouldBeIgnored(element)) {
                  List<TextRange> list = injection.getInjectedArea(element);
                  InjectedLanguage l =
                    InjectedLanguage.create(injection.getInjectedLanguageId(), injection.getPrefix(), injection.getSuffix(), false);
                  for (TextRange textRange : list) {
                    result.add(new InjectionInfo((PsiLanguageInjectionHost)element, l, textRange));
                  }
                }
              }
              else if (element instanceof XmlTag) {
                if (!separateFiles) unparsableRef.set(Boolean.TRUE);
                if (injection instanceof AbstractTagInjection && ((AbstractTagInjection)injection).isApplyToSubTags()) {
                  element.acceptChildren(this);
                }
              }
            }
          });
          if (!result.isEmpty()) {
            if (separateFiles) {
              for (InjectionInfo trinity : result) {
                processor.process(language, Collections.singletonList(trinity));
              }
            }
            else {
              processor.process(language, result);
            }
          }
          if (injection.isTerminal()) {
            break;
          }
        }
      }
    }
    else if (place instanceof XmlAttributeValue value && place.getParent() instanceof XmlAttribute attribute) {
      //if (value == null) return;
      // Check that we don't inject anything into embedded (e.g. JavaScript) content:
      // XmlToken: "
      // JSEmbeddedContent
      // XmlToken "

      // Actually IDEA shouldn't ask for injected languages at all in this case.
      final PsiElement[] children = value.getChildren();
      if (children.length < 3 || !(children[1] instanceof XmlToken) ||
          ((XmlToken)children[1]).getTokenType() != XmlTokenType.XML_ATTRIBUTE_VALUE_TOKEN) {
        return;
      }

      List<BaseInjection> injections = getConfiguration().getInjections(XmlLanguageInjectionSupport.XML_SUPPORT_ID);
      for (int i = 0, size = injections.size(); i < size; i++) {
        BaseInjection injection = injections.get(i);
        if (injection.acceptsPsiElement(attribute) && !injection.shouldBeIgnored(value)) {
          final Language language = InjectedLanguage.findLanguageById(injection.getInjectedLanguageId());
          if (language == null) continue;
          final boolean separateFiles = !injection.isSingleFile() && StringUtil.isNotEmpty(injection.getValuePattern());

          final List<TextRange> ranges = injection.getInjectedArea(value);
          if (ranges.isEmpty()) continue;
          final List<InjectionInfo> result = new ArrayList<>();
          final InjectedLanguage l =
            InjectedLanguage.create(injection.getInjectedLanguageId(), injection.getPrefix(), injection.getSuffix(), false);
          for (TextRange textRange : ranges) {
            result.add(new InjectionInfo((PsiLanguageInjectionHost)value, l, textRange));
          }
          if (separateFiles) {
            for (InjectionInfo info : result) {
              processor.process(language, Collections.singletonList(info));
            }
          }
          else {
            processor.process(language, result);
          }
          if (injection.isTerminal()) {
            break;
          }
        }
      }
    }
  }
void getInjectedLanguage(final PsiElement place,
                           final Ref<? super Boolean> unparsableRef,
                           final PairProcessor<? super Language, ? super List<InjectionInfo>> processor)