public async Task <XDocument> GenerateResults(MutationTestingSession session,
                                                      bool includeDetailedTestResults, bool includeCodeDifferenceListings,
                                                      ProgressCounter progress, CancellationToken token)
        {
            _log.Info("Generating session results to file.");

            int multiplier = 1;

            if (includeDetailedTestResults)
            {
                multiplier++;
            }
            if (includeCodeDifferenceListings)
            {
                multiplier++;
            }

            List <Mutant> mutants = session.MutantsGrouped.Cast <CheckedNode>()
                                    .SelectManyRecursive(n => n.Children ?? new NotifyingCollection <CheckedNode>(),
                                                         leafsOnly: true).OfType <Mutant>().ToList();
            List <Mutant> mutantsWithErrors = mutants.Where(m => m.State == MutantResultState.Error).ToList();
            List <Mutant> testedMutants     = mutants.Where(m => m.MutantTestSession.IsComplete).ToList();
            List <Mutant> live = testedMutants.Where(m => m.State == MutantResultState.Live).ToList();
            //AKB
            List <Mutant> markedAsEquivalentAmongLive = mutants.Where(m => m.IsEquivalent).ToList();
            List <Mutant> unpairedFOMs = mutants.Where(m => m.Id.IndexOf("First Order Mutant") != -1).ToList();

            progress.Initialize(mutants.Count * multiplier);

            var mutantsNode = new XElement("Mutants",
                                           new XAttribute("Total", mutants.Count),
                                           new XAttribute("Live", live.Count),
                                           //AKB
                                           new XAttribute("MarkedAsEquivalentAmongLive", markedAsEquivalentAmongLive.Count),
                                           new XAttribute("UnpairedFirstOrderMutants", unpairedFOMs.Count),
                                           new XAttribute("Killed", testedMutants.Count - live.Count),
                                           new XAttribute("Untested", mutants.Count - testedMutants.Count),
                                           new XAttribute("WithError", mutantsWithErrors.Count),
                                           new XAttribute("AverageCreationTimeMiliseconds", testedMutants
                                                          .AverageOrZero(mut => mut.CreationTimeMilis)),
                                           new XAttribute("AverageTestingTimeMiliseconds", testedMutants
                                                          .AverageOrZero(mut => mut.MutantTestSession.TestingTimeMiliseconds)),
                                           from assemblyNode in session.MutantsGrouped
                                           select new XElement("Assembly",

                                                               new XAttribute("Name", assemblyNode.Name),

                                                               from type in assemblyNode.Children.SelectManyRecursive(
                                                                   n => n.Children ?? new NotifyingCollection <CheckedNode>())
                                                               .OfType <TypeNode>()
                                                               select new XElement("Type",
                                                                                   new XAttribute("Name", type.Name),
                                                                                   new XAttribute("Namespace", type.Namespace),
                                                                                   from method in type.Children.Cast <MethodNode>()//TODO: what if nested type?
                                                                                   select new XElement("Method",
                                                                                                       new XAttribute("Name", method.Name),
                                                                                                       from mutant in method.Children.SelectManyRecursive(
                                                                                                           n => n.Children ?? new NotifyingCollection <CheckedNode>()).OfType <Mutant>()
                                                                                                       select new XElement("Mutant",
                                                                                                                           new XAttribute("Id", mutant.Id),
                                                                                                                           new XAttribute("Description", mutant.Description),
                                                                                                                           new XAttribute("State", mutant.State),
                                                                                                                           new XAttribute("IsEquivalent", mutant.IsEquivalent),
                                                                                                                           new XAttribute("CreationTimeMiliseconds", mutant.CreationTimeMilis),
                                                                                                                           new XAttribute("TestingTimeMiliseconds", mutant.MutantTestSession.TestingTimeMiliseconds),
                                                                                                                           new XAttribute("TestingEndRelativeSeconds", (mutant.MutantTestSession.TestingEnd - _sessionController.SessionStartTime).TotalSeconds),
                                                                                                                           new XElement("ErrorInfo",
                                                                                                                                        new XElement("Description", mutant.MutantTestSession.ErrorDescription),
                                                                                                                                        new XElement("ExceptionMessage", mutant.MutantTestSession.ErrorMessage)
                                                                                                                                        ).InArrayIf(mutant.State == MutantResultState.Error)
                                                                                                                           )

                                                                                                       )
                                                                                   )
                                                               )
                                           );

            var optionalElements = new List <XElement>();

            if (includeCodeDifferenceListings)
            {
                var res = await CreateCodeDifferenceListings(mutants, progress, token);

                optionalElements.Add(res);
            }

            if (includeDetailedTestResults)
            {
                var res = await Task.Run(() => CreateDetailedTestingResults(mutants, progress, token));

                optionalElements.Add(res);
            }

            return
                (new XDocument(
                     new XElement("MutationTestingSession",
                                  new XAttribute("SessionCreationWindowShowTime", _choices.SessionCreationWindowShowTime),
                                  new XAttribute("SessionStartTime", _sessionController.SessionStartTime),
                                  new XAttribute("SessionEndTime", _sessionController.SessionEndTime),
                                  new XAttribute("SessionRunTimeSeconds", (_sessionController.SessionEndTime
                                                                           - _sessionController.SessionStartTime).TotalSeconds),
                                  new XAttribute("MutationScore", ((int)(session.MutationScore * 100)).ToString()),
                                  mutantsNode,
                                  optionalElements)));
        }
        public async Task<XDocument> GenerateResults(MutationTestingSession session, 
            bool includeDetailedTestResults, bool includeCodeDifferenceListings, 
            ProgressCounter progress, CancellationToken token)
        {
            _log.Info("Generating session results to file.");


      
            int multiplier = 1;
            if (includeDetailedTestResults)
            {
                multiplier++;
            }
            if (includeCodeDifferenceListings)
            {
                multiplier++;
            }

            

            List<Mutant> mutants = session.MutantsGrouped.Cast<CheckedNode>()
                .SelectManyRecursive(n => n.Children ?? new NotifyingCollection<CheckedNode>(),
                leafsOnly:true).OfType<Mutant>().ToList();
            List<Mutant> mutantsWithErrors = mutants.Where(m => m.State == MutantResultState.Error).ToList();
            List<Mutant> testedMutants = mutants.Where(m => m.MutantTestSession.IsComplete).ToList();
            List<Mutant> live = testedMutants.Where(m => m.State == MutantResultState.Live).ToList();

            progress.Initialize(mutants.Count * multiplier);

            

            var mutantsNode = new XElement("Mutants",
                new XAttribute("Total", mutants.Count),
                new XAttribute("Live", live.Count),
                new XAttribute("Killed", testedMutants.Count - live.Count),
                new XAttribute("Untested", mutants.Count - testedMutants.Count),
                new XAttribute("WithError", mutantsWithErrors.Count),
                new XAttribute("AverageCreationTimeMiliseconds", testedMutants
                    .AverageOrZero(mut => mut.CreationTimeMilis)),
                new XAttribute("AverageTestingTimeMiliseconds", testedMutants
                    .AverageOrZero(mut => mut.MutantTestSession.TestingTimeMiliseconds)),
                from assemblyNode in session.MutantsGrouped
                select new XElement("Assembly",

                    new XAttribute("Name", assemblyNode.Name),

                    from type in assemblyNode.Children.SelectManyRecursive(
                        n => n.Children?? new NotifyingCollection<CheckedNode>())
                        .OfType<TypeNode>()
                    select new XElement("Type",
                        new XAttribute("Name", type.Name),
                        new XAttribute("Namespace", type.Namespace),
                            from method in type.Children.Cast<MethodNode>()//TODO: what if nested type?
                            select new XElement("Method",
                            new XAttribute("Name", method.Name),
                            from mutant in method.Children.SelectManyRecursive(
                                n=>n.Children ?? new NotifyingCollection<CheckedNode>()).OfType<Mutant>()
                            select new XElement("Mutant",
                                new XAttribute("Id", mutant.Id),
                                new XAttribute("Description", mutant.Description),
                                new XAttribute("State", mutant.State),
                                new XAttribute("IsEquivalent", mutant.IsEquivalent),
                                new XAttribute("CreationTimeMiliseconds", mutant.CreationTimeMilis),
                                new XAttribute("TestingTimeMiliseconds", mutant.MutantTestSession.TestingTimeMiliseconds),
                                new XAttribute("TestingEndRelativeSeconds", (mutant.MutantTestSession.TestingEnd - _sessionController.SessionStartTime).TotalSeconds),
                                new XElement("ErrorInfo",
                                        new XElement("Description", mutant.MutantTestSession.ErrorDescription),
                                        new XElement("ExceptionMessage", mutant.MutantTestSession.ErrorMessage)
                                ).InArrayIf(mutant.State == MutantResultState.Error)
                            )
                            
                        )
                    )
                )
            );


            var optionalElements = new List<XElement>();

            if (includeCodeDifferenceListings)
            {
                var res = await CreateCodeDifferenceListings(mutants, progress, token);
                optionalElements.Add(res);
            }

            if (includeDetailedTestResults)
            {
                var res = await Task.Run(() => CreateDetailedTestingResults(mutants, progress, token));
                optionalElements.Add(res);
            }

            return
                new XDocument(
                    new XElement("MutationTestingSession",
                        new XAttribute("SessionCreationWindowShowTime", _choices.SessionCreationWindowShowTime),
                        new XAttribute("SessionStartTime", _sessionController.SessionStartTime),
                        new XAttribute("SessionEndTime", _sessionController.SessionEndTime),
                        new XAttribute("SessionRunTimeSeconds", (_sessionController.SessionEndTime
                        - _sessionController.SessionStartTime).TotalSeconds),
                        new XAttribute("MutationScore", ((int)(session.MutationScore*100)).ToString()),
                        mutantsNode,
                        optionalElements));
            
        }