internal PullRequestRecommendationResult Recommend(PullRequestContext pullRequestContext)
        {
            var pullRequestRecommendationResult = RecommendReviewers(pullRequestContext);

            // we sort the names alphabetically. Helps when analyzing the results later.
            pullRequestRecommendationResult.ActualReviewers   = pullRequestContext.ActualReviewers.Select(q => q.DeveloperName).OrderBy(q => q).ToArray();
            pullRequestRecommendationResult.SelectedReviewers = pullRequestRecommendationResult.SelectedReviewers?.OrderBy(q => q).ToArray();

            var selectedReviewersKnowledge = pullRequestRecommendationResult.GetSelectedReviewersKnowledge()
                                             .SelectMany(q => q.GetTouchedFiles())
                                             .ToHashSet();

            var actualReviewersKnowledge = pullRequestContext.ActualReviewers
                                           .SelectMany(q => q.GetTouchedFiles())
                                           .ToHashSet();

            var prFiles = pullRequestContext.PullRequestFiles
                          .Select(q => pullRequestContext.CanononicalPathMapper.GetValueOrDefault(q.FileName));

            if (prFiles.Count() > 0)
            {
                pullRequestRecommendationResult.Expertise = prFiles.Count(q => selectedReviewersKnowledge.Contains(q)) / (double)prFiles.Count();
            }

            pullRequestRecommendationResult.PullRequestNumber = pullRequestContext.PullRequest.Number;
            pullRequestRecommendationResult.IsSimulated       = true;

            CalculateMetrics(pullRequestRecommendationResult);

            if (!ChangePast)
            {
                pullRequestRecommendationResult.SelectedReviewers = pullRequestRecommendationResult.ActualReviewers;
            }

            return(pullRequestRecommendationResult);
        }
 protected static bool IsDeveloperAvailable(PullRequestContext pullRequestContext, string developerName)
 {
     return(pullRequestContext.AvailableDevelopers.Any(d => d.NormalizedName == developerName));
 }
 protected static bool IsDevelperAmongActualReviewers(PullRequestContext pullRequestContext, string developerName)
 {
     return(pullRequestContext.ActualReviewers.Any(a => a.DeveloperName == developerName));
 }
 protected abstract PullRequestRecommendationResult RecommendReviewers(PullRequestContext pullRequestContext);