private void calculateStats()
        {
            foreach (Player player in log.getPlayerList())
            {
                Statistics.FinalStats[] phaseStats = new Statistics.FinalStats[phases.Count];
                for (int phaseIndex = 0; phaseIndex < phases.Count; phaseIndex++)
                {
                    Statistics.FinalStats final = new Statistics.FinalStats();

                    PhaseData phase = phases[phaseIndex];
                    long      start = phase.getStart() + log.getBossData().getFirstAware();
                    long      end   = phase.getEnd() + log.getBossData().getFirstAware();

                    List <DamageLog> damageLogs     = player.getDamageLogs(0, log, phase.getStart(), phase.getEnd());
                    List <DamageLog> damageLogsBoss = player.getDamageLogs(log.getBoss().getInstid(), log, phase.getStart(), phase.getEnd());
                    List <CastLog>   castLogs       = player.getCastLogs(log, phase.getStart(), phase.getEnd());

                    int instid = player.getInstid();

                    final.powerLoopCount = 0;
                    final.criticalRate   = 0;
                    final.criticalDmg    = 0;
                    final.scholarRate    = 0;
                    final.scholarDmg     = 0;
                    final.movingRate     = 0;
                    final.flankingRate   = 0;
                    final.glanceRate     = 0;
                    final.missed         = 0;
                    final.interupts      = 0;
                    final.invulned       = 0;
                    final.wasted         = 0;
                    final.timeWasted     = 0;
                    final.saved          = 0;
                    final.timeSaved      = 0;

                    final.powerLoopCountBoss = 0;
                    final.criticalRateBoss   = 0;
                    final.criticalDmgBoss    = 0;
                    final.scholarRateBoss    = 0;
                    final.scholarDmgBoss     = 0;
                    final.movingRateBoss     = 0;
                    final.flankingRateBoss   = 0;
                    final.glanceRateBoss     = 0;
                    final.missedBoss         = 0;
                    final.interuptsBoss      = 0;
                    final.invulnedBoss       = 0;

                    foreach (DamageLog log in damageLogs)
                    {
                        if (log.isCondi() == 0)
                        {
                            if (log.getResult() == ParseEnum.Result.Crit)
                            {
                                final.criticalRate++;
                                final.criticalDmg += log.getDamage();
                            }

                            if (log.isNinety() > 0)
                            {
                                final.scholarRate++;
                                final.scholarDmg += (int)(log.getDamage() / 11.0); //regular+10% damage
                            }

                            final.movingRate   += log.isMoving();
                            final.flankingRate += log.isFlanking();

                            if (log.getResult() == ParseEnum.Result.Glance)
                            {
                                final.glanceRate++;
                            }

                            if (log.getResult() == ParseEnum.Result.Blind)
                            {
                                final.missed++;
                            }

                            if (log.getResult() == ParseEnum.Result.Interrupt)
                            {
                                final.interupts++;
                            }

                            if (log.getResult() == ParseEnum.Result.Absorb)
                            {
                                final.invulned++;
                            }
                            final.powerLoopCount++;
                        }
                    }
                    foreach (DamageLog log in damageLogsBoss)
                    {
                        if (log.isCondi() == 0)
                        {
                            if (log.getResult() == ParseEnum.Result.Crit)
                            {
                                final.criticalRateBoss++;
                                final.criticalDmgBoss += log.getDamage();
                            }

                            if (log.isNinety() > 0)
                            {
                                final.scholarRateBoss++;
                                final.scholarDmgBoss += (int)(log.getDamage() / 11.0); //regular+10% damage
                            }

                            final.movingRateBoss   += log.isMoving();
                            final.flankingRateBoss += log.isFlanking();

                            if (log.getResult() == ParseEnum.Result.Glance)
                            {
                                final.glanceRateBoss++;
                            }

                            if (log.getResult() == ParseEnum.Result.Blind)
                            {
                                final.missedBoss++;
                            }

                            if (log.getResult() == ParseEnum.Result.Interrupt)
                            {
                                final.interuptsBoss++;
                            }

                            if (log.getResult() == ParseEnum.Result.Absorb)
                            {
                                final.invulnedBoss++;
                            }
                            final.powerLoopCountBoss++;
                        }
                    }
                    foreach (CastLog cl in castLogs)
                    {
                        if (cl.endActivation() == ParseEnum.Activation.CancelCancel)
                        {
                            final.wasted++;
                            final.timeWasted += cl.getActDur();
                        }
                        if (cl.endActivation() == ParseEnum.Activation.CancelFire)
                        {
                            final.saved++;
                            if (cl.getActDur() < cl.getExpDur())
                            {
                                final.timeSaved += cl.getExpDur() - cl.getActDur();
                            }
                        }
                    }

                    final.timeSaved  = final.timeSaved / 1000f;
                    final.timeWasted = final.timeWasted / 1000f;

                    final.totalDmg       = damageLogs.Sum(x => x.getDamage());
                    final.powerLoopCount = final.powerLoopCount == 0 ? 1 : final.powerLoopCount;

                    final.totalDmgBoss       = damageLogsBoss.Sum(x => x.getDamage());
                    final.powerLoopCountBoss = final.powerLoopCountBoss == 0 ? 1 : final.powerLoopCountBoss;

                    // Counts
                    CombatData combatData = log.getCombatData();
                    final.swapCount  = combatData.getStates(instid, ParseEnum.StateChange.WeaponSwap, start, end).Count();
                    final.downCount  = combatData.getStates(instid, ParseEnum.StateChange.ChangeDown, start, end).Count();
                    final.dodgeCount = combatData.getSkillCount(instid, 65001, start, end) + combatData.getBuffCount(instid, 40408, start, end); //dodge = 65001 mirage cloak =40408
                    final.ressCount  = combatData.getSkillCount(instid, 1066, start, end);                                                       //Res = 1066

                    // R.I.P
                    List <CombatItem> dead = combatData.getStates(instid, ParseEnum.StateChange.ChangeDead, start, end);
                    final.died = 0.0;
                    if (dead.Count() > 0)
                    {
                        final.died = dead[0].getTime() - start;
                    }

                    List <CombatItem> disconect = combatData.getStates(instid, ParseEnum.StateChange.Despawn, start, end);
                    final.dcd = 0.0;
                    if (disconect.Count() > 0)
                    {
                        final.dcd = disconect[0].getTime() - start;
                    }

                    phaseStats[phaseIndex] = final;
                }
                statistics.stats[player] = phaseStats;
            }
        }