/** Creates a 'sidx' box */
  protected Box createSidx(
      Track track,
      long earliestPresentationTime,
      long firstOffset,
      int referencedSize,
      long subSegmentDuration,
      byte sap,
      int sapDelta) {
    SegmentIndexBox sidx = new SegmentIndexBox();

    sidx.setEarliestPresentationTime(earliestPresentationTime);
    sidx.setFirstOffset(firstOffset);
    sidx.setReferenceId(track.getTrackMetaData().getTrackId());
    sidx.setTimeScale(track.getTrackMetaData().getTimescale());
    sidx.setFlags(0);
    sidx.setReserved(0);
    SegmentIndexBox.Entry sidxentry =
        createSidxEntry(referencedSize, subSegmentDuration, sap, sapDelta);

    ArrayList<SegmentIndexBox.Entry> sidxEntries = new ArrayList<SegmentIndexBox.Entry>();
    sidxEntries.add(sidxentry);
    sidx.setEntries(sidxEntries);
    return sidx;
  }
  @Override
  protected List<Box> createMoofMdat(Movie movie) {
    List<Box> moofsMdats = new LinkedList<Box>();
    HashMap<Track, long[]> intersectionMap = new HashMap<Track, long[]>();

    int maxNumberOfFragments = 0;
    for (Track track : movie.getTracks()) {
      long[] intersects = intersectionFinder.sampleNumbers(track);
      intersectionMap.put(track, intersects);
      maxNumberOfFragments = Math.max(maxNumberOfFragments, intersects.length);
    }

    int sequence = 1;
    // this loop has two indices:

    for (int cycle = 0; cycle < maxNumberOfFragments; cycle++) {

      final List<Track> sortedTracks =
          sortTracksInSequence(movie.getTracks(), cycle, intersectionMap);

      for (Track track : sortedTracks) {
        if (getAllowedHandlers().isEmpty() || getAllowedHandlers().contains(track.getHandler())) {
          long[] startSamples = intersectionMap.get(track);
          sequence = createFragment(moofsMdats, track, startSamples, cycle, sequence);
        }
      }
    }

    List<SegmentIndexBox> sidx_boxes = new LinkedList<SegmentIndexBox>();

    int inserter = 0;
    List<Box> newboxes = new ArrayList<Box>();
    int counter = 0;
    SegmentIndexBox sidx = new SegmentIndexBox();

    for (int i = 0; i < moofsMdats.size(); i++) {

      if (moofsMdats.get(i).getType().equals("sidx")) {
        sidx_boxes.add((SegmentIndexBox) moofsMdats.get(i));
        counter++;
        if (counter == 1) {
          inserter = i;
        }
      } else {
        newboxes.add(moofsMdats.get(i));
      }
    }
    long earliestPresentationTime = sidx_boxes.get(0).getEarliestPresentationTime();
    if (earliestPresentationTime < 0) {
      System.err.println(
          "negative earlist_presentation_time in sidx. Setting to 0. May cause sync issues");
      earliestPresentationTime = 0;
    }
    sidx.setEarliestPresentationTime(earliestPresentationTime);
    sidx.setFirstOffset(sidx_boxes.get(0).getFirstOffset());
    sidx.setReferenceId(sidx_boxes.get(0).getReferenceId());
    sidx.setTimeScale(sidx_boxes.get(0).getTimeScale());
    sidx.setFlags(sidx_boxes.get(0).getFlags());
    List<SegmentIndexBox.Entry> sidxbox_entries = new ArrayList<SegmentIndexBox.Entry>();
    for (SegmentIndexBox sidxbox : sidx_boxes) {
      List<SegmentIndexBox.Entry> entryfrag = sidxbox.getEntries();
      for (SegmentIndexBox.Entry entry : entryfrag) {
        sidxbox_entries.add(entry);
      }
    }

    sidx.setEntries(sidxbox_entries);
    newboxes.add(inserter, sidx);
    return newboxes;
  }