/// <inheritdoc />
        public AssetDependencies ComputeDependencies(AssetId assetId, AssetDependencySearchOptions dependenciesOptions = AssetDependencySearchOptions.All, ContentLinkType linkTypes = ContentLinkType.Reference, HashSet <AssetId> visited = null)
        {
            bool recursive = (dependenciesOptions & AssetDependencySearchOptions.Recursive) != 0;

            if (visited == null && recursive)
            {
                visited = new HashSet <AssetId>();
            }

            //var clock = Stopwatch.StartNew();

            lock (Initialize())
            {
                AssetDependencies dependencies;
                if (!Dependencies.TryGetValue(assetId, out dependencies))
                {
                    return(null);
                }

                dependencies = new AssetDependencies(dependencies.Item);

                int inCount = 0, outCount = 0;

                if ((dependenciesOptions & AssetDependencySearchOptions.In) != 0)
                {
                    CollectInputReferences(dependencies, assetId, visited, recursive, linkTypes, ref inCount);
                }

                if ((dependenciesOptions & AssetDependencySearchOptions.Out) != 0)
                {
                    visited?.Clear();
                    CollectOutputReferences(dependencies, assetId, visited, recursive, linkTypes, ref outCount);
                }

                //Console.WriteLine("Time to compute dependencies: {0}ms in: {1} out:{2}", clock.ElapsedMilliseconds, inCount, outCount);

                return(dependencies);
            }
        }
        /// <summary>
        /// Computes the dependencies for the specified asset.
        /// </summary>
        /// <param name="assetItem">The asset item.</param>
        /// <param name="dependenciesOptions">The dependencies options.</param>
        /// <param name="linkTypes">The type of links to visit while computing the dependencies</param>
        /// <param name="visited">The list of element already visited.</param>
        /// <returns>The dependencies.</returns>
        public AssetDependencies ComputeDependencies(AssetItem assetItem, AssetDependencySearchOptions dependenciesOptions = AssetDependencySearchOptions.All, ContentLinkType linkTypes = ContentLinkType.All, HashSet <Guid> visited = null)
        {
            if (assetItem == null)
            {
                throw new ArgumentNullException(nameof(assetItem));
            }
            bool recursive = (dependenciesOptions & AssetDependencySearchOptions.Recursive) != 0;

            if (visited == null && recursive)
            {
                visited = new HashSet <Guid>();
            }

            //var clock = Stopwatch.StartNew();

            lock (Initialize())
            {
                var dependencies = new AssetDependencies(assetItem);

                int inCount = 0, outCount = 0;

                if ((dependenciesOptions & AssetDependencySearchOptions.In) != 0)
                {
                    CollectInputReferences(dependencies, assetItem, visited, recursive, linkTypes, ref inCount);
                }

                if ((dependenciesOptions & AssetDependencySearchOptions.Out) != 0)
                {
                    visited?.Clear();
                    CollectOutputReferences(dependencies, assetItem, visited, recursive, linkTypes, ref outCount);
                }

                //Console.WriteLine("Time to compute dependencies: {0}ms in: {1} out:{2}", clock.ElapsedMilliseconds, inCount, outCount);

                return(dependencies);
            }
        }
        /// <summary>
        /// Computes the dependencies for the specified asset.
        /// </summary>
        /// <param name="assetItem">The asset item.</param>
        /// <param name="dependenciesOptions">The dependencies options.</param>
        /// <param name="visited">The list of element already visited.</param>
        /// <returns>The dependencies.</returns>
        public AssetDependencies ComputeDependencies(AssetItem assetItem, AssetDependencySearchOptions dependenciesOptions = AssetDependencySearchOptions.All, HashSet<Guid> visited = null)
        {
            if (assetItem == null) throw new ArgumentNullException("assetItem");
            bool recursive = (dependenciesOptions & AssetDependencySearchOptions.Recursive) != 0;
            if (visited == null && recursive)
                visited = new HashSet<Guid>();

            //var clock = Stopwatch.StartNew();

            lock (Initialize())
            {
                var dependencies = new AssetDependencies(assetItem);

                int inCount = 0, outCount = 0;

                if ((dependenciesOptions & AssetDependencySearchOptions.In) != 0)
                {
                    CollectInputReferences(dependencies, assetItem, visited, recursive, ref inCount);
                }

                if ((dependenciesOptions & AssetDependencySearchOptions.Out) != 0)
                {
                    if (visited != null)
                    {
                        visited.Clear();
                    }
                    CollectOutputReferences(dependencies, assetItem, visited, recursive, ref outCount);
                }

                //Console.WriteLine("Time to compute dependencies: {0}ms in: {1} out:{2}", clock.ElapsedMilliseconds, inCount, outCount);

                return dependencies;
            }

        }
        /// <summary>
        /// Computes the dependencies for the specified asset.
        /// </summary>
        /// <param name="assetId">The asset id.</param>
        /// <param name="dependenciesOptions">The dependencies options.</param>
        /// <param name="linkTypes">The type of links to visit while computing the dependencies</param>
        /// <param name="visited">The list of element already visited.</param>
        /// <returns>The dependencies, or null if the object is not tracked.</returns>
        public AssetDependencies ComputeDependencies(AssetId assetId, AssetDependencySearchOptions dependenciesOptions = AssetDependencySearchOptions.All, ContentLinkType linkTypes = ContentLinkType.All, HashSet<AssetId> visited = null)
        {
            bool recursive = (dependenciesOptions & AssetDependencySearchOptions.Recursive) != 0;
            if (visited == null && recursive)
                visited = new HashSet<AssetId>();

            //var clock = Stopwatch.StartNew();

            lock (Initialize())
            {
                AssetDependencies dependencies;
                if (!Dependencies.TryGetValue(assetId, out dependencies))
                    return null;

                dependencies = new AssetDependencies(dependencies.Item);

                int inCount = 0, outCount = 0;

                if ((dependenciesOptions & AssetDependencySearchOptions.In) != 0)
                {
                    CollectInputReferences(dependencies, assetId, visited, recursive, linkTypes, ref inCount);
                }

                if ((dependenciesOptions & AssetDependencySearchOptions.Out) != 0)
                {
                    visited?.Clear();
                    CollectOutputReferences(dependencies, assetId, visited, recursive, linkTypes, ref outCount);
                }

                //Console.WriteLine("Time to compute dependencies: {0}ms in: {1} out:{2}", clock.ElapsedMilliseconds, inCount, outCount);

                return dependencies;
            }

        }