docs: static void copyTracksToCache(List<Message> trackListEntries, int playlistId, Client client, SlotReference slot,
                                    File cache, MetadataCacheCreationListener listener)
              throws IOException, TimeoutException {
          FileOutputStream fos = null;
          BufferedOutputStream bos = null;
          ZipOutputStream zos = null;
          WritableByteChannel channel = null;
          final Set<Integer> tracksAdded = new HashSet<Integer>();
          final Set<Integer> artworkAdded = new HashSet<Integer>();
          try {
              fos = new FileOutputStream(cache);
              bos = new BufferedOutputStream(fos);
              zos = new ZipOutputStream(bos);
              zos.setMethod(ZipOutputStream.DEFLATED);
  
              addCacheFormatEntry(trackListEntries, playlistId, zos);
              channel = Channels.newChannel(zos);
              addCacheDetailsEntry(slot, zos, channel);
  
              // Write the actual metadata entries
              final int totalToCopy = trackListEntries.size();
              TrackMetadata lastTrackAdded = null;
              int tracksCopied = 0;
  
              for (Message entry : trackListEntries) {
                  if (entry.getMenuItemType() == Message.MenuItemType.UNKNOWN) {
                      logger.warn("Encountered unrecognized track list entry item type: {}", entry);
                  }
  
                  int rekordboxId = (int)((NumberField)entry.arguments.get(1)).getValue();
                  if (!tracksAdded.contains(rekordboxId)) {  // Ignore extra copies of a track present on a playlist.
                      lastTrackAdded = copyTrackToCache(client, slot, zos, channel, artworkAdded, rekordboxId);
                      tracksAdded.add(rekordboxId);
                  }
  
                  if (listener != null) {
                      if (!listener.cacheCreationContinuing(lastTrackAdded, ++tracksCopied, totalToCopy)) {
                          logger.info("Track metadata cache creation canceled by listener");
                          if (!cache.delete()) {
                              logger.warn("Unable to delete metadata cache file, {}", cache);
                          }
                          return;
                      }
                  }
  
                  Thread.sleep(getCachePauseInterval());
              }
          } catch (InterruptedException e) {
              logger.warn("Interrupted while building metadata cache file, aborting", e);
              if (!cache.delete()) {
                  logger.warn("Unable to delete metadata cache file, {}", cache);
              }
          } finally {
              try {
                  if (channel != null) {
                      channel.close();
                  }
              } catch (Exception e) {
                  logger.error("Problem closing byte channel for writing to metadata cache", e);
              }
              try {
                  if (zos != null) {
                      zos.close();
                  }
              } catch (Exception e) {
                  logger.error("Problem closing Zip Output Stream of metadata cache", e);
              }
              try {
                  if (bos != null) {
                      bos.close();
                  }
              } catch (Exception e) {
                  logger.error("Problem closing Buffered Output Stream of metadata cache", e);
              }
              try {
                  if (fos != null) {
                      fos.close();
                  }
              } catch (Exception e) {
                  logger.error("Problem closing File Output Stream of metadata cache", e);
              }
          }
      }