/*
   * @see org.eclipse.core.internal.filebuffers.textmanipulation.IFileBufferOperation#run(org.eclipse.core.filebuffers.IFileBuffer, org.eclipse.core.runtime.IProgressMonitor)
   */
  public void run(IFileBuffer fileBuffer, IProgressMonitor progressMonitor)
      throws CoreException, OperationCanceledException {

    if (fileBuffer instanceof ITextFileBuffer) {
      ITextFileBuffer textFileBuffer = (ITextFileBuffer) fileBuffer;
      IPath path = textFileBuffer.getLocation();
      String taskName = path == null ? getOperationName() : path.lastSegment();
      progressMonitor = Progress.getMonitor(progressMonitor);
      progressMonitor.beginTask(taskName, 100);
      try {
        IProgressMonitor subMonitor = Progress.getSubMonitor(progressMonitor, 10);
        MultiTextEditWithProgress edit = computeTextEdit(textFileBuffer, subMonitor);
        subMonitor.done();
        if (edit != null) {
          Object stateData = startRewriteSession(textFileBuffer);
          try {
            subMonitor = Progress.getSubMonitor(progressMonitor, 90);
            applyTextEdit(textFileBuffer, edit, subMonitor);
            subMonitor.done();
          } finally {
            stopRewriteSession(textFileBuffer, stateData);
          }
        }
      } finally {
        progressMonitor.done();
      }
    }
  }
  /*
   * @see org.eclipse.core.internal.filebuffers.textmanipulation.TextFileBufferOperation#computeTextEdit(org.eclipse.core.filebuffers.ITextFileBuffer, org.eclipse.core.runtime.IProgressMonitor)
   */
  protected MultiTextEditWithProgress computeTextEdit(
      ITextFileBuffer fileBuffer, IProgressMonitor progressMonitor) throws CoreException {
    IDocument document = fileBuffer.getDocument();
    int lineCount = document.getNumberOfLines();

    progressMonitor = Progress.getMonitor(progressMonitor);
    progressMonitor.beginTask(
        FileBuffersMessages.RemoveTrailingWhitespaceOperation_task_generatingChanges, lineCount);
    try {

      MultiTextEditWithProgress multiEdit =
          new MultiTextEditWithProgress(
              FileBuffersMessages.RemoveTrailingWhitespaceOperation_task_applyingChanges);

      for (int i = 0; i < lineCount; i++) {
        if (progressMonitor.isCanceled()) throw new OperationCanceledException();

        IRegion region = document.getLineInformation(i);
        if (region.getLength() == 0) continue;

        int lineStart = region.getOffset();
        int lineExclusiveEnd = lineStart + region.getLength();
        int j = lineExclusiveEnd - 1;
        while (j >= lineStart && Character.isWhitespace(document.getChar(j))) --j;
        ++j;
        if (j < lineExclusiveEnd) multiEdit.addChild(new DeleteEdit(j, lineExclusiveEnd - j));
        progressMonitor.worked(1);
      }

      return multiEdit.getChildrenSize() <= 0 ? null : multiEdit;

    } catch (BadLocationException x) {
      throw new CoreException(
          new Status(
              IStatus.ERROR,
              FileBuffersPlugin.PLUGIN_ID,
              IFileBufferStatusCodes.CONTENT_CHANGE_FAILED,
              "",
              x)); //$NON-NLS-1$
    } finally {
      progressMonitor.done();
    }
  }