private void DedicatedQueue_MessageReceived(object sender, MessageReceivedEventArgs e)
        {
            //var signatureIsValid = clientServerHandshakeComplete && SignatureIsValid(e.RawData, PublicKeystore[e.Message.ClientName].Dsa);

            if (e.MessageEnevelope.BasicProperties.CorrelationId != null &&
                RpcCallWaitInfo.ContainsKey(e.MessageEnevelope.BasicProperties.CorrelationId))
            {
                var waitInfo = RpcCallWaitInfo[e.MessageEnevelope.BasicProperties.CorrelationId];
                waitInfo.ResponseMessageEnvelope = e.MessageEnevelope;
                //waitInfo.RawResponse = e.RawData;
                waitInfo.WaitHandle.Set();
            }
            else if (e.MessageEnevelope.SignatureVerificationStatus == SignatureVerificationStatus.SignatureValid)
            {
                if (e.MessageEnevelope.Message.GetType() == typeof(ClientReannounceRequestMessage))
                {
                    Log.Information("Server requested reannouncement of clients.");
                    var message = new ClientAnnounceMessage(PublicKeystore.ParentClientInfo);

                    //todo: Encrypt?
                    WriteToServerNoWait(message, false);
                }
                else if (e.MessageEnevelope.Message.GetType() == typeof(HeartbeatMessage))
                {
#if false
                    if (!serverHeartbeatTimer.Enabled)
                    {
                        Log.Information("Server heartbeat re-established.");
                    }

                    serverHeartbeatTimer.Restart();
#endif
                }
                else if (e.MessageEnevelope.Message.GetType() == typeof(PublicKeyUpdate))
                {
                    var tempMessage = (PublicKeyUpdate)e.MessageEnevelope.Message;
                    PublicKeystore.Add(tempMessage.ClientInfo);
                    //TODO: Re-enable Log.Verbose($"Received public key '{tempMessage.ClientInfo.ECKey.GetPublicKeyHash()}' for client '{tempMessage.ClientInfo.Name}'.");
                }
                else if (e.MessageEnevelope.Message.GetType() == typeof(TrustZoneSharedKeyUpdate))
                {
                    var tempMessage = (TrustZoneSharedKeyUpdate)e.MessageEnevelope.Message;

                    if (e.MessageEnevelope.SenderIdentityHash != this.PublicKeystore.TrustCoordinatorIdentity.IdentityHash)
                    {
                        throw new Exception("Trust Zone Key Update from client that is not the coordinator.");
                    }

                    PublicKeystore.TrustZoneSharedKeys.Add(tempMessage.SharedKey);
                    Log.Verbose($"Received trust zone shared key");
                }
                else
                {
                    FireMessageReceivedEvent(e);
                }
            }
#if false
            else if (clientServerHandshakeComplete)
            {
                throw new Exception();
            }
#endif
        }
        /// <summary>
        /// Connects the server's queues to the RabbitMQ server and begins processing of messages.
        /// </summary>
        /// <param name="timeout">The maximum amount of time to wait for a successful connection.  An exception occurs upon timeout.</param>
        /// <param name="subscriptionTags"></param>
        public void Connect(TimeSpan timeout, MessageTagCollection subscriptionTags)
        {
            //TODO: Add subscription of broadcast tags

            SetupConnections(timeout, subscriptionTags);

            DedicatedQueue = MessageQueue.CreateExchangeBoundMessageQueue <ReadableMessageQueue>(this, Channel, ClientName, BroadcastExchangeName, DedicatedQueueName, this.QueuesAreDurable, this.AutoDeleteQueuesOnClose);
            DedicatedQueue.MessageReceived       += DedicatedQueue_MessageReceived;
            DedicatedQueue.AsynchronousException += (sender, eventArgs) => FireAsynchronousExceptionEvent(this, eventArgs);

            DedicatedQueue.BeginFullConsume(true);

            // Announce client to server
            ClientAnnounceMessage message = new ClientAnnounceMessage(PublicKeystore.ParentClientInfo);

            //TODO: Encrypt this?
            this.BroadcastToAllClients(message, false);

            //var result = this.WriteToServer(message, out response, out rawResponse, (int)timeout.TotalMilliseconds);

#if false
            if (result.CallResult == RpcCallResult.Timeout)
            {
                throw new ConnectionException("Timeout trying to communicate with the server.");
            }

            var resultMessage = (ClientAnnounceResponseMessage)result.ResponseMessageEnvelope.Message;

            switch (resultMessage.Response)
            {
            case AnnounceResponse.Accepted:
                clientServerHandshakeComplete = true;
                //serverName = result.ResponseMessageEnvelope.SenderName;
                PublicKeystore.SystemSharedKeys[resultMessage.SystemSharedKeyId] = resultMessage.SystemSharedKey;
                break;

            case AnnounceResponse.Rejected:
                throw new ConnectionException($"Client rejected by server with the following message: {result.ResponseMessageEnvelope.Message.MessageText}.");
            }

            //result.ResponseMessageEnvelope.ReverifySignature(PublicKeystore[result.ResponseMessageEnvelope.SenderName].Dsa);

            //TODO: This is where we need to determine what to do with a new unstrusted signature

            if (result.ResponseMessageEnvelope.SignatureVerificationStatus != SignatureVerificationStatus.SignatureValid &&
                result.ResponseMessageEnvelope.SignatureVerificationStatus != SignatureVerificationStatus.SignatureValidButUntrusted)
            {
                throw new Exception("Bad server key.");
            }
            else
            {
                //PublicKeystore.Merge(((ClientAnnounceResponseMessage)result.ResponseMessageEnvelope.Message).PublicKeystore);
                //TODO: Fix PublicKeystore[result.ResponseMessageEnvelope.SenderName].Iv = ((ClientAnnounceResponseMessage)result.ResponseMessageEnvelope.Message).Iv;

                if (HeartbeatInterval > 0)
                {
                    serverHeartbeatTimer.Interval = HeartbeatInterval * 2;
                    serverHeartbeatTimer.Elapsed += ServerHeartbeatTimer_Elapsed;
                    serverHeartbeatTimer.Start();

                    heartbeatSendTimer.Interval = HeartbeatInterval;
                    heartbeatSendTimer.Elapsed += HeartbeatSendTimer_Elapsed;
                    heartbeatSendTimer.Start();
                }
            }
#endif
            IsConnected = true;
        }