/// <summary>
        /// Invoked when a filter is selected using the ComboBox in snapped view state.
        /// </summary>
        /// <param name="sender">The ComboBox instance.</param>
        /// <param name="e">Event data describing how the selected filter was changed.</param>
        void Filter_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            // Determine what filter was selected
            var selectedFilter = e.AddedItems.FirstOrDefault() as Filter;

            if (selectedFilter != null)
            {
                // Mirror the results into the corresponding Filter object to allow the
                // RadioButton representation used when not snapped to reflect the change
                selectedFilter.Active = true;

                // TODO: Respond to the change in active filter by setting this.DefaultViewModel["Results"]
                //       to a collection of items with bindable Image, Title, Subtitle, and Description properties
                var videos = App.DataSource.TopicGroups.SelectMany(g =>
                                                                   g.Playlists.SelectMany(p => p.Videos.Where(v =>
                                                                                                              Regex.IsMatch(v.Name ?? "", _queryText, RegexOptions.IgnoreCase) ||
                                                                                                              Regex.IsMatch(v.Description ?? "", _queryText, RegexOptions.IgnoreCase))))
                             .Distinct(VideoItem.CreateComparer());

                this.DefaultViewModel["Results"] = videos.ToArray();

                // Ensure results are found
                object      results;
                ICollection resultsCollection;
                if (this.DefaultViewModel.TryGetValue("Results", out results) &&
                    (resultsCollection = results as ICollection) != null &&
                    resultsCollection.Count != 0)
                {
                    VisualStateManager.GoToState(this, "ResultsFound", true);
                    return;
                }
            }

            // Display informational text when there are no search results.
            VisualStateManager.GoToState(this, "NoResultsFound", true);
        }
        public async void LaunchApp(ApplicationExecutionState previousExecutionState)
        {
            DataSource = new KhanDataSource();
            await DataSource.LoadAllData();

            SearchPane searchPane = SearchPane.GetForCurrentView();

            searchPane.PlaceholderText = "Search Khan Academy";
            searchPane.QuerySubmitted +=
                (sender, queryArgs) =>
            {
                KhanAcademy.SearchResultsPage.Activate(queryArgs.QueryText, previousExecutionState);
            };

            searchPane.SuggestionsRequested +=
                (sender, suggestionArgs) =>
            {
                var videos = App.DataSource.TopicGroups.SelectMany(g =>
                                                                   g.Playlists.SelectMany(p => p.Videos.Where(v =>
                                                                                                              Regex.IsMatch(v.Name ?? "", suggestionArgs.QueryText, RegexOptions.IgnoreCase) ||
                                                                                                              Regex.IsMatch(v.Description ?? "", suggestionArgs.QueryText, RegexOptions.IgnoreCase))))
                             .Distinct(VideoItem.CreateComparer())
                             .Take(3);

                foreach (VideoItem vi in videos)
                {
                    suggestionArgs.Request.SearchSuggestionCollection.AppendQuerySuggestion(vi.Title);
                }

                var recommended = App.DataSource.TopicGroups.SelectMany(g =>
                                                                        g.Playlists.SelectMany(p => p.Videos.Where(v =>
                                                                                                                   Regex.IsMatch(v.Name ?? "", suggestionArgs.QueryText, RegexOptions.IgnoreCase)))).FirstOrDefault();

                if (recommended != null)
                {
                    suggestionArgs.Request.SearchSuggestionCollection.AppendSearchSeparator("Recommended");

                    IRandomAccessStreamReference imgStream = RandomAccessStreamReference.CreateFromUri(recommended.ImagePath);
                    suggestionArgs.Request.SearchSuggestionCollection.AppendResultSuggestion(recommended.Title, recommended.Description, recommended.VideoPath.ToString(), imgStream, recommended.Title);
                }
            };

            searchPane.ResultSuggestionChosen +=
                (sender, resultArgs) =>
            {
                var recommended = App.DataSource.TopicGroups.SelectMany(g =>
                                                                        g.Playlists.SelectMany(p => p.Videos.Where(v =>
                                                                                                                   Regex.IsMatch(v.VideoPath.ToString() ?? "", resultArgs.Tag, RegexOptions.IgnoreCase)))).FirstOrDefault();

                Frame f = Window.Current.Content as Frame;
                f.Navigate(typeof(VideoPage), JsonSerializer.Serialize(recommended));
            };

            if (previousExecutionState == ApplicationExecutionState.Running)
            {
                Window.Current.Activate();
                return;
            }

            var rootFrame = new Frame();

            SuspensionManager.RegisterFrame(rootFrame, "AppFrame");

            if (previousExecutionState == ApplicationExecutionState.Terminated)
            {
                await SuspensionManager.RestoreAsync();
            }

            if (rootFrame.Content == null)
            {
                // When the navigation stack isn't restored navigate to the first page,
                // configuring the new page by passing required information as a navigation
                // parameter
                if (!rootFrame.Navigate(typeof(HubPage), JsonSerializer.Serialize(DataSource.TopicGroups)))
                {
                    throw new Exception("Failed to create initial page");
                }
            }

            // Place the frame in the current Window and ensure that it is active
            Window.Current.Content = rootFrame;
            Window.Current.Activate();
        }