private static INuGetResourceCollection GetResourcesImpl(string baseUrl, RequestWrapper request)
        {
            INuGetResourceCollection res = null;
            HttpClient          client   = request.GetClientWithHeaders();
            HttpResponseMessage response = PathUtility.GetHttpResponse(client, baseUrl, (() => request.IsCanceled()),
                                                                       ((msg, num) => request.Verbose(Resources.Messages.RetryingDownload, msg, num)), (msg) => request.Verbose(msg), (msg) => request.Debug(msg));

            if (!response.IsSuccessStatusCode)
            {
                throw new Exception(Resources.Messages.NuGetEndpointDiscoveryFailed);
            }

            string content = new StreamReader(NuGetClient.DownloadDataToStream(baseUrl, request)).ReadToEnd();

            // If the response starts with the magic XML header, it's v2
            if (content.StartsWith(Constants.XmlStartContent))
            {
                res = NuGetResourceCollection2.Make(baseUrl);
            }
            else
            {
                try
                {
                    dynamic root    = DynamicJsonParser.Parse(content);
                    string  version = root.version;
                    if (version != null && version.StartsWith("3."))
                    {
                        // v3 feed
                        res = NuGetResourceCollection3.Make(root, baseUrl, request);
                    }
                }
                catch (Exception ex)
                {
                    Exception discoveryException = new Exception(Resources.Messages.NuGetEndpointDiscoveryFailed, ex);
                    throw discoveryException;
                }
            }

            if (res == null)
            {
                // Couldn't figure out what this is
                throw new Exception(Resources.Messages.NuGetEndpointDiscoveryFailed);
            }

            return(res);
        }
        public static NuGetResourceCollection3 Make(dynamic root, string baseUrl, RequestWrapper request)
        {
            request.Debug(Messages.DebugInfoCallMethod3, "NuGetResourceCollection3", "Make", baseUrl);
            NuGetResourceCollection3 collection = new NuGetResourceCollection3();
            Dictionary <NuGetServiceType, NuGetServiceInfo> currentServiceMap = new Dictionary <NuGetServiceType, NuGetServiceInfo>();

            foreach (dynamic resourceElement in root.resources)
            {
                NuGetServiceInfo serviceInfo = NuGetServiceInfo.GetV3Endpoint(resourceElement);
                if (serviceInfo == null)
                {
                    continue;
                }

                bool serviceUsed       = currentServiceMap.ContainsKey(serviceInfo.Type) && currentServiceMap[serviceInfo.Type].Preference <= serviceInfo.Preference;
                bool serviceSupplement = currentServiceMap.ContainsKey(serviceInfo.Type) && currentServiceMap[serviceInfo.Type].Preference == serviceInfo.Preference;
                switch (serviceInfo.Type)
                {
                case NuGetServiceType.AutoComplete:
                    // No feed yet OR no version (lowest possible stable version) OR greater version
                    if (serviceUsed || collection.AutoCompleteFeed == null)
                    {
                        serviceUsed = true;
                        if (serviceSupplement)
                        {
                            ((NuGetAutoCompleteFeed3)collection.AutoCompleteFeed).Endpoints.Add(serviceInfo);
                        }
                        else
                        {
                            collection.AutoCompleteFeed = new NuGetAutoCompleteFeed3(serviceInfo);
                        }
                    }

                    break;

                case NuGetServiceType.Registrations:
                    if (serviceUsed || collection.PackagesFeed == null)
                    {
                        serviceUsed = true;
                        if (serviceSupplement)
                        {
                            ((NuGetPackageFeed3)collection.PackagesFeed).Endpoints.Add(serviceInfo);
                        }
                        else
                        {
                            collection.PackagesFeed = new NuGetPackageFeed3(serviceInfo);
                        }
                    }

                    break;

                case NuGetServiceType.Query:
                    if (serviceUsed || collection.QueryFeed == null)
                    {
                        serviceUsed = true;
                        if (serviceSupplement)
                        {
                            ((NuGetQueryFeed3)collection.QueryFeed).Endpoints.Add(serviceInfo);
                        }
                        else
                        {
                            collection.QueryFeed = new NuGetQueryFeed3(serviceInfo);
                        }
                    }

                    break;

                case NuGetServiceType.Files:
                    if (serviceUsed || collection.FilesFeed == null)
                    {
                        serviceUsed          = true;
                        collection.FilesFeed = new NuGetFilesFeed3(serviceInfo.Url);
                    }

                    break;

                case NuGetServiceType.ReportAbuse:
                    if (serviceUsed || collection.AbuseFeed == null)
                    {
                        serviceUsed          = true;
                        collection.AbuseFeed = new NuGetAbuseFeed3(serviceInfo.Url);
                    }

                    break;
                }

                if (serviceUsed)
                {
                    request.Debug(Messages.NuGetEndpointDiscovered, serviceInfo.Type, serviceInfo.Url);
                    if (!serviceSupplement)
                    {
                        currentServiceMap[serviceInfo.Type] = serviceInfo;
                    }
                }
            }

            collection.GetSearchQueryDelegate = (searchTerms) =>
            {
                string searchString = String.Empty;
                // TODO: encode search terms?
                foreach (NuGetSearchTerm searchTerm in searchTerms)
                {
                    switch (searchTerm.Term)
                    {
                    case NuGetSearchTerm.NuGetSearchTermType.SearchTerm:
                        searchString += searchTerm.Text;
                        break;

                    case NuGetSearchTerm.NuGetSearchTermType.Tag:
                        HttpQueryBuilder tQb = new HttpQueryBuilder().Add(Constants.TagQueryParam, searchTerm.Text, separator: ":", encode: false);
                        searchString += " " + tQb.ToQueryString();
                        break;

                    case NuGetSearchTerm.NuGetSearchTermType.Contains:
                        HttpQueryBuilder cQb = new HttpQueryBuilder().Add(Constants.DescriptionQueryParam, searchTerm.Text, separator: ":", encode: false);
                        searchString += " " + cQb.ToQueryString();
                        break;

                    default:
                        break;
                    }
                }

                return(searchString.Trim());
            };

            collection.PackageConverter              = new PackageBaseConverter();
            collection.PackageDependencyConverter    = new PackageDependencyConverter();
            collection.PackageDependencySetConverter = new DependencyGroupConverter();
            collection.CatalogUrlConverter           = new CatalogUrlConverter();
            Uri uri = new Uri(baseUrl);

            if (uri.Host.Contains(Constants.NuGetOrgHost))
            {
                collection.GalleryFeed = new NuGetGalleryFeedOrg();
            }
            else if (uri.Host.Contains(Constants.MyGetOrgHost))
            {
                collection.GalleryFeed = new NuGetGalleryFeedMyGet(baseUrl);
            }

            request.Debug(Messages.DebugInfoReturnCall, "NuGetResourceCollection3", "Make");
            return(collection);
        }