private async void ProcessCompatibility(IEnumerable <string> namespaces,
                                                Dictionary <string, List <string> > foundPackages,
                                                Dictionary <string, TaskCompletionSource <RecommendationDetails> > recommendationTaskCompletionSources)
        {
            var namespacesFound      = new HashSet <string>();
            var namespacesWithErrors = new HashSet <string>();

            try
            {
                foreach (var url in foundPackages)
                {
                    try
                    {
                        _logger.LogInformation("Downloading {0} from {1}", url.Key, CompatibilityCheckerType);
                        using var stream = await _httpService.DownloadGitHubFileAsync("recommendation/" + url.Key);

                        using var streamReader = new StreamReader(stream);
                        var packageFromGithub = JsonConvert.DeserializeObject <RecommendationDetails>(streamReader.ReadToEnd());

                        foreach (var @namespace in url.Value)
                        {
                            if (recommendationTaskCompletionSources.TryGetValue(@namespace, out var taskCompletionSource))
                            {
                                taskCompletionSource.SetResult(packageFromGithub);
                                namespacesFound.Add(@namespace);
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        _logger.LogError("Failed when downloading recommendation and parsing {0} from {1}, {2}", url.Key, CompatibilityCheckerType, ex);
                        foreach (var @namespace in url.Value)
                        {
                            if (recommendationTaskCompletionSources.TryGetValue(@namespace, out var taskCompletionSource))
                            {
                                taskCompletionSource.SetException(new PortingAssistantClientException(ExceptionMessage.NamespaceFailedToProcess(@namespace), ex));
                                namespacesWithErrors.Add(@namespace);
                            }
                        }
                    }
                }

                foreach (var @namespace in namespaces)
                {
                    if (namespacesFound.Contains(@namespace) || namespacesWithErrors.Contains(@namespace))
                    {
                        continue;
                    }

                    if (recommendationTaskCompletionSources.TryGetValue(@namespace, out var taskCompletionSource))
                    {
                        var errorMessage = $"Could not find {@namespace} recommendation in external source; discarding this namespace.";
                        _logger.LogInformation(errorMessage);

                        var innerException = new NamespaceNotFoundException(errorMessage);
                        taskCompletionSource.TrySetException(new PortingAssistantClientException(ExceptionMessage.NamespaceNotFound(@namespace), innerException));
                    }
                }
            }
            catch (Exception ex)
            {
                foreach (var @namespace in namespaces)
                {
                    if (recommendationTaskCompletionSources.TryGetValue(@namespace, out var taskCompletionSource))
                    {
                        taskCompletionSource.TrySetException(
                            new PortingAssistantClientException(ExceptionMessage.NamespaceFailedToProcess(@namespace), ex));
                    }
                }

                _logger.LogError("Error encountered while processing recommendations: {0}", ex);
            }
        }