/// <summary>
        ///
        /// </summary>
        public List <IRankedCategory> GetAllCategories()
        {
            List <IRankedCategory> ret = new List <IRankedCategory>();

            double highestScore = 0;

            foreach (IToken token in Tokens)
            {
                foreach (IRank rank in token.Scores)
                {
                    if (highestScore < rank.Score)
                    {
                        highestScore = rank.Score;
                    }

                    var c = GetCategory(rank.Id);

                    var ranked = new RankedCategory()
                    {
                        Id               = c.Id,
                        Name             = c.Name,
                        LinkedCategories = c.LinkedCategories,
                        ParentCategory   = c.ParentCategory
                    };

                    int index = ret.IndexOf(ranked);
                    if (index < 0)
                    {
                        ret.Add(ranked);
                    }
                    else
                    {
                        ret[index].Score++;
                    }
                }
            }

            ret.Sort();
            return(ret);
        }
        public List <IRankedCategory> GetWeightedCategories(string[] tokens, string negatedPrefix = null)
        {
            List <IRankedCategory> ret = new List <IRankedCategory>();

            float  divisor = 0.0f;
            bool   negated = false;
            string token;

            foreach (var t in tokens)
            {
                if (!string.IsNullOrEmpty(negatedPrefix) && t.StartsWith(negatedPrefix))
                {
                    negated = true;
                    token   = t.Replace(negatedPrefix, "").ToLowerInvariant();
                }
                else
                {
                    negated = false;
                    token   = t.ToLowerInvariant();
                }

                Dictionary <int, List <double> > dic = new Dictionary <int, List <double> >();

                List <IToken> knownTokens = Tokens.FindAll(x => x.Value == token);

                foreach (IToken known in knownTokens)
                {
                    foreach (IRank rank in known.Scores)
                    {
                        double val = negated ? 1.0f - rank.Score : rank.Score;

                        if (!dic.ContainsKey(rank.Id))
                        {
                            dic.Add(rank.Id, new List <double>()
                            {
                                val
                            });
                        }
                        else
                        {
                            dic[rank.Id].Add(val);
                        }
                    }
                }

                foreach (KeyValuePair <int, List <double> > kv in dic)
                {
                    ICategory category = GetCategory(kv.Key);

                    if (category == null)
                    {
                        continue;
                    }

                    IRankedCategory ranked = new RankedCategory()
                    {
                        Id               = category.Id,
                        Name             = category.Name,
                        LinkedCategories = category.LinkedCategories,
                        ParentCategory   = category.ParentCategory
                    };

                    foreach (var cat in kv.Value)
                    {
                        ranked.Score += (float)cat;
                    }


                    if (ranked.Score <= 0)
                    {
                        continue;
                    }

                    int index = ret.IndexOf(ranked);

                    if (index > -1)
                    {
                        ret[index].Score += ranked.Score;
                    }
                    else
                    {
                        ret.Add(ranked);
                    }

                    divisor += ranked.Score;
                }
            }

            foreach (IRankedCategory cat in ret)
            {
                cat.Score = cat.Score / divisor;
            }

            ret.Sort();
            return(ret);
        }