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;
  }
 private void highlightUsages() {
   if (mySearchResults.getEditor() == null) return;
   if (mySearchResults.getMatchesCount() >= mySearchResults.getMatchesLimit()) return;
   for (FindResult range : mySearchResults.getOccurrences()) {
     TextAttributes attributes =
         EditorColorsManager.getInstance()
             .getGlobalScheme()
             .getAttributes(EditorColors.TEXT_SEARCH_RESULT_ATTRIBUTES);
     if (range.getLength() == 0) {
       attributes = attributes.clone();
       attributes.setEffectType(EffectType.BOXED);
       attributes.setEffectColor(attributes.getBackgroundColor());
     }
     if (mySearchResults.isExcluded(range)) {
       highlightRange(range, strikout(attributes), myHighlighters);
     } else {
       highlightRange(range, attributes, myHighlighters);
     }
   }
   updateInSelectionHighlighters();
   if (!myListeningSelection) {
     mySearchResults.getEditor().getSelectionModel().addSelectionListener(this);
     myListeningSelection = true;
   }
 }
  private void updateCursorHighlighting(boolean scroll) {
    hideBalloon();

    if (myCursorHighlighter != null) {
      HighlightManager.getInstance(mySearchResults.getProject())
          .removeSegmentHighlighter(mySearchResults.getEditor(), myCursorHighlighter);
      myCursorHighlighter = null;
    }

    final FindResult cursor = mySearchResults.getCursor();
    Editor editor = mySearchResults.getEditor();
    SelectionModel selection = editor.getSelectionModel();
    if (cursor != null) {
      Set<RangeHighlighter> dummy = new HashSet<RangeHighlighter>();
      highlightRange(
          cursor, new TextAttributes(null, null, Color.BLACK, EffectType.ROUNDED_BOX, 0), dummy);
      if (!dummy.isEmpty()) {
        myCursorHighlighter = dummy.iterator().next();
      }

      if (scroll) {
        if (mySearchResults.getFindModel().isGlobal()) {
          FoldingModel foldingModel = editor.getFoldingModel();
          final FoldRegion[] allRegions = editor.getFoldingModel().getAllFoldRegions();

          foldingModel.runBatchFoldingOperation(
              new Runnable() {
                @Override
                public void run() {
                  for (FoldRegion region : allRegions) {
                    if (!region.isValid()) continue;
                    if (cursor.intersects(TextRange.create(region))) {
                      region.setExpanded(true);
                    }
                  }
                }
              });
          selection.setSelection(cursor.getStartOffset(), cursor.getEndOffset());

          editor.getCaretModel().moveToOffset(cursor.getEndOffset());
          editor.getScrollingModel().scrollToCaret(ScrollType.CENTER);
        } else {
          if (!SearchResults.insideVisibleArea(editor, cursor)) {
            LogicalPosition pos = editor.offsetToLogicalPosition(cursor.getStartOffset());
            editor.getScrollingModel().scrollTo(pos, ScrollType.CENTER);
          }
        }
      }
      editor
          .getScrollingModel()
          .runActionOnScrollingFinished(
              new Runnable() {
                @Override
                public void run() {
                  showReplacementPreview();
                }
              });
    }
  }
    @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;
  }
    @Override
    public void doExecute(Editor editor, @Nullable Caret c, DataContext dataContext) {
      Caret caret = c == null ? editor.getCaretModel().getPrimaryCaret() : c;

      if (!caret.hasSelection()) {
        TextRange wordSelectionRange = getSelectionRange(editor, caret);
        if (wordSelectionRange != null) {
          setSelection(editor, caret, wordSelectionRange);
        }
      }

      String selectedText = caret.getSelectedText();
      Project project = editor.getProject();
      if (project == null || selectedText == null) {
        return;
      }

      int caretShiftFromSelectionStart = caret.getOffset() - caret.getSelectionStart();
      FindManager findManager = FindManager.getInstance(project);

      FindModel model = new FindModel();
      model.setStringToFind(selectedText);
      model.setCaseSensitive(true);
      model.setWholeWordsOnly(true);

      int searchStartOffset = 0;
      FindResult findResult =
          findManager.findString(editor.getDocument().getCharsSequence(), searchStartOffset, model);
      while (findResult.isStringFound()) {
        int newCaretOffset = caretShiftFromSelectionStart + findResult.getStartOffset();
        EditorActionUtil.makePositionVisible(editor, newCaretOffset);
        Caret newCaret =
            editor.getCaretModel().addCaret(editor.offsetToVisualPosition(newCaretOffset));
        if (newCaret != null) {
          setSelection(editor, newCaret, findResult);
        }
        findResult =
            findManager.findString(
                editor.getDocument().getCharsSequence(), findResult.getEndOffset(), model);
      }
      editor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE);
    }
 @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;
  }