public void SaveMessage(ShadowMessageCommand shadowMessage)
        {
            PeerMessageQueue queue;
            if (!_savedMessages.TryGetValue(shadowMessage.PrimaryRecipient, out queue))
            {
                queue = new PeerMessageQueue(shadowMessage.PrimaryRecipient);
                _savedMessages[shadowMessage.PrimaryRecipient] = queue;
            }

            if (queue.OutOfOrderAcks.Count > 0 && queue.OutOfOrderAcks.ContainsKey(shadowMessage.Message.MessageIdentity))
            {
                Console.WriteLine(string.Format("removing out of order ack {0}", shadowMessage.Message.MessageIdentity));
                queue.OutOfOrderAcks.Remove(shadowMessage.Message.MessageIdentity);
                return;
            }
            queue[shadowMessage.TargetEndpoint].Enqueue(shadowMessage);
            queue.GlobalQueue.Enqueue(shadowMessage);
        }
        private void SendShadowMessages(IEnumerable<MessageSubscription> concernedSubscriptions, MessageWireData messageData, OutboundDisruptorEntry disruptorData)
        {
            foreach (var subscription in concernedSubscriptions)
            {
                HashSet<ServicePeer> targetShadows;
                if (_peersToShadows.TryGetValue(subscription.Peer, out targetShadows))
                {
                    var endpoints = targetShadows.Select(x => x.HandledMessages.Single(y => y.MessageType == typeof(ShadowMessageCommand)).Endpoint).Distinct();

                    foreach (var endpoint in endpoints)
                    {
                        var shadowMessage = new ShadowMessageCommand(messageData, subscription.Peer, true, subscription.Endpoint);
                        var shadowMessageData = CreateMessageWireData(shadowMessage);
                        var wireMessage = new WireSendingMessage(shadowMessageData, endpoint);
                        disruptorData.NetworkSenderData.WireMessages.Add(wireMessage);
                    }
                }
            }
        }