/// <summary>
        /// Call this to say that the upload is complete.
        /// The returned FileUploadInfo.TempFileName gives you the actual file that has been uploaded.
        /// FileUploadInfo.FileName tells you what that file should be called (was originally called on the client).
        /// You should call UploadReset() when you have finished with the temp file.
        /// </summary>
        /// <param name="logonId">Logon id of user</param>
        /// <param name="TransferId">Transfer id</param>
        /// <returns></returns>
        public static FileUploadInfo UploadComplete(Guid logonId, Guid TransferId)
        {
            FileTransferData FileTransferData = Host.GetFileTransferData(logonId);

            if (!FileTransferData.IsUpload)
            {
                throw new Exception("File upload has not been started");
            }

            if (FileTransferData.TransferId != TransferId)
            {
                throw new Exception("Transfer id does not match");
            }

            if (FileTransferData.FileStream == null)
            {
                throw new Exception("File upload has not been started or has timed out");
            }

            FileTransferData.FileStream.Close();

            FileUploadInfo FileUploadInfo = new FileUploadInfo();

            try
            {
                if (new FileInfo(FileTransferData.TempFileName).Length != FileTransferData.Size)
                {
                    throw new Exception("File upload failed, file size is wrong");
                }

                byte[] LocalHash = FileTransferHash.CreateFileMD5Hash(FileTransferData.TempFileName);

                if (!FileTransferHash.CheckHash(LocalHash, FileTransferData.Hash))
                {
                    throw new Exception("File upload failed, checksum does not match");
                }

                File.SetLastWriteTime(FileTransferData.TempFileName, FileTransferData.ModifiedDate);

                FileUploadInfo.TempFileName = FileTransferData.TempFileName;
                FileUploadInfo.FileName     = FileTransferData.FileName;
                FileUploadInfo.ModifiedDate = FileTransferData.ModifiedDate;
                FileUploadInfo.Size         = FileTransferData.Size;
            }
            catch
            {
                FileTransferData.Reset();
                throw;
            }

            return(FileUploadInfo);
        }
        /// <summary>
        /// Start the file download
        /// </summary>
        /// <param name="logonId">Logon id of user</param>
        /// <param name="FileName">Source file to be downloaded</param>
        /// <param name="FileIsTemp">If the source file to be downloaded is a temp file set this to true so that
        /// it will automatically be deleted at the end.
        /// e.g. if you have extratced a file from an archive into a temp file for download then set this
        /// to true</param>
        /// <returns></returns>
        public static FileDownloadInfo StartFileDownload(Guid logonId, string SourceFileName, bool FileIsTemp)
        {
            FileTransferData FileTransferData = Host.GetFileTransferData(logonId);

            FileTransferData.TransferId = Guid.NewGuid();
            FileTransferData.IsDownload = true;

            FileTransferData.FileName = SourceFileName;

            if (FileIsTemp)
            {
                FileTransferData.TempFileName = SourceFileName;
            }
            else
            {
                FileTransferData.TempFileName = null;
            }

            FileDownloadInfo FileDownloadInfo = new FileDownloadInfo();

            FileTransferData.FileStream = new FileStream(SourceFileName, FileMode.Open, FileAccess.Read, FileShare.Read);

            try
            {
                FileInfo FInfo = new FileInfo(SourceFileName);

                FileTransferData.ModifiedDate = FInfo.LastWriteTime;
                FileTransferData.Size         = FInfo.Length;

                FileDownloadInfo.TransferId = FileTransferData.TransferId;
                // Only return the filename without the path as this is irrelavent to the client
                FileDownloadInfo.FileName     = Path.GetFileName(SourceFileName);
                FileDownloadInfo.ModifiedDate = FInfo.LastWriteTime;
                FileDownloadInfo.Size         = FInfo.Length;
                FileDownloadInfo.Hash         = FileTransferHash.CreateStreamMD5Hash(FileTransferData.FileStream);
                FileTransferData.FileStream.Seek(0, SeekOrigin.Begin);
            }
            catch
            {
                FileTransferData.Reset();
                throw;
            }

            return(FileDownloadInfo);
        }