public void Refresh(bool wantClobber = true)
        {
            LogDebug(string.Format("[LimitItems] Refresh: {0} {1} {2} {3}", index, filteredInventory.Count, itemLimit, inventoryWidget.scrollbarArea.verticalNormalizedPosition));
            if (index > filteredInventory.Count - itemsOnScreen)
            {
                index = filteredInventory.Count - itemsOnScreen;
            }
            if (filteredInventory.Count < itemsOnScreen)
            {
                index = 0;
            }
            if (index < 0)
            {
                index = 0;
            }
            if (Spam)
            {
                LogSpam(string.Format("[LimitItems] Refresh(F): {0} {1} {2} {3}", index, filteredInventory.Count, itemLimit, inventoryWidget.scrollbarArea.verticalNormalizedPosition));
            }

            Func <ListElementController_BASE_NotListView, string> pp = lec => {
                return(string.Format("[id:{0},damage:{1},quantity:{2},id:{3}]"
                                     , GetRef(lec).ComponentDefID
                                     , GetRef(lec).DamageLevel
                                     , lec.quantity
                                     , lec.GetId()));
            };

            var iw_corrupted_add = inventoryWidget.localInventory.Where(x => !ielCache.Contains(x)).ToList();

            if (iw_corrupted_add.Count > 0)
            {
                LogError("inventoryWidget has been corrupted, items were added directly: " + string.Join(", ", iw_corrupted_add.Select(c => c.controller).Select(pp).ToArray()));
            }
            var iw_corrupted_remove = ielCache.Where(x => !inventoryWidget.localInventory.Contains(x)).ToList();

            if (iw_corrupted_remove.Count > 0)
            {
                LogError("inventoryWidget has been corrupted, iel elements were removed.");
            }

            if (iw_corrupted_add.Any() || iw_corrupted_remove.Any())
            {
                LogWarning("Restoring to last good state. Duplication or item loss may occur.");
                inventoryWidget.localInventory = ielCache.ToArray().ToList();
            }

            var toShow = filteredInventory.Skip(index).Take(itemLimit).ToList();

            var icc = ielCache.ToList();



            if (Spam)
            {
                LogSpam("[LimitItems] Showing: " + string.Join(", ", toShow.Select(pp).ToArray()));
            }

            var details = new List <string>();

            toShow.ForEach(lec => {
                var iw   = icc[0]; icc.RemoveAt(0);
                var cref = GetRef(lec);
                iw.ClearEverything();
                iw.ComponentRef = cref;
                lec.ItemWidget  = iw;
                iw.SetData(lec, inventoryWidget, lec.quantity, false, null);
                lec.SetupLook(iw);
                iw.gameObject.SetActive(true);
                details.Insert(0, string.Format("enabled {0} {1}", iw.ComponentRef.ComponentDefID, iw.GetComponent <UnityEngine.RectTransform>().anchoredPosition));
            });
            icc.ForEach(unused => unused.gameObject.SetActive(false));

            var listElemSize = 64.0f;
            var spacerTotal  = 16.0f; // IEL elements are 64 tall, but have a total of 80 pixels between each when considering spacing.
            var spacerHalf   = spacerTotal * .5f;
            var tsize        = listElemSize + spacerTotal;

            var virtualStartSize = tsize * index - spacerHalf;

            DummyStart.gameObject.SetActive(index > 0); //If nothing prefixing, must disable to prevent halfspacer offset.
            DummyStart.sizeDelta = new UnityEngine.Vector2(100, virtualStartSize);
            DummyStart.SetAsFirstSibling();

            var itemsHanging = filteredInventory.Count - (index + ielCache.Count(ii => ii.gameObject.activeSelf));

            var ap1 = ielCache[0].GetComponent <UnityEngine.RectTransform>().anchoredPosition;
            var ap2 = ielCache[1].GetComponent <UnityEngine.RectTransform>().anchoredPosition;

            LogDebug(string.Format("[LimitItems] Items prefixing {0} hanging {1} total {2} {3}/{4}", index, itemsHanging, filteredInventory.Count, ap1, ap2));



            var virtualEndSize = tsize * itemsHanging - spacerHalf;

            DummyEnd.gameObject.SetActive(itemsHanging > 0); //If nothing postfixing, must disable to prevent halfspacer offset.
            DummyEnd.sizeDelta = new UnityEngine.Vector2(100, virtualEndSize);
            DummyEnd.SetAsLastSibling();

            instance.RefreshInventorySelectability();
            if (Spam)
            {
                var sr = inventoryWidget.scrollbarArea;
                LogSpam(string.Format("[LimitItems] RefreshDone dummystart {0} dummyend {1} vnp {2} lli {3}"
                                      , DummyStart.anchoredPosition.y
                                      , DummyEnd.anchoredPosition.y
                                      , sr.verticalNormalizedPosition
                                      , "(" + string.Join(", ", details.ToArray()) + ")"
                                      ));
            }
        }