protected override async Task SendFile(string clientName, byte[] fileHash)
        {
            var fileInfo   = new FileInfo(Path.Combine(StoragePath, Hasher.GetDirectoryNameFromHash(fileHash), Hasher.GetFileNameFromHash(fileHash)));
            var buffer     = new byte[BufferSize];
            var totalBytes = fileInfo.Length;

            await Communicator.SendMessage(clientName, new FileStartMessage(fileHash));

            var chunkMessage = new FileChunckMessage {
                FileHash = fileHash
            };

            if (FileTransferResponse.ContainsKey(fileHash))
            {
                FileTransferResponse.Remove(fileHash);
            }
            FileTransferResponse.Add(fileHash, false);
            using (var fileStream = fileInfo.OpenRead())
            {
                var bytesRemaining = totalBytes;
                while (bytesRemaining > 0)
                {
                    var chunkSize = (int)((bytesRemaining < BufferSize) ? bytesRemaining : BufferSize);
                    if (chunkSize < BufferSize)
                    {
                        buffer = new byte[chunkSize];
                    }

                    var bytesRead = fileStream.Read(buffer, 0, chunkSize);
                    chunkMessage.FileData = buffer;
                    await Communicator.SendMessage(clientName, chunkMessage);

                    bytesRemaining -= bytesRead;

                    while (!FileTransferResponse[fileHash])
                    {
                        await Task.Delay(1);
                    }

                    FileTransferResponse[fileHash] = false;
                }
            }

            await Communicator.SendMessage(clientName, new FileEndMessage(fileHash));
        }
        public async Task <bool> StoreFile(IBackupFile file, byte[] hash)
        {
            var success = false;

            await Communicator.SendMessage(new FileStartMessage(hash));

            var totalBytes = file.Length;
            var buffer     = new byte[BufferSize];

            var position       = 0L;
            var remainingBytes = totalBytes;
            var message        = new FileChunckMessage()
            {
                FileHash = hash
            };

            if (FileTransferResponse.ContainsKey(hash))
            {
                FileTransferResponse.Remove(hash);
            }
            FileTransferResponse.Add(hash, false);
            using (var fileStream = file.OpenRead())
            {
                while (position < totalBytes)
                {
                    var bytesToRead = (int)((remainingBytes > BufferSize) ? BufferSize : remainingBytes);
                    if (bytesToRead < BufferSize)
                    {
                        buffer = new byte[bytesToRead];
                    }
                    position        += fileStream.Read(buffer, 0, bytesToRead);
                    remainingBytes   = totalBytes - position;
                    message.FileData = buffer;
                    await Communicator.SendMessage(message);

                    while (!FileTransferResponse[hash])
                    {
                        await Task.Delay(1);
                    }

                    FileTransferResponse[hash] = false;
                }
            }

            await Communicator.SendMessage(new FileEndMessage(hash));

            // Watch the inbound messages for a verification message
            var gotVerificationMessage = false;

            while (!gotVerificationMessage)
            {
                if (VerificationMessages.ContainsKey(hash))
                {
                    var verifyMessage = VerificationMessages[hash] as FileStoredVerificationMessage;
                    success = verifyMessage?.Success ?? false;
                    VerificationMessages.Remove(hash);
                    gotVerificationMessage = true;
                }

                await Task.Delay(1);
            }

            return(success);
        }