public static void ListenOnceForOne(this BaseSignalListener[] listeners)
    {
        bool returned = false;

        for (int i = 0; i < listeners.Length; i++)
        {
            BaseSignalListener listener = listeners[i];

            listener.proxy =
                (s, xs) => {
                if (returned)
                {
                    return;
                }
                returned = true;

                for (int j = 0; j < listeners.Length; j++)
                {
                    // TODO May need to check that i != j
                    listeners[j].listeningOn.RemoveListener(listener.proxy);
                }

                listener.Callback(xs);
            };

            listeners[i].listeningOn.AddOnce(listener.proxy);
        }
    }
    public static UniRx.IObservable <object> ToObservable(this SignalRequester[] requests, BaseSignalListener[] returns)
    {
        if (returns == null || returns.Length == 0)
        {
            throw new ArgumentNullException("returns not valid");
        }

        Subject <object>          notYetReturned = new Subject <object>();
        List <BaseSignalListener> returnsLeft    = new List <BaseSignalListener>(returns);

        for (int i = 0; i < returns.Length; i++)
        {
            BaseSignalListener ret = returns[i];

            Action <IBaseSignal, object[]> handler = null;
            handler = (s, xs) => {
                if (!returnsLeft.Contains(ret))
                {
                    throw new Exception("Something went wrong...");
                }

                Assert.AreEqual(s, ret.listeningOn);

                ret.listeningOn.RemoveListener(handler);
                returnsLeft.Remove(ret);
                notYetReturned.OnNext(ret);

                ret.Callback(xs);

                if (returnsLeft.Count == 0)
                {
                    notYetReturned.OnCompleted();
                }
            };

            ret.listeningOn.AddListener(handler);
        }

        return(notYetReturned);
    }