private static void ApplySkinModifications(GameObject modelObject, AppliedModifications modifications)
        {
            var characterModel = modelObject.GetComponent <CharacterModel>();

            LastModelObject = modelObject;
            //////////////////////////////////////////////////////////////////////////////////////
            ///
            foreach (var mod in ModificationList)
            {
                ApplyModification(modelObject, characterModel, mod, modifications);
            }
            ///
            //////////////////////////////////////////////////////////////////////////////////////
        }
        private static void ApplySkinModifications(GameObject modelObject, AppliedModifications modifications)
        {
            var characterModel = modelObject.GetComponent <CharacterModel>();

            LastModelObject = modelObject;
            //////////////////////////////////////////////////////////////////////////////////////
            /// TODO: create a loop that iterates through the list of modifications and applies them
            foreach (var mod in ModificationList)
            {
                ApplyModification(modelObject, characterModel, mod, modifications);
            }
            ///
            //////////////////////////////////////////////////////////////////////////////////////
        }
        private static void ClearSkinModifications(GameObject modelObject, AppliedModifications modifications)
        {
            //NOTE: modifications that modify the base bone list need to have their bones removed first before destruction
            //Modifications that modify the base bone list have to be removed in reverse order in order to maintain correct indexing

            //Clear Mods that modify base bone list, these need to be done in reverse order
            while (modifications.BaseModelModifications.Count != 0)
            {
                var mod = modifications.BaseModelModifications.Pop();

                clearModification(mod, modelObject, modifications);
            }

            //clear rest of mods
            while (modifications.OtherModifications.Count != 0)
            {
                clearModification(modifications.OtherModifications[0], modelObject, modifications); //clearmodification calls remove on applied Mod.
            }
            //remove the object from modified once all mods are cleared
            ModifiedObjects.Remove(modelObject);
        }
        ////////////////////////////////////////////////////////////////////////////
        ////// Local Functions (these should not need to be changed when added to different skins)

        //private static void SkinDefApply(On.RoR2.SkinDef.orig_Apply orig, SkinDef self, GameObject modelObject) //Old SkinDefApply for use w/ mmhook
        private static void SkinDefApply(Action <SkinDef, GameObject> orig, SkinDef self, GameObject modelObject)
        {
            orig(self, modelObject);

            RemoveInvalidModelObjects();

            ModifiedObjects.TryGetValue(modelObject, out var modificatons);

            try
            {
                //if we are on another character/skin
                if (self != SkinDef)
                {
                    if (modificatons != null)
                    {
                        ClearSkinModifications(LastModelObject, modificatons);
                    }
                    return;
                }

                if (modificatons == null)
                {
                    //otherwise if are now applying modded skin and no modifcations have been made, then apply modifications

                    //create new Applied Entry and pass into Apply
                    AppliedModifications NewMods = new AppliedModifications();
                    ModifiedObjects.Add(modelObject, NewMods);
                    ApplySkinModifications(modelObject, NewMods);
                }
            }
            catch (Exception e)
            {
                //error logging may need to be skin specific
                InstanceLogger.LogWarning("An error occured while adding accessories to a skin");
                InstanceLogger.LogError(e);
            }

            //print heiarchy
            //RuneFoxMods.Utils.readheiarchy(modelObject);
        }
        private static void clearModification(Modification modification, GameObject modelObject, AppliedModifications modifications)
        {
            //Destroy Dynamic Bones colliders
            if (modification.inst_DB_colliders != null)
            {
                foreach (var collider in modification.inst_DB_colliders)
                {
                    Destroy(collider);
                }
            }

            //Remove Additions to Bone Arrays
            if (modification.affectsbasemodel)
            {
                var renderers = GetBaseSkinRenderers(modelObject);
                var oldBones  = renderers[0].bones.ToList();

                oldBones.RemoveRange(modification.boneIndex, modification.boneCount);

                foreach (var renderer in renderers)
                {
                    renderer.bones = oldBones.ToArray();
                }
            }

            //Destroy Dynamic Bones Component (Probably don't have to do this since it will be destroyed along with PrefabInstance if parented to it)
            Destroy(modifications.OtherModifications[0].inst_dynamicBone);
            //Destroy Armature
            Destroy(modifications.OtherModifications[0].inst_armature);
            //Destroy Prefab Instance
            Destroy(modifications.OtherModifications[0].instance);

            bool removed = modifications.OtherModifications.Remove(modification);

            if (!removed)
            {
                InstanceLogger.LogError("Skin Modification was not removed");
            }
        }
        ////// Local Functions
        ////////////////////////////////////////////////////////////////////////////


        /// <summary>
        ///
        /// </summary>
        /// <param name="modelObject">GameObject of ModelObject</param>
        /// <param name="modifications">List for Storing Modifctions</param>
        /// <param name="characterModel">Character Model of ModelObject</param>
        /// <param name="modification">Modification to be apllied</param>
        private static void ApplyModification(GameObject modelObject, CharacterModel characterModel, Modification modification, AppliedModifications modifications)
        {
            //Get aramture bone that new prefab will be parented to
            var bodyname   = modification.bodyname;
            var parentname = modification.parentname;

            var parentBone = RuneFoxMods.Utils.FindChildInTree(modelObject.transform, parentname);
            //var parentBone = modelObject.transform.Find(RuneFoxMods.ChildHelper.GetPath(bodyname, parentname));

            GameObject newPart;

            //we have to instantiate the prefabs in two different ways based on if they affect the model or not

            if (modification.affectsbasemodel)
            {
                //instantiate the model
                newPart                    = GameObject.Instantiate(modification.prefab, parentBone, false);
                newPart.name               = RuneFoxMods.Utils.RemoveCloneNaming(newPart.name);
                modification.instance      = newPart;
                modification.inst_armature = newPart; //the armature of the modifications that affect the base mode is the whole prefab

                ///////////////////////////////////////////////////////////
                /// Add Bones to Base Armature here
                var skinRenderers = GetBaseSkinRenderers(modelObject);

                var newBones = skinRenderers[0].bones.ToList();//assumption is that we find a skinrenderer here, if not then whoops

                var newBoneIndex = FindBoneIndex2(parentBone, newBones);
                //insert new bones into array at end of array
                var modBoneArray = BoneArrayBuilder(modification.instance.transform);
                newBones.InsertRange(newBoneIndex, modBoneArray);

                //add index and bonecount to modification
                modification.boneIndex = newBoneIndex;
                modification.boneCount = modBoneArray.Length;

                //assign bones to skin renderers
                foreach (var renderer in skinRenderers)
                {
                    renderer.bones = newBones.ToArray();
                }

                modifications.BaseModelModifications.Push(modification);

                /// Add Bones to Base Armature here
                ///////////////////////////////////////////////////////////
            }
            else
            {
                //instantiate it w/ model as parent
                newPart               = GameObject.Instantiate(modification.prefab, modelObject.transform, false);
                newPart.name          = RuneFoxMods.Utils.RemoveCloneNaming(newPart.name);
                modification.instance = newPart;

                var armature = GetArmature(newPart);

                //if (armature == null)
                //  Debug.Log("Armature not found");
                //else
                //  Debug.Log("armature found: " + armature.name);

                //then parent the armature to the parentboned
                armature.transform.SetParent(parentBone, false);
                modification.inst_armature = armature.gameObject;
            }
            modification.instance = newPart;

            //TODO: add a way to load multiple DynamicBone Scripts for a single modification



            ///////////////////////////////////////////////////////////
            /// Add dynamic bones stuff here
            /// Things like DynamicBones Component, assigning values to dynamic bones component, adding DB_Colliders and editing them, etc.

            if (modification.dynamicBoneData != null)
            {
                //======================================
                //Add Dynamic Bone Component
                DynamicBone DB = modification.instance.AddComponent <DynamicBone>();
                modification.inst_dynamicBone = DB;

                //======================================
                /// Add DynamicBones Colliders to other armature bones (Need to do this before Modifying Dynamic Bones component as we add them to the DB list during modification)
                List <DynamicBoneCollider> bonelist = new List <DynamicBoneCollider>();

                foreach (var colliderData in modification.dynamicBoneData.m_Colliders)
                {
                    var parent = RuneFoxMods.Utils.FindChildInTree(modelObject.transform, colliderData.m_parent_name);
                    //var parent = modelObject.transform.Find(RuneFoxMods.ChildHelper.GetPath(bodyname, colliderData.m_parent_name));

                    var bonecollider = parent.gameObject.AddComponent <DynamicBoneCollider>();

                    bonecollider.m_Direction = colliderData.m_Direction;
                    bonecollider.m_Center    = colliderData.m_Center;
                    bonecollider.m_Bound     = colliderData.m_Bound;
                    bonecollider.m_Radius    = colliderData.m_Radius;
                    bonecollider.m_Height    = colliderData.m_Height;

                    bonelist.Add(bonecollider);
                }

                modification.inst_DB_colliders = bonelist;

                //======================================
                // Modify DynamicBones Component with data

                var root = RuneFoxMods.Utils.FindChildInTree(modification.inst_armature.transform, modification.dynamicBoneData.m_Root);

                DB.m_Root              = root;
                DB.m_Damping           = modification.dynamicBoneData.m_Damping;
                DB.m_DampingDistrib    = modification.dynamicBoneData.m_DampingDistrib;
                DB.m_Elasticity        = modification.dynamicBoneData.m_Elasticity;
                DB.m_ElasticityDistrib = modification.dynamicBoneData.m_ElasticityDistrib;
                DB.m_Stiffness         = modification.dynamicBoneData.m_Stiffness;
                DB.m_StiffnessDistrib  = modification.dynamicBoneData.m_StiffnessDistrib;
                DB.m_Inert             = modification.dynamicBoneData.m_Inert;
                DB.m_InertDistrib      = modification.dynamicBoneData.m_InertDistrib;
                DB.m_Radius            = modification.dynamicBoneData.m_Radius;
                DB.m_RadiusDistrib     = modification.dynamicBoneData.m_RadiusDistrib;
                DB.m_EndLength         = modification.dynamicBoneData.m_EndLength;
                DB.m_EndOffset         = modification.dynamicBoneData.m_EndOffset;
                DB.m_Gravity           = modification.dynamicBoneData.m_Gravity;
                DB.m_Force             = modification.dynamicBoneData.m_Force;

                DB.m_Colliders  = bonelist;
                DB.m_Exclusions = new List <Transform>();
                foreach (var exclude in modification.dynamicBoneData.m_Exclusions)
                {
                    //NOTE: Assumption here is that the dynamic bone root is part of the new armature and we are only excluding bones located in root
                    var transform = RuneFoxMods.Utils.FindChildInTree(root, exclude);

                    if (transform != null)
                    {
                        DB.m_Exclusions.Add(transform);
                    }
                    else
                    {
                        Debug.Log("Tried to exclude a transform that could not be found");
                    }
                }


                DB.m_FreezeAxis = modification.dynamicBoneData.m_FreezeAxis;

                //TODO: Read DB and compare it to what's made in OG mod cause skirt is behaving oddly
            }

            /// Add dynamic bones stuff here
            ///////////////////////////////////////////////////////////

            ///////////////////////////////////////////////////////////
            /// Add renderers to the character's renderer list

            //get renderers
            var renderers = newPart.GetComponentsInChildren <SkinnedMeshRenderer>(true);

            //resize render array to account for new renderers
            Array.Resize(ref characterModel.baseRendererInfos, characterModel.baseRendererInfos.Length + renderers.Length);

            //NOTE: Need to save the number of renderers added to the character render info so we can remove them cleanly. Probably add this to modifications
            if (renderers.Length != 0)
            {
                int i = renderers.Length;
                foreach (var renderer in renderers)
                {
                    //2 to add - 3 in
                    //resize array to 5
                    //first is added at 5-2 (3) which is position 4
                    //second is added at 5-1 (4) which is position 5
                    //exits

                    characterModel.baseRendererInfos[characterModel.baseRendererInfos.Length - i] = new CharacterModel.RendererInfo
                    {
                        renderer                 = renderers[renderers.Length - i],
                        ignoreOverlays           = false,
                        defaultShadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.On,
                        defaultMaterial          = renderer.sharedMaterial
                    };

                    i--; //decrement i to reach the next renederer
                }
            }
            /// Add renderers to the character's renderer list
            ///////////////////////////////////////////////////////////

            //Push to applied modifications when done
            modifications.OtherModifications.Add(modification);
        }