private void RemoveMilestone(GitHubEventRepository repository, GitHubEventMilestone milestone)
            {
                var index = _indexService.Index;

                if (index is null)
                {
                    return;
                }

                var crawledRepo = index.Repos.SingleOrDefault(r => r.Id == repository.Id);

                if (crawledRepo is null)
                {
                    return;
                }

                var crawledMilestone = crawledRepo.Milestones.SingleOrDefault(m => m.Id == milestone.Id);

                if (crawledMilestone is null)
                {
                    return;
                }

                crawledRepo.Milestones = crawledRepo.Milestones.CopyAndRemove(crawledMilestone);

                var removedTrieTerms = new[] { $"milestone:{crawledMilestone.Title}" };

                foreach (var issue in crawledRepo.Issues.Values)
                {
                    RemoveTrieTerms(issue, removedTrieTerms);
                }

                _indexService.NotifyIndexChanged();
            }
            private static CrawledMilestone CreateMilestone(CrawledRepo crawledRepo, GitHubEventMilestone milestone)
            {
                var crawledMilestone = new CrawledMilestone();

                crawledMilestone.Id     = milestone.Id;
                crawledMilestone.Number = milestone.Number;
                UpdateMilestone(milestone, crawledMilestone);

                crawledRepo.Milestones = crawledRepo.Milestones.CopyAndAdd(crawledMilestone);

                return(crawledMilestone);
            }
            private void UpdateMilestone(GitHubEventRepository repository, GitHubEventMilestone milestone)
            {
                var index = _indexService.Index;

                if (index is null)
                {
                    return;
                }

                var crawledRepo = index.Repos.SingleOrDefault(r => r.Id == repository.Id);

                if (crawledRepo is null)
                {
                    return;
                }

                var crawledMilestone = crawledRepo.Milestones.SingleOrDefault(m => m.Id == m.Id);

                if (crawledMilestone is null)
                {
                    return;
                }

                var oldTitle = crawledMilestone.Title;

                UpdateMilestone(milestone, crawledMilestone);

                var newTitle = crawledMilestone.Title;

                if (!string.Equals(oldTitle, newTitle, StringComparison.OrdinalIgnoreCase))
                {
                    var removedTrieTerms = new[] { $"milestone:{oldTitle}" };
                    var addedTrieTerms   = new[] { $"milestone:{newTitle}" };

                    foreach (var issue in crawledRepo.Issues.Values)
                    {
                        RemoveTrieTerms(issue, removedTrieTerms);
                        AddTrieTerms(issue, addedTrieTerms);
                    }
                }

                _indexService.NotifyIndexChanged();
            }
            private void AddMilestone(GitHubEventRepository repository, GitHubEventMilestone milestone)
            {
                var index = _indexService.Index;

                if (index is null)
                {
                    return;
                }

                var crawledRepo = index.Repos.SingleOrDefault(r => r.Id == repository.Id);

                if (crawledRepo is null)
                {
                    return;
                }

                CreateMilestone(crawledRepo, milestone);

                _indexService.NotifyIndexChanged();
            }
            private CrawledMilestone GetOrCreateMilestone(GitHubEventRepository repository, GitHubEventMilestone milestone)
            {
                if (milestone is null)
                {
                    return(null);
                }

                var index = _indexService.Index;

                Debug.Assert(index is not null);

                var crawledRepo = index.Repos.SingleOrDefault(r => r.Id == repository.Id);

                Debug.Assert(crawledRepo is not null);

                var matchingMilestones = crawledRepo.Milestones.Where(m => m.Id == milestone.Id).ToArray();

                if (matchingMilestones.Length == 0)
                {
                    return(CreateMilestone(crawledRepo, milestone));
                }

                if (matchingMilestones.Length > 1)
                {
                    var milestone1 = matchingMilestones[0];
                    var milestone2 = matchingMilestones[1];
                    _logger.LogError("In repo {org}/{repo} multiple milestones have id {milestoneId}: '{milestone1Name}', '{milestone2Name}'", crawledRepo.Org, crawledRepo.Name, milestone.Id, milestone1.Title, milestone2.Title);
                }

                return(matchingMilestones[0]);
            }
 private static void UpdateMilestone(GitHubEventMilestone milestone, CrawledMilestone crawledMilestone)
 {
     crawledMilestone.Title       = milestone.Title;
     crawledMilestone.Description = milestone.Description;
 }
            protected override void ProcessMilestoneMessage(GitHubEventMessage message, GitHubEventRepository repository, GitHubEventMilestone milestone, GitHubEventMilestoneAction action)
            {
                switch (action)
                {
                case GitHubEventMilestoneAction.Created:
                    AddMilestone(repository, milestone);
                    break;

                case GitHubEventMilestoneAction.Edited:
                case GitHubEventMilestoneAction.Opened:
                case GitHubEventMilestoneAction.Closed:
                    UpdateMilestone(repository, milestone);
                    break;

                case GitHubEventMilestoneAction.Deleted:
                    RemoveMilestone(repository, milestone);
                    break;
                }
            }