class ConcatenatingMediaSource extends CompositeMediaSource<MediaSourceHolder> {

  @Override
  public final MediaPeriod createPeriod(
      MediaPeriodId id, Allocator allocator, long startPositionUs) {
    Object mediaSourceHolderUid = getMediaSourceHolderUid(id.periodUid);
    MediaSourceHolder holder = mediaSourceByUid.get(mediaSourceHolderUid);
    if (holder == null) {
      // Stale event. The media source has already been removed.
      holder = new MediaSourceHolder(new DummyMediaSource());
      holder.hasStartedPreparing = true;
    }
    DeferredMediaPeriod mediaPeriod =
        new DeferredMediaPeriod(holder.mediaSource, id, allocator, startPositionUs);
    mediaSourceByMediaPeriod.put(mediaPeriod, holder);
    holder.activeMediaPeriods.add(mediaPeriod);
    if (!holder.hasStartedPreparing) {
      holder.hasStartedPreparing = true;
      prepareChildSource(holder, holder.mediaSource);
    } else if (holder.isPrepared) {
      MediaPeriodId idInSource = id.copyWithPeriodUid(getChildPeriodUid(holder, id.periodUid));
      mediaPeriod.createPeriod(idInSource);
    }
    return mediaPeriod;
  }

  public  ConcatenatingMediaSource(MediaSource... mediaSources);
  public  ConcatenatingMediaSource(boolean isAtomic, MediaSource... mediaSources);
  public  ConcatenatingMediaSource(
      boolean isAtomic, ShuffleOrder shuffleOrder, MediaSource... mediaSources);
  @SuppressWarnings("initialization") public  ConcatenatingMediaSource(
      boolean isAtomic,
      boolean useLazyPreparation,
      ShuffleOrder shuffleOrder,
      MediaSource... mediaSources);

}