/// <summary>
        ///     Async searching of similar tracks on spotify via default track model.
        /// </summary>
        /// <param name="tracks">Tracks models</param>
        /// <param name="ct">Cancellation token.</param>
        /// <param name="progress">Callback to inform about current progress.</param>
        /// <returns>Dictionary of default models and spotify tracks.</returns>
        public async Task <IEnumerable <SpotifyTrack> > FindTracksPairsAsync(IEnumerable <TIn> tracks,
                                                                             CancellationToken ct, Action <float> progress = null)
        {
            Guarantee.IsEnumerableNotNullOrEmpty(tracks, nameof(tracks));

            var songPairs = new List <SpotifyTrack>();

            try
            {
                //to avoid enumeration if it isn't necessary
                var tracksCount = progress == null ? 0 : tracks.Count();
                var processed   = 0;

                foreach (var track in tracks)
                {
                    ct.ThrowIfCancellationRequested();

                    SpotifyTrack spotifyTrack;
                    try
                    {
                        spotifyTrack = await FindTrackPairAsync(track, new CancellationToken());
                    }
                    catch (APITooManyRequestsException tooManyRequestsException)
                    {
                        await Task.Delay(tooManyRequestsException.RetryAfter + TimeSpan.FromSeconds(1), ct);

                        spotifyTrack = await FindTrackPairAsync(track, new CancellationToken());
                    }

                    if (spotifyTrack != null)
                    {
                        songPairs.Add(spotifyTrack);
                    }

                    progress?.Invoke(100f / tracksCount * ++processed);
                }

                return(songPairs);
            }
            catch
            {
                return(songPairs);
            }
        }
        /// <summary>
        ///     Async saving of tracks into the library of user.
        /// </summary>
        /// <param name="spotifyTracks">Spotify tracks which is gonna be added.</param>
        /// <param name="ct">Token to cancel.</param>
        /// <returns></returns>
        public async Task <bool> SaveTracksAsync(IEnumerable <SpotifyTrack> spotifyTracks, CancellationToken ct)
        {
            Guarantee.IsEnumerableNotNullOrEmpty(spotifyTracks, nameof(spotifyTracks));

            foreach (var list in CommonUtils.SplitOnLists(spotifyTracks, 50))
            {
                ct.ThrowIfCancellationRequested();

                try
                {
                    return(await SaveTracks(list));
                }
                catch (APITooManyRequestsException tooManyRequestsException)
                {
                    await Task.Delay(tooManyRequestsException.RetryAfter + TimeSpan.FromSeconds(1), ct);

                    return(await SaveTracks(list));
                }
            }

            return(true);
        }