/// <summary>
        /// Using the contents of the unit configs and their templates,
        /// finish the interpretation of the unit configs, resolving any
        /// references inside them including inheritance from the templates, and
        /// create an armory from them.
        /// </summary>
        /// <param name="configs">
        /// The unit configs that will go into the armory.
        /// </param>
        /// <param name="templateConfigs">
        /// Configs that exist to be inherited from and don't turn into units themselves.
        /// </param>
        public Armory(
            Dictionary <string, UnitConfig> configs,
            Dictionary <string, UnitConfig> templateConfigs)
        {
            Categories          = new List <Unit> [(int)UnitCategory._SIZE];
            Units               = new Dictionary <string, Unit>();
            UniqueMobilityTypes = new List <MobilityData>();

            for (int i = 0; i < (int)UnitCategory._SIZE; i++)
            {
                Categories[i] = new List <Unit>();
            }

            FinalizeTemplateConfigs(ref templateConfigs);

            foreach (KeyValuePair <string, UnitConfig> pair in configs)
            {
                UnitConfig unitConfig = pair.Value;
                bool       valid      = unitConfig.ParsingDone(templateConfigs, false);
                if (!valid)
                {
                    continue;
                }

                MobilityData mobility = null;
                foreach (MobilityData m in UniqueMobilityTypes)
                {
                    if (m.Equals(unitConfig.Mobility))
                    {
                        mobility = m;
                        break;
                    }
                }

                if (mobility == null)
                {
                    mobility = new MobilityData(
                        unitConfig.Mobility, UniqueMobilityTypes.Count);
                    UniqueMobilityTypes.Add(mobility);
                }


                int i = (int)Enum.Parse(
                    typeof(UnitCategory), unitConfig.CategoryKey);

                Unit unit = new Unit(unitConfig, mobility)
                {
                    CategoryId = (byte)i,
                    Id         = Categories[i].Count
                };
                Categories[i].Add(unit);

                Units.Add(pair.Key, unit);
            }
        }
        private void FinalizeTemplateConfigs(
            ref Dictionary <string, UnitConfig> templateConfigs)
        {
            // The template configs themselves are allowed to inherit. So,
            // here we need to take extra care in what order we call them (it is
            // unsafe to call ParsingDone() on a child config if its base config
            // has not had ParsingDone() called on it yet).
            // TODO code a neat dependency tree here instead of brute forcing..
            int retries = 10;
            var finalizedTemplateConfigs = new Dictionary <string, UnitConfig>();

            while (templateConfigs.Count > 0)
            {
                List <string> keysToRemove = new List <string>();

                foreach (KeyValuePair <string, UnitConfig> pair in templateConfigs)
                {
                    UnitConfig templateConfig = pair.Value;
                    bool       result         = templateConfig.ParsingDone(finalizedTemplateConfigs, true);
                    if (result)
                    {
                        finalizedTemplateConfigs.Add(pair.Key, pair.Value);
                        keysToRemove.Add(pair.Key);
                    }
                }

                // TODO With .net core 3.0 we will be able
                // to remove from a dictionary while iterating it
                foreach (string key in keysToRemove)
                {
                    templateConfigs.Remove(key);
                }

                retries--;
                if (retries == 0 && templateConfigs.Count > 0)
                {
                    Logger.LogConfig(
                        LogLevel.ERROR,
                        "Could not resolve all template config dependencies. " +
                        "It is possible that there is a circular dependency somewhere. " +
                        "List of unresolved configs: ");
                    foreach (KeyValuePair <string, UnitConfig> pair in templateConfigs)
                    {
                        Logger.LogConfig(
                            LogLevel.ERROR,
                            $"{pair.Key}, with dependencies to {pair.Value.Inherits}");
                    }
                }
            }

            templateConfigs = finalizedTemplateConfigs;
        }