void CompareLists(IEnumerable <FindEventResult> list1, IEnumerable <FindEventResult> list2,
                          Dictionary <FindEventResult, XmlElement> rawMessages1, Dictionary <FindEventResult, XmlElement> rawMessages2,
                          string descr1, string descr2)
        {
            bool          ok   = true;
            StringBuilder dump = new StringBuilder();

            Dictionary <FindEventResult, FindEventResult> intersection = new Dictionary <FindEventResult, FindEventResult>();

            Func <FindEventResult, string, string> getDescription =
                new Func <FindEventResult, string, string>(
                    (e, topic) =>
            {
                return(string.Format("Event with Time={0}, RecordingToken='{1}', TrackToken='{2}', Topic='{3}'", e.Time, e.RecordingToken, e.TrackToken, topic));
            });


            // check events in list1, find events that are not in list2,
            // find events that are in both lists (intersection)

            foreach (FindEventResult ev1 in list1)
            {
                if (!ev1.StartStateEvent)
                {
                    XmlText   topicText = GetTopicElement(ev1);
                    TopicInfo topicInfo = CreateTopicInfo(ev1, rawMessages1[ev1]);

                    FindEventResult ev2   = list2.FirstOrDefault(E => AreTheSame(ev1, topicInfo, E, rawMessages2[E]));
                    string          topic = topicText.Value;

                    string descr = getDescription(ev1, topic);

                    if (ev2 == null)
                    {
                        ok = false;
                        dump.AppendFormat("{0} not found in {1}{2}",
                                          descr, descr2, Environment.NewLine);
                    }
                    else
                    {
                        intersection.Add(ev1, ev2);
                    }
                }
            }

            // check events in list2, find events that are not in list1

            foreach (FindEventResult ev2 in list2)
            {
                if (!ev2.StartStateEvent)
                {
                    XmlText   topicText = GetTopicElement(ev2);
                    TopicInfo topicInfo = CreateTopicInfo(ev2, rawMessages2[ev2]);
                    string    topic     = topicText.Value;
                    string    descr     = getDescription(ev2, topic);

                    FindEventResult ev1 = list1.FirstOrDefault(E => AreTheSame(ev2, topicInfo, E, rawMessages1[E]));

                    if (ev1 == null)
                    {
                        ok = false;
                        dump.AppendFormat("{0} not found in {1}{2}",
                                          descr, descr1, Environment.NewLine);
                    }
                }
            }

            // compare event in intersection
            // StartStateEvent
            // in Event:  ProducerReference, SubscriptionReference (should not both be empty?)
            // message items...

            foreach (FindEventResult ev1 in intersection.Keys)
            {
                bool          localOk = true;
                StringBuilder sb      = new StringBuilder(getDescription(ev1, GetTopicElement(ev1).Value));
                sb.AppendLine(" is different: ");

                FindEventResult ev2 = intersection[ev1];

                if (ev1.StartStateEvent != ev2.StartStateEvent)
                {
                    sb.AppendLine("StartStateEvent fields don't match");
                }

                // ProducerReference ?
                if (ev1.Event.ProducerReference != null && ev2.Event.ProducerReference != null)
                {
                    if (ev1.Event.ProducerReference.Address.Value != ev2.Event.ProducerReference.Address.Value)
                    {
                        localOk = false;
                        sb.AppendFormat("Event.ProducerReference fields don't match {0}", Environment.NewLine);
                    }
                }
                else
                {
                    if (ev1.Event.ProducerReference != null)
                    {
                        localOk = false;
                        sb.AppendFormat("Event.ProducerReference is missing in message from {0}{1}", descr2,
                                        Environment.NewLine);
                    }
                    if (ev2.Event.ProducerReference != null)
                    {
                        localOk = false;
                        sb.AppendFormat("Event.ProducerReference is missing in message from {0}{1}", descr1,
                                        Environment.NewLine);
                    }
                }

                // SubscriptionReference (?)
                if (ev1.Event.SubscriptionReference != null && ev2.Event.SubscriptionReference != null)
                {
                    if (ev1.Event.SubscriptionReference.Address.Value != ev2.Event.SubscriptionReference.Address.Value)
                    {
                        localOk = false;
                        sb.AppendFormat("Event.SubscriptionReference fields don't match {0}", Environment.NewLine);
                    }
                }
                else
                {
                    if (ev1.Event.SubscriptionReference != null)
                    {
                        localOk = false;
                        sb.AppendFormat("Event.SubscriptionReference is missing in message from {0}{1}", descr2,
                                        Environment.NewLine);
                    }
                    if (ev2.Event.SubscriptionReference != null)
                    {
                        localOk = false;
                        sb.AppendFormat("Event.SubscriptionReference is missing in message from {0}{1}", descr1,
                                        Environment.NewLine);
                    }
                }


                // Message items
                if (ev1.Event.Message != null && ev2.Event.Message != null)
                {
                    Dictionary <string, string> items1 = GetMessageSimpleItems(ev1.Event.Message);
                    Dictionary <string, string> items2 = GetMessageSimpleItems(ev2.Event.Message);

                    List <string> common = new List <string>();

                    foreach (string key in items1.Keys)
                    {
                        if (!items2.ContainsKey(key))
                        {
                            localOk = false;
                            sb.AppendFormat("SimpleItem with name='{0}' not found in message from {1}{2}", key, descr2,
                                            Environment.NewLine);
                        }
                        else
                        {
                            common.Add(key);
                        }
                    }
                    foreach (string key in items2.Keys)
                    {
                        if (!items2.ContainsKey(key))
                        {
                            localOk = false;
                            sb.AppendFormat("SimpleItem with name='{0}' not found in message from {1}{2}", key, descr1,
                                            Environment.NewLine);
                        }
                    }

                    foreach (string key in common)
                    {
                        if (items1[key] != items2[key])
                        {
                            localOk = false;
                            sb.AppendFormat("SimpleItem elements with name='{0}' have different values {1}", key, Environment.NewLine);
                        }
                    }

                    if (!localOk)
                    {
                        ok = false;
                        dump.Append(sb.ToString());
                    }
                }
                else
                {
                    if (ev1.Event.Message == null)
                    {
                        sb.AppendLine(string.Format("Message field is missing in structure from {0}", descr1));
                    }
                    if (ev2.Event.Message == null)
                    {
                        sb.AppendLine(string.Format("Message field is missing in structure from {0}", descr2));
                    }
                }
            }

            Assert(ok, dump.ToStringTrimNewLine(), "Check that events lists are the same");
        }
        void CompareLists(IEnumerable <FindEventResult> list1, IEnumerable <FindEventResult> list2,
                          Dictionary <FindEventResult, XmlElement> rawMessages1, Dictionary <FindEventResult, XmlElement> rawMessages2,
                          string descr1, string descr2)
        {
            bool          ok   = true;
            StringBuilder dump = new StringBuilder();

            Dictionary <FindEventResult, FindEventResult> intersection = new Dictionary <FindEventResult, FindEventResult>();

            Func <FindEventResult, string, string> getDescription =
                (e, topic) =>
            {
                return(string.Format("Event with Time={0}, RecordingToken='{1}', TrackToken='{2}', Topic='{3}'", e.Time, e.RecordingToken, e.TrackToken, topic));
            };


            // check events in list1, find events that are not in list2,
            // find events that are in both lists (intersection)

            foreach (FindEventResult ev1 in list1)
            {
                if (!ev1.StartStateEvent)
                {
                    XmlText   topicText = GetTopicElement(ev1);
                    TopicInfo topicInfo = CreateTopicInfo(ev1, rawMessages1[ev1]);

                    List <FindEventResult> filtered2 = list2.Where(E => AreTheSame(ev1, topicInfo, E, rawMessages2[E])).ToList();
                    string topic = topicText.Value;

                    string descr = getDescription(ev1, topic);

                    if (!filtered2.Any())
                    {
                        ok = false;
                        dump.AppendFormat("{0} not found in {1}{2}", descr, descr2, Environment.NewLine);
                    }
                    else
                    {
                        FindEventResult ev2 = filtered2.FirstOrDefault(E => HaveTheSamePayload(ev1, E));

                        if (ev2 != null)
                        {
                            intersection.Add(ev1, ev2);
                        }
                        else
                        {
                            // how to describe the error ?????
                            ok = false;
                            dump.AppendFormat("For {0} (or one of them) in {1}, no event with the same Data can be found in {2}{3}", descr, descr1, descr2, Environment.NewLine);
                        }
                    }
                }
            }

            // check events in list2, find events that are not in list1

            foreach (FindEventResult ev2 in list2)
            {
                if (!ev2.StartStateEvent)
                {
                    XmlText   topicText = GetTopicElement(ev2);
                    TopicInfo topicInfo = CreateTopicInfo(ev2, rawMessages2[ev2]);
                    string    topic     = topicText.Value;
                    string    descr     = getDescription(ev2, topic);

                    List <FindEventResult> filtered1 = list1.Where(E => AreTheSame(ev2, topicInfo, E, rawMessages1[E])).ToList();


                    if (!filtered1.Any())
                    {
                        ok = false;
                        dump.AppendFormat("{0} not found in {1}{2}", descr, descr1, Environment.NewLine);
                    }
                    else
                    {
                        FindEventResult ev1 = filtered1.FirstOrDefault(E => HaveTheSamePayload(ev2, E));
                        if (ev1 == null)
                        {
                            ok = false;
                            dump.AppendFormat("For {0} (or one of them) in {1}, no event with the same Data can be found in {2}{3}", descr, descr2, descr1, Environment.NewLine);
                        }
                    }
                }
            }


            // compare event in intersection
            // StartStateEvent
            // in Event:  ProducerReference, SubscriptionReference (should not both be empty?)
            // message items...

            foreach (FindEventResult ev1 in intersection.Keys)
            {
                bool          localOk = true;
                StringBuilder sb      = new StringBuilder(getDescription(ev1, GetTopicElement(ev1).Value));
                sb.AppendLine(" is different: ");

                FindEventResult ev2 = intersection[ev1];

                if (ev1.StartStateEvent != ev2.StartStateEvent)
                {
                    sb.AppendLine("StartStateEvent fields don't match");
                }

                // ProducerReference ?
                if (ev1.Event.ProducerReference != null && ev2.Event.ProducerReference != null)
                {
                    if (ev1.Event.ProducerReference.Address.Value != ev2.Event.ProducerReference.Address.Value)
                    {
                        localOk = false;
                        sb.AppendFormat("Event.ProducerReference fields don't match {0}", Environment.NewLine);
                    }
                }
                else
                {
                    if (ev1.Event.ProducerReference != null)
                    {
                        localOk = false;
                        sb.AppendFormat("Event.ProducerReference is missing in message from {0}{1}", descr2,
                                        Environment.NewLine);
                    }
                    if (ev2.Event.ProducerReference != null)
                    {
                        localOk = false;
                        sb.AppendFormat("Event.ProducerReference is missing in message from {0}{1}", descr1,
                                        Environment.NewLine);
                    }
                }

                // SubscriptionReference (?)
                if (ev1.Event.SubscriptionReference != null && ev2.Event.SubscriptionReference != null)
                {
                    if (ev1.Event.SubscriptionReference.Address.Value != ev2.Event.SubscriptionReference.Address.Value)
                    {
                        localOk = false;
                        sb.AppendFormat("Event.SubscriptionReference fields don't match {0}", Environment.NewLine);
                    }
                }
                else
                {
                    if (ev1.Event.SubscriptionReference != null)
                    {
                        localOk = false;
                        sb.AppendFormat("Event.SubscriptionReference is missing in message from {0}{1}", descr2,
                                        Environment.NewLine);
                    }
                    if (ev2.Event.SubscriptionReference != null)
                    {
                        localOk = false;
                        sb.AppendFormat("Event.SubscriptionReference is missing in message from {0}{1}", descr1,
                                        Environment.NewLine);
                    }
                }

                if (!localOk)
                {
                    ok = false;
                    dump.Append(sb.ToString());
                }
            }

            Assert(ok, dump.ToStringTrimNewLine(), "Check that events lists are the same");
        }