public static Task CopyToAsync(this Stream source,
                                       Stream destination,
                                       long? lengthToCopy = null,
                                       CancellationToken cancellationToken = default(CancellationToken)) {
            if (source == null) {
                throw new ArgumentNullException("source");
            }
            if (destination == null) {
                throw new ArgumentNullException("destination");
            }
            long bufferSize = 4096;
            if (lengthToCopy.HasValue) {
                bufferSize = Math.Min(bufferSize, lengthToCopy.Value);
            }

            var copyExecutor = new AsyncCopyExecutor(source, destination, (int)bufferSize, lengthToCopy, cancellationToken);
            return copyExecutor.Start();
        }
        public static Task CopyToAsync(this Stream source,
                                       Stream destination,
                                       long?lengthToCopy = null,
                                       CancellationToken cancellationToken = default(CancellationToken))
        {
            if (source == null)
            {
                throw new ArgumentNullException("source");
            }
            if (destination == null)
            {
                throw new ArgumentNullException("destination");
            }
            long bufferSize = 4096;

            if (lengthToCopy.HasValue)
            {
                bufferSize = Math.Min(bufferSize, lengthToCopy.Value);
            }

            var copyExecutor = new AsyncCopyExecutor(source, destination, (int)bufferSize, lengthToCopy, cancellationToken);

            return(copyExecutor.Start());
        }