Program: 199285
Project: 199285
Buggy source:
private void scrollIfNeeded(int y,MotionEvent vtev){
  int rawDeltaY=y - mMotionY;
  if (dispatchNestedPreScroll(0,rawDeltaY,mScrollConsumed,mScrollOffset)) {
    rawDeltaY-=mScrollConsumed[1];
    mMotionCorrection-=mScrollOffset[1];
    if (mLastY != Integer.MIN_VALUE) {
      mLastY-=mScrollOffset[1] + mScrollConsumed[1];
    }
    if (vtev != null) {
      vtev.offsetLocation(0,mScrollOffset[1]);
    }
  }
  final int deltaY=rawDeltaY - mMotionCorrection;
  int incrementalDeltaY=mLastY != Integer.MIN_VALUE ? y - mLastY : deltaY;
  int lastYCorrection=0;
  if (mTouchMode == TOUCH_MODE_SCROLL) {
    if (PROFILE_SCROLLING) {
      if (!mScrollProfilingStarted) {
        Debug.startMethodTracing("String_Node_Str");
        mScrollProfilingStarted=true;
      }
    }
    if (mScrollStrictSpan == null) {
      mScrollStrictSpan=StrictMode.enterCriticalSpan("String_Node_Str");
    }
    if (y != mLastY) {
      if ((mGroupFlags & FLAG_DISALLOW_INTERCEPT) == 0 && Math.abs(rawDeltaY) > mTouchSlop) {
        final ViewParent parent=getParent();
        if (parent != null) {
          parent.requestDisallowInterceptTouchEvent(true);
        }
      }
      final int motionIndex;
      if (mMotionPosition >= 0) {
        motionIndex=mMotionPosition - mFirstPosition;
      }
 else {
        motionIndex=getChildCount() / 2;
      }
      int motionViewPrevTop=0;
      View motionView=this.getChildAt(motionIndex);
      if (motionView != null) {
        motionViewPrevTop=motionView.getTop();
      }
      boolean atEdge=false;
      if (incrementalDeltaY != 0) {
        atEdge=trackMotionScroll(deltaY,incrementalDeltaY);
      }
      motionView=this.getChildAt(motionIndex);
      if (motionView != null) {
        final int motionViewRealTop=motionView.getTop();
        if (atEdge) {
          int overscroll=-incrementalDeltaY - (motionViewRealTop - motionViewPrevTop);
          if (dispatchNestedScroll(0,overscroll - incrementalDeltaY,0,overscroll,mScrollOffset)) {
            mMotionCorrection-=mScrollOffset[1];
            lastYCorrection-=mScrollOffset[1];
            if (vtev != null) {
              vtev.offsetLocation(0,mScrollOffset[1]);
            }
          }
 else {
            overScrollBy(0,overscroll,0,mScrollY,0,0,0,mOverscrollDistance,true);
            if (Math.abs(mOverscrollDistance) == Math.abs(mScrollY)) {
              if (mVelocityTracker != null) {
                mVelocityTracker.clear();
              }
            }
            final int overscrollMode=getOverScrollMode();
            if (overscrollMode == OVER_SCROLL_ALWAYS || (overscrollMode == OVER_SCROLL_IF_CONTENT_SCROLLS && !contentFits())) {
              mDirection=0;
              mTouchMode=TOUCH_MODE_OVERSCROLL;
              if (deltaY > 0) {
                mEdgeGlowTop.onPull((float)overscroll / getHeight());
                if (!mEdgeGlowBottom.isFinished()) {
                  mEdgeGlowBottom.onRelease();
                }
                invalidate(mEdgeGlowTop.getBounds(false));
              }
 else               if (deltaY < 0) {
                mEdgeGlowBottom.onPull((float)overscroll / getHeight());
                if (!mEdgeGlowTop.isFinished()) {
                  mEdgeGlowTop.onRelease();
                }
                invalidate(mEdgeGlowBottom.getBounds(true));
              }
            }
          }
        }
        mMotionY=y;
      }
      mLastY=y + lastYCorrection;
    }
  }
 else   if (mTouchMode == TOUCH_MODE_OVERSCROLL) {
    if (y != mLastY) {
      final int oldScroll=mScrollY;
      final int newScroll=oldScroll - incrementalDeltaY;
      int newDirection=y > mLastY ? 1 : -1;
      if (mDirection == 0) {
        mDirection=newDirection;
      }
      int overScrollDistance=-incrementalDeltaY;
      if ((newScroll < 0 && oldScroll >= 0) || (newScroll > 0 && oldScroll <= 0)) {
        overScrollDistance=-oldScroll;
        incrementalDeltaY+=overScrollDistance;
      }
 else {
        incrementalDeltaY=0;
      }
      if (overScrollDistance != 0) {
        overScrollBy(0,overScrollDistance,0,mScrollY,0,0,0,mOverscrollDistance,true);
        final int overscrollMode=getOverScrollMode();
        if (overscrollMode == OVER_SCROLL_ALWAYS || (overscrollMode == OVER_SCROLL_IF_CONTENT_SCROLLS && !contentFits())) {
          if (rawDeltaY > 0) {
            mEdgeGlowTop.onPull((float)overScrollDistance / getHeight());
            if (!mEdgeGlowBottom.isFinished()) {
              mEdgeGlowBottom.onRelease();
            }
            invalidate(mEdgeGlowTop.getBounds(false));
          }
 else           if (rawDeltaY < 0) {
            mEdgeGlowBottom.onPull((float)overScrollDistance / getHeight());
            if (!mEdgeGlowTop.isFinished()) {
              mEdgeGlowTop.onRelease();
            }
            invalidate(mEdgeGlowBottom.getBounds(true));
          }
        }
      }
      if (incrementalDeltaY != 0) {
        if (mScrollY != 0) {
          mScrollY=0;
          invalidateParentIfNeeded();
        }
        trackMotionScroll(incrementalDeltaY,incrementalDeltaY);
        mTouchMode=TOUCH_MODE_SCROLL;
        final int motionPosition=findClosestMotionRow(y);
        mMotionCorrection=0;
        View motionView=getChildAt(motionPosition - mFirstPosition);
        mMotionViewOriginalTop=motionView != null ? motionView.getTop() : 0;
        mMotionY=y;
        mMotionPosition=motionPosition;
      }
      mLastY=y;
      mDirection=newDirection;
    }
  }
}

