FromEventPattern
using System.Reactive.Concurrency;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Threading;
namespace System.Reactive.Linq.ObservableImpl
{
    [System.Runtime.CompilerServices.NullableContext(1)]
    [System.Runtime.CompilerServices.Nullable(0)]
    internal sealed class FromEventPattern
    {
        [System.Runtime.CompilerServices.Nullable(new byte[] {
            0,
            1,
            1,
            1
        })]
        public sealed class Impl<[System.Runtime.CompilerServices.Nullable(2)] TDelegate, [System.Runtime.CompilerServices.Nullable(2)] TEventArgs> : ClassicEventProducer<TDelegate, EventPattern<TEventArgs>>
        {
            [System.Runtime.CompilerServices.Nullable(new byte[] {
                2,
                1,
                1,
                1
            })]
            private readonly Func<EventHandler<TEventArgs>, TDelegate> _conversion;
            public Impl(Action<TDelegate> addHandler, Action<TDelegate> removeHandler, IScheduler scheduler)
                : base(addHandler, removeHandler, scheduler)
            {
            }
            public Impl(Func<EventHandler<TEventArgs>, TDelegate> conversion, Action<TDelegate> addHandler, Action<TDelegate> removeHandler, IScheduler scheduler)
                : base(addHandler, removeHandler, scheduler)
            {
                _conversion = conversion;
            }
            protected override TDelegate GetHandler(Action<EventPattern<TEventArgs>> onNext)
            {
                if (_conversion != null)
                    return _conversion(delegate(object sender, TEventArgs eventArgs) {
                        onNext(new EventPattern<TEventArgs>(sender, eventArgs));
                    });
                return ReflectionUtils.CreateDelegate<TDelegate>((object)(Action<object, TEventArgs>)delegate(object sender, TEventArgs eventArgs) {
                    onNext(new EventPattern<TEventArgs>(sender, eventArgs));
                }, typeof(Action<object, TEventArgs>).GetMethod("Invoke"));
            }
        }
        [System.Runtime.CompilerServices.NullableContext(2)]
        [System.Runtime.CompilerServices.Nullable(new byte[] {
            0,
            1,
            1,
            1,
            1
        })]
        public sealed class Impl<TDelegate, TSender, TEventArgs> : ClassicEventProducer<TDelegate, EventPattern<TSender, TEventArgs>>
        {
            [System.Runtime.CompilerServices.NullableContext(1)]
            public Impl(Action<TDelegate> addHandler, Action<TDelegate> removeHandler, IScheduler scheduler)
                : base(addHandler, removeHandler, scheduler)
            {
            }
            [System.Runtime.CompilerServices.NullableContext(1)]
            protected override TDelegate GetHandler(Action<EventPattern<TSender, TEventArgs>> onNext)
            {
                return ReflectionUtils.CreateDelegate<TDelegate>((object)(Action<TSender, TEventArgs>)delegate(TSender sender, TEventArgs eventArgs) {
                    onNext(new EventPattern<TSender, TEventArgs>(sender, eventArgs));
                }, typeof(Action<TSender, TEventArgs>).GetMethod("Invoke"));
            }
        }
        [System.Runtime.CompilerServices.Nullable(new byte[] {
            0,
            1,
            1
        })]
        public sealed class Handler<[System.Runtime.CompilerServices.Nullable(2)] TSender, [System.Runtime.CompilerServices.Nullable(2)] TEventArgs, [System.Runtime.CompilerServices.Nullable(2)] TResult> : EventProducer<Delegate, TResult>
        {
            [System.Runtime.CompilerServices.NullableContext(0)]
            private sealed class RemoveHandlerDisposable : IDisposable
            {
                [System.Runtime.CompilerServices.Nullable(2)]
                private Action _removeHandler;
                [System.Runtime.CompilerServices.NullableContext(1)]
                public RemoveHandlerDisposable(Action removeHandler)
                {
                    Volatile.Write<Action>(ref _removeHandler, removeHandler);
                }
                public void Dispose()
                {
                    try {
                        Interlocked.Exchange<Action>(ref _removeHandler, (Action)null)?.Invoke();
                    } catch (TargetInvocationException ex) when (ex.InnerException != null) {
                        throw ex.InnerException;
                    }
                }
            }
            [System.Runtime.CompilerServices.Nullable(2)]
            private readonly object _target;
            private readonly Type _delegateType;
            private readonly MethodInfo _addMethod;
            private readonly MethodInfo _removeMethod;
            private readonly Func<TSender, TEventArgs, TResult> _getResult;
            private readonly bool _isWinRT;
            public Handler([System.Runtime.CompilerServices.Nullable(2)] object target, Type delegateType, MethodInfo addMethod, MethodInfo removeMethod, Func<TSender, TEventArgs, TResult> getResult, bool isWinRT, IScheduler scheduler)
                : base(scheduler)
            {
                _isWinRT = isWinRT;
                _target = target;
                _delegateType = delegateType;
                _addMethod = addMethod;
                _removeMethod = removeMethod;
                _getResult = getResult;
            }
            protected override Delegate GetHandler(Action<TResult> onNext)
            {
                Action<TSender, TEventArgs> o = delegate(TSender sender, TEventArgs eventArgs) {
                    onNext(_getResult(sender, eventArgs));
                };
                return ReflectionUtils.CreateDelegate(_delegateType, o, typeof(Action<TSender, TEventArgs>).GetMethod("Invoke"));
            }
            protected override IDisposable AddHandler(Delegate handler)
            {
                Action removeHandler;
                try {
                    removeHandler = ((!_isWinRT) ? AddHandlerCore(handler) : AddHandlerCoreWinRT(handler));
                } catch (TargetInvocationException ex) when (ex.InnerException != null) {
                    throw ex.InnerException;
                }
                return new RemoveHandlerDisposable(removeHandler);
            }
            private Action AddHandlerCore(Delegate handler)
            {
                _addMethod.Invoke(_target, new object[1] {
                    handler
                });
                return delegate {
                    _removeMethod.Invoke(_target, new object[1] {
                        handler
                    });
                };
            }
            private Action AddHandlerCoreWinRT(Delegate handler)
            {
                object token = _addMethod.Invoke(_target, new object[1] {
                    handler
                });
                return delegate {
                    _removeMethod.Invoke(_target, new object[1] {
                        token
                    });
                };
            }
        }
    }
}