/// <summary>
        /// Gets the localized URL.
        /// </summary>
        /// <param name="umbracoContext">The umbraco context.</param>
        /// <param name="id">The identifier.</param>
        /// <param name="current">The current.</param>
        /// <param name="mode">The mode.</param>
        /// <param name="culture">The culture.</param>
        /// <returns></returns>
        /// <exception cref="System.ArgumentException">Current url must be absolute.;current</exception>
        public string GetUrl(
            UmbracoContext umbracoContext,
            int id,
            Uri current,
            UrlProviderMode mode,
            CultureInfo culture)
        {
            if (FindByUrlAliasEnabled /* && umbracoContext.IsFrontEndUmbracoRequest*/)
            {
                if (current.IsAbsoluteUri == false)
                {
                    throw new ArgumentException("Current url must be absolute.", "current");
                }

                if (OnUrlGenerating != null)
                {
                    OnUrlGeneratingEventArgs e = new OnUrlGeneratingEventArgs(umbracoContext, id, current, mode, culture);
                    OnUrlGenerating(this, e);
                    if (e.Cancel)
                    {
                        return(null);
                    }
                }

                string isoCode = culture.Name;

                // will not use cache if previewing
                bool   anyLocalizedUrl;
                string route = _routingHelper.GetRouteById(
                    umbracoContext,
                    umbracoContext.InPreviewMode,
                    id,
                    isoCode,
                    out anyLocalizedUrl);

                // NO! We want to localize it because of Surface/Api Controller!
                //if (anyLocalizedUrl == false) return null; // other provider should take care of it

                if (string.IsNullOrWhiteSpace(route))
                {
                    LogHelper.Debug <AliasUrlProvider>(
                        "Couldn't find any page with contentId={0}. This is most likely caused by the page not being published.",
                        () => id);
                    return(null);
                }

                // assemble the url from domainUri (maybe null) and path
                return(_routingHelper.AssembleUrl(
                           route: route,
                           current: current,
                           mode: mode,
                           isoCode: isoCode));
            }
            else
            {
                return(null);                // Other provider should take care of it.
            }
        }
        /// <summary>
        /// Gets the other urls of a published content.
        /// </summary>
        /// <param name="umbracoContext">The Umbraco context.</param>
        /// <param name="id">The published content id.</param>
        /// <param name="current">The current absolute url.</param>
        /// <returns>
        /// The other urls for the published content.
        /// </returns>
        /// <remarks>
        /// Other urls are those that <c>GetUrl</c> would not return in the current context, but would be valid
        /// urls for the node in other contexts (different domain for current request, umbracoUrlAlias...).
        /// </remarks>
        public IEnumerable <string> GetOtherUrls(UmbracoContext umbracoContext, int id, Uri current)
        {
            if (FindByUrlAliasEnabled == false)
            {
                return(Enumerable.Empty <string>());
            }

            IPublishedContent content = umbracoContext.ContentCache.GetById(id);

            if (OnOtherUrlsGenerating != null)
            {
                OnUrlGeneratingEventArgs e = new OnUrlGeneratingEventArgs(umbracoContext, id, current);
                OnOtherUrlsGenerating(this, e);
                if (e.Cancel)
                {
                    return(Enumerable.Empty <string>());
                }
            }

            bool hasDomains = _routingHelper.NodeHasDomains(
                contentId: content.Id);

            if (hasDomains)
            {
                // If content has domains we do not have to walk up
                // but when not then we have to, because we don't know if somewhere is a localized url
                return(Enumerable.Empty <string>());
            }

            IPublishedContent          node       = content;
            IEnumerable <DomainAndUri> domainUris = _routingHelper.UmbracoDomainsForNode(
                contentId: node.Id,
                current: current,
                excludeDefault: false);

            List <IPublishedContent> parents = new List <IPublishedContent>();

            while (domainUris == null && node != null)             // n is null at root
            {
                // move to parent node
                node = node.Parent;

                if (node != null)
                {
                    parents.Add(node);
                }

                domainUris = node == null ? null : _routingHelper.UmbracoDomainsForNode(
                    contentId: node.Id,
                    current: current,
                    excludeDefault: false);
            }

            /*parents.Reverse(); // Reverse from root down to the node*/

            List <string> otherUrls = new List <string>();

            if (domainUris == null)
            {
                // If there are no domains (hostnames) we don't have to do anything
                // because we do not have smth. like /de /en, right?!
                return(otherUrls);
            }

            // We have to assemble the other urls by the url alias
            // but we have to do that with all possible languages
            // because the urlAlias could be null but the parent could have one

            /*string path;
             * bool isLocalized;
             * UrlAlias alias;*/
            string path;

            foreach (CultureInfo cultureInfo in LocalizationContext.Cultures)
            {
                //TODO: We use the same as the Frontend would use it... the question is, if that is ok?
                // Due to performance... I don't know we have less code here but populate always the parents and it's domains?
                path = content.GetLocalizedUrl(language: cultureInfo.TwoLetterISOLanguageName);

                // Url per language will be added because of the domainAndUris
                // so /about-us is possible for all languages e.g. /en/about-us /de/about-us /it/about-us...

                foreach (DomainAndUri domainUri in domainUris)
                {
                    // We have to replace the host and the language so we can populate the other urls correctly
                    path = path.Replace(domainUri.Uri.GetBaseUrl(), string.Empty);
                    path = path.EnsureStartsWith('/').EnsureEndsWith('/');
                    path = path.Replace("/" + cultureInfo.TwoLetterISOLanguageName.ToLowerInvariant() + "/", string.Empty);
                    path = path.EnsureStartsWith('/').EnsureEndsWith('/');
                }

                //alias = urlAlias.SingleOrDefault(o => o.ISOCode.Equals(cultureInfo.Name));

                //otherUrls.Add(path);

                /*path = "/" + string.Join("/", _routingHelper.GetUrlNamesByISOCode(contents: parents, isoCode: cultureInfo.Name));
                 * path += (parents.Count > 1 ? "/" : string.Empty) + _routingHelper.GetUrlName(false, content, alias, out isLocalized);*/

                otherUrls.AddRange(AssembleOtherUrls(
                                       domainUris: domainUris,
                                       path: path));
            }

            return(otherUrls
                   .Where(o => o.Equals(content.Url) == false)                 // Except the url made from umbraco
                   .OrderBy(o => o)
                   .Distinct()
                   .ToList());
        }