/// <summary>
        /// Searches package sources given name and version information 
        /// 
        /// Package information must be returned using <c>request.YieldPackage(...)</c> function.
        /// </summary>
        /// <param name="name">a name or partial name of the package(s) requested</param>
        /// <param name="requiredVersion">A specific version of the package. Null or empty if the user did not specify</param>
        /// <param name="minimumVersion">A minimum version of the package. Null or empty if the user did not specify</param>
        /// <param name="maximumVersion">A maximum version of the package. Null or empty if the user did not specify</param>
        /// <param name="id">if this is greater than zero (and the number should have been generated using <c>StartFind(...)</c>, the core is calling this multiple times to do a batch search request. The operation can be delayed until <c>CompleteFind(...)</c> is called</param>
        /// <param name="request">An object passed in from the CORE that contains functions that can be used to interact with the CORE and HOST</param>
        public void FindPackage(string name, string requiredVersion, string minimumVersion, string maximumVersion, int id, Request request)
        {
            request.Debug("Calling '{0}::FindPackage' '{1}','{2}','{3}','{4}'", PackageProviderName, requiredVersion, minimumVersion, maximumVersion, id);

            List<PackageSource> sources;
            var providerPackageSources = ProviderStorage.GetPackageSources(request);

            if (request.PackageSources != null && request.PackageSources.Any())
            {
                sources = new List<PackageSource>();

                foreach (var userRequestedSource in request.PackageSources)
                {
                    if (providerPackageSources.ContainsKey(userRequestedSource))
                    {
                        sources.Add(providerPackageSources[userRequestedSource]);
                    }
                }
            }
            else
            {
                sources = providerPackageSources.Select(i => i.Value).ToList();
            }

            if (request.IsCanceled)
            {
                return;
            }

            var packageItem = new PackageItem(sources.FirstOrDefault(), "notepad", "1.0");

            // YieldPackage returns false when operation was cancelled
            if (!request.YieldPackage(packageItem, name))
            {
                return;
            }
        }
        internal static bool YieldPackage(this Request request, PackageItem pkg, string searchKey)
        {
            try
            {
                if (request.YieldSoftwareIdentity(pkg.FastPath, pkg.Id, pkg.Version.ToString(), "semver", pkg.Summary, pkg.PackageSource.Name, searchKey, pkg.FullPath, pkg.PackageFilename) != null)
                {
                    if (request.AddMetadata(pkg.FastPath, "FromTrustedSource", pkg.PackageSource.Trusted.ToString()) == null)
                    {
                        return false;
                    }

                    /*
                    // AddMetadata seems to return null for good values, commenting out the below
                    if (pkg.Copyright != null)
                    {
                        if (request.AddMetadata(pkg.FastPath, "copyright", pkg.Copyright) != null)
                        {
                            return false;
                        }
                    }

                    if (pkg.Description != null)
                    {
                        if (request.AddMetadata(pkg.FastPath, "description", pkg.Description) != null)
                        {
                            return false;
                        }
                    }

                    if (pkg.Language != null)
                    {
                        if (request.AddMetadata(pkg.FastPath, "language", pkg.Language) != null)
                        {
                            return false;
                        }
                    }

                    if (pkg.Tags != null)
                    {
                        if (request.AddMetadata(pkg.FastPath, "tags", pkg.Tags) != null)
                        {
                            return false;
                        }
                    }

                    if (pkg.Title != null)
                    {
                        if (request.AddMetadata(pkg.FastPath, "title", pkg.Title) != null)
                        {
                            return false;
                        }
                    }

                    if (pkg.PackageSource != null)
                    {
                        if (request.AddMetadata(pkg.FastPath, "FromTrustedSource", pkg.PackageSource.Trusted.ToString()) != null)
                        {
                            return false;
                        }
                    }
                    */
                }
                else
                {
                    return false;
                }
            }
            catch (NullReferenceException)
            {
                request.Error("", ErrorCategory.InvalidData.ToString(), pkg.Id, Strings.PackageMissingProperty);
            }

            return true;
        }
        internal static bool YieldPackage(this Request request, PackageItem pkg, string searchKey)
        {
            try
            {
                if (request.YieldSoftwareIdentity(pkg.FastPath, pkg.Id, pkg.Version.ToString(), "semver", pkg.Summary, pkg.PackageSource.Name, searchKey, pkg.FullPath, pkg.PackageFilename) != null)
                {
                    if (request.AddMetadata(pkg.FastPath, "FromTrustedSource", pkg.PackageSource.Trusted.ToString()) == null)
                    {
                        return(false);
                    }

                    /*
                     * // AddMetadata seems to return null for good values, commenting out the below
                     * if (pkg.Copyright != null)
                     * {
                     *  if (request.AddMetadata(pkg.FastPath, "copyright", pkg.Copyright) != null)
                     *  {
                     *      return false;
                     *  }
                     * }
                     *
                     * if (pkg.Description != null)
                     * {
                     *  if (request.AddMetadata(pkg.FastPath, "description", pkg.Description) != null)
                     *  {
                     *      return false;
                     *  }
                     * }
                     *
                     * if (pkg.Language != null)
                     * {
                     *  if (request.AddMetadata(pkg.FastPath, "language", pkg.Language) != null)
                     *  {
                     *      return false;
                     *  }
                     * }
                     *
                     * if (pkg.Tags != null)
                     * {
                     *  if (request.AddMetadata(pkg.FastPath, "tags", pkg.Tags) != null)
                     *  {
                     *      return false;
                     *  }
                     * }
                     *
                     * if (pkg.Title != null)
                     * {
                     *  if (request.AddMetadata(pkg.FastPath, "title", pkg.Title) != null)
                     *  {
                     *      return false;
                     *  }
                     * }
                     *
                     * if (pkg.PackageSource != null)
                     * {
                     *  if (request.AddMetadata(pkg.FastPath, "FromTrustedSource", pkg.PackageSource.Trusted.ToString()) != null)
                     *  {
                     *      return false;
                     *  }
                     * }
                     */
                }
                else
                {
                    return(false);
                }
            }
            catch (NullReferenceException)
            {
                request.Error("", ErrorCategory.InvalidData.ToString(), pkg.Id, Strings.PackageMissingProperty);
            }

            return(true);
        }