public static IObservable<Unit> ConnectObservable(this Socket socket, EndPoint remoteEndPoint)
        {
            Contract.Requires(socket != null);
            Contract.Requires(remoteEndPoint != null);
            Contract.Ensures(Contract.Result<IObservable<Unit>>() != null);

            var args = new SocketAsyncEventArgs()
            {
                RemoteEndPoint = remoteEndPoint
            };

            return socket
                .ConnectObservable(args)
                .Select(_ => Unit.Default)
                .Finally(args.Dispose);
        }
        public static IObservable<Unit> ConnectObservable(this Socket socket, IPAddress address, int port)
        {
            Contract.Requires(socket != null);
            Contract.Requires(address != null);
            Contract.Requires(port >= IPEndPoint.MinPort);
            Contract.Requires(port <= IPEndPoint.MaxPort);
            Contract.Ensures(Contract.Result<IObservable<Unit>>() != null);

            var args = new SocketAsyncEventArgs()
            {
                RemoteEndPoint = new IPEndPoint(address, port)
            };

            return socket
                .ConnectObservable(args)
                .Select(_ => Unit.Default)
                .Finally(args.Dispose);
        }
    public static IObservable<Unit> DisconnectObservable(this Socket socket, bool reuseSocket)
    {
      Contract.Requires(socket != null);
      Contract.Ensures(Contract.Result<IObservable<Unit>>() != null);

      var args = new SocketAsyncEventArgs()
      {
        DisconnectReuseSocket = reuseSocket
      };

      return socket
        .ConnectObservable(args)
        .Select(_ => Unit.Default)
        .Finally(args.Dispose);
    }