/// <exception cref="DataSourceException">Exception while fetching data.</exception>
        /// <exception cref="ConnectionException">No data available (disconnected from data source and not in cache).</exception>
        public async Task <ICollection <Category> > GetAllCategoriesAsync()
        {
            var cachedCategories = await GetCachedCategoriesAsync().ConfigureAwait(false);

            if (cachedCategories.Any())
            {
                UpdateCategoryListCacheAsync();
                return(cachedCategories);
            }
            if (!Current.IsConnected)
            {
                throw new ConnectionException();
            }
            ICollection <Category> categories;

            try
            {
                categories = await _userInitiatedClient.GetCategoriesAsync().ConfigureAwait(false);

                categories.SetCountProperty(c => c.PresentationOrder);
            }
            catch (Exception exc)
            {
                throw new DataSourceException(exc);
            }
            UpdateCategoryListCacheAsync(categories);
            return(categories);
        }
        private async Task UpdateCategoryListCacheAsync(ICollection <Category> categories = null)
        {
            if (!Current.IsConnected || _isBackgroundFetching)
            {
                return;
            }
            lock (LockObject)
            {
                _isBackgroundFetching = true;
            }
            if (categories == null)
            {
                categories = await _speculativeClient.GetCategoriesAsync().ConfigureAwait(false);
            }
            categories.SetCountProperty(c => c.PresentationOrder);
            if (Current.IsFast())
            {
                // ReSharper disable once PossibleMultipleEnumeration
                var detailed = new List <Category>();
                foreach (var category in categories)
                {
                    try
                    {
                        var cat = await _speculativeClient.GetCategoryDetailsAsync(category.Id).ConfigureAwait(false);

                        cat.Subcategories.SetCountProperty(sc => sc.PresentationOrder);
                        detailed.Add(cat);
                    }
                    catch (Exception e)
                    {
                        _loggingService.Report(e, this);
                    }
                }
                await
                Cache.InsertAllIfMoreDetailsAsync(detailed.ToDictionary(GetCategoryCacheKey, c => c),
                                                  TimeSpan.FromDays(Constants.Internet.DefaultCacheDays)).ConfigureAwait(false);
            }
            else if (Current.IsSlow())
            {
                await
                Cache.InsertAllIfMoreDetailsAsync(categories.ToDictionary(GetCategoryCacheKey, c => c),
                                                  TimeSpan.FromDays(Constants.Internet.DefaultCacheDays)).ConfigureAwait(false);
            }
            var catlist = string.Join(",", categories.Select(c => c.Id));
            await Cache.InsertObject(CategoryListKey, catlist);

            lock (LockObject)
            {
                _isBackgroundFetching = false;
            }
        }