private void RemoveIssue(GitHubEventRepository repository, GitHubEventIssue issue)
            {
                var index = _indexService.Index;

                if (index is null)
                {
                    return;
                }

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

                if (crawledRepo is null)
                {
                    return;
                }

                if (!crawledRepo.Issues.TryGetValue(issue.Number, out var crawledIssue))
                {
                    return;
                }

                RemoveIssue(crawledRepo, crawledIssue);

                _indexService.NotifyIndexChanged();
            }
            private void UpdateIssue(GitHubEventRepository repository, GitHubEventIssue issue)
            {
                var index = _indexService.Index;

                if (index is null)
                {
                    return;
                }

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

                if (crawledRepo is null)
                {
                    return;
                }

                if (!crawledRepo.Issues.TryGetValue(issue.Number, out var crawledIssue))
                {
                    return;
                }

                var oldTrieTerms = crawledIssue.GetTrieTerms();

                UpdateIssueOrPullRequest(repository, issue, crawledIssue);
                UpdateTrie(crawledIssue, oldTrieTerms);

                _indexService.NotifyIndexChanged();
            }
            private void TransferIssue(GitHubEventRepository repository, GitHubEventIssue issue)
            {
                // When an issue is being transferred, GitHub sends two events:
                //
                // 1. Issue transferred (existing repo, existing issue, new repo, new issue)
                // 2. Issue opened (new repo, new issue)
                //
                // The existing issue in event (1) isn't marked as closed yet, but we also don't get
                // a dedicated "issue closed" event either.
                //
                // Hence, handling a transfer only requires us to remove the existing issue. We can
                // ignore the new repo and new issue because we'll get a dedicated "isse opened"
                // event anyways.

                var index = _indexService.Index;

                if (index is null)
                {
                    return;
                }

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

                if (crawledRepo is null)
                {
                    return;
                }

                if (!crawledRepo.Issues.TryGetValue(issue.Number, out var crawledIssue))
                {
                    return;
                }

                RemoveIssue(crawledRepo, crawledIssue);

                _indexService.NotifyIndexChanged();
            }
            protected override void ProcessIssueMessage(GitHubEventMessage message, GitHubEventRepository repository, GitHubEventIssue issue, GitHubEventIssueAction action)
            {
                switch (action)
                {
                case GitHubEventIssueAction.Opened:
                    AddIssueOrPullRequest(repository, issue);
                    break;

                case GitHubEventIssueAction.Closed:
                case GitHubEventIssueAction.Reopened:
                case GitHubEventIssueAction.Edited:
                case GitHubEventIssueAction.Assigned:
                case GitHubEventIssueAction.Unassigned:
                case GitHubEventIssueAction.Labeled:
                case GitHubEventIssueAction.Unlabeled:
                case GitHubEventIssueAction.Milestoned:
                case GitHubEventIssueAction.Demilestoned:
                case GitHubEventIssueAction.Locked:
                case GitHubEventIssueAction.Unlocked:
                    UpdateIssue(repository, issue);
                    break;

                case GitHubEventIssueAction.Deleted:
                    RemoveIssue(repository, issue);
                    break;

                case GitHubEventIssueAction.Transferred:
                    TransferIssue(repository, issue);
                    break;
                }
            }