/// <summary>
 /// Called when the state of a playlist changes.
 /// If the playlist is in the playlist container and fully loaded, it introduces the
 /// playlist if that has not happened before.
 /// If no pending changes are present and no update is in progress, the playlist
 /// will be stored / updated.
 /// </summary>
 void playlist_StateChanged(SpotiFire.Playlist sender, PlaylistEventArgs e)
 {
     lock (sender) {
         //LogPlaylist(sender, "state changed");
         if (this.IsInSession(sender) && sender.IsFullyLoaded())
         {
             if (!sender.IsKnown())
             {
                 Introduce(sender);
             }
             if (!sender.HasPendingChanges && !sender.IsUpdateInProgress())
             {
                 CreateOrUpdate(sender);
             }
         }
     }
 }
 void LogPlaylist(SpotiFire.Playlist playlist, string ev, PlaylistEventArgs e = null)
 {
     lock (this) {
         Console.WriteLine(ev.ToUpper());
         Console.WriteLine("  Playlist: " + (playlist.IsLoaded ? playlist.Name : "<unknown>"));
         Console.WriteLine("  - Loaded:             " + playlist.IsLoaded.ToString());
         Console.WriteLine("  - Known:              " + playlist.IsKnown().ToString());
         if (playlist.IsLoaded)
         {
             Console.WriteLine("  - IsCollaborative:    " + playlist.IsCollaborative.ToString());
             Console.WriteLine("  - HasPendingChanges:  " + playlist.HasPendingChanges.ToString());
             Console.WriteLine("  - IsUpdateInProgress: " + playlist.IsUpdateInProgress().ToString());
             Console.WriteLine("  - AllTracksLoaded:    " + playlist.AllTracksLoaded().ToString());
         }
         if (e != null)
         {
             Console.WriteLine("  - Update completed:   " + e.UpdateComplete.ToString());
         }
     }
 }