public PatchMechlabLimitItems(MechLabPanel instance)
        {
            try {
                var sw = new Stopwatch();
                sw.Start();
                this.instance        = instance;
                this.inventoryWidget = new Traverse(instance).Field("inventoryWidget")
                                       .GetValue <MechLabInventoryWidget>()
                                       .LogIfNull("inventoryWidget is null");

                LogDebug($"StorageInventory contains {instance.storageInventory.Count}");

                if (instance.IsSimGame)
                {
                    new Traverse(instance).Field("originalStorageInventory").SetValue(instance.storageInventory.LogIfNull("storageInventory is null"));
                }

                LogDebug($"Mechbay Patch initialized :simGame? {instance.IsSimGame}");

                List <ListElementController_BASE_NotListView> BuildRawInventory()
                => instance.storageInventory.Select <MechComponentRef, ListElementController_BASE_NotListView>(componentRef => {
                    componentRef.LogIfNull("componentRef is null");
                    componentRef.DataManager = instance.dataManager.LogIfNull("(MechLabPanel instance).dataManager is null");
                    componentRef.RefreshComponentDef();
                    componentRef.Def.LogIfNull("componentRef.Def is null");
                    var count = (!instance.IsSimGame
                                          ? int.MinValue
                                          : instance.sim.GetItemCount(componentRef.Def.Description, componentRef.Def.GetType(), instance.sim.GetItemCountDamageType(componentRef)));

                    if (componentRef.ComponentDefType == ComponentType.Weapon)
                    {
                        ListElementController_InventoryWeapon_NotListView controller = new ListElementController_InventoryWeapon_NotListView();
                        controller.InitAndFillInSpecificWidget(componentRef, null, instance.dataManager, null, count, false);
                        return(controller);
                    }
                    else
                    {
                        ListElementController_InventoryGear_NotListView controller = new ListElementController_InventoryGear_NotListView();
                        controller.InitAndFillInSpecificWidget(componentRef, null, instance.dataManager, null, count, false);
                        return(controller);
                    }
                }).ToList();

                /* Build a list of data only for all components. */
                rawInventory = Sort(BuildRawInventory());

                InventoryItemElement_NotListView mkiie(bool nonexistant)
                {
                    var nlv = instance.dataManager.PooledInstantiate(ListElementController_BASE_NotListView.INVENTORY_ELEMENT_PREFAB_NotListView
                                                                     , BattleTechResourceType.UIModulePrefabs, null, null, null)
                              .LogIfNull("Unable to instantiate INVENTORY_ELEMENT_PREFAB_NotListView")
                              .GetComponent <InventoryItemElement_NotListView>()
                              .LogIfNull("Inventory_Element_prefab does not contain a NLV");

                    nlv.gameObject.IsDestroyedError("NLV gameObject has been destroyed");
                    nlv.gameObject.LogIfNull("NLV gameObject has been destroyed");
                    if (!nonexistant)
                    {
                        nlv.SetRadioParent(new Traverse(inventoryWidget).Field("inventoryRadioSet").GetValue <HBSRadioSet>().LogIfNull("inventoryRadioSet is null"));
                        nlv.gameObject.transform.SetParent(new Traverse(inventoryWidget).Field("listParent").GetValue <UnityEngine.Transform>().LogIfNull("listParent is null"), false);
                        nlv.gameObject.transform.localScale = UnityEngine.Vector3.one;
                    }
                    return(nlv);
                };

                iieTmp = mkiie(true);

                /* Allocate very few visual elements, as this is extremely slow for both allocation and deallocation.
                 * It's the difference between a couple of milliseconds and several seconds for many unique items in inventory
                 * This is the core of the fix, the rest is just to make it work within HBS's existing code.
                 */
                List <InventoryItemElement_NotListView> make_ielCache()
                => Enumerable.Repeat <Func <InventoryItemElement_NotListView> >(() => mkiie(false), itemLimit)
                .Select(thunk => thunk())
                .ToList();

                ielCache = make_ielCache();

                var li = new Traverse(inventoryWidget).Field("localInventory").GetValue <List <InventoryItemElement_NotListView> >();
                ielCache.ForEach(iw => li.Add(iw));
                // End

                var lp = new Traverse(inventoryWidget).Field("listParent").GetValue <UnityEngine.Transform>();

                // DummyStart&End are blank rects stored at the beginning and end of the list so that unity knows how big the scrollrect should be
                // "placeholders"
                if (DummyStart == null)
                {
                    DummyStart = new UnityEngine.GameObject().AddComponent <UnityEngine.RectTransform>();
                }
                if (DummyEnd == null)
                {
                    DummyEnd = new UnityEngine.GameObject().AddComponent <UnityEngine.RectTransform>();
                }

                DummyStart.SetParent(lp, false);
                DummyEnd.SetParent(lp, false);
                LogDebug(string.Format("[LimitItems] inventory cached in {0} ms", sw.Elapsed.TotalMilliseconds));

                FilterChanged();
            } catch (Exception e) {
                LogException(e);
            }
        }