private static void GuaranteedExecuteInfo(
            IItemContainer container, ItemChangeInfo info)
        {
            // make sure we're in range.
            if (0 > info.Index || info.Index >= container.Provider.Count)
            {
                return;
            }

            // try managed
            if (!container.ExecuteChangeInfo(info))
            {
                // it failed, force it
                container.Provider[info.Index] = info.NewItem;
            }
        }
        public static IEntityHandle PlayerDropItem(this IItemContainer container, int itemIndex, [NotNull] IPlayerComponent player)
        {
            if (player == null)
            {
                throw new ArgumentNullException(nameof(player));
            }

            var item = container.GetItem(itemIndex);

            if (item == null)
            {
                return(null);
            }

            var itemFactory = (IGroundItemFactory)player.Parent.Server.Services.GetService(typeof(IGroundItemFactory));

            if (itemFactory == null)
            {
                return(null);
            }

            var itemEntityHandle = itemFactory.CreatePlayerDrop(item, player, $"Dropped item {item.Id.Name}x{item.Amount}");

            if (itemEntityHandle.IsDead())
            {
                return(null);
            }

            var itemEntity      = itemEntityHandle.Get();
            var itemTransform   = itemEntity.GetTransform();
            var playerTransform = player.Parent.GetTransform();

            itemTransform.SwitchPoE(playerTransform.PoE);
            itemTransform.Teleport(playerTransform);

            container.ExecuteChangeInfo(ItemChangeInfo.Remove(itemIndex));

            return(itemEntityHandle);
        }
        /// <summary>
        /// Executes two ItemChangeInfo's in such a way that change will only occur if the two of them are successful.
        /// </summary>
        /// <returns>True if both infos were executed succesfully, false otherwise.</returns>
        private static bool SafeDoubleInfoExecute(
            IItemContainer managerA, ItemChangeInfo infoA,
            IItemContainer managerB, ItemChangeInfo infoB)
        {
            // cache state of A.
            var idx    = infoA.Index;
            var cacheA = new ItemChangeInfo(idx, managerA.Provider[idx], 0);

            // execute
            if (!managerA.ExecuteChangeInfo(infoA))
            {
                return(false);
            }
            if (!managerB.ExecuteChangeInfo(infoB))
            {
                // A succeeded, B didn't. Revert changes to A.
                GuaranteedExecuteInfo(managerA, cacheA);

                return(false);
            }

            return(true);
        }