/// <summary>
        /// Context-preserving variant of <see cref="SourceOperations.Collect{T,TOut,TMat}"/>
        /// </summary>
        public static SourceWithContext <TCtx, TOut2, TMat> Collect <TCtx, TOut, TOut2, TMat>(
            this SourceWithContext <TCtx, TOut, TMat> flow, Func <TOut, TOut2> fn) where TOut2 : class
        {
            var stage = new Collect <(TOut, TCtx), (TOut2, TCtx)>(func: x =>
            {
                var result = fn(x.Item1);
                return(ReferenceEquals(result, null) ? default((TOut2, TCtx)) : (result, x.Item2));
            });

            return(flow.Via(Flow.FromGraph(stage)));
        }
        /// <summary>
        /// Context-preserving variant of <see cref="SourceOperations.StatefulSelectMany{T,TOut,TMat}"/>.
        /// </summary>
        public static SourceWithContext <TCtx, TOut2, TMat> StatefulSelectConcat <TCtx, TOut, TOut2, TMat>(
            this SourceWithContext <TCtx, TOut, TMat> flow, Func <Func <TOut, IEnumerable <TOut2> > > fn)
        {
            var stage = new StatefulSelectMany <(TOut, TCtx), (TOut2, TCtx)>(() =>
            {
                var fun = fn();
                return(itemWithContext =>
                {
                    var items = fun(itemWithContext.Item1);
                    return items.Select(i => (i, itemWithContext.Item2));
                });
            });

            return(flow.Via(Flow.FromGraph(stage)));
        }