private boolean getStringToReplace(
      int textOffset,
      int textEndOffset,
      Document document,
      FindModel findModel,
      Ref<String> stringToReplace)
      throws FindManager.MalformedReplacementStringException {
    if (textOffset < 0 || textOffset >= document.getTextLength()) {
      return false;
    }
    if (textEndOffset < 0 || textOffset > document.getTextLength()) {
      return false;
    }
    FindManager findManager = FindManager.getInstance(myProject);
    final CharSequence foundString =
        document.getCharsSequence().subSequence(textOffset, textEndOffset);
    PsiFile file = PsiDocumentManager.getInstance(myProject).getPsiFile(document);
    FindResult findResult =
        findManager.findString(
            document.getCharsSequence(),
            textOffset,
            findModel,
            file != null ? file.getVirtualFile() : null);
    if (!findResult.isStringFound()) {
      return false;
    }

    stringToReplace.set(
        FindManager.getInstance(myProject)
            .getStringToReplace(foundString.toString(), findModel, textOffset, document.getText()));

    return true;
  }
    @Override
    public void doExecute(Editor editor, @Nullable Caret c, DataContext dataContext) {
      Caret caret = c == null ? editor.getCaretModel().getPrimaryCaret() : c;
      TextRange wordSelectionRange = getSelectionRange(editor, caret);
      boolean notFoundPreviously = getAndResetNotFoundStatus(editor);
      boolean wholeWordSearch = isWholeWordSearch(editor);
      if (caret.hasSelection()) {
        Project project = editor.getProject();
        String selectedText = caret.getSelectedText();
        if (project == null || selectedText == null) {
          return;
        }
        FindManager findManager = FindManager.getInstance(project);

        FindModel model = getFindModel(selectedText, wholeWordSearch);

        findManager.setSelectNextOccurrenceWasPerformed();
        findManager.setFindNextModel(model);

        int searchStartOffset = notFoundPreviously ? 0 : caret.getSelectionEnd();
        FindResult findResult =
            findManager.findString(
                editor.getDocument().getCharsSequence(), searchStartOffset, model);
        if (findResult.isStringFound()) {
          boolean caretAdded =
              FindUtil.selectSearchResultInEditor(
                  editor, findResult, caret.getOffset() - caret.getSelectionStart());
          if (!caretAdded) {
            // this means that the found occurence is already selected
            if (notFoundPreviously) {
              setNotFoundStatus(
                  editor); // to make sure we won't show hint anymore if there are no more
                           // occurrences
            }
          }
        } else {
          setNotFoundStatus(editor);
          showHint(editor);
        }
      } else {
        if (wordSelectionRange == null) {
          return;
        }
        setSelection(editor, caret, wordSelectionRange);
        setWholeWordSearch(editor, true);
      }
      editor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE);
    }
  private static int addToUsages(
      @NotNull Document document,
      @NotNull Processor<UsageInfo> consumer,
      @NotNull FindModel findModel,
      @NotNull final PsiFile psiFile,
      @NotNull int[] offsetRef,
      int maxUsages) {
    int count = 0;
    CharSequence text = document.getCharsSequence();
    int textLength = document.getTextLength();
    int offset = offsetRef[0];

    Project project = psiFile.getProject();

    FindManager findManager = FindManager.getInstance(project);
    while (offset < textLength) {
      FindResult result = findManager.findString(text, offset, findModel, psiFile.getVirtualFile());
      if (!result.isStringFound()) break;

      final SearchScope customScope = findModel.getCustomScope();
      if (customScope instanceof LocalSearchScope) {
        final TextRange range = new TextRange(result.getStartOffset(), result.getEndOffset());
        if (!((LocalSearchScope) customScope).containsRange(psiFile, range)) break;
      }
      UsageInfo info = new FindResultUsageInfo(findManager, psiFile, offset, findModel, result);
      if (!consumer.process(info)) {
        throw new ProcessCanceledException();
      }
      count++;

      final int prevOffset = offset;
      offset = result.getEndOffset();

      if (prevOffset == offset) {
        // for regular expr the size of the match could be zero -> could be infinite loop in finding
        // usages!
        ++offset;
      }
      if (maxUsages > 0 && count >= maxUsages) {
        break;
      }
    }
    offsetRef[0] = offset;
    return count;
  }
 @Nullable
 public TextRange performReplace(
     final FindResult occurrence, final String replacement, final Editor editor) {
   if (myReplaceDenied
       || !ReadonlyStatusHandler.ensureDocumentWritable(editor.getProject(), editor.getDocument()))
     return null;
   FindModel findModel = mySearchResults.getFindModel();
   TextRange result =
       FindUtil.doReplace(
           editor.getProject(),
           editor.getDocument(),
           findModel,
           new FindResultImpl(occurrence.getStartOffset(), occurrence.getEndOffset()),
           replacement,
           true,
           new ArrayList<Pair<TextRange, String>>());
   myLivePreview.inSmartUpdate();
   mySearchResults.updateThreadSafe(findModel, true, result, mySearchResults.getStamp());
   return result;
 }
  @Override
  public String getStringToReplace(Editor editor, FindResult findResult) {
    if (findResult == null) {
      return null;
    }
    String foundString = editor.getDocument().getText(findResult);
    String documentText = editor.getDocument().getText();
    FindModel currentModel = mySearchResults.getFindModel();
    String stringToReplace = null;

    if (currentModel != null) {
      if (currentModel.isReplaceState()) {
        FindManager findManager = FindManager.getInstance(editor.getProject());
        try {
          stringToReplace =
              findManager.getStringToReplace(
                  foundString, currentModel, findResult.getStartOffset(), documentText);
        } catch (FindManager.MalformedReplacementStringException e) {
          return null;
        }
      }
    }
    return stringToReplace;
  }