/// <summary>
 /// Remove item from NonFull cache.
 /// </summary>
 /// <param name="item"> Item to remove. </param>
 /// <remarks> If the add and update operation runs correctly, there will always be only one or zero non-full stack per kind. </remarks>
 private void RemoveFromNonFull(Thing item)
 {
     if (NonFullThings.TryGetValue(item, out Thing nonFullThings) &&
         nonFullThings == item)
     {
         NonFullThings.Remove(item);
     }
 }
        /// <summary>
        /// Update items in storage.
        /// </summary>
        /// <param name="item"> The updated item. </param>
        /// <summary>
        ///     There could be many reason why the stackCount of an item changes in storage,
        /// e.g., decay, partially taken out for construction of projects. Therefore, it is necessary
        /// to update the NonFullThings here.
        /// </summary>
        public void Update(Thing item)
        {
            // Do not update things that are not already in storage.
            if (!this.ThingCache.TryGetValue(item.def, out Dictionary <Thing, float> things))
            {
                return;
            }

            if (!things.ContainsKey(item))
            {
                return;
            }

            float newWeight   = item.GetStatValue(StatDefOf.Mass) * item.stackCount;
            float oldWeight   = things[item];
            float deltaWeight = newWeight - oldWeight;

            TotalWeight += deltaWeight;
            things[item] = newWeight;

            if (this.NonFullThings.TryGetValue(item, out Thing nonFullThing))
            {
                if (item.stackCount == item.def.stackLimit)
                {
                    if (nonFullThing == item)
                    {
                        NonFullThings.Remove(item);
                    }
                }
                else
                {
                    // Possible states:
                    // 1. Item is the same as the one stored in NonFullThings, no action required.
                    // 2. Item is not the same as the one in NonFullThings.

                    // State 2
                    if (nonFullThing != item)
                    {
                        // TryAbsorbStack() will trigger a re-entry to this method for nonFullThing.
                        // The other branches in this method will take care of the re-entry.
                        if (!nonFullThing.TryAbsorbStack(item, true))
                        {
                            NonFullThings[item] = item;
                        }
                    }
                }
            }
            else
            {
                if (item.stackCount != item.def.stackLimit)
                {
                    this.NonFullThings[item] = item;
                }
            }
        }