public static Dictionary <ID, ID> GetRecommendedCategories([NotNull] Item item)
        {
            Assert.ArgumentNotNull(item, "item");

            var field = item.Fields[TaxonomyFields.RecommendedCategories];

            if (field.HasValue)
            {
                return(ClassificationField.Parse(field.Value));
            }

            Dictionary <ID, ID> weights = ClassificationField.Parse(StringUtil.GetString(field.GetStandardValue()));

            foreach (var pair in ClassificationField.Parse(GetInheritedRecommendedCategories(item)))
            {
                weights[pair.Key] = pair.Value;
            }
            return(weights);
        }
        public static Dictionary <ID, RelationInfo> GetAllCategories([NotNull] Item item, [NotNull] string value)
        {
            Assert.ArgumentNotNull(item, "item");
            Assert.ArgumentNotNull(value, "value");

            Dictionary <ID, RelationInfo> result;

            if (string.IsNullOrEmpty(value))
            {
                result = GetRecommendedCategories(item).ToDictionary(
                    pair => pair.Key, pair => new RelationInfo
                {
                    Category        = pair.Key,
                    RelatedCategory = new List <ID> {
                        ID.Null
                    },
                    Calculated       = true,
                    Weight           = Convert.ToSingle(item.Database.GetItem(pair.Value)["Weight"]),
                    ConflictCategory = GetConflictIDs(item.Database.GetItem(pair.Value)["ConflictTags"]).ToList()
                });
            }
            else
            {
                result = ClassificationField.Parse(value).ToDictionary(
                    pair => pair.Key,
                    pair =>
                {
                    return(new RelationInfo
                    {
                        Category = pair.Key,
                        RelatedCategory = new List <ID> {
                            ID.Null
                        },
                        Calculated = false,
                        Weight = Convert.ToSingle(item.Database.GetItem(pair.Value)["Weight"]),
                        ConflictCategory = GetConflictIDs(item.Database.GetItem(pair.Value)["ConflictTags"]).ToList()
                    });
                });
            }
            var queue = new Queue <RelationInfo>(result.Values);

            while (queue.Count > 0)
            {
                RelationInfo info      = queue.Dequeue();
                var          innerItem = item.Database.GetItem(info.Category);
                if (innerItem == null)
                {
                    continue;
                }

                var category       = new CategoryItem(innerItem);
                var parentCategory = category.Parent;
                if (parentCategory == null)
                {
                    continue;
                }
                RelationInfo parentInfo;
                if (result.TryGetValue(parentCategory.ID, out parentInfo))
                {
                    int entry = parentInfo.RelatedCategory.Count;

                    float nWeight = (float)Math.Sqrt(parentCategory.RelatedWithChildren * category.RelatedToParent) *
                                    info.Weight;

                    parentInfo.Weight = (float)Math.Pow(parentInfo.Weight, entry);
                    parentInfo.Weight = (float)Math.Pow(parentInfo.Weight * nWeight, 1.0 / (entry + 1));

                    parentInfo.RelatedCategory.Add(category.ID);
                }
                else
                {
                    parentInfo = new RelationInfo
                    {
                        Category        = parentCategory.ID,
                        RelatedCategory = new List <ID> {
                            category.ID
                        },
                        Calculated = true,
                        Weight     =
                            (float)Math.Sqrt(parentCategory.RelatedWithChildren * category.RelatedToParent) * info.Weight
                    };
                    result[parentInfo.Category] = parentInfo;
                }
                queue.Enqueue(parentInfo);
            }
            return(result);
        }