/// <summary>
        /// Discovers the version of the Nuget package used in this version of Sitecore by checking the DLL version,
        /// and attempting to find that package on the public Nuget repository.
        /// </summary>
        /// <param name="packageName"></param>
        /// <param name="binFolderPath"></param>
        /// <returns></returns>
        public ManifestDependency FindPublicThirdPartyNugetPackage(string packageName, string binFolderPath)
        {
            // convert package name to DLL name
              var assemlbyName = this.ResolveKnownAssemblyNameForPackage(packageName);
              var fullAssemblyPath = Path.Combine(binFolderPath, assemlbyName + ".DLL");

              // find name of DLL in binDirectory
              if (!File.Exists(fullAssemblyPath))
              {
            Console.WriteLine("--- Assembly for Nuget Package Not Found: " + packageName);
            return null;
              }

              // find the version of that DLL
              var fvi = FileVersionInfo.GetVersionInfo(fullAssemblyPath);
              var ver = new VersionInfo(fvi.FileMajorPart, fvi.FileMinorPart, fvi.FileBuildPart, fvi.FilePrivatePart);

              // find equivalent on public Nuget Repo
              return this.SearchForPackage(packageName, ver);
        }
        /// <summary>
        /// Attempts to find the correct available version of a Nuget package.
        /// It will Try the version {Major, Minor, Build, Revision}, Then {Major, Minor, Build}, then {Major, Minor}, then {Major}
        /// </summary>
        /// <param name="packages"></param>
        /// <param name="assemblyVersion"></param>
        /// <returns></returns>
        private IPackage FindMatchingPackageVersion(IReadOnlyCollection<IPackage> packages, VersionInfo assemblyVersion)
        {
            Assert.ArgumentNotNull(packages, nameof(packages));
              Assert.ArgumentNotNull(assemblyVersion, nameof(assemblyVersion));

              var matchingPackage = packages.FirstOrDefault(package => package.Version.Version.Equals(assemblyVersion));
              if (matchingPackage != null)
              {
            return matchingPackage;
              }

              var major = assemblyVersion.Major;
              var minor = assemblyVersion.Minor;
              var build = assemblyVersion.Build;

              // Major, Minor, Build
              var buildVersionMatch = new Version(major, minor, build, 0);
              matchingPackage = packages.FirstOrDefault(package => package.Version.Version.Equals(buildVersionMatch));

              if (matchingPackage != null)
              {
            return matchingPackage;
              }

              // Major, Minor, BuildDigit1 (i.e 5.2.30706 becomes 5.2.3)
              var firstDigitBuildNumber = Math.Abs(build);
              while (firstDigitBuildNumber >= 10)
              {
            firstDigitBuildNumber /= 10;
              }

              var firstDigitiBuildVersionMatch = new Version(major, minor, firstDigitBuildNumber, 0);

              matchingPackage = packages.FirstOrDefault(package => package.Version.Version.Equals(firstDigitiBuildVersionMatch));

              if (matchingPackage != null)
              {
            return matchingPackage;
              }

              // Major, Minor
              var minorVersionMatch = new Version(major, minor, 0, 0);

              matchingPackage = packages.FirstOrDefault(package => package.Version.Version.Equals(minorVersionMatch));

              if (matchingPackage != null)
              {
            return matchingPackage;
              }

              // Major
              var majorVersionMatch = new Version(major, 0, 0, 0);

              matchingPackage = packages.FirstOrDefault(package => package.Version.Version.Equals(majorVersionMatch));

              // ReSharper disable once UseNullPropagation
              if (matchingPackage != null)
              {
            return matchingPackage;
              }

              return null;
        }
        /// <summary>
        /// Searches the public Nuget repository for the given package name and version.
        /// </summary>
        /// <param name="nugetPackageID"></param>
        /// <param name="assemblyVersionInfo"></param>
        /// <returns></returns>
        private ManifestDependency SearchForPackage(string nugetPackageID, VersionInfo assemblyVersionInfo)
        {
            // http://blog.nuget.org/20130520/Play-with-packages.html
              // Connect to the official package repository
              var repo = PackageRepositoryFactory.Default.CreateRepository("https://packages.nuget.org/api/v2");

              // Get the list of all NuGet packages with the ID provided
              var packages = repo.FindPackagesById(nugetPackageID).ToList();
              if (!packages.Any())
              {
            // error package not found
            Console.WriteLine("- Package Not Found: " + nugetPackageID);

            return null;
              }

              var matchingPackage = this.FindMatchingPackageVersion(packages, assemblyVersionInfo);
              if (matchingPackage == null) // || IsNotCompleteVersion) - DotNetOpenAuth issue
              {
            Console.WriteLine("--- Version Not Found: " + nugetPackageID + ", " + assemblyVersionInfo);

            return null;
              }

              return new ManifestDependency { Id = matchingPackage.Id, Version = matchingPackage.Version.Version.ToString() };
        }