/// <summary>
        /// Launch the loading of a data page.
        /// If a task is currently running, it gets discarded (callbacks won't be called).
        /// If the first page loading is asked whereas one or several pages have already been loaded, a "refresh" is detected.
        /// </summary>
        /// <param name="pageNumber">The page number to load (pageNumber = 1 for the first page).</param>
        /// <param name="calledFromScroll">True if LoadPage has been called from OnScroll method of the IInfiniteListLoader.</param>
        public Task <PageResult <TResult> > LoadPage(int pageNumber, bool calledFromScroll = false)
        {
            Contract.Requires(() => pageNumber > 0);
            Contract.Requires(
                () => calledFromScroll || (pageNumber == 1 || pageNumber == (PageLoadedCount + 1)),
                "The paginator can only load sequential pages");

            InternalLogger.Info($"Requesting page n°{pageNumber} load, {PageLoadedCount} pages loaded so far");
            lock (_syncRoot)
            {
                if (calledFromScroll)
                {
                    if (pageNumber <= PageLoadedCount)
                    {
                        InternalLogger.Info($"Aborting IInfiniteListLoader call: only a direct call to LoadPage can lead to a refresh");
                        return(Task.FromResult(PageResult <TResult> .Empty));
                    }
                }

                if (pageNumber > PageLoadedCount && IsFull)
                {
                    InternalLogger.Info($"Cannot load page {pageNumber} total item count has already been reached ({TotalCount})");
                    return(Task.FromResult(PageResult <TResult> .Empty));
                }

                if (pageNumber == 1 && PageLoadedCount > 0)
                {
                    InternalLogger.Info("Refresh detected");
                    _refreshRequested = true;
                }
                else
                {
                    _refreshRequested = false;
                }

                if (LoadingTask != null && LoadingTask.IsNotCompleted)
                {
                    // Cancels callbacks of previous task if not completed
                    LoadingTask.CancelCallbacks();
                }

                LoadingTask = new TaskMonitor <PageResult <TResult> > .Builder(
                    () => _pageSourceLoader(pageNumber, PageSize, _refreshRequested))
                              .WithWhenSuccessfullyCompleted(OnPageRetrieved)
                              .WithWhenCompleted(OnTaskCompleted)
                              .Build();

                InternalLogger.Info($"Page n°{pageNumber} loading started");
                LoadingTask.Start();
                return(LoadingTask.Task);
            }
        }