             }
             
             //The only currently reliable notficiation of track/queue completion is
-            // this test for playbackPosition > mediaItemDuration on .paused.
+            // to test for playbackPosition > mediaItemDuration on .paused.
             if playbackPosition > mediaItemDuration {
                 DispatchQueue.main.async {
                     self.delegate?.playbackStopped(trackCompleted: true)

            return
        }
        
        MusicPlayer.player.setQueue(with: [id])
        
        //Despite what documentation says this does not appear
        // to be required and it seems to cause numerous race
        // conditions and generally unreliable behavior.
        //I've also never seen the completion fire.
//        player.prepareToPlay() { error in
//            if let error = error {
//                print("Error in \(#function): \(error)")
//            }
//        }
        
        MusicPlayer.player.currentPlaybackTime = 0.0
    }
    
    @objc private func handleStateChange(notification: Notification) {
        //As of iOS 14.3 .MPMusicPlayerControllerPlaybackStateDidChange and .playbackState are completely fucked.
        // I can't tell if it's a race condition between the state change and the notification but this is the behavior
        // I observe when reading state based on the notification. There is, of course, no state in the notification itself.
        //
        // .stopped is NOT called when stop() is invoked
        // .stopped is called AFTER play() begins on new queue
        // .paused is called when prepareToPlay() is called (can be at play() time) with player.currentPlaybackTime == nowPlayingItem.playbackDuration
        // .paused is called when playback is complete with player.currentPlaybackTime > nowPlayingItem.playbackDuration
        // .paused is called when playback restarts, but after .playing, with player.currentPlaybackTime == 0.0
        // .paused is called when playback is actually paused with player.currentPlaybackTime == actual playback progress

        //I would prefer to use this for delegate notification but it is unreliable so delegate is now tied to
        // calls to the play/pause/stop methods. I still need to handle .paused here to know when
        // track/queue is complete, however.
        
        switch playbackState {
        case .stopped:

    }
    
    @discardableResult public func play() -> Bool {
        //Setting currentPlaybackRate has side effect of initiating playback.
        // Attempting to call play() immediately followed by
        // setting currentPlaybackRate introduces a race condition
        // that prevents currentPlaybackRate from taking effect.
        MusicPlayer.player.currentPlaybackRate = playbackRate
        
        delegate?.playbackStarted()
