/// <summary>
        /// Creates an observable sequence of bytes by asynchronously reading to the end of the specified <paramref name="stream"/>
        /// each time the underlying file is updated and advances the position within the stream to the end.
        /// </summary>
        /// <param name="stream">The object from which bytes are read as data becomes available.</param>
        /// <remarks>
        /// <para>
        /// The generated sequence is intended to match the specified stream; however, this behavior
        /// depends on whether the stream is well-behaved and whether the stream is not being shared.  Reading always starts from the
        /// current position of the stream.  The stream is expected to increment its position
        /// when it's read.  Each time that the underlying file is updated on disc, reading is expected to begin at the previous position
        /// in the stream, but if the stream is shared or it's not well-behaved, then the generated sequence may contain unexpected data.
        /// </para>
        /// <para>
        /// Furthermore, specific changes to the file are not detected.  Only the date/time of the last write is monitored for changes.
        /// All changes to the date/time of the last write to the file are assumed to indicate that new data has been appended to the
        /// end of the file.  If data is overwritten in the file after it has already been read from the specified stream, then the last
        /// write date/time will be updated causing the stream to be read again, although it will already be at the end of the file so
        /// nothing will happen.  It is the responsibility of consumers to prevent the file from being deleted, truncated or mutated in
        /// any other way that may cause I/O errors or may cause the generated sequence to contain unexpected data.
        /// </para>
        /// </remarks>
        /// <returns>An observable sequence of byte arrays of a default maximum size read from the specified <paramref name="stream"/>.</returns>
        public static IObservable <byte[]> ToObservable(this FileStream stream)
        {
            Contract.Requires(stream != null);
            Contract.Requires(stream.CanRead);
            Contract.Ensures(Contract.Result <IObservable <byte[]> >() != null);

            return(stream.ToObservable(StreamExtensions.defaultBufferSize));
        }
        /// <summary>
        /// Creates an observable sequence by reading to the end of the specified <paramref name="stream"/>
        /// each time the underlying file is updated and advances the position within the stream to the end.
        /// </summary>
        /// <param name="stream">The object from which text is read as it becomes available.</param>
        /// <param name="encoding">The character encoding to use.</param>
        /// <remarks>
        /// <para>
        /// The generated sequence is intended to match the specified stream; however, this behavior
        /// depends on whether the stream is well-behaved and whether the stream is not being shared.  Reading always starts from the
        /// current position of the stream.  The stream is expected to increment its position
        /// when it's read.  Each time that the underlying file is updated on disc, reading is expected to begin at the previous position
        /// in the stream, but if the stream is shared or it's not well-behaved, then the generated sequence may contain unexpected data.
        /// </para>
        /// <para>
        /// Furthermore, specific changes to the file are not detected.  Only the date/time of the last write is monitored for changes.
        /// All changes to the date/time of the last write to the file are assumed to indicate that new data has been appended to the
        /// end of the file.  If data is overwritten in the file after it has already been read from the specified stream, then the last
        /// write date/time will be updated causing the stream to be read again, although it will already be at the end of the file so
        /// nothing will happen.  It is the responsibility of consumers to prevent the file from being deleted, truncated or mutated in
        /// any other way that may cause I/O errors or may cause the generated sequence to contain unexpected data.
        /// </para>
        /// </remarks>
        /// <returns>An observable sequence of strings read from the specified <paramref name="stream"/>.</returns>
        public static IObservable <string> ToObservable(this FileStream stream, Encoding encoding)
        {
            Contract.Requires(stream != null);
            Contract.Requires(stream.CanRead);
            Contract.Requires(encoding != null);
            Contract.Ensures(Contract.Result <IObservable <string> >() != null);

            return(stream.ToObservable(encoding, TaskPoolScheduler.Default));
        }
        public static IObservable <byte[]> ToObservable(this FileStream stream, int bufferSize)
        {
            Contract.Requires(stream != null);
            Contract.Requires(stream.CanRead);
            Contract.Requires(bufferSize > 0);
            Contract.Ensures(Contract.Result <IObservable <byte[]> >() != null);

            return(Observable.Using(
                       () => new FileSystemWatcher(Path.GetDirectoryName(stream.Name), Path.GetFileName(stream.Name))
            {
                NotifyFilter = NotifyFilters.LastWrite
            },
                       watcher => stream.ToObservable(
                           bufferSize,
                           watcher.Watch(WatcherChangeTypes.Created | WatcherChangeTypes.Changed)
                           .StartWith((FileSystemNotification)null))));
        }