private async Task DoSearch(NuGetFactory factory, D3DependencyChild current,
                                 int maxLevel,
                                 PackageIdentity package, NuGetFramework fx)
        {
            if (current.Level > maxLevel)
            {
                return;
            }

            // same package may be traversed multiple times, so we can cache it
            // don't cache the tree as depth may change for the same package
            SourcePackageDependencyInfo packageDependencyInfo = await CacheResolvePackage(factory, package, fx);
            if (packageDependencyInfo.Dependencies.Any())
            {
                if (current.children == null)
                {
                    current.children = new List<D3DependencyChild>();
                }

                foreach (var dependency in packageDependencyInfo.Dependencies)
                {
                    // unlikely that the version of a particular dependency will change in 30 minutes
                    // so we can cache it
                    IEnumerable<NuGetVersion> allVersions = await CacheGetAllVersionsOfDependency(factory, dependency);
                    if (allVersions.Any())
                    {
                        var bestMatch = dependency.VersionRange.FindBestMatch(allVersions);

                        var child = new D3DependencyChild
                        {
                            key = dependency.Id,
                            version = bestMatch.Version.ToString(),
                            parent = current.key,
                            Level = current.Level + 1
                        };

                        current.children.Add(child);

                        var nextPackage = new PackageIdentity(child.key, bestMatch);
                        await DoSearch(factory, child, maxLevel, nextPackage, fx);
                    }
                }
            }
        }
        public async Task<D3DependencyChild> ViewDependencies(string packageID, string packageVersion, string source,
            string framework, string frameworkVersion, string frameworkProfile, int maxLevel = 3)
        {
            if (string.IsNullOrEmpty(packageID))
                throw new ArgumentNullException("packageID");

            if (string.IsNullOrEmpty(packageVersion))
                throw new ArgumentNullException("packageVersion");

            if (string.IsNullOrEmpty(source))
                throw new ArgumentNullException("source");

            if (string.IsNullOrEmpty(framework))
                throw new ArgumentNullException("framework");

            if (string.IsNullOrEmpty(frameworkVersion))
                throw new ArgumentNullException("frameworkVersion");

            var factory = new NuGetFactory(source);
            NuGetFramework fx = new NuGetFramework(framework, Version.Parse(frameworkVersion), frameworkProfile);
            PackageIdentity package = new PackageIdentity(packageID, NuGetVersion.Parse(packageVersion));
            var root = new D3DependencyChild
            {
                key = packageID,
                version = packageVersion,
                Level = 0
            };

            await DoSearch(factory, root, maxLevel, package, fx);

            return root;

        }