public async Task <FindBestPackageVersionMatchOutput> FindBestPackageVersionMatchAsync(
            FindBestPackageVersionMatchInput input,
            CancellationToken cancellationToken)
        {
            var output = new FindBestPackageVersionMatchOutput
            {
                InputStatus = InputStatus.Missing,
                Input       = input,
            };

            if (input == null)
            {
                return(output);
            }

            var validatedPackageId    = InputValidator.PackageId(input.PackageId);
            var validatedVersionRange = InputValidator.VersionRange(input.VersionRange);

            if (validatedPackageId.IsMissing || validatedPackageId.IsMissing)
            {
                return(output);
            }

            if (validatedVersionRange.IsInvalid || validatedVersionRange.IsInvalid)
            {
                output.InputStatus = InputStatus.Invalid;
                return(output);
            }

            IEnumerable <NuGetVersion> versions;
            HashSet <NuGetVersion>     listed;

            using (var cache = new SourceCacheContext())
            {
                var resource = await _metadataResourceTask;
                var metadata = await resource.GetMetadataAsync(
                    input.PackageId,
                    includePrerelease : true,
                    includeUnlisted : true,
                    cache,
                    _nuGetLogger,
                    cancellationToken);

                listed   = new HashSet <NuGetVersion>(metadata.Where(x => x.IsListed).Select(x => x.Identity.Version));
                versions = metadata.Select(x => x.Identity.Version).ToList();
            }

            output.InputStatus  = InputStatus.Valid;
            output.PackageId    = validatedPackageId.Data;
            output.ShowUnlisted = input.ShowUnlisted;
            output.Result       = GetBestVersionMatch(validatedVersionRange.Data, versions.ToList(), listed, output.ShowUnlisted);

            return(output);
        }
            public async Task CanIncludeUnlistedThatAreNotBestMatch()
            {
                var input = new FindBestPackageVersionMatchInput
                {
                    PackageId    = "BaseTestPackage.Unlisted",
                    VersionRange = "1.2.0",
                    ShowUnlisted = true,
                };

                var output = await Target.FindBestPackageVersionMatchAsync(input, Token);

                Assert.Contains("1.1.0", output.Result.Versions.Select(v => v.Version.ToNormalizedString()));
            }
            public async Task UnlistedVersionIsBestMatch(bool showUnlisted)
            {
                var input = new FindBestPackageVersionMatchInput
                {
                    PackageId    = "BaseTestPackage.Unlisted",
                    VersionRange = "1.1.0",
                    ShowUnlisted = showUnlisted,
                };

                var output = await Target.FindBestPackageVersionMatchAsync(input, Token);

                Assert.Equal("1.1.0", output.Result.BestMatch.Version.ToNormalizedString());
            }
            public async Task FindBestPackageVersionMatch()
            {
                var input = new FindBestPackageVersionMatchInput
                {
                    PackageId    = "NuGet.Versioning",
                    VersionRange = "[4.3.0, 5.0.0)",
                    ShowUnlisted = false,
                };

                var output = await Target.FindBestPackageVersionMatchAsync(input, Token);

                Assert.Equal("4.3.0", output.Result.BestMatch.Version.ToNormalizedString());
            }
            public async Task CanFilterOutUnlistedThatAreNotBestMatch()
            {
                var input = new FindBestPackageVersionMatchInput
                {
                    PackageId    = "BaseTestPackage.Unlisted",
                    VersionRange = "1.2.0",
                    ShowUnlisted = false,
                };

                var output = await Target.FindBestPackageVersionMatchAsync(input, Token);

                Assert.Empty(output.Result.Versions);
                Assert.Null(output.Result.BestMatch);
            }