/**
   * Actions a Pull Event
   *
   * @return true if the Event has been handled, false if there has been no change
   */
  private boolean pullEvent() {

    final int newHeight;
    final int oldHeight = getScrollY();

    switch (mCurrentMode) {
      case PULL_UP_TO_REFRESH:
        newHeight = Math.round(Math.max(mInitialMotionY - mLastMotionY, 0) / FRICTION);
        break;
      case PULL_DOWN_TO_REFRESH:
      default:
        newHeight = Math.round(Math.min(mInitialMotionY - mLastMotionY, 0) / FRICTION);
        break;
    }

    setHeaderScroll(newHeight);

    if (newHeight != 0) {

      float scale = Math.abs(newHeight) / (float) mHeaderHeight;
      switch (mCurrentMode) {
        case PULL_UP_TO_REFRESH:
          mFooterLayout.onPullY(scale);
          break;
        case PULL_DOWN_TO_REFRESH:
          mHeaderLayout.onPullY(scale);
          break;
      }

      if (mState == PULL_TO_REFRESH && mHeaderHeight < Math.abs(newHeight)) {
        mState = RELEASE_TO_REFRESH;
        onReleaseToRefresh();
        return true;

      } else if (mState == RELEASE_TO_REFRESH && mHeaderHeight >= Math.abs(newHeight)) {
        mState = PULL_TO_REFRESH;
        onPullToRefresh();
        return true;
      }
    }

    return oldHeight != newHeight;
  }