/// <summary>
        /// Pipe to the next filter(s)
        /// </summary>
        /// <param name="item">the item to filter and pipe</param>
        public void Pipe(T item)
        {
            if (ParallelExecution)
            {
                foreach (var filterAndPipe in FilterList)
                {
                    ExecutePipe(filterAndPipe, item);
                }

                ExecuteFilter(item);
            }
            else
            {
                ExecuteFilter(item);

                foreach (var filterAndPipe in FilterList)
                {
                    ExecutePipe(filterAndPipe, item);
                }
            }

            FilterCompleteEventArgs eventArgs = new FilterCompleteEventArgs(Name);

            FilterCompleted?.Invoke(this, eventArgs);
        }
        private void ExecuteFilter(T item)
        {
            try
            {
                Filter(item);
                FilterCompleteEventArgs eventArgs = new FilterCompleteEventArgs(Name);
                eventArgs.Message += $"Complete";

                FilterCompleted?.Invoke(this, eventArgs);
            }
            catch (Exception e)
            {
                FilterExceptionEventArgs eventArgs = new FilterExceptionEventArgs(Name)
                {
                    Exception = e
                };

                FilterExceptionEncountered?.Invoke(this, eventArgs);
            }
        }
 private void NextFilter_FilterCompleted(object sender, EventArgs e)
 {
     FilterCompleted?.Invoke(this, e);
 }