internal static bool CheckUserProfileReplacement(string newPath,
                                                         TabInfo tab,
                                                         PortalSettings portalSettings,
                                                         FriendlyUrlSettings settings,
                                                         FriendlyUrlOptions options,
                                                         out string changedPath,
                                                         out bool changeToSiteRoot,
                                                         out bool allowOtherParameters,
                                                         ref List <string> meessages,
                                                         Guid parentTraceId)
        {
            if (meessages == null)
            {
                meessages = new List <string>();
            }
            bool urlWasChanged = false;

            //initialise defaults to always return valid items
            changedPath          = newPath;
            changeToSiteRoot     = false;
            allowOtherParameters = true;

            //determine if this url should be converted to a userprofile url by checking the saved rules matching the tab/portalid
            if (portalSettings != null && tab.PortalID == portalSettings.PortalId &&
                (tab.TabID == portalSettings.UserTabId || portalSettings.UserTabId == -1 ||
                 tab.ParentId == portalSettings.UserTabId))        //-1 == all tabs in portal
            {
                int    userId;
                string rawUserId, remainingPath;
                //split the userid and other profile parameters from the friendly url path,
                //and return the userid and remaining parts as separate items
                SplitUserIdFromFriendlyUrlPath(newPath,
                                               "UserId",
                                               "",
                                               out rawUserId,
                                               out remainingPath);
                if (rawUserId != null)
                {
                    meessages.Add("User Profile Url : RawUserId = " + rawUserId + " remainingPath = " + remainingPath);
                }
                else
                {
                    meessages.Add("User Profile Url : RawUserId = " + "null" + " remainingPath = " + remainingPath);
                }

                //the rawuserid is just the string representation of the userid from the path.
                //It should be considered 'untrusted' until cleaned up,
                //converted to an int and checked against the database
                if (!String.IsNullOrEmpty(rawUserId) && Int32.TryParse(rawUserId, out userId))
                {
                    bool   doReplacement = false;
                    string urlName       = String.Empty;

                    //Get the User
                    var user = UserController.GetUserById(portalSettings.PortalId, userId);

                    if (user != null && !String.IsNullOrEmpty(user.VanityUrl))
                    {
                        doReplacement = true;
                        urlName       = (!String.IsNullOrEmpty(settings.VanityUrlPrefix)) ? String.Format("{0}/{1}", settings.VanityUrlPrefix, user.VanityUrl) : user.VanityUrl;
                        urlWasChanged = true;
                    }

                    if (doReplacement)
                    {
                        //check to see whether this is a match on the parentid or not
                        if (portalSettings.UserTabId == tab.ParentId && portalSettings.UserTabId > -1)
                        {
                            //replacing for the parent tab id
                            string childTabPath = TabIndexController.GetTabPath(tab, options, parentTraceId);
                            if (string.IsNullOrEmpty(childTabPath) == false)
                            {
                                //remove the parent tab path from the child tab path
                                var     tc              = new TabController();
                                TabInfo profilePage     = tc.GetTab(tab.ParentId, tab.PortalID, false);
                                string  profilePagePath = TabIndexController.GetTabPath(profilePage, options, parentTraceId);
                                if (childTabPath.Contains(profilePagePath))
                                {
                                    //only replace when the child tab path contains the parent path - if it's a custom url that
                                    //doesn't incorporate the parent path, then leave it alone
                                    childTabPath   = childTabPath.Replace(profilePagePath, "");
                                    childTabPath   = childTabPath.Replace("//", "/");
                                    remainingPath += FriendlyUrlController.EnsureLeadingChar("/", childTabPath);
                                }
                            }
                        }
                        changedPath = "/" + urlName;
                        //append any extra remaining path value to the end
                        if (!string.IsNullOrEmpty(remainingPath))
                        {
                            if (remainingPath.StartsWith("/") == false)
                            {
                                changedPath += "/" + remainingPath;
                            }
                            else
                            {
                                changedPath += remainingPath;
                            }
                        }
                        urlWasChanged        = true;
                        changeToSiteRoot     = true; //we will be doing domain.com/urlname
                        allowOtherParameters = false;
                        //can't have any others (wouldn't have matched in the regex if there were)
                    }
                    else
                    {
                        meessages.Add("User Profile : doReplacement = false");
                    }
                }
            }
            return(urlWasChanged);
        }
        /// <summary>
        /// For the supplied options, return a tab path for the specified tab
        /// </summary>
        /// <param name="tab">TabInfo object of selected tab</param>
        /// <param name="settings">FriendlyUrlSettings</param>
        /// <param name="options"></param>
        /// <param name="ignoreCustomRedirects">Whether to add in the customised Tab redirects or not</param>
        /// <param name="homePageSiteRoot"></param>
        /// <param name="isHomeTab"></param>
        /// <param name="cultureCode"></param>
        /// <param name="isDefaultCultureCode"></param>
        /// <param name="hasPath"></param>
        /// <param name="dropLangParms"></param>
        /// <param name="customHttpAlias"></param>
        /// <param name="isCustomPath"></param>
        /// <param name="parentTraceId"></param>
        /// <remarks>751 : include isDefaultCultureCode flag to determine when using the portal default language
        /// 770 : include custom http alias output for when the Url uses a specific alias due to custom Url rules
        ///  : include new out parameter 'isCustomPath' to return whether the Url was generated from Url-Master custom url
        /// </remarks>
        /// <returns>The tab path as specified</returns>
        internal static string GetTabPath(TabInfo tab,
                                          FriendlyUrlSettings settings,
                                          FriendlyUrlOptions options,
                                          bool ignoreCustomRedirects,
                                          bool homePageSiteRoot,
                                          bool isHomeTab,
                                          string cultureCode,
                                          bool isDefaultCultureCode,
                                          bool hasPath,
                                          out bool dropLangParms,
                                          out string customHttpAlias,
                                          out bool isCustomPath,
                                          Guid parentTraceId)
        {
            string newTabPath;

            dropLangParms   = false;
            customHttpAlias = null;
            isCustomPath    = false;
            if (homePageSiteRoot && isHomeTab && !hasPath)
            // && !isDefaultCultureCode - not working for non-language specifc custom root urls
            {
                newTabPath = "/"; //site root for home page
            }
            else
            {
                //build the tab path and check for space replacement
                string baseTabPath = TabIndexController.GetTabPath(tab, options, parentTraceId);

                //this is the new tab path
                newTabPath = baseTabPath;
                //871 : case insensitive compare for culture code, all lookups done on lower case
                string cultureCodeKey = "";
                if (cultureCode != null)
                {
                    cultureCodeKey = cultureCode.ToLower();
                }

                bool checkForCustomHttpAlias = false;
                //get a custom tab name if redirects are being used
                SharedDictionary <string, string> customAliasForTabs = null;
                SharedDictionary <int, SharedDictionary <string, string> > urlDict;
                //886 : don't fetch custom urls for host tabs (host tabs can't have redirects or custom Urls)
                if (tab.PortalID > -1)
                {
                    urlDict = CustomUrlDictController.FetchCustomUrlDictionary(tab.PortalID, false, false, settings, out customAliasForTabs, parentTraceId);
                }
                else
                {
                    urlDict = new SharedDictionary <int, SharedDictionary <string, string> >();
                    //create dummy dictionary for this tab
                }

                if (ignoreCustomRedirects == false)
                {
                    //if not ignoring the custom redirects, look for the Url of the page in this list
                    //this will be used as the page path if there is one.

                    using (urlDict.GetReadLock())
                    {
                        if (urlDict.ContainsKey(tab.TabID))
                        {
                            //we want the custom value
                            string customTabPath = null;
                            SharedDictionary <string, string> tabpaths = urlDict[tab.TabID];

                            using (tabpaths.GetReadLock())
                            {
                                if (tabpaths.ContainsKey(cultureCodeKey))
                                {
                                    customTabPath = tabpaths[cultureCodeKey];
                                    dropLangParms = true;
                                    //the url is based on a custom value which has embedded language parms, therefore don't need them in the url
                                }
                                else
                                {
                                    if (isDefaultCultureCode && tabpaths.ContainsKey(""))
                                    {
                                        customTabPath = tabpaths[""];
                                        //dropLangParms = true;//drop the language parms if they exist, because this is the default language
                                    }
                                }
                            }
                            if (customTabPath != null)
                            {
                                //770 : pull out custom http alias if in string
                                int aliasSeparator = customTabPath.IndexOf("::", StringComparison.Ordinal);
                                if (aliasSeparator > 0)
                                {
                                    customHttpAlias = customTabPath.Substring(0, aliasSeparator);
                                    newTabPath      = customTabPath.Substring(aliasSeparator + 2);
                                }
                                else
                                {
                                    newTabPath = customTabPath;
                                }
                            }
                            if (newTabPath == "" && hasPath)
                            {
                                //can't pass back a custom path which is blank if there are path segments to the requested final Url
                                newTabPath = baseTabPath; //revert back to the standard DNN page path
                            }
                            else
                            {
                                isCustomPath = true; //we are providing a custom Url
                            }
                        }
                        else
                        {
                            checkForCustomHttpAlias = true;
                        }
                    }
                }
                else
                {
                    checkForCustomHttpAlias = true;
                    //always want to check for custom alias, even when we don't want to see any custom redirects
                }

                //770 : check for custom alias in these tabs
                if (checkForCustomHttpAlias && customAliasForTabs != null)
                {
                    string key = tab.TabID.ToString() + ":" + cultureCodeKey;
                    using (customAliasForTabs.GetReadLock())
                    {
                        if (customAliasForTabs.ContainsKey(key))
                        {
                            //this tab uses a custom alias
                            customHttpAlias = customAliasForTabs[key];
                            isCustomPath    = true; //using custom alias
                        }
                    }
                }

                if (!dropLangParms)
                {
                    string tabCultureCode = tab.CultureCode;
                    if (!string.IsNullOrEmpty(tabCultureCode))
                    {
                        dropLangParms = true;
                        //if the tab has a specified culture code, then drop the language parameters from the friendly Url
                    }
                }
                //make lower case if necessary
                newTabPath = AdvancedFriendlyUrlProvider.ForceLowerCaseIfAllowed(tab, newTabPath, settings);
            }
            return(newTabPath);
        }