/// <summary>
    /// Registers an predefined event handler that works with a weak reference to the target object.
    /// Access to the event and to the real event handler is done through lambda expressions.
    /// The code holds strong references to these expressions, so they must not capture any
    /// variables!
    /// </summary>
    /// </example>
    public static WeakEventHandler Register <TEventSource, TEventListener>(
        TEventSource senderObject,
        Action <TEventSource, TEventHandler> registerEvent,
        Action <TEventSource, TEventHandler> deregisterEvent,
        TEventListener listeningObject,
        Action <TEventListener, object, TEventArgs> forwarderAction
        )
        where TEventSource : class
        where TEventListener : class
    {
        if (senderObject == null)
        {
            throw new ArgumentNullException("senderObject");
        }
        if (listeningObject == null)
        {
            throw new ArgumentNullException("listeningObject");
        }
        WeakEventHandler.VerifyDelegate(registerEvent, "registerEvent");
        WeakEventHandler.VerifyDelegate(deregisterEvent, "deregisterEvent");
        WeakEventHandler.VerifyDelegate(forwarderAction, "forwarderAction");
        WeakEventHandler weh = new WeakEventHandler(listeningObject);
        TEventHandler    eh  = MakeDeregisterCodeAndWeakEventHandler(weh, senderObject, deregisterEvent, forwarderAction);

        registerEvent(senderObject, eh);
        return(weh);
    }