/// <summary>
        /// Downloads and tags a track. Returns true if the track has been correctly downloaded; false otherwise.
        /// </summary>
        /// <param name="albumDirectoryPath">The path where to save the tracks.</param>
        /// <param name="album">The album of the track to download.</param>
        /// <param name="track">The track to download.</param>
        /// <param name="tagTrack">True to tag the track; false otherwise.</param>
        /// <param name="saveCoverArtInTags">True to save the cover art in the tag tracks; false otherwise.</param>
        /// <param name="artwork">The cover art.</param>
        private Boolean DownloadAndTagTrack(String albumDirectoryPath, Album album, Track track, Boolean tagTrack,
            Boolean saveCoverArtInTags, TagLib.Picture artwork) {
                
            Log("Downloading track \"" + track.Title + "\" from url: " + track.Mp3Url, LogType.VerboseInfo);
                
            // Set location to save the file
            String trackPath = albumDirectoryPath + track.GetFileName(album.Artist);

            int tries = 0;
            Boolean trackDownloaded = false;

            do {
                var doneEvent = new AutoResetEvent(false);

                using (var webClient = new WebClient()) {
                    // Update progress bar when downloading
                    webClient.DownloadProgressChanged += (s, e) => {
                        UpdateProgress(track.Mp3Url, e.BytesReceived);
                    };

                    // Warn & tag when downloaded
                    webClient.DownloadFileCompleted += (s, e) => {
                        tries++;

                        if (!e.Cancelled && e.Error == null) {
                            trackDownloaded = true;

                            if (tagTrack) {
                                // Tag (ID3) the file when downloaded
                                TagLib.File tagFile = TagLib.File.Create(trackPath);
                                tagFile.Tag.Album = album.Title;
                                tagFile.Tag.AlbumArtists = new String[1] { album.Artist };
                                tagFile.Tag.Performers = new String[1] { album.Artist };
                                tagFile.Tag.Title = track.Title;
                                tagFile.Tag.Track = (uint) track.Number;
                                tagFile.Tag.Year = (uint) album.ReleaseDate.Year;
                                tagFile.Save();
                            }

                            if (saveCoverArtInTags && artwork != null) {
                                // Save cover in tags when downloaded
                                TagLib.File tagFile = TagLib.File.Create(trackPath);
                                tagFile.Tag.Pictures = new TagLib.IPicture[1] { artwork };
                                tagFile.Save();
                            }

                            Log("Downloaded track \"" + track.GetFileName(album.Artist) + "\" from album \"" + album.Title + "\"",
                                LogType.IntermediateSuccess);
                        } else if (!e.Cancelled && e.Error != null) {
                            if (tries < Constants.DownloadMaxTries) {
                                Log("Unable to download track \"" + track.GetFileName(album.Artist) + "\" from album \"" + album.Title +
                                    "\". " + "Try " + tries + " of " + Constants.DownloadMaxTries, LogType.Warning);
                            } else {
                                Log("Unable to download track \"" + track.GetFileName(album.Artist) + "\" from album \"" + album.Title +
                                    "\". " + "Hit max retries of " + Constants.DownloadMaxTries, LogType.Error);
                            }
                        } // Else the download has been cancelled (by the user)

                        doneEvent.Set();
                    };

                    lock (this.pendingDownloads) {
                        if (this.userCancelled) {
                            // Abort
                            return false;
                        }
                        // Register current download
                        this.pendingDownloads.Add(webClient);
                        // Start download
                        webClient.DownloadFileAsync(new Uri(track.Mp3Url), trackPath);
                    }

                    // Wait for download to be finished
                    doneEvent.WaitOne();
                    lock (this.pendingDownloads) {
                        this.pendingDownloads.Remove(webClient);
                    }
                }
            } while (!trackDownloaded && tries < Constants.DownloadMaxTries);

            return trackDownloaded;
        }