protected override bool HandleData(ScheduleResponse data, CancellationToken token)
        {
            if (data == null)
            {
                return(false);
            }
            if (data.Status == ResponseStatus.AuthenticationError)
            {
                _requestHandler.Authenticate <MainViewModel>();
                return(false);
            }
            if (data.Status != ResponseStatus.Success)
            {
                throw new Exception("An error occurred on the server while fetching the schedule.");
            }

            if (!token.IsCancellationRequested)
            {
                // Now for the fun part!
                // The days group their periods by UTC date
                // but since we're in local date, some "days" may hold periods outside of their UTC date
                // so we have to disassemble them and re-assemble new days
                var days = data.Days.SelectMany(d => ForceSameStartAndEndDays(d.Periods))
                           .GroupBy(p => p.Start.Date)
                           .Select(g => new StudyDay {
                    Day = g.Key, Periods = g.ToArray()
                })
                           .ToArray();
                var missingDays = Enumerable.Range(0, MinimumDaysInWeek)
                                  .Select(n => WeekDate.AddDays(n))
                                  .Where(d => days.All(d2 => d.Date != d2.Day.Date))
                                  .Select(d => new StudyDay {
                    Day = d.Date, Periods = new Period[0]
                });
                Days = days.Concat(missingDays)
                       .OrderBy(d => d.Day)
                       .ToArray();
            }

            return(true);
        }
        protected override CachedTask <ScheduleResponse> GetData(bool force, CancellationToken token)
        {
            if (!force)
            {
                return(CachedTask.NoNewData <ScheduleResponse>());
            }

            Func <Task <ScheduleResponse> > getter = () => _requestHandler.ExecuteAsync(() =>
            {
                var request = new ScheduleRequest
                {
                    Language  = CultureInfo.CurrentUICulture.TwoLetterISOLanguageName,
                    WeekStart = WeekDate
                };
                return(_isaService.GetScheduleAsync(request, token));
            });

            if (DateTime.Now >= WeekDate && (DateTime.Now - WeekDate).TotalDays < DaysInWeek)
            {
                // cache ID must be non-zero so that other requests don't think this can be used as a placeholder
                return(CachedTask.Create(getter, 1, WeekDate.AddDays(DaysInWeek)));
            }
            return(CachedTask.DoNotCache(getter));
        }