public void initMarkers(Place shreds) {
    SmartPointerManager smartPointerManager = SmartPointerManager.getInstance(myProject);
    int curOffset = -1;
    for (PsiLanguageInjectionHost.Shred shred : shreds) {
      final RangeMarker rangeMarker =
          myNewDocument.createRangeMarker(
              shred.getRange().getStartOffset() + shred.getPrefix().length(),
              shred.getRange().getEndOffset() - shred.getSuffix().length());
      final TextRange rangeInsideHost = shred.getRangeInsideHost();
      PsiLanguageInjectionHost host = shred.getHost();
      RangeMarker origMarker =
          myOrigDocument.createRangeMarker(
              rangeInsideHost.shiftRight(host.getTextRange().getStartOffset()));
      SmartPsiElementPointer<PsiLanguageInjectionHost> elementPointer =
          smartPointerManager.createSmartPsiElementPointer(host);
      Trinity<RangeMarker, RangeMarker, SmartPsiElementPointer> markers =
          Trinity.<RangeMarker, RangeMarker, SmartPsiElementPointer>create(
              origMarker, rangeMarker, elementPointer);
      myMarkers.add(markers);

      origMarker.setGreedyToRight(true);
      rangeMarker.setGreedyToRight(true);
      if (origMarker.getStartOffset() > curOffset) {
        origMarker.setGreedyToLeft(true);
        rangeMarker.setGreedyToLeft(true);
      }
      curOffset = origMarker.getEndOffset();
    }
    initGuardedBlocks(shreds);
  }
 /**
  * intersection may spread over several injected fragments
  *
  * @param rangeToEdit range in encoded(raw) PSI
  * @return list of ranges in encoded (raw) PSI
  */
 @Override
 @SuppressWarnings({"ConstantConditions", "unchecked"})
 @NotNull
 public List<TextRange> intersectWithAllEditableFragments(
     @NotNull PsiFile injectedPsi, @NotNull TextRange rangeToEdit) {
   Place shreds = InjectedLanguageUtil.getShreds(injectedPsi);
   if (shreds == null) return Collections.emptyList();
   Object result = null; // optimization: TextRange or ArrayList
   int count = 0;
   int offset = 0;
   for (PsiLanguageInjectionHost.Shred shred : shreds) {
     TextRange encodedRange =
         TextRange.from(
             offset + shred.getPrefix().length(), shred.getRangeInsideHost().getLength());
     TextRange intersection = encodedRange.intersection(rangeToEdit);
     if (intersection != null) {
       count++;
       if (count == 1) {
         result = intersection;
       } else if (count == 2) {
         TextRange range = (TextRange) result;
         if (range.isEmpty()) {
           result = intersection;
           count = 1;
         } else if (intersection.isEmpty()) {
           count = 1;
         } else {
           List<TextRange> list = new ArrayList<TextRange>();
           list.add(range);
           list.add(intersection);
           result = list;
         }
       } else if (intersection.isEmpty()) {
         count--;
       } else {
         ((List<TextRange>) result).add(intersection);
       }
     }
     offset +=
         shred.getPrefix().length()
             + shred.getRangeInsideHost().getLength()
             + shred.getSuffix().length();
   }
   return count == 0
       ? Collections.<TextRange>emptyList()
       : count == 1 ? Collections.singletonList((TextRange) result) : (List<TextRange>) result;
 }
  private boolean addInjectedPsiHighlights(
      @NotNull PsiFile injectedPsi,
      TextAttributes injectedAttributes,
      @NotNull Collection<HighlightInfo> outInfos,
      @NotNull ProgressIndicator progress,
      @NotNull InjectedLanguageManager injectedLanguageManager) {
    DocumentWindow documentWindow =
        (DocumentWindow) PsiDocumentManager.getInstance(myProject).getCachedDocument(injectedPsi);
    if (documentWindow == null) return true;
    Place places = InjectedLanguageUtil.getShreds(injectedPsi);
    for (PsiLanguageInjectionHost.Shred place : places) {
      PsiLanguageInjectionHost host = place.getHost();
      if (host == null) continue;
      TextRange textRange =
          place.getRangeInsideHost().shiftRight(host.getTextRange().getStartOffset());
      if (textRange.isEmpty()) continue;
      String desc = injectedPsi.getLanguage().getDisplayName() + ": " + injectedPsi.getText();
      HighlightInfo.Builder builder =
          HighlightInfo.newHighlightInfo(HighlightInfoType.INJECTED_LANGUAGE_BACKGROUND)
              .range(textRange);
      if (injectedAttributes != null && InjectedLanguageUtil.isHighlightInjectionBackground(host)) {
        builder.textAttributes(injectedAttributes);
      }
      builder.unescapedToolTip(desc);
      HighlightInfo info = builder.createUnconditionally();
      info.setFromInjection(true);
      outInfos.add(info);
    }

    HighlightInfoHolder holder = createInfoHolder(injectedPsi);
    runHighlightVisitorsForInjected(injectedPsi, holder, progress);
    for (int i = 0; i < holder.size(); i++) {
      HighlightInfo info = holder.get(i);
      final int startOffset = documentWindow.injectedToHost(info.startOffset);
      final TextRange fixedTextRange = getFixedTextRange(documentWindow, startOffset);
      addPatchedInfos(
          info, injectedPsi, documentWindow, injectedLanguageManager, fixedTextRange, outInfos);
    }
    int injectedStart = holder.size();
    highlightInjectedSyntax(injectedPsi, holder);
    for (int i = injectedStart; i < holder.size(); i++) {
      HighlightInfo info = holder.get(i);
      final int startOffset = info.startOffset;
      final TextRange fixedTextRange = getFixedTextRange(documentWindow, startOffset);
      if (fixedTextRange == null) {
        info.setFromInjection(true);
        outInfos.add(info);
      } else {
        HighlightInfo patched =
            new HighlightInfo(
                info.forcedTextAttributes,
                info.forcedTextAttributesKey,
                info.type,
                fixedTextRange.getStartOffset(),
                fixedTextRange.getEndOffset(),
                info.getDescription(),
                info.getToolTip(),
                info.type.getSeverity(null),
                info.isAfterEndOfLine(),
                null,
                false,
                0,
                info.getProblemGroup(),
                info.getGutterIconRenderer());
        patched.setFromInjection(true);
        outInfos.add(patched);
      }
    }

    if (!isDumbMode()) {
      List<HighlightInfo> todos = new ArrayList<HighlightInfo>();
      highlightTodos(
          injectedPsi,
          injectedPsi.getText(),
          0,
          injectedPsi.getTextLength(),
          progress,
          myPriorityRange,
          todos,
          todos);
      for (HighlightInfo info : todos) {
        addPatchedInfos(info, injectedPsi, documentWindow, injectedLanguageManager, null, outInfos);
      }
    }
    advanceProgress(1);
    return true;
  }