private async void OnHandshakeStartReceived(
     HandshakeStartArgs handshakeStartArgs
 )
 {
     try
     {
         using (_stateHelper.GetFuncWrapper())
         {
             string fromDestination
                 = handshakeStartArgs.Destination;
             if (_dropDestinations.Contains(fromDestination))
                 return;
             if (!SamHelper.IsDestinationStringValid(fromDestination))
                 return;
             DestinationInfo destinationInfo;
             using (await _destinationDbLockSem.GetDisposable().ConfigureAwait(false))
             {
                 if (
                     !_destinationDb.ContainsKey(
                         handshakeStartArgs.Destination
                         )
                     )
                 {
                     destinationInfo = new DestinationInfo();
                     _destinationDb.Add(
                         handshakeStartArgs.Destination,
                         destinationInfo
                     );
                 }
                 else
                 {
                     destinationInfo =
                         _destinationDb[
                             handshakeStartArgs.Destination
                         ];
                 }
             }
             using (await destinationInfo.InMessagesDbLockSem.GetDisposable().ConfigureAwait(false))
             {
                 if (
                     destinationInfo.InMessagesDb.ContainsKey(
                         handshakeStartArgs.MessageId
                     )
                 )
                 {
                     var inMessageInfo
                         = destinationInfo.InMessagesDb[
                             handshakeStartArgs.MessageId
                         ];
                     if (
                         inMessageInfo.Status
                         == InMessageStatus.HandshakeReceived
                     )
                     {
                         await
                             SendMessageStatus(
                                 fromDestination,
                                 handshakeStartArgs.MessageId,
                                 MessageStatusArgs.MessageStatusCode.HandshakeOk,
                                 0
                             ).ConfigureAwait(false);
                         return;
                     }
                     else if (
                         inMessageInfo.Status
                         == InMessageStatus.AllBlocksReceived
                     )
                     {
                         await SendMessageStatus(
                             fromDestination,
                             handshakeStartArgs.MessageId,
                             MessageStatusArgs.MessageStatusCode.AllBlocksReceived,
                             inMessageInfo.BlocksReceivedCount
                         ).ConfigureAwait(false);
                         return;
                     }
                     else
                     {
                         await SendMessageStatus(
                             fromDestination,
                             handshakeStartArgs.MessageId,
                             MessageStatusArgs
                                 .MessageStatusCode
                                 .HandshakeErrorDuplicatedId,
                             inMessageInfo.BlocksReceivedCount
                         ).ConfigureAwait(false);
                         return;
                     }
                 }
                 else
                 {
                     if (
                         handshakeStartArgs.MessageSize
                         > _settings.MaxMesageLength
                     )
                     {
                         await SendMessageStatus(
                             fromDestination,
                             handshakeStartArgs.MessageId,
                             MessageStatusArgs.MessageStatusCode
                                 .HandshakeErrorWrongTotalSize,
                             0
                             ).ConfigureAwait(false);
                         return;
                     }
                     if (handshakeStartArgs.BlockSize > _settings.MaxBlockSize)
                     {
                         await SendMessageStatus(
                             fromDestination,
                             handshakeStartArgs.MessageId,
                             MessageStatusArgs.MessageStatusCode
                                 .HandshakeErrorWrongBlockSize,
                             0
                             ).ConfigureAwait(false);
                         return;
                     }
                     var inMessageInfo = new InMessageInfo(
                         handshakeStartArgs.MessageSize,
                         handshakeStartArgs.BlockSize,
                         handshakeStartArgs.ReplyToMessageId,
                         handshakeStartArgs.MessageKind,
                         handshakeStartArgs.MessageHash
                     );
                     if (
                         inMessageInfo.ReceivedDataChunkSizes[0]
                         != handshakeStartArgs.FirstBlockData.Length
                     )
                     {
                         await SendMessageStatus(
                             fromDestination,
                             handshakeStartArgs.MessageId,
                             MessageStatusArgs.MessageStatusCode
                                 .HandshakeErrorWrongBlockSize,
                             0
                         ).ConfigureAwait(false);
                         return;
                     }
                     destinationInfo.InMessagesDb.Add(
                         handshakeStartArgs.MessageId,
                         inMessageInfo
                     );
                     await SendMessageStatus(
                         fromDestination,
                         handshakeStartArgs.MessageId,
                         MessageStatusArgs.MessageStatusCode.HandshakeOk,
                         0
                     ).ConfigureAwait(false);
                     OnBlockSendReceived(
                         new BlockSendArgs()
                         {
                             BlockData = handshakeStartArgs.FirstBlockData,
                             BlockId = 0,
                             Destination = handshakeStartArgs.Destination,
                             MessageId = handshakeStartArgs.MessageId
                         }
                     );
                     return;
                 }
             }
         }
     }
     catch (OperationCanceledException)
     {
     }
     catch (WrongDisposableObjectStateException)
     {
     }
     catch (Exception exc)
     {
         _log.Error(
             "OnHandshakeStartReceive" +
                 " unexpected error '{0}'",
             exc.ToString()
         );
     }
 }
        private async void OnHandshakeStartReceived(
            HandshakeStartArgs handshakeStartArgs
            )
        {
            try
            {
                using (_stateHelper.GetFuncWrapper())
                {
                    string fromDestination
                        = handshakeStartArgs.Destination;
                    if (_dropDestinations.Contains(fromDestination))
                    {
                        return;
                    }
                    if (!SamHelper.IsDestinationStringValid(fromDestination))
                    {
                        return;
                    }
                    DestinationInfo destinationInfo;
                    using (await _destinationDbLockSem.GetDisposable().ConfigureAwait(false))
                    {
                        if (
                            !_destinationDb.ContainsKey(
                                handshakeStartArgs.Destination
                                )
                            )
                        {
                            destinationInfo = new DestinationInfo();
                            _destinationDb.Add(
                                handshakeStartArgs.Destination,
                                destinationInfo
                                );
                        }
                        else
                        {
                            destinationInfo =
                                _destinationDb[
                                    handshakeStartArgs.Destination
                                ];
                        }
                    }
                    using (await destinationInfo.InMessagesDbLockSem.GetDisposable().ConfigureAwait(false))
                    {
                        if (
                            destinationInfo.InMessagesDb.ContainsKey(
                                handshakeStartArgs.MessageId
                                )
                            )
                        {
                            var inMessageInfo
                                = destinationInfo.InMessagesDb[
                                      handshakeStartArgs.MessageId
                                  ];
                            if (
                                inMessageInfo.Status
                                == InMessageStatus.HandshakeReceived
                                )
                            {
                                await
                                SendMessageStatus(
                                    fromDestination,
                                    handshakeStartArgs.MessageId,
                                    MessageStatusArgs.MessageStatusCode.HandshakeOk,
                                    0
                                    ).ConfigureAwait(false);

                                return;
                            }
                            else if (
                                inMessageInfo.Status
                                == InMessageStatus.AllBlocksReceived
                                )
                            {
                                await SendMessageStatus(
                                    fromDestination,
                                    handshakeStartArgs.MessageId,
                                    MessageStatusArgs.MessageStatusCode.AllBlocksReceived,
                                    inMessageInfo.BlocksReceivedCount
                                    ).ConfigureAwait(false);

                                return;
                            }
                            else
                            {
                                await SendMessageStatus(
                                    fromDestination,
                                    handshakeStartArgs.MessageId,
                                    MessageStatusArgs
                                    .MessageStatusCode
                                    .HandshakeErrorDuplicatedId,
                                    inMessageInfo.BlocksReceivedCount
                                    ).ConfigureAwait(false);

                                return;
                            }
                        }
                        else
                        {
                            if (
                                handshakeStartArgs.MessageSize
                                > _settings.MaxMesageLength
                                )
                            {
                                await SendMessageStatus(
                                    fromDestination,
                                    handshakeStartArgs.MessageId,
                                    MessageStatusArgs.MessageStatusCode
                                    .HandshakeErrorWrongTotalSize,
                                    0
                                    ).ConfigureAwait(false);

                                return;
                            }
                            if (handshakeStartArgs.BlockSize > _settings.MaxBlockSize)
                            {
                                await SendMessageStatus(
                                    fromDestination,
                                    handshakeStartArgs.MessageId,
                                    MessageStatusArgs.MessageStatusCode
                                    .HandshakeErrorWrongBlockSize,
                                    0
                                    ).ConfigureAwait(false);

                                return;
                            }
                            var inMessageInfo = new InMessageInfo(
                                handshakeStartArgs.MessageSize,
                                handshakeStartArgs.BlockSize,
                                handshakeStartArgs.ReplyToMessageId,
                                handshakeStartArgs.MessageKind,
                                handshakeStartArgs.MessageHash
                                );
                            if (
                                inMessageInfo.ReceivedDataChunkSizes[0]
                                != handshakeStartArgs.FirstBlockData.Length
                                )
                            {
                                await SendMessageStatus(
                                    fromDestination,
                                    handshakeStartArgs.MessageId,
                                    MessageStatusArgs.MessageStatusCode
                                    .HandshakeErrorWrongBlockSize,
                                    0
                                    ).ConfigureAwait(false);

                                return;
                            }
                            destinationInfo.InMessagesDb.Add(
                                handshakeStartArgs.MessageId,
                                inMessageInfo
                                );
                            await SendMessageStatus(
                                fromDestination,
                                handshakeStartArgs.MessageId,
                                MessageStatusArgs.MessageStatusCode.HandshakeOk,
                                0
                                ).ConfigureAwait(false);

                            OnBlockSendReceived(
                                new BlockSendArgs()
                            {
                                BlockData   = handshakeStartArgs.FirstBlockData,
                                BlockId     = 0,
                                Destination = handshakeStartArgs.Destination,
                                MessageId   = handshakeStartArgs.MessageId
                            }
                                );
                            return;
                        }
                    }
                }
            }
            catch (OperationCanceledException)
            {
            }
            catch (WrongDisposableObjectStateException)
            {
            }
            catch (Exception exc)
            {
                _log.Error(
                    "OnHandshakeStartReceive" +
                    " unexpected error '{0}'",
                    exc.ToString()
                    );
            }
        }