public bool Equals(PackageDependency x, PackageDependency y)
        {
            if (ReferenceEquals(x, y))
            {
                return(true);
            }

            if (ReferenceEquals(x, null) ||
                ReferenceEquals(y, null))
            {
                return(false);
            }

            var result = StringComparer.OrdinalIgnoreCase.Equals(x.Id, y.Id);

            if (result)
            {
                result = _versionRangeComparer.Equals(x.VersionRange ?? VersionRange.All, y.VersionRange ?? VersionRange.All);
            }

            if (result)
            {
                result = x.Include.OrderedEquals(y.Include, s => s, StringComparer.OrdinalIgnoreCase, StringComparer.OrdinalIgnoreCase);
            }

            if (result)
            {
                result = x.Exclude.OrderedEquals(y.Exclude, s => s, StringComparer.OrdinalIgnoreCase, StringComparer.OrdinalIgnoreCase);
            }

            return(result);
        }
        /// <summary>
        /// Use the VersionRangeComparer for equality checks
        /// </summary>
        public bool Equals(VersionRangeBase other, IVersionRangeComparer comparer)
        {
            if (comparer == null)
            {
                throw new ArgumentNullException("comparer");
            }

            return(comparer.Equals(this, other));
        }
        public bool Equals(PackageDependency x, PackageDependency y)
        {
            if (Object.ReferenceEquals(x, y))
            {
                return(true);
            }

            if (Object.ReferenceEquals(x, null) || Object.ReferenceEquals(y, null))
            {
                return(false);
            }

            bool result = StringComparer.OrdinalIgnoreCase.Equals(x.Id, y.Id);

            if (result)
            {
                result = _versionRangeComparer.Equals(x.VersionRange ?? VersionRange.All, y.VersionRange ?? VersionRange.All);
            }

            return(result);
        }
        // Thread safe fetch for the target only, no child dependencies
        private async Task Ensure(NuGet.Packaging.Core.PackageDependency target, NuGetFramework projectFramework, bool includePrerelease, CancellationToken token)
        {
            object lockObj = _lockObjsById.GetOrAdd(target.Id, new object());

            // lock per package Id
            lock (lockObj)
            {
                VersionRange alreadySearched = null;

                if (!_rangeSearched.TryGetValue(target.Id, out alreadySearched))
                {
                    alreadySearched = EmptyRange;
                }

                if (alreadySearched == null || !target.VersionRange.IsSubSetOrEqualTo(alreadySearched))
                {
                    // find what we haven't checked already
                    var needed = NeededRange(alreadySearched, target.VersionRange);

                    // adjust prerelease, is this needed?
                    needed = ModifyRange(needed, includePrerelease);

                    if (!_versionRangeComparer.Equals(needed, EmptyRange))
                    {
                        // server search
                        IEnumerable <IPackage> repoPackages = null;

                        if (_useFindById)
                        {
                            // Ranges fail in some cases for local repos, to work around this just collect every
                            // version of the package to filter later
                            repoPackages = V2Client.FindPackagesById(target.Id);
                        }
                        else
                        {
                            // DataService Repository
                            repoPackages = V2Client.FindPackages(target.Id, GetVersionSpec(needed), includePrerelease, false);
                        }

                        List <VersionRange> currentRanges = new List <VersionRange>();
                        currentRanges.Add(target.VersionRange);

                        if (alreadySearched != null)
                        {
                            currentRanges.Add(alreadySearched);
                        }

                        // update the already searched range
                        VersionRange combined = null;

                        if (_useFindById)
                        {
                            // for local repos we found all possible versions
                            combined = VersionRange.All;
                        }
                        else
                        {
                            // for non-local repos find the real range
                            combined = VersionRange.Combine(currentRanges);
                        }

                        _rangeSearched.AddOrUpdate(target.Id, combined, (k, v) => combined);

                        HashSet <PackageDependencyInfo> foundPackages = null;

                        // add everything to found
                        if (!_found.TryGetValue(target.Id, out foundPackages))
                        {
                            foundPackages = new HashSet <PackageDependencyInfo>(PackageIdentity.Comparer);
                            _found.TryAdd(target.Id, foundPackages);
                        }

                        // add current packages to found
                        IEnumerable <PackageDependencyInfo> packageVersions = repoPackages.Select(p => CreateDependencyInfo(p, projectFramework));
                        foundPackages.UnionWith(packageVersions);
                    }
                }
            }
        }