public static void CalcAll()
            {
                TotalEnhancements = 0;
                EnhObtained       = 0;
                EnhCatalysts      = 0;
                EnhBoosters       = 0;

                foreach (var p in MidsContext.Character.CurrentBuild.Powers)
                {
                    for (var j = 0; j < p.Slots.Length; j++)
                    {
                        var enhIdx = p.Slots[j].Enhancement.Enh;

                        if (enhIdx > -1)
                        {
                            TotalEnhancements++;
                        }
                        if (p.Slots[j].Enhancement.Obtained & enhIdx > -1)
                        {
                            EnhObtained++;
                        }
                        if (enhIdx == -1)
                        {
                            continue;
                        }

                        var enhName = Database.Instance.Enhancements[enhIdx].UID;
                        if (DatabaseAPI.EnhHasCatalyst(enhName) && DatabaseAPI.EnhIsSuperior(enhIdx))
                        {
                            EnhCatalysts++;
                        }

                        var relativeLevel = p.Slots[j].Enhancement.RelativeLevel;
                        if (DatabaseAPI.EnhIsIO(enhIdx))
                        {
                            EnhBoosters += relativeLevel switch
                            {
                                Enums.eEnhRelative.PlusOne => 1,
                                Enums.eEnhRelative.PlusTwo => 2,
                                Enums.eEnhRelative.PlusThree => 3,
                                Enums.eEnhRelative.PlusFour => 4,
                                Enums.eEnhRelative.PlusFive => 5,
                                _ => 0
                            };
                        }
                    }
                }
            }
            public static void CalcEnhCatalysts()
            {
                EnhCatalysts = 0;
                for (var i = 0; i < MidsContext.Character.CurrentBuild.Powers.Count; i++)
                {
                    for (var j = 0; j < MidsContext.Character.CurrentBuild.Powers[i].Slots.Length; i++)
                    {
                        var enhIdx = MidsContext.Character.CurrentBuild.Powers[i].Slots[j].Enhancement.Enh;
                        if (enhIdx == -1)
                        {
                            continue;
                        }
                        var enhName = Database.Instance.Enhancements[enhIdx].UID;

                        if (DatabaseAPI.EnhHasCatalyst(enhName) && DatabaseAPI.EnhIsSuperior(enhIdx))
                        {
                            EnhCatalysts++;
                        }
                    }
                }
            }
        public List <PowerEntry>?Parse()
        {
            Regex r;
            Match m;
            Regex r1;
            Regex r2;
            Regex r3;
            Match m1;
            Match m2;
            Match m3;

            string rawPowerset;
            var    p = new RawPowerData {
                Valid = false
            };
            var        powerSlots = new List <RawEnhData>();
            RawEnhData e;

            var listPowers = new List <PowerEntry>();

            string[] powerIDChunks;

            r1 = new Regex(@"^Level ([0-9]+)\: (.+)$");                                 // Picked power
            r2 = new Regex(@"^[\t\s]*EMPTY$");                                          // Empty enhancement slot
            r3 = new Regex(@"^[\t\s]*([0-9a-zA-Z\+\:\-_]+) \(([0-9]+)(\+([1-5]))?\)$"); // Filled enhancement slot

            var    line = -1;
            string lineText;

            using var streamReader = new StreamReader(BuildString);
            while ((lineText = streamReader.ReadLine()) != null)
            {
                line++;

                if (line == 0)
                {
                    // Name, Level, Origin, ClassID
                    r = new Regex(@"^([^\:]+)\: Level ([0-9]+) ([a-zA-Z]+) ([a-zA-Z_]+)$");
                    m = r.Match(lineText);
                    if (!m.Success)
                    {
                        MessageBox.Show("This build cannot be imported because it doesn't match the expected format.",
                                        "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                        return(null);
                    }

                    CharacterInfo.Name      = m.Groups[1].Value;
                    CharacterInfo.Archetype = m.Groups[4].Value.Replace("Class_", string.Empty);
                    CharacterInfo.Origin    = m.Groups[3].Value;
                    CharacterInfo.Level     = Convert.ToInt32(m.Groups[2].Value, null);

                    SetCharacterInfo();
                }
                else if (line < HeaderSize)
                {
                    continue;
                }

                m1 = r1.Match(lineText);
                m2 = r2.Match(lineText);
                m3 = r3.Match(lineText);

                if (m1.Success)
                {
                    if (p.Valid)
                    {
                        AddPowerToBuildSheet(p, ref listPowers);
                    }

                    powerIDChunks = m1.Groups[2].Value.Split(' ');
                    rawPowerset   = (powerIDChunks[0] + "." + powerIDChunks[1]).Trim();
                    p.FullName    = m1.Groups[2].Value.Replace(" ", ".");
                    p.Powerset    = DatabaseAPI.GetPowersetByName(rawPowerset);
                    p.pData       = DatabaseAPI.GetPowerByFullName(p.FullName);
                    if (p.pData == null)
                    {
                        p.FullName    = FixKheldPowerNames(p.FullName);
                        powerIDChunks = p.FullName.Split('.');
                        rawPowerset   = (powerIDChunks[0] + "." + powerIDChunks[1]).Trim();
                        p.Powerset    = DatabaseAPI.GetPowersetByName(rawPowerset);
                        p.pData       = DatabaseAPI.GetPowerByFullName(p.FullName);
                    }

                    p.Valid = CheckValid(p.pData);
                    p.Level = Convert.ToInt32(m1.Groups[1].Value, null);
                    p.Slots = new List <RawEnhData>();
                    if (CheckValid(p.Powerset))
                    {
                        PowerSets.Add(p.Powerset.FullName);
                    }
                }
                else if (m2.Success)
                {
                    // Empty slot
                    e = new RawEnhData
                    {
                        InternalName = "Empty",
                        Level        = 0,
                        Boosters     = 0,
                        HasCatalyst  = false,
                        eData        = -1
                    };
                    p.Slots.Add(e);
                }
                else if (m3.Success)
                {
                    // Enhancement: internal name, level, (dummy), boosters
                    e = new RawEnhData();
                    e.InternalName = DatabaseAPI.GetEnhancementBaseUIDName(m3.Groups[1].Value);
                    e.Level        = Convert.ToInt32(m3.Groups[2].Value, null);
                    e.Boosters     = (m3.Groups.Count > 3) & !string.IsNullOrWhiteSpace(m3.Groups[4].Value)
                        ? Convert.ToInt32(m3.Groups[4].Value, null)
                        : 0;
                    e.HasCatalyst = DatabaseAPI.EnhHasCatalyst(m3.Groups[1].Value);
                    e.eData       = DatabaseAPI.GetEnhancementByUIDName(e.InternalName);

                    p.Slots.Add(e);
                }
            }

            streamReader.Close();
            if (p.Valid)
            {
                AddPowerToBuildSheet(p, ref listPowers);
            }

            return(listPowers);
        }