Program: 110323
Project: 110323
Buggy source:
private void handleSourceInfoRefreshed(Pair<Timeline,Object> timelineAndManifest) throws ExoPlaybackException, IOException {
  eventHandler.obtainMessage(MSG_SOURCE_INFO_REFRESHED,timelineAndManifest).sendToTarget();
  Timeline oldTimeline=this.timeline;
  this.timeline=timelineAndManifest.first;
  if (pendingInitialSeekCount > 0) {
    Pair<Integer,Long> periodPosition=resolveSeekPosition(pendingSeekPosition);
    if (periodPosition == null) {
      stopInternal();
      return;
    }
    playbackInfo=new PlaybackInfo(periodPosition.first,periodPosition.second);
    eventHandler.obtainMessage(MSG_SEEK_ACK,pendingInitialSeekCount,0,playbackInfo).sendToTarget();
    pendingInitialSeekCount=0;
    pendingSeekPosition=null;
  }
  if (playingPeriodHolder != null) {
    int index=timeline.getIndexOfPeriod(playingPeriodHolder.uid);
    if (index == C.INDEX_UNSET) {
      attemptRestart(playingPeriodHolder.index,oldTimeline,timeline);
      return;
    }
    timeline.getPeriod(index,period,true);
    playingPeriodHolder.setIndex(timeline,timeline.getWindow(period.windowIndex,window),index);
    MediaPeriodHolder previousPeriodHolder=playingPeriodHolder;
    boolean seenReadingPeriod=false;
    bufferAheadPeriodCount=0;
    while (previousPeriodHolder.next != null) {
      MediaPeriodHolder periodHolder=previousPeriodHolder.next;
      index++;
      timeline.getPeriod(index,period,true);
      if (!periodHolder.uid.equals(period.uid)) {
        if (!seenReadingPeriod) {
          index=playingPeriodHolder.index;
          releasePeriodHoldersFrom(playingPeriodHolder);
          playingPeriodHolder=null;
          readingPeriodHolder=null;
          loadingPeriodHolder=null;
          long newPositionUs=seekToPeriodPosition(index,playbackInfo.positionUs);
          if (newPositionUs != playbackInfo.positionUs) {
            playbackInfo=new PlaybackInfo(index,newPositionUs);
            eventHandler.obtainMessage(MSG_POSITION_DISCONTINUITY,playbackInfo).sendToTarget();
          }
          return;
        }
        loadingPeriodHolder=previousPeriodHolder;
        loadingPeriodHolder.next=null;
        releasePeriodHoldersFrom(periodHolder);
        break;
      }
      bufferAheadPeriodCount++;
      int windowIndex=timeline.getPeriod(index,period).windowIndex;
      periodHolder.setIndex(timeline,timeline.getWindow(windowIndex,window),index);
      if (periodHolder == readingPeriodHolder) {
        seenReadingPeriod=true;
      }
      previousPeriodHolder=periodHolder;
    }
  }
 else   if (loadingPeriodHolder != null) {
    Object uid=loadingPeriodHolder.uid;
    int index=timeline.getIndexOfPeriod(uid);
    if (index == C.INDEX_UNSET) {
      attemptRestart(loadingPeriodHolder.index,oldTimeline,timeline);
      return;
    }
 else {
      int windowIndex=timeline.getPeriod(index,this.period).windowIndex;
      loadingPeriodHolder.setIndex(timeline,timeline.getWindow(windowIndex,window),index);
    }
  }
  if (oldTimeline != null) {
    int newPlayingIndex=playingPeriodHolder != null ? playingPeriodHolder.index : loadingPeriodHolder != null ? loadingPeriodHolder.index : C.INDEX_UNSET;
    if (newPlayingIndex != C.INDEX_UNSET && newPlayingIndex != playbackInfo.periodIndex) {
      playbackInfo=new PlaybackInfo(newPlayingIndex,playbackInfo.positionUs);
      updatePlaybackPositions();
      eventHandler.obtainMessage(MSG_POSITION_DISCONTINUITY,playbackInfo).sendToTarget();
    }
  }
}

