@Override
      public void adjustmentValueChanged(AdjustmentEvent e) {
        JScrollPane scrollpane = (JScrollPane)SwingUtilities.getAncestorOfClass(JScrollPane.class, scrollbar);
        JViewport viewport = scrollpane == null ? null : scrollpane.getViewport();

        if (viewport == null) {
          oldViewportPosition = null;
          return;
        }

        boolean vertical = isVertical();
        Point position = viewport.getViewPosition();
        // we don't take viewport's size here, since it often changes on scrollbar appearance.
        // instead, we want to only react on visible area resizes
        Dimension dimension = scrollpane.getSize();

        boolean scrolled = false;
        if (oldViewportPosition != null) {
          int scrollH = position.x - oldViewportPosition.x;
          int scrollV = position.y - oldViewportPosition.y;
          scrolled = vertical && scrollH == 0 && scrollV != 0 ||
                     !vertical && scrollV == 0 && scrollH != 0;
        }
        oldViewportPosition = position;

        boolean resized = false;
        if (oldViewportDimension != null) {
          int resizedH = dimension.width - oldViewportDimension.width;
          int resizedV = dimension.height - oldViewportDimension.height;
          resized = vertical ? resizedV != 0 : resizedH != 0;
        }
        oldViewportDimension = dimension;

        if (scrolled) {
          // hide the opposite scrollbar when user scrolls
          JScrollBar other = vertical ? scrollpane.getHorizontalScrollBar()
                                      : scrollpane.getVerticalScrollBar();
          ScrollBarUI otherUI = other == null ? null : other.getUI();
          if (otherUI instanceof ButtonlessScrollBarUI) {
            ((ButtonlessScrollBarUI)otherUI).startMacScrollbarFadeout(true);
          }

          restart();
        }
        else if (resized) {
          startMacScrollbarFadeout();
        }
      }
@Override
      public void adjustmentValueChanged(AdjustmentEvent e)