private void GenerateMonsters()
        {
            Mouse.OverrideCursor = Cursors.Wait;

            int minTotalMonsterXP = 0;
            int maxTotalMonsterXP = 0;

            foreach (EncounterCharacterModel character in _encounterCharacters)
            {
                int baseThreshold = _statService.BaseXPThresholds[1];
                if (_statService.BaseXPThresholds.ContainsKey(character.Level))
                {
                    baseThreshold = _statService.BaseXPThresholds[character.Level];
                }

                if (_selectedDifficultyOption.Key == EncounterChallenge.Easy)
                {
                    maxTotalMonsterXP += (2 * baseThreshold);
                }
                else if (_selectedDifficultyOption.Key == EncounterChallenge.Medium)
                {
                    minTotalMonsterXP += (2 * baseThreshold);
                    maxTotalMonsterXP += (3 * baseThreshold);
                }
                else if (_selectedDifficultyOption.Key == EncounterChallenge.Hard)
                {
                    minTotalMonsterXP += (3 * baseThreshold);
                    maxTotalMonsterXP += (4 * baseThreshold);
                }
                else if (_selectedDifficultyOption.Key == EncounterChallenge.Deadly)
                {
                    minTotalMonsterXP += (4 * baseThreshold);
                    maxTotalMonsterXP += (5 * baseThreshold);
                }
                else if (_selectedDifficultyOption.Key == EncounterChallenge.TPK)
                {
                    minTotalMonsterXP += (5 * baseThreshold);
                    maxTotalMonsterXP += (20 * baseThreshold);
                }
            }

            int attempts = 0;
            List <EncounterMonsterModel> monsters = new List <EncounterMonsterModel>();

            while (attempts++ < 50)
            {
                int    totalMonsterXP         = 0;
                int    totalMonsters          = 0;
                int    adjustedTotalMonsterXP = 0;
                string selectedEnvironment    = _selectedEnvironmentOption.Key != null?_selectedEnvironmentOption.Key.ToLower() : null;

                foreach (MonsterModel monsterModel in _compendium.Monsters.OrderBy(x => Guid.NewGuid()))
                {
                    if (selectedEnvironment == null || (monsterModel.Environment != null && monsterModel.Environment.ToLower().Contains(selectedEnvironment)))
                    {
                        int maxMonsterXP = Math.Min(maxTotalMonsterXP / _minMonsters, maxTotalMonsterXP - adjustedTotalMonsterXP);

                        if (maxMonsterXP < 25 ||
                            totalMonsters >= _maxMonsters ||
                            adjustedTotalMonsterXP > minTotalMonsterXP)
                        {
                            break;
                        }

                        int monsterXP = _statService.GetMonsterXP(monsterModel);

                        if (monsterXP > 0 && monsterXP <= maxMonsterXP)
                        {
                            EncounterMonsterModel encounterMonsterModel = new EncounterMonsterModel();
                            encounterMonsterModel.MonsterModel = monsterModel;

                            int maxQuantity     = 0;
                            int potentialAdjust = (int)(_statService.GetXPMultiplier(totalMonsters + 1) * (float)(totalMonsterXP + monsterXP));
                            while (potentialAdjust < maxTotalMonsterXP)
                            {
                                potentialAdjust = (int)(_statService.GetXPMultiplier(totalMonsters + ++maxQuantity + 1) * (float)(totalMonsterXP + (monsterXP * (maxQuantity + 1))));
                            }

                            maxQuantity = Math.Min(maxQuantity, _maxMonsters - monsters.Count);

                            if (maxQuantity > 0)
                            {
                                encounterMonsterModel.Quantity = new Random((int)DateTime.Now.Ticks).Next(1, maxQuantity);
                                monsters.Add(encounterMonsterModel);

                                totalMonsters  += encounterMonsterModel.Quantity;
                                totalMonsterXP += (monsterXP * encounterMonsterModel.Quantity);

                                adjustedTotalMonsterXP = (int)(_statService.GetXPMultiplier(totalMonsters) * (float)totalMonsterXP);
                            }
                        }
                    }
                }

                if (_statService.EstimateEncounterChallenge(_encounterCharacters, monsters) == _selectedDifficultyOption.Key)
                {
                    break;
                }
                else
                {
                    monsters.Clear();
                }
            }

            Mouse.OverrideCursor = null;

            if (monsters.Count > 0)
            {
                _monsters.Clear();
                foreach (EncounterMonsterModel encounterMonster in monsters.OrderBy(x => x.Name))
                {
                    _monsters.Add(new EncounterMonsterViewModel(encounterMonster));
                }
            }
            else
            {
                _dialogService.ShowConfirmationDialog("Encounter Creation Failed", "Unable to generate an encounter using the selected criteria.", "OK", null, null);
            }
        }