public async Task <IActionResult> Report(string bundleId, string dumpId)
        {
            ViewData["Message"] = "Get Report";
            var id = DumpIdentifier.Create(bundleId, dumpId);

            var bundleInfo = superDumpRepo.GetBundle(bundleId);

            if (bundleInfo == null)
            {
                logger.LogNotFound("Report: Bundle not found", HttpContext, "BundleId", bundleId);
                return(View(null));
            }

            var dumpInfo = superDumpRepo.GetDump(id);

            if (dumpInfo == null)
            {
                logger.LogNotFound("Report: Dump not found", HttpContext, "Id", id.ToString());
                return(View(null));
            }

            logger.LogDumpAccess("Report", HttpContext, bundleInfo, dumpId);

            string   sdReadError = string.Empty;
            SDResult res         = null;

            try {
                res = await superDumpRepo.GetResultAndThrow(id);
            } catch (Exception e) {
                sdReadError = e.ToString();
            }

            // don't add relationships when the repo is not ready yet. it might take some time with large amounts.
            IEnumerable <KeyValuePair <DumpMetainfo, double> > similarDumps =
                !relationshipRepo.IsPopulated ? Enumerable.Empty <KeyValuePair <DumpMetainfo, double> >() :
                (await relationshipRepo.GetRelationShips(DumpIdentifier.Create(bundleId, dumpId)))
                .Select(x => new KeyValuePair <DumpMetainfo, double>(dumpRepo.Get(x.Key), x.Value)).Where(dump => dump.Key != null);

            return(base.View("Report", new ReportViewModel(id)
            {
                BundleFileName = bundleInfo.BundleFileName,
                DumpFileName = dumpInfo.DumpFileName,
                Result = res,
                CustomProperties = Utility.Sanitize(bundleInfo.CustomProperties),
                TimeStamp = dumpInfo.Created,
                Files = dumpRepo.GetFileNames(id),
                AnalysisError = dumpInfo.ErrorMessage,
                ThreadTags = res != null ? res.GetThreadTags() : new HashSet <SDTag>(),
                PointerSize = res == null ? 8 : (res.SystemContext?.ProcessArchitecture == "X86" ? 8 : 12),
                CustomTextResult = await ReadCustomTextResult(dumpInfo),
                SDResultReadError = sdReadError,
                DumpType = dumpInfo.DumpType,
                RepositoryUrl = settings.RepositoryUrl,
                InteractiveGdbHost = settings.InteractiveGdbHost,
                SimilarityDetectionEnabled = settings.SimilarityDetectionEnabled,
                Similarities = similarDumps,
                MainBundleJiraIssues = !settings.UseJiraIntegration || !jiraIssueRepository.IsPopulated ? Enumerable.Empty <JiraIssueModel>() : await jiraIssueRepository.GetAllIssuesByBundleIdWithoutWait(bundleId),
                SimilarDumpIssues = !settings.UseJiraIntegration || !jiraIssueRepository.IsPopulated ? new Dictionary <string, IEnumerable <JiraIssueModel> >() : await jiraIssueRepository.GetAllIssuesByBundleIdsWithoutWait(similarDumps.Select(dump => dump.Key.BundleId)),
                UseJiraIntegration = settings.UseJiraIntegration,
                DumpStatus = dumpInfo.Status,
                IsRelationshipsPopulated = relationshipRepo.IsPopulated || !settings.SimilarityDetectionEnabled,
                IsJiraIssuesPopulated = jiraIssueRepository.IsPopulated || !settings.UseJiraIntegration,
                UseAutomaticDumpDeletion = settings.IsDumpRetentionEnabled(),
                DumpRetentionExtensionDays = settings.DumpRetentionExtensionDays,
                RetentionViewModel = new RetentionViewModel(
                    dumpInfo,
                    dumpRepo.IsPrimaryDumpAvailable(id),
                    TimeSpan.FromDays(settings.WarnBeforeDeletionInDays),
                    settings.UseJiraIntegration && jiraIssueRepository.IsPopulated && jiraIssueRepository.HasBundleOpenIssues(bundleId))
            }));
        }
        public async Task TestJiraIssueRepository()
        {
            // setup dependencies
            var settings = Options.Create(new SuperDumpSettings {
                UseJiraIntegration      = true,
                JiraIntegrationSettings = new JiraIntegrationSettings {
                }
            });
            var pathHelper    = new PathHelper("", "", "");
            var dumpStorage   = new FakeDumpStorage(CreateFakeDumps());
            var bundleStorage = dumpStorage;
            var dumpRepo      = new DumpRepository(dumpStorage, pathHelper);
            var bundleRepo    = new BundleRepository(bundleStorage, dumpRepo);

            var jiraApiService   = new FakeJiraApiService();
            var jiraIssueStorage = new FakeJiraIssueStorage();

            var identicalDumpStorage    = new FakeIdenticalDumpStorage();
            var identicalDumpRepository = new IdenticalDumpRepository(identicalDumpStorage, bundleRepo);

            var loggerFactory = new LoggerFactory();

            var jiraIssueRepository = new JiraIssueRepository(settings, jiraApiService, bundleRepo, jiraIssueStorage, identicalDumpRepository, loggerFactory);

            // population
            await jiraIssueStorage.Store("bundle1", new List <JiraIssueModel> {
                new JiraIssueModel("JRA-1111")
            });

            await jiraIssueStorage.Store("bundle2", new List <JiraIssueModel> {
                new JiraIssueModel("JRA-2222"), new JiraIssueModel("JRA-3333")
            });

            await jiraIssueStorage.Store("bundle9", new List <JiraIssueModel> {
                new JiraIssueModel("JRA-9999")
            });

            await bundleRepo.Populate();

            await jiraIssueRepository.Populate();

            // actual test

            Assert.Collection(jiraIssueRepository.GetIssues("bundle1"),
                              item => Assert.Equal("JRA-1111", item.Key));

            Assert.Collection(jiraIssueRepository.GetIssues("bundle2"),
                              item => Assert.Equal("JRA-2222", item.Key),
                              item => Assert.Equal("JRA-3333", item.Key));

            Assert.Collection(jiraIssueRepository.GetIssues("bundle9"),
                              item => Assert.Equal("JRA-9999", item.Key));

            Assert.Empty(jiraIssueRepository.GetIssues("bundle3"));

            // fake, that in jira some bundles have been referenced in new issues
            jiraApiService.SetFakeJiraIssues("bundle1", new JiraIssueModel[] { new JiraIssueModel("JRA-1111") });                                 // same
            jiraApiService.SetFakeJiraIssues("bundle2", new JiraIssueModel[] { new JiraIssueModel("JRA-2222"), new JiraIssueModel("JRA-4444") }); // one added, one removed
            jiraApiService.SetFakeJiraIssues("bundle3", new JiraIssueModel[] { new JiraIssueModel("JRA-1111"), new JiraIssueModel("JRA-5555") }); // new
            jiraApiService.SetFakeJiraIssues("bundle9", null);                                                                                    // removed jira issues

            await jiraIssueRepository.SearchBundleIssuesAsync(bundleRepo.GetAll(), true);

            Assert.Collection(jiraIssueRepository.GetIssues("bundle1"),
                              item => Assert.Equal("JRA-1111", item.Key));

            Assert.Collection(jiraIssueRepository.GetIssues("bundle2"),
                              item => Assert.Equal("JRA-2222", item.Key),
                              item => Assert.Equal("JRA-4444", item.Key));

            Assert.Collection(jiraIssueRepository.GetIssues("bundle3"),
                              item => Assert.Equal("JRA-1111", item.Key),
                              item => Assert.Equal("JRA-5555", item.Key));

            Assert.Empty(jiraIssueRepository.GetIssues("bundle9"));

            var res = await jiraIssueRepository.GetAllIssuesByBundleIdsWithoutWait(new string[] { "bundle1", "bundle2", "bundle7", "bundle666", "bundle9" });

            Assert.Equal(2, res.Count());

            Assert.Collection(res["bundle1"],
                              item => Assert.Equal("JRA-1111", item.Key));

            Assert.Collection(res["bundle2"],
                              item => Assert.Equal("JRA-2222", item.Key),
                              item => Assert.Equal("JRA-4444", item.Key));


            Assert.Empty(jiraIssueRepository.GetIssues("bundle7"));
            Assert.Empty(jiraIssueRepository.GetIssues("bundle666"));
            Assert.Empty(jiraIssueRepository.GetIssues("bundle9"));
        }