/// <summary>
        /// checks if the token collection is valid
        /// </summary>
        /// <param name="collection"></param>
        /// <returns>boolean for if the token is valid</returns>
        private bool IsCollectionValid(ITokenCollection <IToken> collection)
        {
            if (collection.GetBackingItemId() == (ID)null)
            {
                return(true);
            }

            var item = GetDatabase().GetItem(collection.GetBackingItemId());

            if (item != null && item.Statistics.Updated <= TokenCacheUpdateTimes[collection.GetCollectionLabel()])
            {
                return(true);
            }

            return(false);
        }
 public virtual void LoadTokenCollection(ITokenCollection <IToken> collection)
 {
     if (collection != null)
     {
         TokenCacheUpdateTimes[collection.GetCollectionLabel()] =
             GetDatabase().GetItem(collection.GetBackingItemId()).Statistics.Updated;
         TokenCollections[collection.GetCollectionLabel()] = collection;
     }
 }
        public virtual T ResolveToken <T>(ITokenCollection <IToken> collection, string tokenName) where T : IToken
        {
            var item      = TokenKeeper.CurrentKeeper.GetDatabase().GetItem(collection.GetBackingItemId());
            var tokenItem = item.Children.FirstOrDefault(x => x["Token"] == tokenName);

            if (tokenItem != null)
            {
                var tid = tokenItem.TemplateID.ToString();
                if (templateToType.ContainsKey(tid))
                {
                    Type            t  = Factory.CreateType(templateToType[tid], false);
                    ConstructorInfo ci = t.GetConstructors().FirstOrDefault(x => x.GetParameters().Length == 2 && x.GetParameters()[0].ParameterType == typeof(string) && x.GetParameters()[1].ParameterType == typeof(ID));
                    if (ci == null)
                    {
                        throw new ArgumentException("While trying to initialize token type " + t.Name + " no appropriate constructor was found, it should take two parameters of type String (name) and ID (token sitecore Item Id)");
                    }
                    return((T)ci.Invoke(new object[] { tokenName, tokenItem.ID }));
                }
            }
            return(default(T));
        }
        /// <summary>
        /// Refreshes the token collection with what's in sitecore
        /// </summary>
        /// <param name="category"></param>
        /// <returns>token collection</returns>
        public ITokenCollection <IToken> RefreshTokenCollection(string category = null)
        {
            RefreshAutoTokens();

            var tokenManagerItems = GetDatabase()
                                    .SelectItems($"fast:/sitecore/content//*[@@templateid = '{Constants.TokenRootTemplateId}']")
                                    .Union(Globals.LinkDatabase.GetReferrers(GetDatabase().GetItem(Constants.TokenRootTemplateId))
                                           .Select(x => GetDatabase().GetItem(x.SourceItemID)));

            HashSet <ID> dups = new HashSet <ID>();
            ITokenCollection <IToken> collection = category != null && TokenCollections.ContainsKey(category) ? TokenCollections[category] : null;

            foreach (Item tokenManagerItem in tokenManagerItems)
            {
                if (tokenManagerItem != null)
                {
                    if (dups.Contains(tokenManagerItem.ID))
                    {
                        continue;
                    }

                    dups.Add(tokenManagerItem.ID);

                    Stack <Item> curItems = new Stack <Item>();
                    curItems.Push(tokenManagerItem);

                    while (curItems.Any())
                    {
                        Item cur = curItems.Pop();
                        // this means that the collection exists, it's just out of date, so we need to update it.
                        if (collection != null)
                        {
                            if (collection.GetBackingItemId() == cur.ID)
                            {
                                ITokenCollection <IToken> col = GetCollectionFromItem(cur);
                                RemoveCollection(category);
                                LoadTokenCollection(col);
                                return(col);
                            }
                        }
                        else
                        // this means that the token doesn't exist yet, lets create it.
                        {
                            ITokenCollection <IToken> col = GetCollectionFromItem(cur);
                            if (col != null && col.GetCollectionLabel() == category || category == null)
                            {
                                LoadTokenCollection(col);
                                if (category != null)
                                {
                                    return(col);
                                }
                            }
                        }

                        foreach (Item child in cur.Children)
                        {
                            curItems.Push(child);
                        }
                    }
                }
            }
            return(null);
        }