protected override bool CompareField(XElement field, Datagram parentDatagram, Datagram datagram)
        {
            IpDatagram  ipDatagram  = (IpDatagram)parentDatagram;
            UdpDatagram udpDatagram = (UdpDatagram)datagram;

            switch (field.Name())
            {
            case "udp.srcport":
                field.AssertShowDecimal(udpDatagram.SourcePort);
                break;

            case "udp.dstport":
                field.AssertShowDecimal(udpDatagram.DestinationPort);
                break;

            case "udp.port":
                Assert.IsTrue(ushort.Parse(field.Show()) == udpDatagram.SourcePort ||
                              ushort.Parse(field.Show()) == udpDatagram.DestinationPort);
                break;

            case "udp.length":
                field.AssertShowDecimal(udpDatagram.TotalLength);
                break;

            case "udp.checksum":
                field.AssertShowDecimal(udpDatagram.Checksum);
                if (udpDatagram.Checksum != 0)
                {
                    foreach (var checksumField in field.Fields())
                    {
                        switch (checksumField.Name())
                        {
                        case "udp.checksum_good":
                            checksumField.AssertShowDecimal(ipDatagram.IsTransportChecksumCorrect);
                            break;

                        case "udp.checksum_bad":
                            if (checksumField.Show() == "1")
                            {
                                Assert.IsFalse(ipDatagram.IsTransportChecksumCorrect);
                            }
                            else
                            {
                                checksumField.AssertShowDecimal(0);
                            }
                            break;
                        }
                    }
                }
                break;

            case "udp.checksum_coverage":
                field.AssertShowDecimal(udpDatagram.TotalLength);
                break;

            case "udp.stream":
                break;

            default:
                throw new InvalidOperationException("Invalid udp field " + field.Name());
            }

            return(true);
        }
        protected override bool CompareField(XElement field, Datagram parentDatagram, Datagram datagram)
        {
            IpDatagram  ipDatagram  = (IpDatagram)parentDatagram;
            TcpDatagram tcpDatagram = (TcpDatagram)datagram;

            switch (field.Name())
            {
            case "tcp.len":
                field.AssertShowDecimal(tcpDatagram.Length - tcpDatagram.HeaderLength);
                field.AssertNoFields();
                break;

            case "tcp.srcport":
                field.AssertShowDecimal(tcpDatagram.SourcePort);
                field.AssertNoFields();
                break;

            case "tcp.dstport":
                field.AssertShowDecimal(tcpDatagram.DestinationPort);
                field.AssertNoFields();
                break;

            case "tcp.port":
                Assert.IsTrue(ushort.Parse(field.Show()) == tcpDatagram.SourcePort ||
                              ushort.Parse(field.Show()) == tcpDatagram.DestinationPort);
                field.AssertNoFields();
                break;


            case "tcp.seq":
                field.AssertShowDecimal(tcpDatagram.SequenceNumber);
                field.AssertNoFields();
                break;

            case "tcp.nxtseq":
                field.AssertShowDecimal(tcpDatagram.NextSequenceNumber);
                field.AssertNoFields();
                break;

            case "tcp.ack":
                field.AssertShowDecimal(tcpDatagram.AcknowledgmentNumber);
                foreach (XElement subfield in field.Fields())
                {
                    switch (subfield.Name())
                    {
                    case "_ws.expert":
                        break;

                    default:
                        subfield.AssertNoFields();
                        throw new InvalidOperationException("Invalid TCP subfield name " + subfield.Name());
                    }
                }
                break;

            case "tcp.hdr_len":
                field.AssertShowDecimal(tcpDatagram.HeaderLength);
                field.AssertNoFields();
                break;

            case "tcp.flags":
                ushort flags =
                    (ushort)((tcpDatagram.Reserved << 9) |
                             (((tcpDatagram.ControlBits & TcpControlBits.NonceSum) == TcpControlBits.NonceSum ? 1 : 0) << 8) |
                             (byte)tcpDatagram.ControlBits);
                field.AssertShowDecimal(flags);
                foreach (var flagField in field.Fields())
                {
                    switch (flagField.Name())
                    {
                    case "tcp.flags.res":
                        flagField.AssertNoFields();
                        break;

                    case "tcp.flags.ns":
                        flagField.AssertNoFields();
                        flagField.AssertShowDecimal(tcpDatagram.IsNonceSum);
                        break;

                    case "tcp.flags.cwr":
                        flagField.AssertNoFields();
                        flagField.AssertShowDecimal(tcpDatagram.IsCongestionWindowReduced);
                        break;

                    case "tcp.flags.ecn":
                        flagField.AssertNoFields();
                        flagField.AssertShowDecimal(tcpDatagram.IsExplicitCongestionNotificationEcho);
                        break;

                    case "tcp.flags.urg":
                        flagField.AssertNoFields();
                        flagField.AssertShowDecimal(tcpDatagram.IsUrgent);
                        break;

                    case "tcp.flags.ack":
                        flagField.AssertNoFields();
                        flagField.AssertShowDecimal(tcpDatagram.IsAcknowledgment);
                        break;

                    case "tcp.flags.push":
                        flagField.AssertNoFields();
                        flagField.AssertShowDecimal(tcpDatagram.IsPush);
                        break;

                    case "tcp.flags.reset":
                        flagField.AssertShowDecimal(tcpDatagram.IsReset);
                        foreach (XElement subfield in flagField.Fields())
                        {
                            switch (subfield.Name())
                            {
                            case "_ws.expert":
                                break;

                            default:
                                throw new InvalidOperationException("Invalid TCP subfield name " + subfield.Name());
                            }
                        }
                        break;

                    case "tcp.flags.syn":
                        flagField.AssertShowDecimal(tcpDatagram.IsSynchronize);
                        foreach (XElement subfield in flagField.Fields())
                        {
                            switch (subfield.Name())
                            {
                            case "_ws.expert":
                                break;

                            default:
                                throw new InvalidOperationException("Invalid TCP subfield name " + subfield.Name());
                            }
                        }
                        break;

                    case "tcp.flags.fin":
                        flagField.AssertShowDecimal(tcpDatagram.IsFin);
                        foreach (XElement subfield in flagField.Fields())
                        {
                            switch (subfield.Name())
                            {
                            case "_ws.expert":
                                break;

                            default:
                                throw new InvalidOperationException("Invalid TCP subfield name " + subfield.Name());
                            }
                        }
                        break;

                    default:
                        throw new InvalidOperationException("Invalid TCP flag field name " + flagField.Name());
                    }
                }
                break;

            case "tcp.window_size_value":
                field.AssertShowDecimal(tcpDatagram.Window);
                field.AssertNoFields();
                break;

            case "tcp.checksum":
                field.AssertShowDecimal(tcpDatagram.Checksum);
                IpV4Datagram ipV4Datagram = ipDatagram as IpV4Datagram;
                if (ipV4Datagram != null)
                {
                    foreach (var checksumField in field.Fields())
                    {
                        // When TCP checksum is zero Wireshark assumes it's Checksum Offloading and puts false in both checksum_good and checksum_bad.
                        switch (checksumField.Name())
                        {
                        case "tcp.checksum_good":
                            checksumField.AssertNoFields();
                            checksumField.AssertShowDecimal(tcpDatagram.Checksum != 0 && ipDatagram.IsTransportChecksumCorrect);
                            break;

                        case "tcp.checksum_bad":
                            checksumField.AssertShowDecimal(!ipDatagram.IsTransportChecksumCorrect);
                            if (checksumField.Fields().Any())
                            {
                                checksumField.AssertNumFields(1);
                                checksumField.Fields().First().AssertName("_ws.expert");
                            }
                            break;

                        case "tcp.checksum_calculated":
                            checksumField.AssertNoFields();
                            if (ipDatagram.IsTransportChecksumCorrect)
                            {
                                checksumField.AssertShowDecimal(tcpDatagram.Checksum);
                            }
                            break;

                        default:
                            throw new InvalidOperationException("Invalid checksum field name " + checksumField.Name());
                        }
                    }
                }
                break;

            case "tcp.urgent_pointer":
                field.AssertShowDecimal(tcpDatagram.UrgentPointer);
                break;

            case "tcp.options":
                CompareTcpOptions(field, tcpDatagram.Options);
                break;

            case "tcp.stream":
            case "tcp.pdu.size":
            case "tcp.window_size":
            case "tcp.window_size_scalefactor":
                field.AssertNoFields();
                break;

            case "":
                if (field.Show() == "Short segment. Segment/fragment does not contain a full TCP header (might be NMAP or someone else deliberately sending unusual packets)")
                {
                    field.AssertNumFields(1);
                    field.Fields().First().AssertName("_ws.expert");
                }
                else
                {
                    field.AssertNoFields();
                }
                break;

            default:
                throw new InvalidOperationException("Invalid tcp field " + field.Name());
            }

            return(true);
        }