Fixed version (ground truth):
private void handleSourceInfoRefreshed(Pair<Timeline,Object> timelineAndManifest) throws ExoPlaybackException, IOException {
  Timeline oldTimeline=timeline;
  timeline=timelineAndManifest.first;
  Object manifest=timelineAndManifest.second;
  if (oldTimeline == null) {
    if (pendingInitialSeekCount > 0) {
      Pair<Integer,Long> periodPosition=resolveSeekPosition(pendingSeekPosition);
      if (periodPosition == null) {
        finishSourceInfoRefresh(manifest,false);
        stopInternal();
        return;
      }
      playbackInfo=new PlaybackInfo(periodPosition.first,periodPosition.second);
    }
 else     if (playbackInfo.startPositionUs == C.TIME_UNSET) {
      Pair<Integer,Long> defaultPosition=getPeriodPosition(0,C.TIME_UNSET);
      playbackInfo=new PlaybackInfo(defaultPosition.first,defaultPosition.second);
    }
  }
  if (playingPeriodHolder != null) {
    int index=timeline.getIndexOfPeriod(playingPeriodHolder.uid);
    if (index == C.INDEX_UNSET) {
      boolean restarted=attemptRestart(playingPeriodHolder.index,oldTimeline,timeline);
      finishSourceInfoRefresh(manifest,true);
      if (!restarted) {
        stopInternal();
      }
      return;
    }
    timeline.getPeriod(index,period,true);
    playingPeriodHolder.setIndex(timeline,timeline.getWindow(period.windowIndex,window),index);
    MediaPeriodHolder previousPeriodHolder=playingPeriodHolder;
    boolean seenReadingPeriod=false;
    bufferAheadPeriodCount=0;
    while (previousPeriodHolder.next != null) {
      MediaPeriodHolder periodHolder=previousPeriodHolder.next;
      index++;
      timeline.getPeriod(index,period,true);
      if (!periodHolder.uid.equals(period.uid)) {
        if (!seenReadingPeriod) {
          index=playingPeriodHolder.index;
          releasePeriodHoldersFrom(playingPeriodHolder);
          playingPeriodHolder=null;
          readingPeriodHolder=null;
          loadingPeriodHolder=null;
          long newPositionUs=seekToPeriodPosition(index,playbackInfo.positionUs);
          if (newPositionUs != playbackInfo.positionUs) {
            playbackInfo=new PlaybackInfo(index,newPositionUs);
          }
          finishSourceInfoRefresh(manifest,true);
          return;
        }
        loadingPeriodHolder=previousPeriodHolder;
        loadingPeriodHolder.next=null;
        releasePeriodHoldersFrom(periodHolder);
        break;
      }
      bufferAheadPeriodCount++;
      int windowIndex=timeline.getPeriod(index,period).windowIndex;
      periodHolder.setIndex(timeline,timeline.getWindow(windowIndex,window),index);
      if (periodHolder == readingPeriodHolder) {
        seenReadingPeriod=true;
      }
      previousPeriodHolder=periodHolder;
    }
  }
 else   if (loadingPeriodHolder != null) {
    Object uid=loadingPeriodHolder.uid;
    int index=timeline.getIndexOfPeriod(uid);
    if (index == C.INDEX_UNSET) {
      boolean restarted=attemptRestart(playingPeriodHolder.index,oldTimeline,timeline);
      finishSourceInfoRefresh(manifest,true);
      if (!restarted) {
        stopInternal();
      }
      return;
    }
 else {
      int windowIndex=timeline.getPeriod(index,this.period).windowIndex;
      loadingPeriodHolder.setIndex(timeline,timeline.getWindow(windowIndex,window),index);
    }
  }
  if (oldTimeline != null) {
    int newPlayingIndex=playingPeriodHolder != null ? playingPeriodHolder.index : loadingPeriodHolder != null ? loadingPeriodHolder.index : C.INDEX_UNSET;
    if (newPlayingIndex != C.INDEX_UNSET && newPlayingIndex != playbackInfo.periodIndex) {
      playbackInfo=new PlaybackInfo(newPlayingIndex,playbackInfo.positionUs);
      updatePlaybackPositions();
    }
  }
  finishSourceInfoRefresh(manifest,true);
}