docs: private void updateListenersIfNeeded(int player, TrackPositionUpdate update, Beat beat) {
          // Iterate over a copy to avoid issues with concurrent modification
          for (Map.Entry<TrackPositionListener, TrackPositionUpdate> entry :
                  new HashMap<TrackPositionListener, TrackPositionUpdate>(trackPositionListeners).entrySet()) {
              if (player == listenerPlayerNumbers.get(entry.getKey())) {  // This listener is interested in this player
                  if (update == null) {  // We are reporting a loss of information
                      if (entry.getValue() != NO_INFORMATION) {
                          if (trackPositionListeners.replace(entry.getKey(), entry.getValue(), NO_INFORMATION)) {
                              try {
                                  entry.getKey().movementChanged(null);
                              } catch (Throwable t) {
                                  logger.warn("Problem delivering null movementChanged update", t);
                              }
                          }
                      }
                  } else {  // We have some information, see if it is a significant change from what was last reported
                      final TrackPositionUpdate lastUpdate = entry.getValue();
                      if (lastUpdate == NO_INFORMATION ||
                              lastUpdate.playing != update.playing ||
                              Math.abs(lastUpdate.pitch - update.pitch) > 0.000001 ||
                              interpolationsDisagree(lastUpdate, update)) {
                          if (trackPositionListeners.replace(entry.getKey(), entry.getValue(), update)) {
                              try {
                                  entry.getKey().movementChanged(update);
                              } catch (Throwable t) {
                                  logger.warn("Problem delivering movementChanged update", t);
                              }
                          }
                      }
  
                      // And regardless of whether this was a significant change, if this was a new beat and the listener
                      // implements the interface that requests all beats, send that information.
                      if (update.definitive && entry.getKey() instanceof TrackPositionBeatListener) {
                          try {
                              ((TrackPositionBeatListener) entry.getKey()).newBeat(beat, update);
                          } catch (Throwable t) {
                              logger.warn("Problem delivering newBeat update", t);
                          }
                      }
                  }
              }
          }
      }