/// <summary>
        /// Retrieves data from an array of buffers and writes the data to a file.
        /// </summary>
        /// <param name="segments">Array of pointers to data buffers.
        /// Each buffer must be at least the size of a system memory page and must be aligned
        /// on a system memory page size boundary <seealso cref="SystemPageSize"/>.
        /// The system writes one system memory page of data into each buffer.
        /// Buffers should not be deallocated or moved until operation is completed.</param>
        /// <param name="fileOffset">File pointer</param>
        /// <param name="callback">An optional asynchronous callback, to be called when the write is complete.</param>
        /// <param name="state">A user-provided object that distinguishes this particular asynchronous write request from other requests.</param>
        /// <returns>An IAsyncResult that represents the asynchronous write, which could still be pending.</returns>
        public IAsyncResult BeginWriteGather(
            IntPtr[] segments,
            UInt64 fileOffset,
            AsyncCallback callback,
            object state)
        {
            if (segments == null)
            {
                throw new ArgumentNullException("segments");
            }
            CheckNotDisposed();

            NativeMethods.FILE_SEGMENT_ELEMENT[] nativeSegments = new NativeMethods.FILE_SEGMENT_ELEMENT[segments.Length + 1];
            for (int i = 0; i < segments.Length; i++)
            {
                nativeSegments[i].Buffer = segments[i];
            }

            UInt32 numberOfBytesToWrite = (uint)segments.Length * _systemPageSize;

            AsyncJob job = null;

            try
            {
                job = new AsyncJob(callback, state, fileOffset, nativeSegments);
                bool result;
                unsafe
                {
                    fixed(NativeMethods.FILE_SEGMENT_ELEMENT *ps = &nativeSegments[0])
                    {
                        result = NativeMethods.WriteFileGather(_handle, ps, numberOfBytesToWrite, IntPtr.Zero, job.OverlappedPtr);
                    }
                }

                if (result)
                {
                    job.CompleteSynchronously();
                }
                else
                {
                    CheckErrorPending();
                }

                AsyncJob ret = job; job = null;
                return(ret);
            }
            finally
            {
                if (job != null)
                {
                    job.Dispose();
                }
            }
        }
		/// <summary>
		/// Retrieves data from an array of buffers and writes the data to a file.
		/// </summary>
		/// <param name="segments">Array of pointers to data buffers. 
		/// Each buffer must be at least the size of a system memory page and must be aligned 
		/// on a system memory page size boundary <seealso cref="SystemPageSize"/>. 
		/// The system writes one system memory page of data into each buffer. 
		/// Buffers should not be deallocated or moved until operation is completed.</param>
		/// <param name="fileOffset">File pointer</param>
		/// <param name="callback">An optional asynchronous callback, to be called when the write is complete.</param>
		/// <param name="state">A user-provided object that distinguishes this particular asynchronous write request from other requests.</param>
		/// <returns>An IAsyncResult that represents the asynchronous write, which could still be pending.</returns>
		public IAsyncResult BeginWriteGather(
				IntPtr[] segments,
				UInt64 fileOffset,
				AsyncCallback callback,
				object state) {
			if (segments == null)
				throw new ArgumentNullException("segments");
			CheckNotDisposed();

			NativeMethods.FILE_SEGMENT_ELEMENT[] nativeSegments = new NativeMethods.FILE_SEGMENT_ELEMENT[segments.Length + 1];
			for (int i = 0; i < segments.Length; i++)
				nativeSegments[i].Buffer = segments[i];

			UInt32 numberOfBytesToWrite = (uint)segments.Length * _systemPageSize;

			AsyncJob job = null;
			try {
				job = new AsyncJob(callback, state, fileOffset, nativeSegments);
				bool result;
				unsafe {
					fixed (NativeMethods.FILE_SEGMENT_ELEMENT* ps = &nativeSegments[0]) {
						result = NativeMethods.WriteFileGather(_handle, ps, numberOfBytesToWrite, IntPtr.Zero, job.OverlappedPtr);
					}
				}

				if (result)
					job.CompleteSynchronously();
				else
					CheckErrorPending();

				AsyncJob ret = job; job = null;
				return ret;
			} finally {
				if (job != null)
					job.Dispose();
			}
		}