Program: 7943
Project: 7943
Buggy source:
private void scrollChanged(int reportedFirstVisibleItem){
  int adapterCount=mAdapter == null ? 0 : mAdapter.getCount();
  if (adapterCount == 0 || !mAreHeadersSticky) {
    return;
  }
  final int listViewHeaderCount=getHeaderViewsCount();
  final int firstVisibleItem=fixedFirstVisibleItem(reportedFirstVisibleItem) - listViewHeaderCount;
  if (firstVisibleItem < 0 || firstVisibleItem > adapterCount - 1) {
    reset();
    updateHeaderVisibilities();
    invalidate();
    return;
  }
  long newHeaderId=mAdapter.getHeaderId(firstVisibleItem);
  if (mCurrentHeaderId == null || mCurrentHeaderId != newHeaderId) {
    mHeaderPosition=firstVisibleItem;
    mCurrentHeaderId=newHeaderId;
    mHeader=mAdapter.getHeaderView(mHeaderPosition,mHeader,this);
    measureHeader();
  }
  int childCount=getChildCount();
  if (childCount != 0) {
    View viewToWatch=null;
    int watchingChildDistance=Integer.MAX_VALUE;
    boolean viewToWatchIsFooter=false;
    for (int i=0; i < childCount; i++) {
      final View child=super.getChildAt(i);
      final boolean childIsFooter=mFooterViews != null && mFooterViews.contains(child);
      final int childDistance=child.getTop() - (mClippingToPadding ? getPaddingTop() : 0);
      if (childDistance < 0) {
        continue;
      }
      if (viewToWatch == null || (!viewToWatchIsFooter && !((WrapperView)viewToWatch).hasHeader()) || ((childIsFooter || ((WrapperView)child).hasHeader()) && childDistance < watchingChildDistance)) {
        viewToWatch=child;
        viewToWatchIsFooter=childIsFooter;
        watchingChildDistance=childDistance;
      }
    }
    final int headerHeight=getHeaderHeight();
    if (viewToWatch != null && (viewToWatchIsFooter || ((WrapperView)viewToWatch).hasHeader())) {
      if (firstVisibleItem == listViewHeaderCount && super.getChildAt(0).getTop() > 0 && !mClippingToPadding) {
        mHeaderBottomPosition=0;
      }
 else {
        final int paddingTop=mClippingToPadding ? getPaddingTop() : 0;
        mHeaderBottomPosition=Math.min(viewToWatch.getTop(),headerHeight + paddingTop);
        mHeaderBottomPosition=mHeaderBottomPosition < paddingTop ? headerHeight + paddingTop : mHeaderBottomPosition;
      }
    }
 else {
      mHeaderBottomPosition=headerHeight + (mClippingToPadding ? getPaddingTop() : 0);
    }
  }
  updateHeaderVisibilities();
  invalidate();
}

Fixed version (ground truth):
private void scrollChanged(int reportedFirstVisibleItem){
  int adapterCount=mAdapter == null ? 0 : mAdapter.getCount();
  if (adapterCount == 0 || !mAreHeadersSticky) {
    return;
  }
  final int listViewHeaderCount=getHeaderViewsCount();
  final int firstVisibleItem=fixedFirstVisibleItem(reportedFirstVisibleItem) - listViewHeaderCount;
  if (firstVisibleItem < 0 || firstVisibleItem > adapterCount - 1) {
    reset();
    updateHeaderVisibilities();
    invalidate();
    return;
  }
  if (mHeaderPosition == null || mHeaderPosition != firstVisibleItem) {
    mHeaderPosition=firstVisibleItem;
    mCurrentHeaderId=mAdapter.getHeaderId(firstVisibleItem);
    mHeader=mAdapter.getHeaderView(mHeaderPosition,mHeader,this);
    measureHeader();
  }
  int childCount=getChildCount();
  if (childCount != 0) {
    View viewToWatch=null;
    int watchingChildDistance=Integer.MAX_VALUE;
    boolean viewToWatchIsFooter=false;
    for (int i=0; i < childCount; i++) {
      final View child=super.getChildAt(i);
      final boolean childIsFooter=mFooterViews != null && mFooterViews.contains(child);
      final int childDistance=child.getTop() - (mClippingToPadding ? getPaddingTop() : 0);
      if (childDistance < 0) {
        continue;
      }
      if (viewToWatch == null || (!viewToWatchIsFooter && !((WrapperView)viewToWatch).hasHeader()) || ((childIsFooter || ((WrapperView)child).hasHeader()) && childDistance < watchingChildDistance)) {
        viewToWatch=child;
        viewToWatchIsFooter=childIsFooter;
        watchingChildDistance=childDistance;
      }
    }
    final int headerHeight=getHeaderHeight();
    if (viewToWatch != null && (viewToWatchIsFooter || ((WrapperView)viewToWatch).hasHeader())) {
      if (firstVisibleItem == listViewHeaderCount && super.getChildAt(0).getTop() > 0 && !mClippingToPadding) {
        mHeaderBottomPosition=0;
      }
 else {
        final int paddingTop=mClippingToPadding ? getPaddingTop() : 0;
        mHeaderBottomPosition=Math.min(viewToWatch.getTop(),headerHeight + paddingTop);
        mHeaderBottomPosition=mHeaderBottomPosition < paddingTop ? headerHeight + paddingTop : mHeaderBottomPosition;
      }
    }
 else {
      mHeaderBottomPosition=headerHeight + (mClippingToPadding ? getPaddingTop() : 0);
    }
  }
  updateHeaderVisibilities();
  invalidate();
}