public void AddDynamicActionInfo(IButtonContext buttonContex, ICardInfo cardInfo)
        {
            DynamicActionInfo changedAction;

            lock (_cacheLock) {
                var itemExistsAtLocation = _dynamicActionInfoList.FirstOrDefaultWithContext(buttonContex) != null;
                if (itemExistsAtLocation)
                {
                    //make room for the item we are inserting by shifting the index of everything else up
                    foreach (var dynamicActioninfo in _dynamicActionInfoList)
                    {
                        if (dynamicActioninfo.IsAtSameIndexOrAfter(buttonContex))
                        {
                            dynamicActioninfo.Index++;
                        }
                    }
                }

                changedAction = new DynamicActionInfo(buttonContex);
                changedAction.UpdateFromCardInfo(cardInfo);
                _dynamicActionInfoList.Add(changedAction);
            }

            //we only have to change the one action that changed, as the handler is smart enough to refresh everything else around
            PublishChangeEventsForChangedActions(changedAction);
        }
        /// <summary>
        /// Clear the current list of buttons for this card group and replace it with a new list
        /// </summary>
        /// <param name="eventData">Event data containing list of new buttons</param>
        private void CardGroupButtonsChangedHandler(CardGroupButtonsChanged eventData)
        {
            IList <DynamicActionInfo> actionsUpdated = new List <DynamicActionInfo>();

            lock (_cacheLock) {
                var removedActions = _dynamicActionInfoList.Where(x => x.CardGroupId == eventData.CardGroupId).ToList();

                _dynamicActionInfoList.RemoveAll(x => x.CardGroupId == eventData.CardGroupId);

                foreach (var button in eventData.Buttons)
                {
                    var changedAction = new DynamicActionInfo(button);
                    changedAction.UpdateFromCardInfo(button);
                    _dynamicActionInfoList.Add(changedAction);
                    actionsUpdated.Add(changedAction);
                }

                //if we removed in pool buttons that were not replaced, we need to issue an update for them
                foreach (var removedAction in removedActions)
                {
                    if (removedAction.ButtonMode != ButtonMode.Pool)
                    {
                        continue;
                    }

                    if (actionsUpdated.FirstOrDefaultWithContext(removedAction) != default)
                    {
                        continue;
                    }

                    actionsUpdated.Add(new DynamicActionInfo(removedAction));
                }
            }

            PublishChangeEventsForChangedActions(actionsUpdated);
        }
 private void PublishChangeEventsForChangedActions(DynamicActionInfo action)
 {
     PublishChangeEventsForChangedActions(new List <DynamicActionInfo> {
         action
     });
 }