public void LoadLibrary()
        {
            if (IsLibraryLoaded)
            {
                return;
            }

            /*
             * Sqlite makes a transaction to create a shared lock
             * Wrapping it in one single transactions assures it is only lock and release once
             */
            _sqlService.BeginTransaction();

            var songs   = _sqlService.SelectAll <Song>().OrderByDescending(p => p.Id).ToList();
            var artists = _sqlService.SelectAll <Artist>().OrderByDescending(p => p.Id).ToList();
            var albums  = _sqlService.SelectAll <Album>().OrderByDescending(p => p.Id).ToList();

            Stations =
                new OptimizedObservableCollection <RadioStation>(
                    _sqlService.SelectAll <RadioStation>().OrderByDescending(p => p.Id).ToList());

            // Let go of the lock
            _sqlService.Commit();

            var isForeground = _dispatcher != null;

            foreach (var song in songs)
            {
                song.Artist = artists.FirstOrDefault(p => p.Id == song.ArtistId);
                song.Album  = albums.FirstOrDefault(p => p.Id == song.AlbumId);
            }

            if (isForeground)
            {
                _dispatcher.RunAsync(() => Songs.AddRange(songs)).Wait();
            }
            else
            {
                Songs.AddRange(songs);
            }

            if (isForeground)
            {
                foreach (var artist in artists)
                {
                    _dispatcher.RunAsync(
                        () =>
                    {
                        var artworkPath = string.Format(_artistArtworkFilePath, artist.Id);
                        artist.Artwork  = artist.HasArtwork
                                ? _bitmapFactory.CreateImage(
                            new Uri(_localFilePrefix + artworkPath))
                                : null;

                        if (ScaledImageSize != 0 && artist.Artwork != null)
                        {
                            artist.Artwork.SetDecodedPixel(ScaledImageSize);
                        }
                    }).Wait();
                }
            }

            foreach (var album in albums)
            {
                album.Songs.AddRange(songs.Where(p => !p.IsTemp && p.AlbumId == album.Id).OrderBy(p => p.TrackNumber));
                album.PrimaryArtist = artists.FirstOrDefault(p => p.Id == album.PrimaryArtistId);

                if (isForeground)
                {
                    _dispatcher.RunAsync(
                        () =>
                    {
                        var artworkPath = string.Format(_artworkFilePath, album.Id);
                        if (album.HasArtwork)
                        {
                            var path = _localFilePrefix + artworkPath;

                            album.Artwork = _bitmapFactory.CreateImage(new Uri(path));

                            if (ScaledImageSize != 0)
                            {
                                album.Artwork.SetDecodedPixel(ScaledImageSize);

                                album.MediumArtwork = _bitmapFactory.CreateImage(new Uri(path));
                                album.MediumArtwork.SetDecodedPixel(ScaledImageSize / 2);

                                album.SmallArtwork = _bitmapFactory.CreateImage(new Uri(path));
                                album.SmallArtwork.SetDecodedPixel(50);
                            }
                        }
                        else
                        {
                            var artwork = album.PrimaryArtist.HasArtwork
                                    ? album.PrimaryArtist.Artwork
                                    : _missingArtwork;
                            album.Artwork       = artwork;
                            album.MediumArtwork = artwork;
                            album.SmallArtwork  = artwork;
                        }
                    }).Wait();
                }
            }

            if (isForeground)
            {
                _dispatcher.RunAsync(() => Albums.AddRange(albums)).Wait();
            }
            else
            {
                Albums.AddRange(albums);
            }

            foreach (var artist in artists)
            {
                artist.Songs.AddRange(songs.Where(p => !p.IsTemp && p.ArtistId == artist.Id).OrderBy(p => p.Name));
                artist.Albums.AddRange(
                    albums.Where(p => p.PrimaryArtistId == artist.Id && p.Songs.Count > 0).OrderBy(p => p.Name));

                var songsAlbums = artist.Songs.Select(p => p.Album);
                artist.Albums.AddRange(songsAlbums.Where(p => p.Songs.Count > 0 && !artist.Albums.Contains(p)));
            }

            if (isForeground)
            {
                _dispatcher.RunAsync(() => Artists.AddRange(artists)).Wait();
            }
            else
            {
                Artists.AddRange(artists);
            }

            IsLibraryLoaded = true;

            LoadQueue(songs);
            LoadPlaylists();

            if (!isForeground)
            {
                return;
            }

            var corruptSongs =
                Songs.ToList()
                .Where(p => string.IsNullOrEmpty(p.Name) || p.Album == null || p.Artist == null)
                .ToList();

            foreach (var corruptSong in corruptSongs)
            {
                DeleteSongAsync(corruptSong).Wait();
            }

            _dispatcher.RunAsync(
                () =>
            {
                if (LibraryLoaded != null)
                {
                    LibraryLoaded(this, null);
                }
            }).Wait();

            try
            {
                CleanupFiles(albums, artists);
            }
            catch
            {
                // ignored
            }
        }
        public void LoadLibrary()
        {
            Songs = new OptimizedObservableCollection <Song>
            {
                new Song
                {
                    Name   = "Maps",
                    Artist =
                        new Artist
                    {
                        Name    = "Maroon 5",
                        Artwork =
                            _bitmapFactory.CreateImage(
                                new Uri(
                                    "http://musicimage.xboxlive.com/content/music.1F154700-0200-11DB-89CA-0019B92A3933/image?locale=en-US"))
                    },
                    Album =
                        new Album
                    {
                        Name    = "V",
                        Artwork =
                            _bitmapFactory.CreateImage(
                                new Uri("http://static.musictoday.com/store/bands/93/product_medium/IXDDM501.JPG"))
                    }
                },
                new Song
                {
                    Name   = "Animal",
                    Artist = new Artist {
                        Name = "Maroon 5"
                    },
                    Album =
                        new Album
                    {
                        Name    = "V",
                        Artwork =
                            _bitmapFactory.CreateImage(
                                new Uri("http://static.musictoday.com/store/bands/93/product_medium/IXDDM501.JPG"))
                    }
                }
            };

            Albums = new OptimizedObservableCollection <Album>
            {
                new Album
                {
                    Id      = 0,
                    Name    = "V",
                    Artwork =
                        _bitmapFactory.CreateImage(
                            new Uri("http://static.musictoday.com/store/bands/93/product_medium/IXDDM501.JPG")),
                    PrimaryArtist = new Artist {
                        Name = "Maroon 5"
                    },
                    Genre = "Pop",
                    Songs = new OptimizedObservableCollection <Song>(Songs)
                }
            };

            Artists = new OptimizedObservableCollection <Artist>
            {
                new Artist {
                    Name = "Maroon 5", Albums = Albums, Songs = Songs
                },
                new Artist {
                    Name = "Taylor Swift"
                }
            };

            Playlists = new OptimizedObservableCollection <Playlist>
            {
                new Playlist
                {
                    Name = "Fav 5"
                },
                new Playlist
                {
                    Name = "workout fun!"
                }
            };

            var pSongs = new ObservableCollection <PlaylistSong>();

            foreach (var song in Songs)
            {
                pSongs.Add(new PlaylistSong
                {
                    Song = song
                });
            }

            foreach (var playlist in Playlists)
            {
                playlist.Songs = pSongs;
            }

            PlaybackQueue = new OptimizedObservableCollection <QueueSong>(pSongs);
        }