/// <summary>
        /// Checks the subscriptions for the device and removes all tracks still referred to by other playlists from the proposed deletes.
        /// </summary>
        /// <param name="library">The libray that can be used to access tracks. (for iTunes, the XML library is preferred, COM access is slow for enumeration)</param>
        /// <param name="actions">The actions generated by diff.</param>
        /// <returns>A subset of actions with all damaging deletes removed.</returns>
        public IEnumerable<SyncAction> FixProposedDeletes(iTunesLibrary library, IEnumerable<SyncAction> actions)
        {
            // We don't have anything to compare to = return the proposed actions as-is.
            if (Subscription == null) return actions;

            HashSet<string> subscribedTracks = GetSubscribedTracks(library);

            // Pick all tracks that are set to be deleted.
            HashSet<string> proposedDeletions = new HashSet<string>(
                from a in actions
                where a.Type == SyncType.Remove
                select a.DeviceLocation
            );

            // Remove all proposed deletions that are still referenced by other playlists
            proposedDeletions.ExceptWith(subscribedTracks);

            // Create a new list without the excluded deletes
            return new List<SyncAction>(
                from a in actions
                where (a.Type == SyncType.Add) || ((a.Type == SyncType.Remove) && (proposedDeletions.Contains(a.DeviceLocation)))
                select a
            );
        }
        static HashSet<string> GetSubscribedTracks(IEnumerable<string> playlists, iTunesLibrary library, string root)
        {
            HashSet<string> tracks = new HashSet<string>();

            foreach (string playlistName in playlists)
            {
                IPlaylist playlist = library.GetFirstPlaylistByName(playlistName);
                if(playlist == null)
                {
                    Log.WarnFormat("Subscribed playlist {0} not found.", playlistName);
                    continue;
                }

                foreach (ITrack track in playlist.Tracks)
                {
                    tracks.Add(track.GetPlaylistLine(root));
                }
            }

            return tracks;
        }
        /// <summary>
        /// Compares current subscription to a new subscription and retrieves a list of all tracks that will no longer be referred to by any playlists.
        /// </summary>
        /// <param name="library">The libray that can be used to access tracks. (for iTunes, the XML library is preferred, COM access is slow for enumeration)</param>
        /// <param name="newSubscription">The new subscription request from the client.</param>
        /// <returns>A list of all tracks that will no longer be referred to by any playlists.</returns>
        public IEnumerable<string> GetGarbageTracks(iTunesLibrary library, ISubscription newSubscription)
        {
            // We don't have anything to compare to = nothing to clean up.
            if ((Subscription == null) ||
                (Subscription.Playlists == null) ||
                (Subscription.Playlists.Length <= 0)) return new List<string>();

            HashSet<string> currentTracks = GetSubscribedTracks(library);
            HashSet<string> newTracks = GetSubscribedTracks(newSubscription.Playlists, library, newSubscription.DeviceMediaRoot);

            currentTracks.ExceptWith(newTracks);

            return currentTracks;
        }
 /// <summary>
 /// Returns a list of all unique tracks in subscribed playlists.
 /// </summary>
 /// <returns>A list of all unique tracks in subscribed playlists.</returns>
 public HashSet<string> GetSubscribedTracks(iTunesLibrary library)
 {
     return GetSubscribedTracks(Subscription.Playlists, library, Subscription.DeviceMediaRoot);
 }
 /// <summary>
 /// Compares current subscription to a new subscription and retrieves a list of all tracks that will no longer be referred to by any playlists.
 /// </summary>
 /// <param name="library">The libray that can be used to access tracks. (for iTunes, the XML library is preferred, COM access is slow for enumeration)</param>
 /// <param name="newSubscription">The new subscription request from the client.</param>
 /// <returns>A list of all tracks that will no longer be referred to by any playlists as SyncActions of type Remove.</returns>
 public SyncAction[] GetGarbageActions(iTunesLibrary library, ISubscription newSubscription)
 {
     // Do some lambda magic...
     return GetGarbageTracks(library, newSubscription).Select(
             s => new SyncAction {DeviceLocation = s, Type = SyncType.Remove}
            ).ToArray();
 }