private void LoadPlaylists()
        {
            if (CurrentActivity == null)
            {
                return;
            }
            else if (CurrentActivity.State != ActivityState.Connected)
            {
                Hyena.Log.Debug(String.Format("activity state {0} is invalid.", CurrentActivity.State));
                return;
            }
            else if (CurrentState != State.LoadedMetadata)
            {
                Hyena.Log.Debug(String.Format("state {0} is invalid.", CurrentState));
                return;
            }

            try {
                IMetadataProviderService service = CurrentActivity.GetDBusObject <IMetadataProviderService> (MetadataProviderService.BusName, MetadataProviderService.ObjectPath);
                int [] playlist_ids = service.GetPlaylistIds(LibraryType.Music);

                download_monitor.Reset();

                if (playlist_ids.Length == 0)
                {
                    CurrentState = State.Loaded;
                }
                else
                {
                    foreach (int id in playlist_ids)
                    {
                        string            playlist_path     = service.CreatePlaylistProvider(id).ToString();
                        IPlaylistProvider playlist_provider = CurrentActivity.GetDBusObject <IPlaylistProvider>
                                                                  (PlaylistProvider.BusName, playlist_path);

                        LibraryDownload download = new LibraryDownload();
                        download_monitor.Add(playlist_path, download);
                        //download_monitor.AssociateObject (playlist_path, new ContactPlaylistSource (playlist_provider.GetName (), this));

                        download.ProcessIncomingPayloads(delegate(object sender, object [] o) {
                            OnPlaylistTracksDownloaded(new DownloadedTracksEventArgs(sender as LibraryDownload, o, playlist_provider.GetName()));
                        });

                        playlist_provider.ChunkReady += OnPlaylistChunkReady;
                        playlist_provider.GetChunks(chunk_length);
                    }

                    download_monitor.Start();
                }
            } catch (Exception e) {
                Hyena.Log.Warning(e);
                ResetState();
                OnError(new TubeManagerErrorEventArgs(ErrorReason.ErrorDuringPlaylistLoad));
            }
        }
        private void LoadData()
        {
            Hyena.Log.Debug("TubeManager.LoadData ()");

            if (CurrentState >= State.LoadingMetadata)
            {
                return;
            }
            else if (CurrentActivity == null)
            {
                return;
            }
            else if (CurrentActivity.State != ActivityState.Connected)
            {
                Hyena.Log.Debug(String.Format("activity state {0} is invalid.", CurrentActivity.State));
                return;
            }

            IMetadataProviderService service = CurrentActivity.GetDBusObject <IMetadataProviderService> (MetadataProviderService.BusName, MetadataProviderService.ObjectPath);

            if (service == null)
            {
                Hyena.Log.Debug("ContactSource.LoadData found service null");
                return;
            }

            try {
                // call MetadataProviderService.PermissionGranted () asynchronously to prevent blocking the UI
                // when Telepathy tubes are slow
                if (CurrentState <= State.Waiting)
                {
                    Hyena.Log.Debug("Setting to waiting state");
                    CurrentState      = State.Waiting;
                    permission_caller = new GetBoolPropertyCaller(service.PermissionGranted);
                    permission_caller.BeginInvoke(new AsyncCallback(delegate(IAsyncResult result) {
                        if (CurrentState != State.Waiting)
                        {
                            return;
                        }

                        GetBoolPropertyCaller caller = (GetBoolPropertyCaller)result.AsyncState;
                        bool granted = caller.EndInvoke(result);

                        if (granted)
                        {
                            CurrentState = State.PermissionGranted;
                        }
                        else
                        {
                            CurrentState = State.PermissionNotGranted;
                        }

                        LoadData();
                    }), permission_caller);
                }
                else if (CurrentState == State.PermissionGranted)
                {
                    service.DownloadingAllowedChanged += delegate(bool allowed) {
                        IsDownloadingAllowed = allowed;
                    };

                    // determine if downloading is allowed asynchronously
                    downloading_caller = new GetBoolPropertyCaller(service.DownloadsAllowed);
                    downloading_caller.BeginInvoke(new AsyncCallback(delegate(IAsyncResult result) {
                        GetBoolPropertyCaller caller = (GetBoolPropertyCaller)result.AsyncState;
                        IsDownloadingAllowed         = caller.EndInvoke(result);
                    }), downloading_caller);

                    // clean up any residual tracks
                    download_monitor.Reset();
                    CurrentState = State.LoadingMetadata;

                    string            metadata_path    = service.CreateMetadataProvider(LibraryType.Music).ToString();
                    IMetadataProvider library_provider = CurrentActivity.GetDBusObject <IMetadataProvider> (MetadataProvider.BusName, metadata_path);

                    LibraryDownload download = new LibraryDownload();
                    download_monitor.Add(metadata_path, download);

                    download.ProcessIncomingPayloads(delegate(object sender, object [] o) {
                        OnTracksDownloaded(new DownloadedTracksEventArgs(sender as LibraryDownload, o));
                    });

                    library_provider.ChunkReady += OnLibraryChunkReady;
                    library_provider.GetChunks(chunk_length);

                    download_monitor.Start();
                }
                else if (CurrentState == State.PermissionNotGranted)
                {
                    CurrentState           = State.Waiting;
                    service.PermissionSet += OnPermissionSet;
                    service.RequestPermission();
                }
            } catch (Exception e) {
                Hyena.Log.Warning(e);
                ResetState();
                OnError(new TubeManagerErrorEventArgs(ErrorReason.ErrorDuringLoad));
            }
        }