private void initGuardedBlocks(Place shreds) {
   int origOffset = -1;
   int curOffset = 0;
   for (PsiLanguageInjectionHost.Shred shred : shreds) {
     Segment hostRangeMarker = shred.getHostRangeMarker();
     int start = shred.getRange().getStartOffset() + shred.getPrefix().length();
     int end = shred.getRange().getEndOffset() - shred.getSuffix().length();
     if (curOffset < start) {
       RangeMarker guard = myNewDocument.createGuardedBlock(curOffset, start);
       if (curOffset == 0 && shred == shreds.get(0)) guard.setGreedyToLeft(true);
       String padding =
           origOffset < 0
               ? ""
               : myOrigDocument.getText().substring(origOffset, hostRangeMarker.getStartOffset());
       guard.putUserData(REPLACEMENT_KEY, fixQuotes(padding));
     }
     curOffset = end;
     origOffset = hostRangeMarker.getEndOffset();
   }
   if (curOffset < myNewDocument.getTextLength()) {
     RangeMarker guard =
         myNewDocument.createGuardedBlock(curOffset, myNewDocument.getTextLength());
     guard.setGreedyToRight(true);
     guard.putUserData(REPLACEMENT_KEY, "");
   }
 }
 void setRange(@Nullable Segment range) {
   if (range != null) {
     myStartOffset = range.getStartOffset();
     myEndOffset = range.getEndOffset();
   } else {
     myStartOffset = -1;
     myEndOffset = -1;
   }
 }
  @Override
  public PsiElement restoreElement() {
    Segment segment = getPsiRange();
    if (segment == null) return null;

    PsiFile file = restoreFile();
    if (file == null || !file.isValid()) return null;

    return findElementInside(file, segment.getStartOffset(), segment.getEndOffset(), myType);
  }
  public static void renameNonCodeUsages(
      @NotNull Project project, @NotNull NonCodeUsageInfo[] usages) {
    PsiDocumentManager.getInstance(project).commitAllDocuments();
    Map<Document, List<UsageOffset>> docsToOffsetsMap = new HashMap<Document, List<UsageOffset>>();
    final PsiDocumentManager psiDocumentManager = PsiDocumentManager.getInstance(project);
    for (NonCodeUsageInfo usage : usages) {
      PsiElement element = usage.getElement();

      if (element == null) continue;
      element = CodeInsightUtilBase.forcePsiPostprocessAndRestoreElement(element, true);
      if (element == null) continue;

      final ProperTextRange rangeInElement = usage.getRangeInElement();
      if (rangeInElement == null) continue;

      final PsiFile containingFile = element.getContainingFile();
      final Document document = psiDocumentManager.getDocument(containingFile);

      final Segment segment = usage.getSegment();
      LOG.assertTrue(segment != null);
      int fileOffset = segment.getStartOffset();

      List<UsageOffset> list = docsToOffsetsMap.get(document);
      if (list == null) {
        list = new ArrayList<UsageOffset>();
        docsToOffsetsMap.put(document, list);
      }

      list.add(new UsageOffset(fileOffset, fileOffset + rangeInElement.getLength(), usage.newText));
    }

    for (Document document : docsToOffsetsMap.keySet()) {
      List<UsageOffset> list = docsToOffsetsMap.get(document);
      LOG.assertTrue(list != null, document);
      UsageOffset[] offsets = list.toArray(new UsageOffset[list.size()]);
      Arrays.sort(offsets);

      for (int i = offsets.length - 1; i >= 0; i--) {
        UsageOffset usageOffset = offsets[i];
        document.replaceString(usageOffset.startOffset, usageOffset.endOffset, usageOffset.newText);
      }
      PsiDocumentManager.getInstance(project).commitDocument(document);
    }
    PsiDocumentManager.getInstance(project).commitAllDocuments();
  }
  @Override
  public boolean pointsToTheSameElementAs(@NotNull final SmartPointerElementInfo other) {
    if (other instanceof SelfElementInfo) {
      SelfElementInfo otherInfo = (SelfElementInfo) other;
      if (!getVirtualFile().equals(other.getVirtualFile()) || myType != otherInfo.myType)
        return false;

      Segment range1 = getPsiRange();
      Segment range2 = otherInfo.getPsiRange();
      return range1 != null
          && range2 != null
          && range1.getStartOffset() == range2.getStartOffset()
          && range1.getEndOffset() == range2.getEndOffset();
    }
    return areRestoredElementsEqual(other);
  }