/// <summary>
        /// Returns the navigation settings for the selected web
        /// </summary>
        /// <param name="web"></param>
        /// <returns></returns>
        public static AreaNavigationEntity GetNavigationSettings(this Web web)
        {
            AreaNavigationEntity nav = new AreaNavigationEntity();

            //Read all the properties of the web
            web.Context.Load(web, w => w.AllProperties);
            web.Context.ExecuteQueryRetry();

            if (!ArePublishingFeaturesActivated(web.AllProperties))
            {
                throw new ArgumentException("Structural navigation settings are only supported for publishing sites");
            }

            // Determine if managed navigation is used...if so the other properties are not relevant
            string webNavigationSettings = web.AllProperties.GetPropertyAsString(WebNavigationSettings);
            if (webNavigationSettings == null)
            {
                nav.CurrentNavigation.ManagedNavigation = false;
                nav.GlobalNavigation.ManagedNavigation = false;
            }
            else
            {
                var navigationSettings = XElement.Parse(webNavigationSettings);
                IEnumerable<XElement> navNodes = navigationSettings.XPathSelectElements("./SiteMapProviderSettings/TaxonomySiteMapProviderSettings");
                foreach (var node in navNodes)
                {
                    if (node.Attribute("Name").Value.Equals("CurrentNavigationTaxonomyProvider", StringComparison.InvariantCulture))
                    {
                        bool managedNavigation = true;
                        if (node.Attribute("Disabled") != null)
                        {
                            if (bool.TryParse(node.Attribute("Disabled").Value, out managedNavigation))
                            {
                                managedNavigation = false;
                            }
                        }
                        nav.CurrentNavigation.ManagedNavigation = managedNavigation;
                    }
                    else if (node.Attribute("Name").Value.Equals("GlobalNavigationTaxonomyProvider", StringComparison.InvariantCulture))
                    {
                        bool managedNavigation = true;
                        if (node.Attribute("Disabled") != null)
                        {
                            if (bool.TryParse(node.Attribute("Disabled").Value, out managedNavigation))
                            {
                                managedNavigation = false;
                            }
                        }
                        nav.GlobalNavigation.ManagedNavigation = managedNavigation;
                    }
                }
            }

            // Only read the other values that make sense when not using managed navigation
            if (!nav.CurrentNavigation.ManagedNavigation)
            {
                int currentNavigationIncludeTypes = web.AllProperties.GetPropertyAsInt(CurrentNavigationIncludeTypes);
                if (currentNavigationIncludeTypes > -1)
                {
                    MapFromNavigationIncludeTypes(nav.CurrentNavigation, currentNavigationIncludeTypes);
                }

                int currentDynamicChildLimit = web.AllProperties.GetPropertyAsInt(CurrentDynamicChildLimit);
                if (currentDynamicChildLimit > -1)
                {
                    nav.CurrentNavigation.MaxDynamicItems = currentDynamicChildLimit;
                }

                // For the current navigation there's an option to show the sites siblings in structural navigation
                if (web.IsSubSite())
                {
                    bool showSiblings = false;
                    string navigationShowSiblings = web.AllProperties.GetPropertyAsString(NavigationShowSiblings);
                    if (bool.TryParse(navigationShowSiblings, out showSiblings))
                    {
                        nav.CurrentNavigation.ShowSiblings = showSiblings;
                    }
                }
            }

            if (!nav.GlobalNavigation.ManagedNavigation)
            {
                int globalNavigationIncludeTypes = web.AllProperties.GetPropertyAsInt(GlobalNavigationIncludeTypes);
                if (globalNavigationIncludeTypes > -1)
                {
                    MapFromNavigationIncludeTypes(nav.GlobalNavigation, globalNavigationIncludeTypes);
                }

                int globalDynamicChildLimit = web.AllProperties.GetPropertyAsInt(GlobalDynamicChildLimit);
                if (globalDynamicChildLimit > -1)
                {
                    nav.GlobalNavigation.MaxDynamicItems = globalDynamicChildLimit;
                }
            }

            // Read the sorting value 
            int navigationOrderingMethod = web.AllProperties.GetPropertyAsInt(NavigationOrderingMethod);
            if (navigationOrderingMethod > -1)
            {
                nav.Sorting = (StructuralNavigationSorting)navigationOrderingMethod;
            }

            // Read the sort by value
            int navigationAutomaticSortingMethod = web.AllProperties.GetPropertyAsInt(NavigationAutomaticSortingMethod);
            if (navigationAutomaticSortingMethod > -1)
            {
                nav.SortBy = (StructuralNavigationSortBy)navigationAutomaticSortingMethod;
            }

            // Read the ordering setting
            bool navigationSortAscending = true;
            string navProp = web.AllProperties.GetPropertyAsString(NavigationSortAscending);

            if (bool.TryParse(navProp, out navigationSortAscending))
            {
                nav.SortAscending = navigationSortAscending;
            }

            return nav;
        }
        public void UpdateNavigationSettings2Test()
        {
            using (var clientContext = TestCommon.CreateClientContext())
            {
                var web = clientContext.Web;
                AreaNavigationEntity nav = new AreaNavigationEntity();
                nav.GlobalNavigation.MaxDynamicItems = 12;
                nav.GlobalNavigation.ShowSubsites = true;
                nav.GlobalNavigation.ShowPages = false;

                nav.CurrentNavigation.MaxDynamicItems = 14;
                nav.CurrentNavigation.ShowSubsites = false;
                nav.CurrentNavigation.ShowPages = false;

                // setting this throws an exception
                nav.Sorting = StructuralNavigationSorting.ManuallyButPagesAutomatically;
                nav.SortBy = StructuralNavigationSortBy.LastModifiedDate;
                nav.SortAscending = false;

                web.UpdateNavigationSettings(nav);

            }
        }
        /// <summary>
        /// Updates navigation settings for the current web
        /// </summary>
        /// <param name="web"></param>
        /// <param name="navigationSettings"></param>
        public static void UpdateNavigationSettings(this Web web, AreaNavigationEntity navigationSettings)
        {
            //Read all the properties of the web
            web.Context.Load(web, w => w.AllProperties);
            web.Context.ExecuteQueryRetry();

            if (!ArePublishingFeaturesActivated(web.AllProperties))
            {
                throw new ArgumentException("Structural navigation settings are only supported for publishing sites");
            }

            // Use publishing CSOM API to switch between managed metadata and structural navigation
            TaxonomySession taxonomySession = TaxonomySession.GetTaxonomySession(web.Context);
            web.Context.Load(taxonomySession);
            web.Context.ExecuteQueryRetry();
            Microsoft.SharePoint.Client.Publishing.Navigation.WebNavigationSettings webNav = new Publishing.Navigation.WebNavigationSettings(web.Context, web);
            if (!navigationSettings.GlobalNavigation.ManagedNavigation)
            {
                webNav.GlobalNavigation.Source = Publishing.Navigation.StandardNavigationSource.PortalProvider;
            }
            else
            {
                webNav.GlobalNavigation.Source = Publishing.Navigation.StandardNavigationSource.TaxonomyProvider;
            }

            if (!navigationSettings.CurrentNavigation.ManagedNavigation)
            {
                webNav.CurrentNavigation.Source = Publishing.Navigation.StandardNavigationSource.PortalProvider;
            }
            else
            {
                webNav.CurrentNavigation.Source = Publishing.Navigation.StandardNavigationSource.TaxonomyProvider;
            }
            webNav.Update(taxonomySession);
            web.Context.ExecuteQueryRetry();

            //Read all the properties of the web again after the above update
            web.Context.Load(web, w => w.AllProperties);
            web.Context.ExecuteQueryRetry();

            if (!navigationSettings.GlobalNavigation.ManagedNavigation)
            {
                int globalNavigationIncludeType = MapToNavigationIncludeTypes(navigationSettings.GlobalNavigation);
                web.AllProperties[GlobalNavigationIncludeTypes] = globalNavigationIncludeType;
                web.AllProperties[GlobalDynamicChildLimit] = navigationSettings.GlobalNavigation.MaxDynamicItems;
            }

            if (!navigationSettings.CurrentNavigation.ManagedNavigation)
            {
                int currentNavigationIncludeType = MapToNavigationIncludeTypes(navigationSettings.CurrentNavigation);
                web.AllProperties[CurrentNavigationIncludeTypes] = currentNavigationIncludeType;
                web.AllProperties[CurrentDynamicChildLimit] = navigationSettings.CurrentNavigation.MaxDynamicItems;

                // Call web.update before the IsSubSite call as this might do an ExecuteQuery. Without the update called the changes will be lost
                web.Update();
                // For the current navigation there's an option to show the sites siblings in structural navigation
                if (web.IsSubSite())
                {
                    web.AllProperties[NavigationShowSiblings] = navigationSettings.CurrentNavigation.ShowSiblings.ToString();
                }
            }

            // if there's either global or current structural navigation then update the sorting settings
            if (!navigationSettings.GlobalNavigation.ManagedNavigation || !navigationSettings.CurrentNavigation.ManagedNavigation)
            {
                // If there's automatic sorting or pages are shown with automatic page sorting then we can set all sort options
                if ((navigationSettings.Sorting == StructuralNavigationSorting.Automatically) ||
                    (navigationSettings.Sorting == StructuralNavigationSorting.ManuallyButPagesAutomatically && (navigationSettings.GlobalNavigation.ShowPages || navigationSettings.CurrentNavigation.ShowPages)))
                {
                    // All sort options can be set
                    web.AllProperties[NavigationOrderingMethod] = (int)navigationSettings.Sorting;
                    web.AllProperties[NavigationAutomaticSortingMethod] = (int)navigationSettings.SortBy;
                    web.AllProperties[NavigationSortAscending] = navigationSettings.SortAscending.ToString();
                }
                else
                {
                    // if pages are not shown we can set sorting to either automatic or manual
                    if (!navigationSettings.GlobalNavigation.ShowPages && !navigationSettings.CurrentNavigation.ShowPages)
                    {
                        if (navigationSettings.Sorting == StructuralNavigationSorting.ManuallyButPagesAutomatically)
                        {
                            throw new ArgumentException("Sorting can only be set to StructuralNavigationSorting.ManuallyButPagesAutomatically when ShowPages has been selected in either the global or current structural navigation settings");
                        }
                    }

                    web.AllProperties[NavigationOrderingMethod] = (int)navigationSettings.Sorting;
                }
            }

            //Persist all property updates at once
            web.Update();
            web.Context.ExecuteQueryRetry();
        }
        public void UpdateNavigationSettingsTest()
        {
            using (var clientContext = TestCommon.CreateClientContext())
            {
                //Set MaxDynamicItems upfront to the default value
                clientContext.Load(clientContext.Web, w => w.AllProperties);
                clientContext.ExecuteQueryRetry();
                clientContext.Web.AllProperties[CurrentDynamicChildLimit] = 20;
                clientContext.Web.AllProperties[GlobalDynamicChildLimit] = 20;
                clientContext.Web.Update();
                clientContext.ExecuteQueryRetry();

                AreaNavigationEntity nav = new AreaNavigationEntity();
                nav.GlobalNavigation.ManagedNavigation = false;
                nav.GlobalNavigation.MaxDynamicItems = 13;
                nav.GlobalNavigation.ShowSubsites = true;
                nav.GlobalNavigation.ShowPages = true;

                nav.CurrentNavigation.ManagedNavigation = false;
                nav.CurrentNavigation.MaxDynamicItems = 15;
                nav.CurrentNavigation.ShowSubsites = true;
                nav.CurrentNavigation.ShowPages = true;

                nav.Sorting = StructuralNavigationSorting.Automatically;
                nav.SortBy = StructuralNavigationSortBy.Title ;
                nav.SortAscending = true;

                clientContext.Web.UpdateNavigationSettings(nav);

                clientContext.Load(clientContext.Web, w => w.AllProperties);
                clientContext.ExecuteQueryRetry();
                int currentDynamicChildLimit = -1;
                int.TryParse(clientContext.Web.AllProperties[CurrentDynamicChildLimit].ToString(), out currentDynamicChildLimit);
                int globalDynamicChildLimit = -1;
                int.TryParse(clientContext.Web.AllProperties[GlobalDynamicChildLimit].ToString(), out globalDynamicChildLimit);

                Assert.AreEqual(13, globalDynamicChildLimit);
                Assert.AreEqual(15, currentDynamicChildLimit);

            }
        }