/// <summary>
 /// Tells whether or not the target Uri can be loaded
 /// </summary>
 /// <param name="targetUri">A URI to load</param>
 /// <param name="currentUri">The current URI</param>
 /// <returns>True if the targetURI can be loaded</returns>
 public bool CanLoad(Uri targetUri, Uri currentUri)
 {
     return(UriParsingHelper.InternalUriIsNavigable(targetUri));
 }
        private bool NavigateCore(Uri uri, NavigationMode mode, bool suppressJournalAdd)
        {
            try
            {
                if (uri == null)
                {
                    throw new ArgumentNullException("uri", Resource.NavigationService_NavigationToANullUriIsNotSupported);
                }

                // Make sure we're on the UI thread because of the DependencyProperties we use.
                if (!this.Host.Dispatcher.CheckAccess())
                {
                    // Move to UI thread
                    this.Host.Dispatcher.BeginInvoke(() => this.NavigateCore(uri, mode, suppressJournalAdd));
                    return(true);
                }

                Uri mappedUri = uri;
                // If the Uri is only a fragment, mapping does not take place
                if (!UriParsingHelper.InternalUriIsFragment(uri))
                {
                    UriMapperBase mapper = this.Host.UriMapper;
                    if (mapper != null)
                    {
                        Uri uriFromMapper = mapper.MapUri(uri);
                        if (uriFromMapper != null && !String.IsNullOrEmpty(uriFromMapper.OriginalString))
                        {
                            mappedUri = uriFromMapper;
                        }
                        else
                        {
                            mappedUri = uri;
                        }
                    }
                }

                Uri mergedUriAfterMapping = UriParsingHelper.InternalUriMerge(this._currentSourceAfterMapping, mappedUri) ?? mappedUri;
                Uri mergedUri             = UriParsingHelper.InternalUriMerge(this._currentSource, uri) ?? uri;

                // If we're navigating to just a fragment (i.e. "#frag1") or to a page which differs only in the fragment
                // (i.e. "Page.xaml?id=123" to "Page.xaml?id=123#frag1") then complete navigation without involving the content loader
                bool isFragmentNavigationOnly = UriParsingHelper.InternalUriIsFragment(mappedUri) ||
                                                UriParsingHelper.InternalUriGetAllButFragment(mergedUri) == UriParsingHelper.InternalUriGetAllButFragment(this._currentSource);

                // Check to see if anyone wants to cancel
                if (mode == NavigationMode.New)
                {
                    if (this.RaiseNavigating(mergedUri, mode, isFragmentNavigationOnly) == true)
                    {
                        // Someone stopped us
                        this.RaiseNavigationStopped(null, mergedUri);
                        return(true);
                    }
                }

                if (!UriParsingHelper.InternalUriIsNavigable(mappedUri))
                {
                    throw new ArgumentException(Resource.NavigationService_UriNotNavigable, "uri");
                }

                if (isFragmentNavigationOnly && this.Host.Content == null)
                {
                    // It doesn't make sense to fragment navigate when there's no content, so raise NavigationFailed
                    throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture,
                                                                      Resource.NavigationService_FragmentNavigationRequiresContent,
                                                                      "Frame"));
                }

                // Stop in-progress navigation
                this.StopLoading();

                return(this.NavigateCore_StartNavigation(uri, mode, suppressJournalAdd, mergedUriAfterMapping, mergedUri, isFragmentNavigationOnly));
            }
            catch (Exception ex)
            {
                if (this.RaiseNavigationFailed(uri, ex))
                {
                    throw;
                }
                return(true);
            }
        }