/// <summary>
        /// Creates a new NavigationService for a Frame, registering the frame and NavigationService
        /// for future retrieval and registering the frame with the NavigationContextService.
        /// </summary>
        /// <param name="frame">The frame to register.</param>
        /// <param name="defaultPage">The default page to navigate to if there is no state to restore.</param>
        /// <param name="defaultNavigationContext">The navigation context to provide on navigation to defaultPage.</param>
        /// <param name="restoreState">True to attempt to restore previously saved state, false to just navigate to defaultPage
        ///     without attempting to restore state.</param>
        /// <returns>The NavigationService for the registered frame.</returns>
        public static INavigationService RegisterFrame(Frame frame, Type defaultPage, NavigationContextBase defaultNavigationContext = null, bool restoreState = true)
        {
            if (frame == null)
            {
                throw new ArgumentNullException(nameof(frame));
            }

            if (defaultPage == null)
            {
                throw new ArgumentNullException(nameof(defaultPage));
            }

            if (GetNavigationService(frame) != null)
            {
                throw new InvalidOperationException("Frame already associated with a NavigationService.");
            }

            // Clean up references before adding a new one.
            RemoveFrame();

            NavigationService navigationService = new NavigationService(frame, new NavigationContextService());

            // Ensure navigationService is fully registered before restoring state
            // or navigating so that it can be accessed by PageBase.
            NavigationServices.Add(navigationService);

            if (restoreState)
            {
                // This triggers NavigatedTo on PageBase if there is state restored.
                navigationService.RestoreState();
            }

            // If state wasn't restored, navigate to a default page to populate the Frame.
            if (navigationService.RootFrame.Content == null)
            {
                navigationService.Navigate(defaultPage, defaultNavigationContext);
            }

            return navigationService;
        }
        /// <summary>
        /// Called when the page is navigated to. Initializes properties, such as
        /// the navigation service and view model, as well as restores context
        /// from the suspension manager.
        /// </summary>
        /// <param name="e">The event args.</param>
        protected override async void OnNavigatedTo(NavigationEventArgs e)
        {
            base.OnNavigatedTo(e);

            if (e == null)
            {
                return;
            }

            // Get NavigationService
            if (this.navigationService == null)
            {
                this.navigationService = NavigationService.GetNavigationService(this.Frame) as NavigationService;
                if (this.navigationService == null)
                {
                    throw new InvalidOperationException("Frame not registered before page navigation.");
                }

                this.contextService = this.navigationService.ContextService;
                Debug.Assert(this.contextService != null, "A navigation service's context service should never be null.");
            }

            // Set ViewModel
            if (this.ViewModel == null)
            {
                INavigatableViewModel viewModel = this.DataContext as INavigatableViewModel;
                if (viewModel == null)
                {
                    throw new InvalidOperationException("ViewModel must implement INavigatableViewModel interface.");
                }

                this.ViewModel = viewModel;
            }

            // Load page state if this page wasn't already cached by the frame
            IDictionary<string, PageState> pageStates = this.navigationService.PageStates;
            this.pageKey = "Page-" + this.Frame.BackStackDepth;

            // Get the NavigationContext
            NavigationContextBase context = this.GetContextFromParameter(e.Parameter);

            PageState pageState = null;

            if (e.NavigationMode == NavigationMode.New)
            {
                // Clear existing state for forward navigation when adding a new page to the
                // navigation stack
                var nextPageKey = this.pageKey;
                int nextPageIndex = this.Frame.BackStackDepth;
                while (pageStates.Remove(nextPageKey))
                {
                    nextPageIndex++;
                    nextPageKey = "Page-" + nextPageIndex;
                }

                // TODO: Also clean up stored navigation contexts when removing forward stack.
            }
            else
            {
                // Load page state using the same strategy for loading suspended state and
                // recreating pages discarded from cache
                pageStates.TryGetValue(this.pageKey, out pageState);
            }

            // Activate the ViewModel
            await this.ViewModel.Activate(this.navigationService, context, pageState);
        }