public static IEnumerable <MorphDef> GetAllMorphsInClass([NotNull] this AnimalClassBase classDef)
        {
            if (classDef == null)
            {
                throw new ArgumentNullException(nameof(classDef));
            }

            if (_morphsUnderCache.TryGetValue(classDef, out List <MorphDef> morphs))
            {
                return(morphs);
            }
            morphs = new List <MorphDef>();

            if (classDef is MorphDef morph)
            {
                morphs.Add(morph);
                _morphsUnderCache[classDef] = morphs;
                return(morphs);
            }

            IEnumerable <AnimalClassBase> preorder = TreeUtilities.Preorder(classDef, c => c.Children);

            foreach (MorphDef morphDef in preorder.OfType <MorphDef>())
            {
                morphs.Add(morphDef);
            }
            _morphsUnderCache[classDef] = morphs;
            return(morphs);
        }
        static AnimalClassUtilities()
        {
            foreach (AnimalClassDef animalClassDef in DefDatabase <AnimalClassDef> .AllDefs)
            {
                animalClassDef.FindChildren(); //have to do this after all other def's 'ResolveReferences' have been called
            }
            foreach (AnimalClassDef animalClassDef in DefDatabase <AnimalClassDef> .AllDefs)
            {
                if (animalClassDef.parent != null)
                {
                    continue;
                }
                if (animalClassDef != AnimalClassDefOf.Animal)
                {
                    Log.Warning($"{animalClassDef.defName} does not have a parent! only {nameof(AnimalClassDefOf.Animal)} should not have a parent!");
                }
            }


            if (CheckForCycles()) //don't precede if there are any cycles in the tree
            {
                throw
                    new InvalidDataException("detected cycles in animal class tree!"); //not sure what we should throw here, but we can't continue with
            }
            //cycles in the class tree


            //save the pre and post order traversal orders for performance reasons
            PostorderTreeInternal = TreeUtilities.Postorder <AnimalClassBase>(AnimalClassDefOf.Animal, c => c.Children);
            PreorderTreeInternal  = TreeUtilities.Preorder <AnimalClassBase>(AnimalClassDefOf.Animal, c => c.Children).ToList();


            string treeStr =
                TreeUtilities.PrettyPrintTree <AnimalClassBase>(AnimalClassDefOf.Animal, a => a.Children, a => ((Def)a).defName);

            Log.Message(treeStr); //print a pretty tree c:
        }