code: public void attachMetadataCache(SlotReference slot, File file)
              throws IOException {
          ensureRunning();
          if (slot.player < 1 || slot.player > 4 || DeviceFinder.getInstance().getLatestAnnouncementFrom(slot.player) == null) {
              throw new IllegalArgumentException("unable to attach metadata cache for player " + slot.player);
          }
          if ((slot.slot != CdjStatus.TrackSourceSlot.USB_SLOT) && (slot.slot != CdjStatus.TrackSourceSlot.SD_SLOT)) {
              throw new IllegalArgumentException("unable to attach metadata cache for slot " + slot.slot);
          }
  
          MetadataCache cache = new MetadataCache(file);
          final MediaDetails slotDetails = getMediaDetailsFor(slot);
          if (cache.sourceMedia !=  null && slotDetails != null) {
              if (!slotDetails.hashKey().equals(cache.sourceMedia.hashKey())) {
                  throw new IllegalArgumentException("Cache was created for different media (" + cache.sourceMedia.hashKey() +
                          ") than is in the slot (" + slotDetails.hashKey() + ").");
              }
              if (slotDetails.hasChanged(cache.sourceMedia)) {
                  logger.warn("Media has changed (" + slotDetails + ") since cache was created (" + cache.sourceMedia +
                          "). Attaching anyway as instructed.");
              }
          }
          attachMetadataCacheInternal(slot, cache);
      }
docs: Attach a metadata cache file to a particular player media slot, so the cache will be used instead of querying
  the player for metadata. This supports operation with metadata during shows where DJs are using all four player
  numbers and heavily cross-linking between them.
  
  If the media is ejected from that player slot, the cache will be detached.
  
  @param slot the media slot to which a meta data cache is to be attached
  @param file the metadata cache to be attached
  
  @throws IOException if there is a problem reading the cache file
  @throws IllegalArgumentException if an invalid player number or slot is supplied
  @throws IllegalStateException if the metadata finder is not running