/// <summary>
        /// A dictionary of the static routes and page ids from the agility sitemap.
        /// </summary>
        public static Dictionary <string, AgilityRouteCacheItem> GetRouteTable(string languageCode, int channelID)
        {
            string cacheKey = string.Format("Agility.Web.Providers.AgilitySiteMapProvider.RouteTableCacheKey_{0}_{1}_{2}_{3}", AgilityContext.CurrentMode, languageCode, AgilityContext.WebsiteName, channelID);

            //get the sitemap first, cause the dependancy is based on that...
            AgilityContentServer.AgilitySitemap sitemap = BaseCache.GetSitemap(languageCode, AgilityContext.WebsiteName);

            if (sitemap == null || string.IsNullOrEmpty(sitemap.SitemapXml))
            {
                Agility.Web.Tracing.WebTrace.WriteVerboseLine("Could not load Sitemap data");
                return(new Dictionary <string, AgilityRouteCacheItem>());
            }


            Dictionary <string, AgilityRouteCacheItem> routeTable = AgilityCache.Get(cacheKey) as Dictionary <string, AgilityRouteCacheItem>;

            if (routeTable != null)
            {
                return(routeTable);
            }

            lock (_lockObj)
            {
                Agility.Web.Tracing.WebTrace.WriteVerboseLine(string.Format("Building route table - {0} - {1}", languageCode, channelID));

                //check to see if this has been added to cache while we've been waiting...
                routeTable = AgilityCache.Get(cacheKey) as Dictionary <string, AgilityRouteCacheItem>;
                if (routeTable != null)
                {
                    return(routeTable);
                }

                routeTable = new Dictionary <string, AgilityRouteCacheItem>();

                //get the sitemap xml that we need for the sitemap...

                XmlDocument document = new XmlDocument();
                document.LoadXml(sitemap.SitemapXml);

                XmlNodeList siteMapNodes = document.SelectNodes(string.Format("//SiteNode[@channelID='{0}']", channelID));
                if (siteMapNodes.Count == 0)
                {
                    //if the channels haven't been synced yet...
                    siteMapNodes = document.SelectNodes("//SiteNode");
                }


                foreach (XmlNode node in siteMapNodes)
                {
                    XmlElement elem = node as XmlElement;
                    if (elem == null)
                    {
                        continue;
                    }


                    //add to the route table if this node represents a page...
                    int pageID = -1;
                    if (int.TryParse(elem.GetAttribute("picID"), out pageID) && pageID > 0)
                    {
                        string path = GetRoutePath(elem);

                        if (!routeTable.ContainsKey(path))
                        {
                            AgilityRouteCacheItem item = new AgilityRouteCacheItem()
                            {
                                PageID = pageID
                            };

                            if (!string.IsNullOrEmpty(elem.GetAttribute("dynamicPageContentReferenceName")) ||
                                !string.IsNullOrEmpty(elem.GetAttribute("dynamicPageParentFieldName")))
                            {
                                //update the parent item...
                                XmlElement parentElem = elem.ParentNode as XmlElement;
                                if (parentElem != null)
                                {
                                    string parentPath = GetRoutePath(parentElem);
                                    if (routeTable.ContainsKey(parentPath))
                                    {
                                        routeTable[parentPath].ChildDynamicPagePath = path;
                                    }
                                }
                            }


                            routeTable[path] = item;
                        }
                    }
                }


                //always put the thing in cache...
                //make it dependant of the sitemap file (this way we can cache in live and staging mode...)
                CacheDependency dep = null;
                if (AgilityContext.ContentAccessor != null && AgilityContext.CurrentMode == Enum.Mode.Live)
                {
                    AgilityItemKey itemKey = new AgilityItemKey();
                    itemKey.Key          = BaseCache.ITEMKEY_SITEMAP;
                    itemKey.LanguageCode = languageCode;
                    itemKey.ItemType     = typeof(AgilitySitemap).Name;

                    string sitemapCacheKey = BaseCache.GetCacheKey(itemKey);
                    dep = new CacheDependency(new string[0], new string[1] {
                        sitemapCacheKey
                    });
                }
                else
                {
                    string filename = BaseCache.GetFilePathForItem(sitemap, AgilityContext.WebsiteName, transientPath: true);
                    bool   exists   = File.Exists(filename);
                    dep = new CacheDependency(filename);
                }

                AgilityCache.Set(cacheKey, routeTable, TimeSpan.FromDays(1), dep, AgilityContext.DefaultCachePriority);

                return(routeTable);
            }
        }