/** {@inheritDoc} */
  public IsoFile build(Movie movie) {
    LOG.fine("Creating movie " + movie);
    for (Track track : movie.getTracks()) {
      // getting the samples may be a time consuming activity
      List<ByteBuffer> samples = track.getSamples();
      putSamples(track, samples);
      long[] sizes = new long[samples.size()];
      for (int i = 0; i < sizes.length; i++) {
        sizes[i] = samples.get(i).limit();
      }
      putSampleSizes(track, sizes);
    }

    IsoFile isoFile = new IsoFile();
    // ouch that is ugly but I don't know how to do it else
    List<String> minorBrands = new LinkedList<String>();
    minorBrands.add("isom");
    minorBrands.add("iso2");
    minorBrands.add("avc1");

    isoFile.addBox(new FileTypeBox("isom", 0, minorBrands));
    isoFile.addBox(createMovieBox(movie));
    InterleaveChunkMdat mdat = new InterleaveChunkMdat(movie);
    isoFile.addBox(mdat);

    /*
    dataOffset is where the first sample starts. In this special mdat the samples always start
    at offset 16 so that we can use the same offset for large boxes and small boxes
     */
    long dataOffset = mdat.getDataOffset();
    for (StaticChunkOffsetBox chunkOffsetBox : chunkOffsetBoxes) {
      long[] offsets = chunkOffsetBox.getChunkOffsets();
      for (int i = 0; i < offsets.length; i++) {
        offsets[i] += dataOffset;
      }
    }

    return isoFile;
  }