public void Remove(T item)
        {
            //Before a change is about to happen we have to check if any subscriber wants to reject the change
            var beforeRemove = new RejectableEventArgs_Subclass <T>(Operation.Remove, item, internalStorage.Count);

            OnBeforeChange(beforeRemove);

            // If the wanted item to remove is not on the list then throw InvalidOperationExeption
            if (Contains(item))
            {
                //If change is rejected then throw OperationRejectedExeption
                if (beforeRemove.IsOperationRejected == false)
                {
                    internalStorage.Remove(item);
                    OnChanged(this, new ListChangedEventArgs <T>(Operation.Remove, item, internalStorage.Count));
                }
                else
                {
                    throw new OperationRejectedException("You can not remove this item!");
                }
            }
            else
            {
                throw new InvalidOperationException("This item is not on the list!");
            }
        }
        /// <summary>
        /// Instead of using the real add method, this methods allows you to explore what you are able to add and not, without handling exceptions.
        /// </summary>
        /// <param name="item"></param>
        /// <returns>bool</returns>
        public bool TryAdd(T item)
        {
            var tryAdd = new RejectableEventArgs_Subclass <T>(Operation.Add, item, internalStorage.Count);

            OnBeforeChange(tryAdd);

            if (tryAdd.IsOperationRejected == false)
            {
                internalStorage.Add(item);
                return(true);
            }
            else
            {
                return(false);
            }
        }
        //Methods to manipulate the internal storage
        public void Add(T item)
        {
            //Before a change is about to happen we have to check if any subscriber wants to reject the change
            var beforeAdd = new RejectableEventArgs_Subclass <T>(Operation.Add, item, internalStorage.Count);

            OnBeforeChange(beforeAdd);

            //Check if any subscriber rejected the change, if not, go on and make the change
            if (beforeAdd.IsOperationRejected == false)
            {
                internalStorage.Add(item);
                OnChanged(this, new ListChangedEventArgs <T>(Operation.Add, item, internalStorage.Count));
            }
            else
            {
                throw new OperationRejectedException("You can not add this item!");
            }
        }
        /// <summary>
        /// Instead of using the real remove method, this methods allows you to explore what you are able to remove and not, without handling exeptions.
        /// </summary>
        /// <param name="item"></param>
        /// <returns>bool</returns>
        public bool TryRemove(T item)
        {
            var tryRemove = new RejectableEventArgs_Subclass <T>(Operation.Remove, item, internalStorage.Count);

            OnBeforeChange(tryRemove);

            if (Contains(item))
            {
                if (tryRemove.IsOperationRejected == false)
                {
                    internalStorage.Remove(item);
                    return(true);
                }
                else
                {
                    return(false);
                }
            }
            else
            {
                return(false);
            }
        }
 protected virtual void OnBeforeChange(RejectableEventArgs_Subclass <T> args)
 {
     BeforeChange?.Invoke(this, args);
 }