private void _swimProtocolProvider_ReceivedMessage(object sender, ReceivedMessageEventArgs e)
        {
            try
            {
                foreach (var signedMessage in e.CompositeMessage.Messages)
                {
                    if (!signedMessage.IsValid())
                    {
                        _logger.LogError("Signature check failed!");
                        continue;
                    }

                    var messageType = signedMessage.Message.MessageType;
                    var message     = signedMessage.Message;

                    if (message.IsValid)
                    {
                        switch (messageType)
                        {
                        case MessageType.Alive:
                        {
                            if (AddBroadcastMessage(signedMessage))
                            {
                                var casted = message as AliveMessage;

                                if (casted != null)
                                {
                                    _logger.LogInformation(
                                        $"{signedMessage.Message.SourceNode} marked {casted.SubjectNode} ALIVE");
                                    AddNode(casted.SubjectNode);
                                }
                            }
                        }
                        break;

                        case MessageType.Dead:
                        {
                            if (AddBroadcastMessage(signedMessage))
                            {
                                var casted = message as DeadMessage;

                                if (casted != null)
                                {
                                    _logger.LogInformation(
                                        $"{signedMessage.Message.SourceNode} marked {casted.SubjectNode} SUSPECT");
                                    RemoveNode(casted.SubjectNode);
                                }
                            }
                        }
                        break;

                        case MessageType.Ping:
                        {
                            SendAck(message);
                            AddNode(message.SourceNode);
                        }
                        break;

                        case MessageType.PingReq:
                        {
                            RelayPing(message);
                        }
                        break;

                        case MessageType.Suspect:
                        {
                            if (AddBroadcastMessage(signedMessage))
                            {
                                var casted = message as SuspectMessage;
                                _logger.LogInformation($"{signedMessage.Message.SourceNode} marked {casted.SubjectNode} SUSPECT");
                                MarkNodeSuspicious(casted.SubjectNode);
                            }
                        }
                        break;

                        case MessageType.Ack:
                        {
                            HandleAck(message);
                            AddNode(message.SourceNode);

                            MessageBase ms = null;

                            //  Send swimMessage back to originating node.
                            if (message.CorrelationId.HasValue && CorrelatedMessages.TryRemove(message.CorrelationId.Value, out ms))
                            {
                                var cm = ms as PingReqMessage;
                                _logger.LogInformation(
                                    $"Relaying ACK {message.SourceNode} -> {cm.SourceNode}");
                                _swimProtocolProvider.SendMessage(cm.SourceNode, message);
                            }
                        }

                        break;
                        }
                    }

                    _logger.LogInformation($"Received: {JsonConvert.SerializeObject(message)}");
                }
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Exception during receive message");
            }
        }
        private void AddBroadcastMessage(MessageBase message)
        {
            var signedMessage = _swimProtocolProvider.SignMessage(message);

            AddBroadcastMessage(signedMessage);
        }