private void clbTalents_ItemCheck(object sender, ItemCheckEventArgs e)
        {
            if(sorting)
            {
                return;
            }

            string talentName = clbTalents.SelectedItem.ToString();
            if(talentName.Length > TALENT_DESC_SPACING)
            {
                talentName = talentName.Substring(0, TALENT_DESC_SPACING).Trim();
            }

            //Custom talents
            if(customTalents.Contains(talentName))
            {
                if(e.NewValue == CheckState.Checked)
                {
                    character.customTalents.Add(talentName);
                    ++talentsTaken;
                }
                else
                {
                    character.customTalents.Remove(talentName);
                    --talentsTaken;
                }
            }
            //Built in talents
            else
            {
                if(e.NewValue == CheckState.Checked)
                {
                    character.talents.Add(talentName);

                    //Check if the talent modifies anything (attributes, skills, etc)
                    if(modifyingTalents.Contains(talentName))
                    {
                        ModifiedScore modified = new ModifiedScore();
                        modified.modifiedBy = talentName;
                        modified.modifiedScore = null;
                        modified.userMarks = false;

                        SelectionDialog selection;
                        DialogResult result;

                        switch(talentName)
                        {
                            case "Adaptive Skin":
                            case "Iron Resolve":
                            case "Power Word":
                            case "Power Word II":
                            case "Power Word III":
                                modified.userMarks = true;
                                break;
                            case "Basic Training":
                                modified.userMarks = true;

                                //Have the user select a skill
                                selection = new SelectionDialog(clbSkills.Items, "Select a Skill");
                                result = selection.ShowDialog();

                                if (result == DialogResult.OK)
                                {
                                    modified.modifiedScore = selection.GetSelectedItem();
                                }
                                else
                                {
                                    e.NewValue = e.CurrentValue;
                                    return;
                                }

                                break;
                            case "Skill Specialization": //+3 to any skill
                                //Have the user select a skill
                                selection = new SelectionDialog(clbSkills.Items, "Select a Skill");
                                result = selection.ShowDialog();

                                if(result == DialogResult.OK)
                                {
                                    modified.modifiedScore = selection.GetSelectedItem();
                                }
                                else
                                {
                                    e.NewValue = e.CurrentValue;
                                    return;
                                }

                                break;
                            case "Student of Magic": //additional abilities with requirements met
                                //Figure out which abilities the user can take
                                List<string> validAbilities = new List<string>();

                                DataSet ds = PerformQuery(abilitiesConnection,
                                    "SELECT prereq, ability_name FROM Abilities", "Abilities");
                                DataTable table = ds.Tables["Abilities"];

                                foreach(DataRow row in table.Rows)
                                {
                                    if(row[0] == null || !CheckAbilityHomebrew(row[0].ToString(), row[1].ToString()))
                                    {
                                        validAbilities.Add(row[1].ToString());
                                    }
                                }

                                foreach(CustomAbility customAbility in customAbilities)
                                {
                                    validAbilities.Add(customAbility.name);
                                }

                                //Have the user select the ability they want
                                selection = new SelectionDialog(validAbilities, "Select an Ability");
                                result = selection.ShowDialog();

                                if(result == DialogResult.OK)
                                {
                                    modified.modifiedScore = selection.GetSelectedItem();
                                    clbAbilities.SelectedItem = modified.modifiedScore;
                                    clbAbilities.SetItemChecked(clbAbilities.SelectedIndex, true);

                                    switch(GetAbilitySchool(selection.GetSelectedItem()))
                                    {
                                        case "Alteration":
                                            ++somAlteration;
                                            break;
                                        case "Creation":
                                            ++somCreation;
                                            break;
                                        case "Destruction":
                                            ++somDestruction;
                                            break;
                                        case "Restoration":
                                            ++somRestoration;
                                            break;
                                    }
                                }
                                else
                                {
                                    e.NewValue = e.CurrentValue;
                                    return;
                                }

                                UpdateAbilitiesRemainingLabels();

                                break;
                        }

                        modifiedScores.Add(modified);
                    } //endif for checking for modifying from talents

                    //Check if the talent can be taken multiple times
                    if (multipleTimesTalents.Contains(talentName))
                    {
                        //Add the talent to the list so it can be taken again
                        clbTalents.Items.Add(clbTalents.SelectedItem.ToString());
                        SortCheckedListBox(clbTalents);
                        clbTalents.SelectedIndex = e.Index + 1;
                    }

                    ++talentsTaken;
                } //endif new value == checked
                else
                {
                    character.talents.Remove(talentName);

                    //Check if the talent modifies anything (attributes, skills, etc)
                    if (modifyingTalents.Contains(talentName))
                    {
                        DialogResult result;

                        switch (talentName)
                        {
                            case "Basic Training":
                            case "Skill Specialization":
                                List<string> modifiedSkills = new List<string>();

                                //Find the skills that were modified
                                foreach (ModifiedScore mod in modifiedScores)
                                {
                                    if (mod.modifiedBy.Equals(talentName))
                                    {
                                        modifiedSkills.Add(mod.modifiedScore);
                                    }
                                }

                                SelectionDialog skillSelector = new SelectionDialog(modifiedSkills, "Which skill to remove from?");
                                result = skillSelector.ShowDialog();

                                if(result == DialogResult.OK)
                                {
                                    for(int n = 0; n < modifiedScores.Count; ++n)
                                    {
                                        if(modifiedScores[n].modifiedScore.Equals(skillSelector.GetSelectedItem()) &&
                                            modifiedScores[n].modifiedBy.Equals(talentName))
                                        {
                                            modifiedScores.RemoveAt(n);
                                            break;
                                        }
                                    }
                                }
                                else
                                {
                                    e.NewValue = e.CurrentValue;
                                    return;
                                }

                                break;
                            case "Student of Magic": //additional ability with requirements met
                                List<string> modifiedAbilities = new List<string>();

                                //Find the abilities that were added with Student of Magic
                                foreach(ModifiedScore mod in modifiedScores)
                                {
                                    if(mod.modifiedBy.Equals("Student of Magic"))
                                    {
                                        modifiedAbilities.Add(mod.modifiedScore);
                                    }
                                }

                                SelectionDialog abilitySelector = new SelectionDialog(modifiedAbilities, "Which ability to remove?");
                                result = abilitySelector.ShowDialog();

                                if(result == DialogResult.OK)
                                {
                                    //Remove the ability from the list of modified abilities
                                    for(int n = 0; n > modifiedScores.Count; ++n)
                                    {
                                        if(modifiedScores[n].modifiedScore.Equals(abilitySelector.GetSelectedItem()))
                                        {
                                            modifiedScores.RemoveAt(n);
                                            break;
                                        }
                                    }

                                    clbAbilities.SelectedItem = abilitySelector.GetSelectedItem();
                                    clbAbilities.SetItemChecked(clbAbilities.SelectedIndex, false);

                                    switch (GetAbilitySchool(abilitySelector.GetSelectedItem()))
                                    {
                                        case "Alteration":
                                            --somAlteration;
                                            break;
                                        case "Creation":
                                            --somCreation;
                                            break;
                                        case "Destruction":
                                            --somDestruction;
                                            break;
                                        case "Restoration":
                                            --somRestoration;
                                            break;
                                    }
                                }
                                else
                                {
                                    e.NewValue = e.CurrentValue;
                                    return;
                                }

                                UpdateAbilitiesRemainingLabels();

                                break;
                            default:
                                for(int n = 0; n < modifiedScores.Count; ++n)
                                {
                                    if(modifiedScores[n].modifiedBy.Equals(talentName))
                                    {
                                        modifiedScores.RemoveAt(n);
                                        break;
                                    }
                                }

                                break;
                        } //end switch

                        UpdateInformation();
                    }

                    //Check if the talent can be taken multiple times
                    if(multipleTimesTalents.Contains(talentName))
                    {
                        clbTalents.Items.RemoveAt(e.Index);
                    }

                    --talentsTaken;
                }
            }

            //Show how many talents over/under the homebrew limit the user is
            int talentsRemaining = talentsAvailable - talentsTaken;

            if(talentsRemaining < 0)
            {
                lblTalentsRemaining.Text = Math.Abs(talentsRemaining)
                    + " talent(s) over limit";
                lblTalentsRemaining.ForeColor = Color.Red;
            }
            else
            {
                lblTalentsRemaining.Text = talentsRemaining + " talent(s) remaining";
                lblTalentsRemaining.ForeColor = Color.Black;
            }

            UpdateInformation();

            CheckHomebrew();

            if (!chkAllTalents.Checked)
            {
                object selectedItem = clbTalents.SelectedItem;

                //Refresh the display in case the character now qualifies for new talents (or doesn't qualify for others)
                DisplayEligibleTalents();
                txtTalentsSearch_TextChanged(null, null); //This method is called so it preserves any search made by the user

                clbTalents.SelectedItem = selectedItem;
            }
        }
        private void clbAbilities_ItemCheck(object sender, ItemCheckEventArgs e)
        {
            if(sorting)
            {
                return;
            }

            string abilityName = clbAbilities.Items[e.Index].ToString();
            //Remove the school display from the ability name if necessary
            if(abilityName.Length > ABILITY_SPACING)
            {
                abilityName = abilityName.Substring(0, ABILITY_SPACING);
            }

            abilityName = abilityName.Trim();

            if(IsCustomAbility(abilityName))
            {
                 if(e.NewValue == CheckState.Unchecked)
                 {
                     character.customAbilities.Remove(abilityName);
                 }
                 else
                 {
                     character.customAbilities.Add(abilityName);
                 }
            }
            else
            {
                string school = GetAbilitySchool(abilityName);

                if (e.NewValue == CheckState.Unchecked)
                {
                    //If the ability is a meta ability, use the chosen school. Otherwise use the school for the ability
                    //as listed in the database
                    switch (school.Equals("Meta") ? character.metaAbilities[abilityName] : school)
                    {
                        case "Alteration":
                            --alterationTaken;
                            break;
                        case "Creation":
                            --creationTaken;
                            break;
                        case "Destruction":
                            --destructionTaken;
                            break;
                        case "Restoration":
                            --restorationTaken;
                            break;
                    }

                    character.abilities.Remove(abilityName);
                    character.metaAbilities[abilityName] = null;
                }
                else
                {
                    if (school.Equals("Meta"))
                    {
                        List<string> schools = new List<string>();
                        schools.Add("Alteration");
                        schools.Add("Creation");
                        schools.Add("Destruction");
                        schools.Add("Restoration");

                        //Have the user select which school to use for the meta ability
                        SelectionDialog schoolSelector = new SelectionDialog(schools, "Select a school to use");
                        DialogResult result = schoolSelector.ShowDialog();

                        if(result == DialogResult.OK)
                        {
                            character.metaAbilities[abilityName] = schoolSelector.GetSelectedItem();
                        }
                        else
                        {
                            e.NewValue = e.CurrentValue;
                            return;
                        }
                    }

                    //If the ability is a meta ability, use the chosen school. Otherwise use the school for the ability
                    //as listed in the database
                    switch (school.Equals("Meta") ? character.metaAbilities[abilityName] : school)
                    {
                        case "Alteration":
                            ++alterationTaken;
                            break;
                        case "Creation":
                            ++creationTaken;
                            break;
                        case "Destruction":
                            ++destructionTaken;
                            break;
                        case "Restoration":
                            ++restorationTaken;
                            break;
                    }

                    character.abilities.Add(abilityName);
                }
            }

            UpdateAbilitiesRemainingLabels();

            if(!chkAllAbilities.Checked)
            {
                object selectedItem = clbAbilities.SelectedItem;

                //Refresh the display in case the character now qualifies for new abilities (or doesn't qualify for others)
                DisplayEligibleAbilities();
                txtAbilitiesSearch_TextChanged(null, null); //This method is called so it preserves any search made by the user

                clbAbilities.SelectedItem = selectedItem;
            }

            CheckHomebrew();
        }