Fixed version (ground truth):
private void scrollIfNeeded(int y,MotionEvent vtev){
  int rawDeltaY=y - mMotionY;
  int scrollOffsetCorrection=0;
  int scrollConsumedCorrection=0;
  if (mLastY == Integer.MIN_VALUE) {
    rawDeltaY-=mMotionCorrection;
  }
  if (dispatchNestedPreScroll(0,rawDeltaY,mScrollConsumed,mScrollOffset)) {
    rawDeltaY-=mScrollConsumed[1];
    scrollOffsetCorrection-=mScrollOffset[1];
    scrollConsumedCorrection-=mScrollConsumed[1];
    if (vtev != null) {
      vtev.offsetLocation(0,mScrollOffset[1]);
    }
  }
  final int deltaY=rawDeltaY;
  int incrementalDeltaY=mLastY != Integer.MIN_VALUE ? y - mLastY - scrollConsumedCorrection : deltaY;
  int lastYCorrection=0;
  if (mTouchMode == TOUCH_MODE_SCROLL) {
    if (PROFILE_SCROLLING) {
      if (!mScrollProfilingStarted) {
        Debug.startMethodTracing("String_Node_Str");
        mScrollProfilingStarted=true;
      }
    }
    if (mScrollStrictSpan == null) {
      mScrollStrictSpan=StrictMode.enterCriticalSpan("String_Node_Str");
    }
    if (y != mLastY) {
      if ((mGroupFlags & FLAG_DISALLOW_INTERCEPT) == 0 && Math.abs(rawDeltaY) > mTouchSlop) {
        final ViewParent parent=getParent();
        if (parent != null) {
          parent.requestDisallowInterceptTouchEvent(true);
        }
      }
      final int motionIndex;
      if (mMotionPosition >= 0) {
        motionIndex=mMotionPosition - mFirstPosition;
      }
 else {
        motionIndex=getChildCount() / 2;
      }
      int motionViewPrevTop=0;
      View motionView=this.getChildAt(motionIndex);
      if (motionView != null) {
        motionViewPrevTop=motionView.getTop();
      }
      boolean atEdge=false;
      if (incrementalDeltaY != 0) {
        atEdge=trackMotionScroll(deltaY,incrementalDeltaY);
      }
      motionView=this.getChildAt(motionIndex);
      if (motionView != null) {
        final int motionViewRealTop=motionView.getTop();
        if (atEdge) {
          int overscroll=-incrementalDeltaY - (motionViewRealTop - motionViewPrevTop);
          if (dispatchNestedScroll(0,overscroll - incrementalDeltaY,0,overscroll,mScrollOffset)) {
            lastYCorrection-=mScrollOffset[1];
            if (vtev != null) {
              vtev.offsetLocation(0,mScrollOffset[1]);
            }
          }
 else {
            overScrollBy(0,overscroll,0,mScrollY,0,0,0,mOverscrollDistance,true);
            if (Math.abs(mOverscrollDistance) == Math.abs(mScrollY)) {
              if (mVelocityTracker != null) {
                mVelocityTracker.clear();
              }
            }
            final int overscrollMode=getOverScrollMode();
            if (overscrollMode == OVER_SCROLL_ALWAYS || (overscrollMode == OVER_SCROLL_IF_CONTENT_SCROLLS && !contentFits())) {
              mDirection=0;
              mTouchMode=TOUCH_MODE_OVERSCROLL;
              if (deltaY > 0) {
                mEdgeGlowTop.onPull((float)overscroll / getHeight());
                if (!mEdgeGlowBottom.isFinished()) {
                  mEdgeGlowBottom.onRelease();
                }
                invalidate(mEdgeGlowTop.getBounds(false));
              }
 else               if (deltaY < 0) {
                mEdgeGlowBottom.onPull((float)overscroll / getHeight());
                if (!mEdgeGlowTop.isFinished()) {
                  mEdgeGlowTop.onRelease();
                }
                invalidate(mEdgeGlowBottom.getBounds(true));
              }
            }
          }
        }
        mMotionY=y + scrollOffsetCorrection;
      }
      mLastY=y + lastYCorrection + scrollOffsetCorrection;
    }
  }
 else   if (mTouchMode == TOUCH_MODE_OVERSCROLL) {
    if (y != mLastY) {
      final int oldScroll=mScrollY;
      final int newScroll=oldScroll - incrementalDeltaY;
      int newDirection=y > mLastY ? 1 : -1;
      if (mDirection == 0) {
        mDirection=newDirection;
      }
      int overScrollDistance=-incrementalDeltaY;
      if ((newScroll < 0 && oldScroll >= 0) || (newScroll > 0 && oldScroll <= 0)) {
        overScrollDistance=-oldScroll;
        incrementalDeltaY+=overScrollDistance;
      }
 else {
        incrementalDeltaY=0;
      }
      if (overScrollDistance != 0) {
        overScrollBy(0,overScrollDistance,0,mScrollY,0,0,0,mOverscrollDistance,true);
        final int overscrollMode=getOverScrollMode();
        if (overscrollMode == OVER_SCROLL_ALWAYS || (overscrollMode == OVER_SCROLL_IF_CONTENT_SCROLLS && !contentFits())) {
          if (rawDeltaY > 0) {
            mEdgeGlowTop.onPull((float)overScrollDistance / getHeight());
            if (!mEdgeGlowBottom.isFinished()) {
              mEdgeGlowBottom.onRelease();
            }
            invalidate(mEdgeGlowTop.getBounds(false));
          }
 else           if (rawDeltaY < 0) {
            mEdgeGlowBottom.onPull((float)overScrollDistance / getHeight());
            if (!mEdgeGlowTop.isFinished()) {
              mEdgeGlowTop.onRelease();
            }
            invalidate(mEdgeGlowBottom.getBounds(true));
          }
        }
      }
      if (incrementalDeltaY != 0) {
        if (mScrollY != 0) {
          mScrollY=0;
          invalidateParentIfNeeded();
        }
        trackMotionScroll(incrementalDeltaY,incrementalDeltaY);
        mTouchMode=TOUCH_MODE_SCROLL;
        final int motionPosition=findClosestMotionRow(y);
        mMotionCorrection=0;
        View motionView=getChildAt(motionPosition - mFirstPosition);
        mMotionViewOriginalTop=motionView != null ? motionView.getTop() : 0;
        mMotionY=y;
        mMotionPosition=motionPosition;
      }
      mLastY=y;
      mDirection=newDirection;
    }
  }
}