/**
   * Finds the next instance of the search string in the specified buffer.
   *
   * @param view The view
   * @param buffer The buffer
   * @param start Location where to start the search
   * @param firstTime See {@link
   *     SearchMatcher#nextMatch(CharSequence,boolean,boolean,boolean,boolean)}.
   * @since jEdit 4.1pre7
   */
  public static boolean find(
      View view, Buffer buffer, int start, boolean firstTime, boolean reverse) throws Exception {

    EditBus.send(new PositionChanging(view.getEditPane()));

    SearchMatcher matcher = getSearchMatcher();
    if (matcher == null) {
      view.getToolkit().beep();
      return false;
    }

    CharSequence text;
    boolean startOfLine;
    boolean endOfLine;
    if (reverse) {
      text = new ReverseCharSequence(buffer.getSegment(0, start));
      startOfLine = true;
      endOfLine = (buffer.getLineEndOffset(buffer.getLineOfOffset(start)) - 1 == start);
    } else {
      text = buffer.getSegment(start, buffer.getLength() - start);
      startOfLine = (buffer.getLineStartOffset(buffer.getLineOfOffset(start)) == start);
      endOfLine = true;
    }

    String noWordSep = buffer.getStringProperty("noWordSep");
    matcher.setNoWordSep(noWordSep);
    SearchMatcher.Match match = matcher.nextMatch(text, startOfLine, endOfLine, firstTime, reverse);
    if (match != null) {
      jEdit.commitTemporary(buffer);
      view.setBuffer(buffer, true);
      JEditTextArea textArea = view.getTextArea();

      if (reverse) {
        textArea.setSelection(new Selection.Range(start - match.end, start - match.start));
        // make sure end of match is visible
        textArea.scrollTo(start - match.start, false);
        textArea.moveCaretPosition(start - match.end);
      } else {
        textArea.setSelection(new Selection.Range(start + match.start, start + match.end));
        textArea.moveCaretPosition(start + match.end);
        // make sure start of match is visible
        textArea.scrollTo(start + match.start, false);
      }

      return true;
    } else return false;
  } // }}}
  /**
   * Replaces all occurrences of the search string with the replacement string.
   *
   * @param view The view
   * @param buffer The buffer
   * @param start The start offset
   * @param end The end offset
   * @param matcher The search matcher to use
   * @param smartCaseReplace See user's guide
   * @return The number of occurrences replaced
   */
  private static int _replace(
      View view,
      JEditBuffer buffer,
      SearchMatcher matcher,
      int start,
      int end,
      boolean smartCaseReplace)
      throws Exception {
    String noWordSep = buffer.getStringProperty("noWordSep");
    matcher.setNoWordSep(noWordSep);
    int occurCount = 0;

    boolean endOfLine = (buffer.getLineEndOffset(buffer.getLineOfOffset(end)) - 1 == end);

    int offset = start;
    loop:
    for (int counter = 0; ; counter++) {
      boolean startOfLine = (buffer.getLineStartOffset(buffer.getLineOfOffset(offset)) == offset);

      CharSequence text = buffer.getSegment(offset, end - offset);
      SearchMatcher.Match occur =
          matcher.nextMatch(text, startOfLine, endOfLine, counter == 0, false);
      if (occur == null) break loop;

      CharSequence found = text.subSequence(occur.start, occur.end);

      int length = replaceOne(view, buffer, occur, offset, found, smartCaseReplace);
      if (length == -1) offset += occur.end;
      else {
        offset += occur.start + length;
        end += (length - found.length());
        occurCount++;
      }
    }

    return occurCount;
  } // }}}