public static ItemBase RemoveListItem(ItemBase item, ref List <ItemBase> sourcelist)
        {
            if (item == null)
            {
                return((ItemBase)null);
            }

            List <ItemBase> list = sourcelist.ToList <ItemBase>();

            if (item.IsStack())
            {
                int amount1 = item.GetAmount();
                for (int index = 0; index < list.Count; index++)
                {
                    ItemBase original = list[index];
                    int      amount2  = original.GetAmount();
                    if (original.Compare(item) && amount2 > amount1)
                    {
                        original.DecrementStack(amount1);
                        sourcelist = list;
                        item.SetAmount(0);
                        return(item.NewInstance());
                    }
                    else if (original.Compare(item) && amount2 == amount1)
                    {
                        list.Remove(original);
                        sourcelist = list;
                        item.SetAmount(0);
                        return(item.NewInstance());
                    }
                    else if (original.Compare(item))
                    {
                        item.SetAmount(item.GetAmount() - original.GetAmount());
                        list.Remove(original);
                        sourcelist = list;
                        return(item.NewInstance());
                    }
                }
            }
            else
            {
                for (int index = 0; index < list.Count; index++)
                {
                    ItemBase original = list[index];
                    if (original.Compare(item))
                    {
                        list.Remove(original);
                        sourcelist = list;
                        return(original);
                    }
                }
            }

            sourcelist = list;
            return((ItemBase)null);
        }
        /// <summary>
        ///     Deduct an item from an item list by example
        /// </summary>
        /// <param name="item">The example item to attempt to remove from the list</param>
        /// <param name="sourcelist">The list to take the item from</param>
        /// <param name="returnpartialstack">If true returns partial stack when insufficient stack size found</param>
        /// <returns>The ItemBase object or null if unavailable</returns>
        public static ItemBase RemoveListItem(this ItemBase item, ref List <ItemBase> sourcelist, bool returnpartialstack)
        {
            if (item == null)
            {
                Debug.LogError("RemoveListItem attempted to remove a null item from a list");
                return(null);
            }
            List <ItemBase> workingsource = sourcelist.ToList();

            if (item.IsStack())
            {
                int itemcount = item.GetAmount();
                int listitemcount;

                for (int index = 0; index < workingsource.Count; index++)
                {
                    ItemBase i = workingsource[index];
                    listitemcount = i.GetAmount();
                    if (i.Compare(item) && listitemcount > itemcount)
                    {
                        i.DecrementStack(itemcount);
                        sourcelist = workingsource;
                        return(NewInstance(item));
                    }
                    else if (i.Compare(item) && listitemcount == itemcount)
                    {
                        workingsource.Remove(i);
                        sourcelist = workingsource;
                        return(NewInstance(item));
                    }
                    else if (returnpartialstack)
                    {
                        item.SetAmount(listitemcount);
                        sourcelist = workingsource;
                        return(NewInstance(item));
                    }
                }
            }
            else
            {
                for (int index = 0; index < workingsource.Count; index++)
                {
                    ItemBase i = workingsource[index];
                    if (i.Compare(item))
                    {
                        workingsource.Remove(i);
                        sourcelist = workingsource;
                        return(i);
                    }
                }
            }
            sourcelist = workingsource;
            return(null);
        }
        /// <summary>
        ///     Deduct an item from an item list by example
        /// </summary>
        /// <param name="item">The example item to attempt to remove from the list</param>
        /// <param name="sourcelist">The list to take the item from</param>
        /// <param name="returnpartialstack">If true returns partial stack when insufficient stack size found</param>
        /// <returns>The ItemBase object or null if unavailable</returns>
        public static ItemBase RemoveListItem(this ItemBase item, IEnumerable <ItemBase> sourcelist, bool returnpartialstack)
        {
            List <ItemBase> workingsource = sourcelist.ToList();

            if (item.IsStack())
            {
                int itemcount = item.GetAmount();
                int listitemcount;

                for (int index = 0; index < workingsource.Count; index++)
                {
                    ItemBase i = workingsource[index];
                    listitemcount = i.GetAmount();
                    if (i.Compare(item) && listitemcount > itemcount)
                    {
                        i.DecrementStack(itemcount);
                        sourcelist = workingsource;
                        return(item);
                    }
                    else if (i.Compare(item) && listitemcount == itemcount)
                    {
                        workingsource.Remove(i);
                        sourcelist = workingsource;
                        return(item);
                    }
                    else if (returnpartialstack)
                    {
                        item.SetAmount(listitemcount);
                        sourcelist = workingsource;
                        return(item);
                    }
                }
            }
            else
            {
                for (int index = 0; index < workingsource.Count; index++)
                {
                    ItemBase i = workingsource[index];
                    if (i.Compare(item))
                    {
                        workingsource.Remove(i);
                        sourcelist = workingsource;
                        return(i);
                    }
                }
            }
            sourcelist = workingsource;
            return(null);
        }
        /// <summary>
        ///     Moves specified amount of any items from one list to another obeying target storage capacity.
        /// </summary>
        /// <param name="sourcelist">Source list of items</param>
        /// <param name="targetlist">Target list of items</param>
        /// <param name="amount">Quantity of items to move</param>
        /// <param name="StorageCapacity">Storage capacity of target item list</param>
        /// <param name="takefirstitem">Moves only the first item found</param>
        /// <param name="whiteblacklist">A list of items to server as a whitelist or blacklist for transferring</param>
        /// <param name="iswhitelist">True if whitelist otherwise treat as a blacklist</param>
        public static void MoveItems(IEnumerable <ItemBase> sourcelist, IEnumerable <ItemBase> targetlist, int amount = 1, int StorageCapacity = int.MaxValue, bool takefirstitem = false, IEnumerable <ItemBase> whiteblacklist = null, bool iswhitelist = true)
        {
            int             listcount;
            int             freespace;
            List <ItemBase> workingsource = sourcelist.ToList();
            List <ItemBase> workingtarget = targetlist.ToList();
            List <ItemBase> filter        = new List <ItemBase>();

            if (whiteblacklist != null)
            {
                filter = whiteblacklist.ToList();
            }
            int  filtercount = filter.Count;
            bool matchfound  = false;

            if (amount <= 0)
            {
                return;
            }
            for (int index = 0; index < workingsource.Count; index++)
            {
                listcount = workingsource[index].GetAmount();
                freespace = StorageCapacity - workingtarget.GetItemCount();
                ItemBase i = workingsource[index];

                if (filtercount != 0)
                {
                    for (int index2 = 0; index2 < filtercount; index2++)
                    {
                        ItemBase j = filter[index2];
                        matchfound = (i.Compare(j));
                        if (matchfound)
                        {
                            break;
                        }
                    }
                    //XOR to skip the continue otherwise white/black list violation so go to next item
                    if (matchfound ^ iswhitelist)
                    {
                        continue;
                    }
                }

                if (i.IsStack())
                {
                    if (listcount > amount)
                    {
                        if (amount > freespace)
                        {
                            AddListItem(NewInstance(i).SetAmount(freespace), workingtarget, false);
                            i.DecrementStack(freespace);
                            sourcelist = workingsource;
                            targetlist = workingtarget;
                            return;
                        }
                        else
                        {
                            AddListItem(NewInstance(i).SetAmount(amount), workingtarget, false);
                            i.DecrementStack(amount);
                            sourcelist = workingsource;
                            targetlist = workingtarget;
                            return;
                        }
                    }
                    else if (listcount == amount)
                    {
                        if (amount > freespace)
                        {
                            AddListItem(NewInstance(i).SetAmount(freespace), workingtarget, false);
                            workingsource.Remove(i);
                            sourcelist = workingsource;
                            targetlist = workingtarget;
                            return;
                        }
                        else
                        {
                            AddListItem(NewInstance(i).SetAmount(amount), workingtarget, false);
                            workingsource.Remove(i);
                            sourcelist = workingsource;
                            targetlist = workingtarget;
                            return;
                        }
                    }
                    else
                    {
                        if (listcount > freespace)
                        {
                            AddListItem(NewInstance(i).SetAmount(freespace), workingtarget, false);
                            workingsource.Remove(i);
                            amount -= listcount;
                        }
                        else
                        {
                            AddListItem(NewInstance(i).SetAmount(listcount), workingtarget, false);
                            workingsource.Remove(i);
                            amount -= listcount;
                        }
                    }
                }
                else
                {
                    if (freespace > 0)
                    {
                        AddListItem(NewInstance(i), workingtarget, false);
                        workingsource.Remove(i);
                        amount--;
                    }
                    else
                    {
                        sourcelist = workingsource;
                        targetlist = workingtarget;
                        return;
                    }
                }
                if (takefirstitem)
                {
                    break;
                }
            }
            sourcelist = workingsource;
            targetlist = workingtarget;
        }