public async Task Can_Recover_From_Missing_Data()
        {
            var connection = GetConnection();
            var repository = GetRepository();

            SessionHeader header;
            var           fileLength = 0L;

            using (var sessionStream =
                       File.OpenRead(Path.Combine(TestContext.CurrentContext.TestDirectory, "Content", "SampleSession.glf")))
            {
                sessionStream.Position = 0;
                var reader = new GLFReader(sessionStream);
                header = reader.SessionHeader;

                fileLength = sessionStream.Length;

                repository.AddSession(sessionStream);
            }

            using (var request = new SessionUploadRequest(repository.Id, repository, header.Id, header.FileId, false))
            {
                var progressFile = request.GenerateTemporarySessionFileNamePath();

                //mess with the progress file...
                using (var sessionTrackingFileStream = new FileStream(progressFile, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None))
                {
                    using (var writer = new BinaryWriter(sessionTrackingFileStream, Encoding.UTF8))
                    {
                        var partialFileLength = Convert.ToInt64(fileLength * 0.7);
                        writer.Write(partialFileLength);
                        writer.Flush();
                        sessionTrackingFileStream.SetLength(sessionTrackingFileStream.Position);
                    }
                }

                //because upload request uses a multiprocess lock we put it in a using to ensure it gets disposed.
                //explicitly prepare the session - this returns true if we got the lock meaning no one else is actively transferring this session right now.
                Assert.IsTrue(request.PrepareSession());

                //this should internally recover from starting mid-stream.
                await connection.ExecuteRequest(request, 0).ConfigureAwait(false);
            }
        }
 /// <summary>
 /// Sends a merged session stream or a single session fragment file to the server.
 /// </summary>
 /// <param name="sessionId"></param>
 /// <param name="fileId"></param>
 /// <param name="maxRetries">The maximum number of times to retry the session data upload.</param>
 /// <param name="purgeSentSessions">Indicates whether to purge sessions that have been successfully sent from the repository</param>
 /// <returns>Throws an exception if the upload fails.</returns>
 private async Task PerformSessionFileUpload(Guid sessionId, Guid?fileId, int maxRetries, bool purgeSentSessions)
 {
     using (var request = new SessionUploadRequest(m_SourceRepository.Id, m_SourceRepository, sessionId, fileId, purgeSentSessions))
     {
         //because upload request uses a multiprocess lock we put it in a using to ensure it gets disposed.
         //explicitly prepare the session - this returns true if we got the lock meaning no one else is actively transferring this session right now.
         if (request.PrepareSession() == false)
         {
             if (!Log.SilentMode)
             {
                 Log.Write(LogMessageSeverity.Information, LogCategory, "Skipping sending session to server because another process already is transferring it", "We weren't able to get a transport lock on the session '{0}' so we assume another process is currently sending it.", sessionId);
             }
         }
         else
         {
             await m_HubConnection.ExecuteRequest(request, maxRetries).ConfigureAwait(false);
         }
     }
 }