protected void notifyListenersAtBufferStart() {
    int topIdx = getTable().getTopIndex();
    Object[] listeners = fVirtualContentListeners.getListeners();

    for (int i = 0; i < listeners.length; i++) {
      final IVirtualContentListener listener = (IVirtualContentListener) listeners[i];
      if (topIdx < listener.getThreshold(IVirtualContentListener.BUFFER_START)) {
        SafeRunner.run(
            new ISafeRunnable() {
              public void run() throws Exception {
                listener.handledAtBufferStart();
              }

              public void handleException(Throwable exception) {
                DebugUIPlugin.log(exception);
              }
            });
      }
    }
  }
  protected void notifyListenersAtBufferEnd() {
    Object[] listeners = fVirtualContentListeners.getListeners();
    int topIdx = getTable().getTopIndex();
    int bottomIdx = topIdx + getNumberOfVisibleLines();
    int elementsCnt = getVirtualContentModel().getElements().length;
    int numLinesLeft = elementsCnt - bottomIdx;

    for (int i = 0; i < listeners.length; i++) {
      final IVirtualContentListener listener = (IVirtualContentListener) listeners[i];
      if (numLinesLeft <= listener.getThreshold(IVirtualContentListener.BUFFER_END)) {
        SafeRunner.run(
            new ISafeRunnable() {
              public void run() throws Exception {
                listener.handleAtBufferEnd();
              }

              public void handleException(Throwable exception) {
                DebugUIPlugin.log(exception);
              }
            });
      }
    }
  }