protected override bool CompareField(XElement field, Datagram datagram)
        {
            IpV6Datagram ipV6Datagram = datagram as IpV6Datagram;
            if (ipV6Datagram == null)
                return true;
            if (ipV6Datagram.NextHeader == IpV4Protocol.Cftp ||
                ipV6Datagram.ExtensionHeaders.Any(extensionHeader => extensionHeader.NextHeader == IpV4Protocol.Cftp))
                return false;
            // TODO: Remove after https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=9996 is fixed.
            if (ipV6Datagram.ExtensionHeaders.Select(extensionHeader => extensionHeader.NextHeader).Concat(ipV6Datagram.NextHeader).Any(
                protocol => protocol == IpV4Protocol.WidebandMonitoring ||
                            protocol == IpV4Protocol.SunNetworkDisk ||
                            protocol == IpV4Protocol.Swipe ||
                            protocol == IpV4Protocol.AnyHostInternal ||
                            protocol == IpV4Protocol.SourceDemandRoutingProtocol ||
                            protocol == IpV4Protocol.MobileInternetworkingControlProtocol ||
                            protocol == IpV4Protocol.IsoIp ||
                            protocol == IpV4Protocol.Kryptolan ||
                            protocol == IpV4Protocol.LArp ||
                            protocol == IpV4Protocol.SecureVersatileMessageTransactionProtocol ||
                            protocol == IpV4Protocol.WangSpanNetwork ||
                            protocol == IpV4Protocol.Cbt ||
                            protocol == IpV4Protocol.Visa ||
                            protocol == IpV4Protocol.SimpleMessageProtocol ||
                            protocol == IpV4Protocol.InternetPacketCoreUtility ||
                            protocol == IpV4Protocol.BbnRccMonitoring ||
                            protocol == IpV4Protocol.IpIp ||
                            protocol == IpV4Protocol.FibreChannel ||
                            protocol == IpV4Protocol.ServiceSpecificConnectionOrientedProtocolInAMultilinkAndConnectionlessEnvironment ||
                            protocol == IpV4Protocol.SitaraNetworksProtocol ||
                            protocol == IpV4Protocol.Fire ||
                            protocol == IpV4Protocol.Leaf1 ||
                            protocol == IpV4Protocol.IpsilonFlowManagementProtocol ||
                            protocol == IpV4Protocol.CompaqPeer ||
                            protocol == IpV4Protocol.InterDomainPolicyRoutingProtocolControlMessageTransportProtocol ||
                            protocol == IpV4Protocol.BulkDataTransferProtocol ||
                            protocol == IpV4Protocol.SemaphoreCommunicationsSecondProtocol ||
                            protocol == IpV4Protocol.Mobile ||
                            protocol == IpV4Protocol.HostMonitoringProtocol ||
                            protocol == IpV4Protocol.Chaos ||
                            protocol == IpV4Protocol.DiiDataExchange ||
                            protocol == IpV4Protocol.Emcon ||
                            protocol == IpV4Protocol.ThirdPartyConnect ||
                            protocol == IpV4Protocol.Aris ||
                            protocol == IpV4Protocol.NetworkVoice ||
                            protocol == IpV4Protocol.AnyPrivateEncryptionScheme ||
                            protocol == IpV4Protocol.PacketVideoProtocol ||
                            protocol == IpV4Protocol.PacketRadioMeasurement ||
                            protocol == IpV4Protocol.AnyLocalNetwork ||
                            protocol == IpV4Protocol.Qnx ||
                            protocol == IpV4Protocol.Tcf ||
                            protocol == IpV4Protocol.Ttp ||
                            protocol == IpV4Protocol.ScheduleTransferProtocol ||
                            protocol == IpV4Protocol.TransportLayerSecurityProtocol ||
                            protocol == IpV4Protocol.Ax25 ||
                            protocol == IpV4Protocol.CombatRadioTransportProtocol ||
                            protocol == IpV4Protocol.PerformanceTransparencyProtocol ||
                            protocol == IpV4Protocol.IntegratedNetLayerSecurityProtocol ||
                            protocol == IpV4Protocol.DatagramDeliveryProtocol ||
                            protocol == IpV4Protocol.PrivateNetworkToNetworkInterface ||
                            protocol == IpV4Protocol.Pipe ||
                            protocol == IpV4Protocol.BackroomSatMon ||
                            protocol == IpV4Protocol.Iplt ||
                            protocol == IpV4Protocol.Any0HopProtocol ||
                            protocol == IpV4Protocol.Leaf2 ||
                            protocol == IpV4Protocol.InterDomainPolicyRoutingProtocol ||
                            protocol == IpV4Protocol.NationalScienceFoundationNetworkInteriorGatewayProtocol ||
                            protocol == IpV4Protocol.WidebandExpak ||
                            protocol == IpV4Protocol.Uti ||
                            protocol == IpV4Protocol.Multiplexing ||
                            protocol == IpV4Protocol.Il ||
                            protocol == IpV4Protocol.MulticastTransportProtocol ||
                            protocol == IpV4Protocol.AnyDistributedFileSystem ||
                            protocol == IpV4Protocol.InteractiveAgentTransferProtocol ||
                            protocol == IpV4Protocol.InternetPluribusPacketCore ||
                            protocol == IpV4Protocol.InternetworkPacketExchangeInIp ||
                            protocol == IpV4Protocol.IntermediateSystemToIntermediateSystemOverIpV4 ||
                            protocol == IpV4Protocol.ComputerProtocolNetworkExecutive ||
                            protocol == IpV4Protocol.EncapsulationHeader ||
                            protocol == IpV4Protocol.GatewayToGateway ||
                            protocol == IpV4Protocol.SatMon ||
                            protocol == IpV4Protocol.VersatileMessageTransactionProtocol ||
                            protocol == IpV4Protocol.ReliableDatagramProtocol ||
                            protocol == IpV4Protocol.InternetReliableTransactionProtocol ||
                            protocol == IpV4Protocol.MeritInternodalProtocol ||
                            protocol == IpV4Protocol.Skip ||
                            protocol == IpV4Protocol.BurroughsNetworkArchitecture ||
                            protocol == IpV4Protocol.InterDomainRoutingProtocol ||
                            protocol == IpV4Protocol.ActiveNetworks ||
                            protocol == IpV4Protocol.SpectraLinkRadioProtocol ||
                            protocol == IpV4Protocol.MobileAdHocNetwork ||
                            protocol == IpV4Protocol.DissimilarGatewayProtocol ||
                            protocol == IpV4Protocol.SpriteRpc ||
                            protocol == IpV4Protocol.CombatRadioUserDatagram ||
                            protocol == IpV4Protocol.Gmtp ||
                            protocol == IpV4Protocol.MobileHostRoutingProtocol ||
                            protocol == IpV4Protocol.Shim6 ||  // TODO: Implement Shim6.
                            protocol == IpV4Protocol.RemoteVirtualDiskProtocol))
                return false;

            int currentExtensionHeaderIndex = ipV6Datagram.ExtensionHeaders.TakeWhile(extensionHeader => extensionHeader.Protocol != IpV4Protocol.MobilityHeader).Count();
            if (currentExtensionHeaderIndex >= ipV6Datagram.ExtensionHeaders.Headers.Count && !ipV6Datagram.IsValid)
                return false;
            IpV6ExtensionHeaderMobility mobilityHeader = (IpV6ExtensionHeaderMobility)ipV6Datagram.ExtensionHeaders[currentExtensionHeaderIndex];

            switch (field.Name())
            {
                case "mip6.proto":
                    field.AssertShowDecimal((byte)mobilityHeader.NextHeader);
                    field.AssertNoFields();
                    break;

                case "mip6.hlen":
                    if (mobilityHeader.IsValid)
                        field.AssertShowDecimal(mobilityHeader.Length / 8 - 1);
                    field.AssertNoFields();
                    break;

                case "mip6.mhtype":
                    field.AssertShowDecimal((byte)mobilityHeader.MobilityHeaderType);
                    break;

                case "mip6.reserved":
                    field.AssertShowDecimal(0);
                    field.AssertNoFields();
                    break;

                case "mip6.csum":
                    field.AssertShowDecimal(mobilityHeader.Checksum);
                    break;

                case "mip6.em.data":
                    IpV6ExtensionHeaderMobilityExperimental experimentalHeader = (IpV6ExtensionHeaderMobilityExperimental)mobilityHeader;
                    field.AssertValue(experimentalHeader.MessageData);
                    break;

                case "":
                    switch (field.Show())
                    {
                        case "Binding Refresh Request":
                            Assert.AreEqual(IpV6MobilityHeaderType.BindingRefreshRequest, mobilityHeader.MobilityHeaderType);
                            field.AssertNoFields();
                            break;

                        case "Heartbeat":
                            IpV6ExtensionHeaderMobilityHeartbeatMessage heartbeatMessage = (IpV6ExtensionHeaderMobilityHeartbeatMessage)mobilityHeader;
                            foreach (XElement subfield in field.Fields())
                            {
                                subfield.AssertNoFields();
                                switch (subfield.Name())
                                {
                                    case "mip6.hb.u_flag":
                                        subfield.AssertShowDecimal(heartbeatMessage.IsUnsolicitedHeartbeatResponse);
                                        break;

                                    case "mip6.hb.r_flag":
                                        subfield.AssertShowDecimal(heartbeatMessage.IsResponse);
                                        break;

                                    case "mip6.hb.seqnr":
                                        subfield.AssertShowDecimal(heartbeatMessage.SequenceNumber);
                                        break;

                                    default:
                                        throw new InvalidOperationException(string.Format("Invalid IPv6 Heartbeat mobility header field {0}", subfield.Name()));
                                }
                            }
                            break;

                        case "Binding Revocation Indication":
                            IpV6ExtensionHeaderMobilityBindingRevocationIndicationMessage bindingRevocationIndicationMessage = (IpV6ExtensionHeaderMobilityBindingRevocationIndicationMessage)mobilityHeader;
                            foreach (XElement subfield in field.Fields())
                            {
                                subfield.AssertNoFields();
                                switch (subfield.Name())
                                {
                                    case "mip6.bri_br.type":
                                        subfield.AssertShowDecimal((byte)bindingRevocationIndicationMessage.BindingRevocationType);
                                        break;

                                    case "mip6.bri_r.trigger":
                                        subfield.AssertShowDecimal((byte)bindingRevocationIndicationMessage.RevocationTrigger);
                                        break;

                                    case "mip6.bri_seqnr":
                                        subfield.AssertShowDecimal(bindingRevocationIndicationMessage.SequenceNumber);
                                        break;

                                    case "mip6.bri_ip":
                                        subfield.AssertShowDecimal(bindingRevocationIndicationMessage.ProxyBinding);
                                        break;

                                    case "mip6.bri_iv":
                                        subfield.AssertShowDecimal(bindingRevocationIndicationMessage.IpV4HomeAddressBindingOnly);
                                        break;

                                    case "mip6.bri_ig":
                                        subfield.AssertShowDecimal(bindingRevocationIndicationMessage.Global);
                                        break;

                                    case "mip6.bri_res":
                                        break;

                                    default:
                                        throw new InvalidOperationException(string.Format("Invalid IPv6 Binding Revocation Acknowledgement Message mobility header field {0}", subfield.Name()));
                                }
                            }
                            break;

                        case "Binding Revocation Acknowledge":
                            IpV6ExtensionHeaderMobilityBindingRevocationAcknowledgementMessage bindingRevocationAcknowledgementMessage = (IpV6ExtensionHeaderMobilityBindingRevocationAcknowledgementMessage)mobilityHeader;
                            foreach (XElement subfield in field.Fields())
                            {
                                subfield.AssertNoFields();
                                switch (subfield.Name())
                                {
                                    case "mip6.bri_br.type":
                                        subfield.AssertShowDecimal((byte)bindingRevocationAcknowledgementMessage.BindingRevocationType);
                                        break;

                                    case "mip6.bri_status":
                                        subfield.AssertShowDecimal((byte)bindingRevocationAcknowledgementMessage.Status);
                                        break;

                                    case "mip6.bri_seqnr":
                                        subfield.AssertShowDecimal(bindingRevocationAcknowledgementMessage.SequenceNumber);
                                        break;

                                    case "mip6.bri_ap":
                                        subfield.AssertShowDecimal(bindingRevocationAcknowledgementMessage.ProxyBinding);
                                        break;

                                    case "mip6.bri_av":
                                        subfield.AssertShowDecimal(bindingRevocationAcknowledgementMessage.IpV4HomeAddressBindingOnly);
                                        break;

                                    case "mip6.bri_ag":
                                        subfield.AssertShowDecimal(bindingRevocationAcknowledgementMessage.Global);
                                        break;

                                    case "mip6.bri_res":
                                        break;

                                    default:
                                        throw new InvalidOperationException(string.Format("Invalid IPv6 Binding Revocation Acknowledgement Message mobility header field {0}", subfield.Name()));
                                }
                            }
                            break;

                        case "Care-of Test Init":
                            IpV6ExtensionHeaderMobilityCareOfTestInit careOfTestInit = (IpV6ExtensionHeaderMobilityCareOfTestInit)mobilityHeader;
                            foreach (XElement subfield in field.Fields())
                            {
                                subfield.AssertNoFields();
                                switch (subfield.Name())
                                {
                                    case "mip6.coti.cookie":
                                        subfield.AssertShowDecimal(careOfTestInit.CareOfInitCookie);
                                        break;

                                    default:
                                        throw new InvalidOperationException(string.Format("Invalid IPv6 Care Of Test Init mobility header field {0}", subfield.Name()));
                                }
                            }
                            break;

                        case "Care-of Test":
                            IpV6ExtensionHeaderMobilityCareOfTest careOfTest = (IpV6ExtensionHeaderMobilityCareOfTest)mobilityHeader;
                            foreach (XElement subfield in field.Fields())
                            {
                                subfield.AssertNoFields();
                                switch (subfield.Name())
                                {
                                    case "mip6.cot.nindex":
                                        subfield.AssertShowDecimal(careOfTest.CareOfNonceIndex);
                                        break;

                                    case "mip6.cot.cookie":
                                        subfield.AssertShowDecimal(careOfTest.CareOfInitCookie);
                                        break;

                                    case "mip6.hot.token":
                                        subfield.AssertShowDecimal(careOfTest.CareOfKeygenToken);
                                        break;

                                    default:
                                        throw new InvalidOperationException(string.Format("Invalid IPv6 Care Of Test mobility header field {0}", subfield.Name()));
                                }
                            }
                            break;

                        case "Fast Binding Acknowledgement":
                            IpV6ExtensionHeaderMobilityFastBindingAcknowledgement fastBindingAcknowledgement = (IpV6ExtensionHeaderMobilityFastBindingAcknowledgement)mobilityHeader;
                            foreach (XElement subfield in field.Fields())
                            {
                                subfield.AssertNoFields();
                                switch (subfield.Name())
                                {
                                    case "fmip6.fback.status":
                                        subfield.AssertShowDecimal((byte)fastBindingAcknowledgement.Status);
                                        break;

                                    case "fmip6.fback.k_flag":
                                        subfield.AssertShowDecimal(fastBindingAcknowledgement.KeyManagementMobilityCapability);
                                        break;

                                    case "fmip6.fback.seqnr":
                                        subfield.AssertShowDecimal(fastBindingAcknowledgement.SequenceNumber);
                                        break;

                                    case "fmip6.fback.lifetime":
                                        subfield.AssertShowDecimal(fastBindingAcknowledgement.Lifetime);
                                        break;

                                    default:
                                        throw new InvalidOperationException(string.Format("Invalid IPv6 Fast Binding Acknowledgement mobility header field {0}", subfield.Name()));
                                }
                            }
                            break;

                        case "Binding Error":
                            IpV6ExtensionHeaderMobilityBindingError bindingError = (IpV6ExtensionHeaderMobilityBindingError)mobilityHeader;
                            foreach (XElement subfield in field.Fields())
                            {
                                subfield.AssertNoFields();
                                switch (subfield.Name())
                                {
                                    case "mip6.be.status":
                                        subfield.AssertShowDecimal((byte)bindingError.Status);
                                        break;

                                    case "mip6.be.haddr":
                                        subfield.AssertShow(bindingError.HomeAddress.ToString("x"));
                                        break;

                                    default:
                                        throw new InvalidOperationException(string.Format("Invalid IPv6 Binding Error mobility header field {0}", subfield.Name()));
                                }
                            }
                            break;

                        case "Fast Neighbor Advertisement":
                            Assert.AreEqual(IpV6MobilityHeaderType.FastNeighborAdvertisement, mobilityHeader.MobilityHeaderType);
                            field.AssertNoFields();
                            break;

                        case "Home Test":
                            IpV6ExtensionHeaderMobilityHomeTest homeTest = (IpV6ExtensionHeaderMobilityHomeTest)mobilityHeader;
                            foreach (XElement subfield in field.Fields())
                            {
                                subfield.AssertNoFields();
                                switch (subfield.Name())
                                {
                                    case "mip6.hot.nindex":
                                        subfield.AssertShowDecimal(homeTest.HomeNonceIndex);
                                        break;

                                    case "mip6.hot.cookie":
                                        subfield.AssertShowDecimal(homeTest.HomeInitCookie);
                                        break;

                                    case "mip6.hot.token":
                                        subfield.AssertShowDecimal(homeTest.HomeKeygenToken);
                                        break;

                                    default:
                                        throw new InvalidOperationException(string.Format("Invalid IPv6 Home Test mobility header field {0}", subfield.Name()));
                                }
                            }
                            break;

                        case "Home Test Init":
                            IpV6ExtensionHeaderMobilityHomeTestInit homeTestInit = (IpV6ExtensionHeaderMobilityHomeTestInit)mobilityHeader;
                            foreach (XElement subfield in field.Fields())
                            {
                                subfield.AssertNoFields();
                                switch (subfield.Name())
                                {
                                    case "mip6.hoti.cookie":
                                        subfield.AssertShowDecimal(homeTestInit.HomeInitCookie);
                                        break;

                                    default:
                                        throw new InvalidOperationException(string.Format("Invalid IPv6 Home Test Init mobility header field {0}", subfield.Name()));
                                }
                            }
                            break;

                        case "Binding Update":
                            IpV6ExtensionHeaderMobilityBindingUpdate bindingUpdate = (IpV6ExtensionHeaderMobilityBindingUpdate)mobilityHeader;
                            foreach (XElement subfield in field.Fields())
                            {
                                subfield.AssertNoFields();
                                switch (subfield.Name())
                                {
                                    case "mip6.bu.seqnr":
                                        subfield.AssertShowDecimal(bindingUpdate.SequenceNumber);
                                        break;

                                    case "mip6.bu.a_flag":
                                        subfield.AssertShowDecimal(bindingUpdate.Acknowledge);
                                        break;

                                    case "mip6.bu.h_flag":
                                        subfield.AssertShowDecimal(bindingUpdate.HomeRegistration);
                                        break;

                                    case "mip6.bu.l_flag":
                                        subfield.AssertShowDecimal(bindingUpdate.LinkLocalAddressCompatibility);
                                        break;

                                    case "mip6.bu.k_flag":
                                        subfield.AssertShowDecimal(bindingUpdate.KeyManagementMobilityCapability);
                                        break;

                                    case "mip6.bu.m_flag":
                                        subfield.AssertShowDecimal(bindingUpdate.MapRegistration);
                                        break;

                                    case "mip6.nemo.bu.r_flag":
                                        subfield.AssertShowDecimal(bindingUpdate.MobileRouter);
                                        break;

                                    case "mip6.bu.p_flag":
                                        subfield.AssertShowDecimal(bindingUpdate.ProxyRegistration);
                                        break;

                                    case "mip6.bu.f_flag":
                                        subfield.AssertShowDecimal(bindingUpdate.ForcingUdpEncapsulation);
                                        break;

                                    case "mip6.bu.t_flag":
                                        subfield.AssertShowDecimal(bindingUpdate.TypeLengthValueHeaderFormat);
                                        break;

                                    case "mip6.bu.b_flag":
                                        subfield.AssertShowDecimal(bindingUpdate.BulkBindingUpdate);
                                        break;

                                    case "mip6.bu.lifetime":
                                        subfield.AssertShowDecimal(bindingUpdate.Lifetime);
                                        break;

                                    default:
                                        throw new InvalidOperationException(string.Format("Invalid IPv6 Binding Update mobility header field {0}", subfield.Name()));
                                }
                            }
                            break;

                        case "Binding Acknowledgement":
                            IpV6ExtensionHeaderMobilityBindingAcknowledgement bindingAcknowledgement = (IpV6ExtensionHeaderMobilityBindingAcknowledgement)mobilityHeader;
                            foreach (XElement subfield in field.Fields())
                            {
                                subfield.AssertNoFields();
                                switch (subfield.Name())
                                {
                                    case "mip6.ba.status":
                                        subfield.AssertShowDecimal((byte)bindingAcknowledgement.Status);
                                        break;

                                    case "mip6.ba.k_flag":
                                        subfield.AssertShowDecimal(bindingAcknowledgement.KeyManagementMobilityCapability);
                                        break;

                                    case "mip6.nemo.ba.r_flag":
                                        subfield.AssertShowDecimal(bindingAcknowledgement.MobileRouter);
                                        break;

                                    case "mip6.ba.p_flag":
                                        subfield.AssertShowDecimal(bindingAcknowledgement.ProxyRegistration);
                                        break;

                                    case "mip6.ba.t_flag":
                                        subfield.AssertShowDecimal(bindingAcknowledgement.TypeLengthValueHeaderFormat);
                                        break;

                                    case "mip6.ba.b_flag":
                                        // TODO: Support Bulk Binding Update Support for Proxy Mobile IPv6 (RFC 6602).
                                        break;

                                    case "mip6.ba.seqnr":
                                        subfield.AssertShowDecimal(bindingAcknowledgement.SequenceNumber);
                                        break;

                                    case "mip6.ba.lifetime":
                                        subfield.AssertShowDecimal(bindingAcknowledgement.Lifetime);
                                        break;

                                    default:
                                        throw new InvalidOperationException(string.Format("Invalid IPv6 Binding Acknowledgement mobility header field {0}", subfield.Name()));
                                }
                            }
                            break;

                        case "Fast Binding Update":
                            IpV6ExtensionHeaderMobilityFastBindingUpdate fastBindingUpdate = (IpV6ExtensionHeaderMobilityFastBindingUpdate)mobilityHeader;
                            foreach (XElement subfield in field.Fields())
                            {
                                subfield.AssertNoFields();
                                switch (subfield.Name())
                                {
                                    case "fmip6.fbu.seqnr":
                                        subfield.AssertShowDecimal(fastBindingUpdate.SequenceNumber);
                                        break;

                                    case "fmip6.fbu.a_flag":
                                        subfield.AssertShowDecimal(fastBindingUpdate.Acknowledge);
                                        break;

                                    case "fmip6.fbu.h_flag":
                                        subfield.AssertShowDecimal(fastBindingUpdate.HomeRegistration);
                                        break;

                                    case "fmip6.fbu.l_flag":
                                        subfield.AssertShowDecimal(fastBindingUpdate.LinkLocalAddressCompatibility);
                                        break;

                                    case "fmip6.fbu.k_flag":
                                        subfield.AssertShowDecimal(fastBindingUpdate.KeyManagementMobilityCapability);
                                        break;

                                    case "fmip6.fbu.lifetime":
                                        subfield.AssertShowDecimal(fastBindingUpdate.Lifetime);
                                        break;

                                    default:
                                        throw new InvalidOperationException(string.Format("Invalid IPv6 Fast Binding Update mobility header field {0}", subfield.Name()));
                                }
                            }
                            break;

                        case "Handover Acknowledge ":
                            var handoverAcknowledgeMessage = (IpV6ExtensionHeaderMobilityHandoverAcknowledgeMessage)mobilityHeader;
                            foreach (XElement subfield in field.Fields())
                            {
                                subfield.AssertNoFields();
                                switch (subfield.Name())
                                {
                                    case "mip6.hack.seqnr":
                                        subfield.AssertShowDecimal(handoverAcknowledgeMessage.SequenceNumber);
                                        break;

                                    case "mip6.hack.code":
                                        subfield.AssertShowDecimal((byte)handoverAcknowledgeMessage.Code);
                                        break;

                                    default:
                                        throw new InvalidOperationException(string.Format("Invalid IPv6 Handover Acknowledge mobility header field {0}", subfield.Name()));
                                }
                            }
                            break;

                        case "Handover Initiate":
                            var handoverInitiateMessage = (IpV6ExtensionHeaderMobilityHandoverInitiateMessage)mobilityHeader;
                            foreach (XElement subfield in field.Fields())
                            {
                                subfield.AssertNoFields();
                                switch (subfield.Name())
                                {
                                    case "mip6.hi.seqnr":
                                        subfield.AssertShowDecimal(handoverInitiateMessage.SequenceNumber);
                                        break;

                                    case "mip6.hi.s_flag":
                                        subfield.AssertShowDecimal(handoverInitiateMessage.AssignedAddressConfiguration);
                                        break;

                                    case "mip6.hi.u_flag":
                                        subfield.AssertShowDecimal(handoverInitiateMessage.Buffer);
                                        break;

                                    case "mip6.hi.code":
                                        subfield.AssertShowDecimal((byte)handoverInitiateMessage.Code);
                                        break;

                                    default:
                                        throw new InvalidOperationException(string.Format("Invalid IPv6 mobility header field {0}", subfield.Name()));
                                }
                            }
                            break;

                        case "Mobility Options":
                            int optionIndex = 0;
                            foreach (XElement optionField in field.Fields())
                            {
                                IpV6MobilityOption option = mobilityHeader.MobilityOptions[optionIndex];
                                switch (optionField.Name())
                                {
                                    case "":
                                        switch (option.OptionType)
                                        {
                                            case IpV6MobilityOptionType.LinkLayerAddress:
                                                optionField.AssertShow("Mobility Header Link-Layer Address");
                                                IpV6MobilityOptionLinkLayerAddress linkLayerAddress = (IpV6MobilityOptionLinkLayerAddress)option;
                                                foreach (XElement optionSubfield in optionField.Fields())
                                                {
                                                    if (HandleCommonMobilityOptionSubfield(optionSubfield, option))
                                                        continue;

                                                    switch (optionSubfield.Name())
                                                    {
                                                        case "":
                                                            optionSubfield.AssertShow("Mobility Header Link-Layer Address option");
                                                            foreach (XElement optionSubsubfield in optionSubfield.Fields())
                                                            {
                                                                if (HandleCommonMobilityOptionSubfield(optionSubsubfield, option))
                                                                    continue;

                                                                switch (optionSubsubfield.Name())
                                                                {
                                                                    case "mip6.lla.optcode":
                                                                        optionSubsubfield.AssertShowDecimal((byte)linkLayerAddress.Code);
                                                                        break;

                                                                    case "":
                                                                        // TODO: Uncomment when https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=10627 is fixed.
//                                                                        optionSubsubfield.AssertValue(linkLayerAddress.LinkLayerAddress);
                                                                        break;

                                                                    default:
                                                                        throw new InvalidOperationException(string.Format(
                                                                            "Invalid IPv6 Link Layer Address option subfield {0}", optionSubsubfield.Name()));
                                                                }
                                                            }
                                                            break;

                                                        default:
                                                            throw new InvalidOperationException(string.Format(
                                                                "Invalid IPv6 Link Layer Address option field {0}", optionSubfield.Name()));
                                                    }
                                                }
                                                // TODO: Change to break when https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=10627 is fixed.
                                                return false;

                                            case IpV6MobilityOptionType.IpV4DefaultRouterAddress:
                                                var ipV4DefaultRouterAddress = (IpV6MobilityOptionIpV4DefaultRouterAddress)option;
                                                optionField.AssertShow("IPv4 Default-Router Address: " + ipV4DefaultRouterAddress.DefaultRouterAddress);
                                                foreach (XElement optionSubfield in optionField.Fields())
                                                {
                                                    if (HandleCommonMobilityOptionSubfield(optionSubfield, option))
                                                        continue;
                                                    optionSubfield.AssertNoFields();
                                                    switch (optionSubfield.Name())
                                                    {
                                                        case "mip6.ipv4dra.reserved":
                                                            optionSubfield.AssertShowDecimal(0);
                                                            break;

                                                        case "mip6.ipv4dra.dra":
                                                            optionSubfield.AssertShow(ipV4DefaultRouterAddress.DefaultRouterAddress.ToString());
                                                            break;

                                                        default:
                                                            throw new InvalidOperationException(
                                                                string.Format("Invalid IPv6 IPv4 Default Router Address option field {0}", optionSubfield.Name()));
                                                    }
                                                }
                                                break;

                                            case IpV6MobilityOptionType.Pad1:
                                                optionField.AssertShow("Pad1");
                                                optionField.AssertNoFields();
                                                break;

                                            case IpV6MobilityOptionType.PadN:
                                                if (optionField.Show() != "PadN" && optionIndex == mobilityHeader.MobilityOptions.Count - 1)
                                                {
                                                    Assert.IsFalse(mobilityHeader.IsValid);
                                                    return true;
                                                }
                                                optionField.AssertShow("PadN");
                                                IpV6MobilityOptionPadN padN = (IpV6MobilityOptionPadN)option;
                                                foreach (XElement optionSubfield in optionField.Fields())
                                                {
                                                    if (HandleCommonMobilityOptionSubfield(optionSubfield, option))
                                                        continue;
                                                    optionSubfield.AssertNoFields();
                                                    switch (optionSubfield.Name())
                                                    {
                                                        case "":
                                                            optionSubfield.AssertShow(string.Format("PadN: {0} bytes", padN.PaddingDataLength));
                                                            break;

                                                        default:
                                                            throw new InvalidOperationException(string.Format("Invalid IPv6 Mobility option subfield {0}",
                                                                                                              optionSubfield.Name()));
                                                    }
                                                }
                                                break;

                                            case IpV6MobilityOptionType.IpV4HomeAddressReply:
                                                IpV6MobilityOptionIpV4HomeAddressReply ipV4HomeAddressReply = (IpV6MobilityOptionIpV4HomeAddressReply)option;
                                                foreach (XElement optionSubfield in optionField.Fields())
                                                {
                                                    if (HandleCommonMobilityOptionSubfield(optionSubfield, option))
                                                        continue;
                                                    optionSubfield.AssertNoFields();
                                                    switch (optionSubfield.Name())
                                                    {
                                                        case "mip6.ipv4aa.sts":
                                                            optionSubfield.AssertShowDecimal((byte)ipV4HomeAddressReply.Status);
                                                            break;

                                                        default:
                                                            ValidateIpV6MobilityOptionIpV4HomeAddressField(optionSubfield, ipV4HomeAddressReply);
                                                            break;
                                                    }
                                                }
                                                break;

                                            case IpV6MobilityOptionType.IpV4HomeAddressRequest:
                                                var ipV4HomeAddressRequest = (IpV6MobilityOptionIpV4HomeAddressRequest)option;
                                                optionField.AssertShow("IPv4 Home Address Request: " + ipV4HomeAddressRequest.HomeAddress);
                                                foreach (XElement optionSubfield in optionField.Fields())
                                                {
                                                    if (HandleCommonMobilityOptionSubfield(optionSubfield, option))
                                                        continue;

                                                    optionSubfield.AssertNoFields();
                                                    ValidateIpV6MobilityOptionIpV4HomeAddressField(optionSubfield, ipV4HomeAddressRequest);
                                                }
                                                break;

                                            case IpV6MobilityOptionType.IpV4AddressAcknowledgement:
                                                optionField.AssertShow("IPv4 Address Acknowledgement");
                                                var ipV4AddressAcknowledgement = (IpV6MobilityOptionIpV4AddressAcknowledgement)option;
                                                foreach (XElement optionSubfield in optionField.Fields())
                                                {
                                                    if (HandleCommonMobilityOptionSubfield(optionSubfield, option))
                                                        continue;
                                                    switch (optionSubfield.Name())
                                                    {
                                                        case "":
                                                            optionSubfield.AssertShow("IPv4 Address Acknowledgement");
                                                            foreach (XElement optionSubsubfield in optionSubfield.Fields())
                                                            {
                                                                optionSubsubfield.AssertNoFields();
                                                                switch (optionSubsubfield.Name())
                                                                {
                                                                    case "mip6.ipv4aa.sts":
                                                                        optionSubsubfield.AssertShowDecimal((byte)ipV4AddressAcknowledgement.Status);
                                                                        break;

                                                                    default:
                                                                        ValidateIpV6MobilityOptionIpV4HomeAddressField(optionSubsubfield, ipV4AddressAcknowledgement);
                                                                        break;
                                                                }
                                                            }
                                                            break;

                                                        default:
                                                            throw new InvalidOperationException(string.Format("Invalid IPv6 Mobility option subfield {0}",
                                                                                                              optionSubfield.Name()));
                                                    }
                                                }
                                                break;

                                            case IpV6MobilityOptionType.MobileNetworkPrefix:
                                                optionField.AssertShow("Mobile Network Prefix");
                                                var mobileNetworkPrefix = (IpV6MobilityOptionMobileNetworkPrefix)option;
                                                foreach (XElement optionSubfield in optionField.Fields())
                                                {
                                                    if (HandleCommonMobilityOptionSubfield(optionSubfield, option))
                                                        continue;
                                                    switch (optionSubfield.Name())
                                                    {
                                                        case "":
                                                            optionSubfield.AssertShow("Mobile Network Prefix");
                                                            foreach (XElement optionSubsubfield in optionSubfield.Fields())
                                                            {
                                                                optionSubsubfield.AssertNoFields();
                                                                switch (optionSubsubfield.Name())
                                                                {
                                                                    case "mip6.nemo.mnp.mnp":
                                                                        optionSubsubfield.AssertShow(mobileNetworkPrefix.NetworkPrefix.ToString("x"));
                                                                        break;

                                                                    default:
                                                                        throw new InvalidOperationException(string.Format("Invalid IPv6 Mobility option subsubfield {0}",
                                                                                                                          optionSubsubfield.Name()));
                                                                }
                                                            }
                                                            break;

                                                        case "mip6.nemo.mnp.pfl":
                                                            optionSubfield.AssertNoFields();
                                                            optionSubfield.AssertShowDecimal(mobileNetworkPrefix.PrefixLength);
                                                            break;

                                                        default:
                                                            optionSubfield.AssertNoFields();
                                                            throw new InvalidOperationException(string.Format("Invalid IPv6 Mobility option subfield {0}",
                                                                                                              optionSubfield.Name()));
                                                    }
                                                }
                                                break;

                                            case IpV6MobilityOptionType.HomeNetworkPrefix:
                                                optionField.AssertShow("Home Network Prefix");
                                                var homeNetworkPrefix = (IpV6MobilityOptionHomeNetworkPrefix)option;
                                                foreach (XElement optionSubfield in optionField.Fields())
                                                {
                                                    if (HandleCommonMobilityOptionSubfield(optionSubfield, option))
                                                        continue;

                                                    switch (optionSubfield.Name())
                                                    {
                                                        case "":
                                                            optionSubfield.AssertShow("Home Network Prefix");
                                                            foreach (XElement optionSubsubfield in optionSubfield.Fields())
                                                            {
                                                                switch (optionSubsubfield.Name())
                                                                {
                                                                    case "mip6.nemo.mnp.mnp":
                                                                        optionSubsubfield.AssertShow(homeNetworkPrefix.NetworkPrefix.ToString("x"));
                                                                        break;

                                                                    default:
                                                                        throw new InvalidOperationException(string.Format("Invalid IPv6 Network Prefix option subfield {0}", optionSubsubfield.Name()));
                                                                }
                                                            }
                                                            break;

                                                        case "mip6.nemo.mnp.pfl":
                                                            optionSubfield.AssertShowDecimal(homeNetworkPrefix.PrefixLength);
                                                            break;

                                                        default:
                                                            throw new InvalidOperationException(string.Format("Invalid IPv6 Network Prefix option field {0}", optionSubfield.Name()));
                                                    }
                                                }
                                                break;

                                            case IpV6MobilityOptionType.VendorSpecific:
                                                Assert.IsTrue(optionField.Show().StartsWith("Vendor Specific: "));
                                                IpV6MobilityOptionVendorSpecific vendorSpecific = (IpV6MobilityOptionVendorSpecific)option;
                                                foreach (XElement optionSubfield in optionField.Fields())
                                                {
                                                    if (HandleCommonMobilityOptionSubfield(optionSubfield, option))
                                                        continue;
                                                    optionSubfield.AssertNoFields();
                                                    switch (optionSubfield.Name())
                                                    {
                                                        case "mip6.vsm.vendorId":
                                                            optionSubfield.AssertShowDecimal(vendorSpecific.VendorId);
                                                            break;

                                                        case "mip6.vsm.subtype":
                                                            optionSubfield.AssertShowDecimal(vendorSpecific.Subtype);
                                                            break;

                                                        case "":
                                                            optionSubfield.AssertValue(vendorSpecific.Data);
                                                            break;

                                                        default:
                                                            throw new InvalidOperationException(string.Format("Invalid IPv6 Vendor Specific option field {0}",
                                                                                                              optionSubfield.Name()));
                                                    }
                                                }
                                                break;

                                            case IpV6MobilityOptionType.NonceIndexes:
                                                optionField.AssertShow("Nonce Indices");
                                                IpV6MobilityOptionNonceIndexes nonceIndexes = (IpV6MobilityOptionNonceIndexes)option;
                                                foreach (XElement optionSubfield in optionField.Fields())
                                                {
                                                    if (HandleCommonMobilityOptionSubfield(optionSubfield, option))
                                                        continue;

                                                    switch (optionSubfield.Name())
                                                    {
                                                        case "":
                                                            optionSubfield.AssertShow("Nonce Indices");
                                                            foreach (XElement optionSubsubfield in optionSubfield.Fields())
                                                            {
                                                                optionSubsubfield.AssertNoFields();
                                                                switch (optionSubsubfield.Name())
                                                                {
                                                                    case "mip6.ni.hni":
                                                                        optionSubsubfield.AssertShowDecimal(nonceIndexes.HomeNonceIndex);
                                                                        break;

                                                                    case "mip6.ni.cni":
                                                                        optionSubsubfield.AssertShowDecimal(nonceIndexes.CareOfNonceIndex);
                                                                        break;

                                                                    default:
                                                                        throw new InvalidOperationException(string.Format("Invalid IPv6 Nonce Indices option subfield {0}",
                                                                                                                          optionSubsubfield.Name()));
                                                                }
                                                            }
                                                            break;

                                                        default:
                                                            throw new InvalidOperationException(string.Format("Invalid IPv6 Nonce Indices option field {0}",
                                                                                                              optionSubfield.Name()));
                                                    }
                                                }
                                                break;

                                            case IpV6MobilityOptionType.LinkLocalAddress:
                                                optionField.AssertShow("Link-local Address");
                                                IpV6MobilityOptionLinkLocalAddress linkLocalAddress = (IpV6MobilityOptionLinkLocalAddress)option;
                                                foreach (XElement optionSubfield in optionField.Fields())
                                                {
                                                    if (HandleCommonMobilityOptionSubfield(optionSubfield, option))
                                                        continue;
                                                    switch (optionSubfield.Name())
                                                    {
                                                        case "":
                                                            optionSubfield.AssertShow("Link-local Address");
                                                            foreach (XElement optionSubsubfield in optionSubfield.Fields())
                                                            {
                                                                optionSubsubfield.AssertNoFields();
                                                                switch (optionSubsubfield.Name())
                                                                {
                                                                    case "mip6.lila_lla":
                                                                        optionSubsubfield.AssertShow(linkLocalAddress.LinkLocalAddress.ToString("x"));
                                                                        break;

                                                                    default:
                                                                        throw new InvalidOperationException(string.Format(
                                                                            "Invalid IPv6 Link-local Address option field {0}", optionSubsubfield.Name()));
                                                                }
                                                            }
                                                            break;

                                                        default:
                                                            throw new InvalidOperationException(string.Format(
                                                                "Invalid IPv6 Link-local Address option field {0}", optionSubfield.Name()));
                                                    }
                                                }
                                                break;

                                            case IpV6MobilityOptionType.MobileNodeIdentifier:
                                                Assert.IsTrue(optionField.Show().StartsWith("Mobile Node Identifier"));
                                                IpV6MobilityOptionMobileNodeIdentifier mobileNodeIdentifier = (IpV6MobilityOptionMobileNodeIdentifier)option;
                                                foreach (XElement optionSubfield in optionField.Fields())
                                                {
                                                    if (HandleCommonMobilityOptionSubfield(optionSubfield, option))
                                                        continue;

                                                    optionSubfield.AssertNoFields();
                                                    switch (optionSubfield.Name())
                                                    {
                                                        case "mip6.mnid.subtype":
                                                            optionSubfield.AssertShowDecimal((byte)mobileNodeIdentifier.Subtype);
                                                            break;

                                                        case "":
                                                            optionSubfield.AssertValue(mobileNodeIdentifier.Identifier);
                                                            break;

                                                        default:
                                                            throw new InvalidOperationException(
                                                                string.Format("Invalid IPv6 Mobile Node Identifier option field {0}", optionSubfield.Name()));
                                                    }
                                                }
                                                break;

                                            case IpV6MobilityOptionType.BindingAuthorizationData:
                                                optionField.AssertShow("Authorization Data");
                                                IpV6MobilityOptionBindingAuthorizationData authorizationData =
                                                    (IpV6MobilityOptionBindingAuthorizationData)option;
                                                foreach (XElement optionSubfield in optionField.Fields())
                                                {
                                                    if (HandleCommonMobilityOptionSubfield(optionSubfield, option))
                                                        continue;

                                                    switch (optionSubfield.Name())
                                                    {
                                                        case "":
                                                            foreach (XElement authSubfield in optionSubfield.Fields())
                                                            {
                                                                switch (authSubfield.Name())
                                                                {
                                                                    case "mip6.bad.auth":
                                                                        authSubfield.AssertValue(authorizationData.Authenticator);
                                                                        break;

                                                                    default:
                                                                        throw new InvalidOperationException(
                                                                            string.Format("Invalid IPv6 Authorization Data option subfield {0}",
                                                                                          authSubfield.Name()));
                                                                }
                                                            }
                                                            break;

                                                        default:
                                                            throw new InvalidOperationException(string.Format(
                                                                "Invalid IPv6 Authorization Data option field {0}", optionSubfield.Name()));
                                                    }
                                                }
                                                break;

                                            case IpV6MobilityOptionType.IpV4HomeAddress:
                                                optionField.AssertShow("IPv4 Home Address");
                                                IpV6MobilityOptionIpV4HomeAddress ipV4HomeAddress = (IpV6MobilityOptionIpV4HomeAddress)option;
                                                foreach (XElement optionSubfield in optionField.Fields())
                                                {
                                                    if (HandleCommonMobilityOptionSubfield(optionSubfield, option))
                                                        continue;

                                                    switch (optionSubfield.Name())
                                                    {
                                                        case "":
                                                            foreach (XElement optionSubsubfield in optionSubfield.Fields())
                                                            {
                                                                optionSubsubfield.AssertNoFields();
                                                                switch (optionSubsubfield.Name())
                                                                {
                                                                    case "mip6.ipv4ha.p_flag":
                                                                        optionSubsubfield.AssertShowDecimal(ipV4HomeAddress.RequestPrefix);
                                                                        break;

                                                                    default:
                                                                        ValidateIpV6MobilityOptionIpV4HomeAddressField(optionSubsubfield, ipV4HomeAddress);
                                                                        break;
                                                                }
                                                            }
                                                            break;

                                                        default:
                                                            throw new InvalidOperationException(string.Format(
                                                                "Invalid IPv6 Authorization Data option field {0}", optionSubfield.Name()));
                                                    }
                                                }
                                                break;

                                            case IpV6MobilityOptionType.ServiceSelection:
                                                IpV6MobilityOptionServiceSelection serviceSelection = (IpV6MobilityOptionServiceSelection)option;
                                                foreach (XElement optionSubfield in optionField.Fields())
                                                {
                                                    if (HandleCommonMobilityOptionSubfield(optionSubfield, option))
                                                        continue;
                                                    optionSubfield.AssertNoFields();
                                                    switch (optionSubfield.Name())
                                                    {
                                                        case "mip6.ss.identifier":
                                                            optionSubfield.AssertValue(serviceSelection.Identifier);
                                                            break;

                                                        default:
                                                            throw new InvalidOperationException(string.Format("Invalid IPv6 Mobility option subfield {0}",
                                                                                                              optionSubfield.Name()));
                                                    }
                                                }
                                                break;

                                            case IpV6MobilityOptionType.RedirectCapability:
                                                IpV6MobilityOptionRedirectCapability redirectCapability = (IpV6MobilityOptionRedirectCapability)option;
                                                foreach (XElement optionSubfield in optionField.Fields())
                                                {
                                                    if (HandleCommonMobilityOptionSubfield(optionSubfield, option))
                                                        continue;
                                                    optionSubfield.AssertNoFields();
                                                    switch (optionSubfield.Name())
                                                    {
                                                        case "mip6.recap.reserved":
                                                            optionSubfield.AssertShowDecimal(0);
                                                            break;

                                                        default:
                                                            throw new InvalidOperationException(string.Format("Invalid IPv6 Mobility option subfield {0}",
                                                                                                              optionSubfield.Name()));
                                                    }
                                                }
                                                break;

                                            case IpV6MobilityOptionType.BindingIdentifier:
                                                IpV6MobilityOptionBindingIdentifier bindingIdentifier = (IpV6MobilityOptionBindingIdentifier)option;
                                                foreach (XElement optionSubfield in optionField.Fields())
                                                {
                                                    if (HandleCommonMobilityOptionSubfield(optionSubfield, option))
                                                        continue;
                                                    optionSubfield.AssertNoFields();
                                                    switch (optionSubfield.Name())
                                                    {
                                                        case "mip6.bi.bid":
                                                            optionSubfield.AssertShowDecimal(bindingIdentifier.BindingId);
                                                            break;

                                                        case "mip6.bi.status":
                                                            optionSubfield.AssertShowDecimal((byte)bindingIdentifier.Status);
                                                            break;

                                                        case "mip6.bi.h_flag":
                                                            optionSubfield.AssertShowDecimal(bindingIdentifier.SimultaneousHomeAndForeignBinding);
                                                            break;

                                                        default:
                                                            throw new InvalidOperationException(string.Format("Invalid IPv6 Mobility option subfield {0}",
                                                                                                              optionSubfield.Name()));
                                                    }
                                                }
                                                break;

                                            case IpV6MobilityOptionType.LoadInformation:
                                                IpV6MobilityOptionLoadInformation loadInformation = (IpV6MobilityOptionLoadInformation)option;
                                                foreach (XElement optionSubfield in optionField.Fields())
                                                {
                                                    if (HandleCommonMobilityOptionSubfield(optionSubfield, option))
                                                        continue;

                                                    optionSubfield.AssertNoFields();
                                                    switch (optionSubfield.Name())
                                                    {
                                                        case "mip6.load_inf.priority":
                                                            optionSubfield.AssertShowDecimal(loadInformation.Priority);
                                                            break;

                                                        case "mip6.load_inf.sessions_in_use":
                                                            optionSubfield.AssertShowDecimal(loadInformation.SessionsInUse);
                                                            break;

                                                        case "mip6.load_inf.maximum_sessions":
                                                            optionSubfield.AssertShowDecimal(loadInformation.MaximumSessions);
                                                            break;

                                                        case "mip6.load_inf.used_capacity":
                                                            optionSubfield.AssertShowDecimal(loadInformation.UsedCapacity);
                                                            break;

                                                        case "mip6.load_inf.maximum_capacity":
                                                            optionSubfield.AssertShowDecimal(loadInformation.MaximumCapacity);
                                                            break;

                                                        default:
                                                            throw new InvalidOperationException(string.Format("Invalid IPv6 Mobility option subfield {0}",
                                                                                                              optionSubfield.Name()));
                                                    }
                                                }
                                                break;

                                            case IpV6MobilityOptionType.IpV4CareOfAddress:
                                                IpV6MobilityOptionIpV4CareOfAddress ipV4CareOfAddress = (IpV6MobilityOptionIpV4CareOfAddress)option;
                                                foreach (XElement optionSubfield in optionField.Fields())
                                                {
                                                    if (HandleCommonMobilityOptionSubfield(optionSubfield, option))
                                                        continue;

                                                    optionSubfield.AssertNoFields();
                                                    switch (optionSubfield.Name())
                                                    {
                                                        case "mip6.ipv4coa.reserved":
                                                            optionSubfield.AssertShowDecimal(0);
                                                            break;

                                                        case "mip6.ipv4coa.addr":
                                                            optionSubfield.AssertShow(ipV4CareOfAddress.CareOfAddress.ToString());
                                                            break;

                                                        default:
                                                            throw new InvalidOperationException(string.Format("Invalid IPv6 Mobility option subfield {0}",
                                                                                                              optionSubfield.Name()));
                                                    }
                                                }
                                                break;

                                            case IpV6MobilityOptionType.CryptographicallyGeneratedAddressParametersRequest:
                                                foreach (XElement optionSubfield in optionField.Fields())
                                                {
                                                    if (HandleCommonMobilityOptionSubfield(optionSubfield, option))
                                                        continue;

                                                    optionSubfield.AssertNoFields();
                                                    switch (optionSubfield.Name())
                                                    {
                                                        default:
                                                            throw new InvalidOperationException(string.Format("Invalid IPv6 Mobility option subfield {0}",
                                                                                                              optionSubfield.Name()));
                                                    }
                                                }
                                                break;

                                            case IpV6MobilityOptionType.IpV6AddressPrefix:
                                                var ipV6AddressPrefix = (IpV6MobilityOptionIpV6AddressPrefix)option;
                                                foreach (XElement optionSubfield in optionField.Fields())
                                                {
                                                    if (HandleCommonMobilityOptionSubfield(optionSubfield, option))
                                                        continue;

                                                    optionSubfield.AssertNoFields();
                                                    switch (optionSubfield.Name())
                                                    {
                                                        case "mip6.mhipv6ap.opt_code":
                                                            optionSubfield.AssertShowDecimal((byte)ipV6AddressPrefix.Code);
                                                            break;

                                                        case "mip6.mhipv6ap.len":
                                                            optionSubfield.AssertShowDecimal(ipV6AddressPrefix.PrefixLength);
                                                            break;

                                                        case "mip6.mhipv6ap.ipv6_address":
                                                            optionSubfield.AssertValue(ipV6AddressPrefix.AddressOrPrefix.ToValue());
                                                            break;

                                                        case "mip6.mhipv6ap.ipv6_address_prefix":
                                                            Assert.IsTrue(optionSubfield.Value().EndsWith(ipV6AddressPrefix.AddressOrPrefix.ToValue().ToString("x32")));
                                                            break;

                                                        default:
                                                            throw new InvalidOperationException(string.Format("Invalid IPv6 Mobility option subfield {0}",
                                                                                                              optionSubfield.Name()));
                                                    }
                                                }
                                                break;

                                            case IpV6MobilityOptionType.MobileNodeGroupIdentifier:
                                                var mobileNodeGroupIdentifier = (IpV6MobilityOptionMobileNodeGroupIdentifier)option;
                                                foreach (XElement optionSubfield in optionField.Fields())
                                                {
                                                    if (HandleCommonMobilityOptionSubfield(optionSubfield, option))
                                                        continue;

                                                    optionSubfield.AssertNoFields();
                                                    switch (optionSubfield.Name())
                                                    {
                                                        case "mip6.mng.sub_type":
                                                            optionSubfield.AssertShowDecimal((byte)mobileNodeGroupIdentifier.Subtype);
                                                            break;

                                                        case "mip6.mng.reserved":
                                                            optionSubfield.AssertShowDecimal(0);
                                                            break;

                                                        case "mip6.mng._mng_id":
                                                            optionSubfield.AssertShowDecimal(mobileNodeGroupIdentifier.MobileNodeGroupIdentifier);
                                                            break;

                                                        default:
                                                            throw new InvalidOperationException(string.Format("Invalid IPv6 Mobility option subfield {0}",
                                                                                                              optionSubfield.Name()));
                                                    }
                                                }
                                                break;

                                            case IpV6MobilityOptionType.BindingAuthorizationDataForFmIpV6:
                                                var bindingAuthorizationDataForFmIpV6 = (IpV6MobilityOptionBindingAuthorizationDataForFmIpV6)option;
                                                foreach (XElement optionSubfield in optionField.Fields())
                                                {
                                                    if (HandleCommonMobilityOptionSubfield(optionSubfield, option))
                                                        continue;

                                                    optionSubfield.AssertNoFields();
                                                    switch (optionSubfield.Name())
                                                    {
                                                        case "mip6.badff.spi":
                                                            optionSubfield.AssertShowDecimal(bindingAuthorizationDataForFmIpV6.SecurityParameterIndex);
                                                            break;

                                                        case "mip6.badff.auth":
                                                            optionSubfield.AssertValue(bindingAuthorizationDataForFmIpV6.Authenticator);
                                                            break;

                                                        default:
                                                            throw new InvalidOperationException(string.Format("Invalid IPv6 Mobility option subfield {0}",
                                                                                                              optionSubfield.Name()));
                                                    }
                                                }
                                                break;

                                            case IpV6MobilityOptionType.MobileNodeLinkLayerIdentifier:
                                                var mobileNodeLinkLayerIdentifier = (IpV6MobilityOptionMobileNodeLinkLayerIdentifier)option;
                                                foreach (XElement optionSubfield in optionField.Fields())
                                                {
                                                    if (HandleCommonMobilityOptionSubfield(optionSubfield, option))
                                                        continue;

                                                    optionSubfield.AssertNoFields();
                                                    switch (optionSubfield.Name())
                                                    {
                                                        case "mip6.mnlli.reserved":
                                                            optionSubfield.AssertShowDecimal(0);
                                                            break;

                                                        case "mip6.mnlli.lli":
                                                            optionSubfield.AssertValue(mobileNodeLinkLayerIdentifier.LinkLayerIdentifier);
                                                            break;

                                                        default:
                                                            throw new InvalidOperationException(string.Format("Invalid IPv6 Mobility option subfield {0}",
                                                                                                              optionSubfield.Name()));
                                                    }
                                                }
                                                break;

                                            case IpV6MobilityOptionType.AccessTechnologyType:
                                                var accessTechnologyType = (IpV6MobilityOptionAccessTechnologyType)option;
                                                foreach (XElement optionSubfield in optionField.Fields())
                                                {
                                                    if (HandleCommonMobilityOptionSubfield(optionSubfield, option))
                                                        continue;

                                                    optionSubfield.AssertNoFields();
                                                    switch (optionSubfield.Name())
                                                    {
                                                        case "mip6.att.reserved":
                                                            optionSubfield.AssertShowDecimal(0);
                                                            break;

                                                        case "mip6.att":
                                                            optionSubfield.AssertShowDecimal((byte)accessTechnologyType.AccessTechnologyType);
                                                            break;

                                                        default:
                                                            throw new InvalidOperationException(string.Format("Invalid IPv6 Mobility option subfield {0}",
                                                                                                              optionSubfield.Name()));
                                                    }
                                                }
                                                break;

                                            case IpV6MobilityOptionType.AccessNetworkIdentifier:
                                                foreach (XElement optionSubfield in optionField.Fields())
                                                {
                                                    if (HandleCommonMobilityOptionSubfield(optionSubfield, option))
                                                        continue;

                                                    switch (optionSubfield.Name())
                                                    {
                                                        case "_ws.expert":
                                                            break;

                                                        default:
                                                            throw new InvalidOperationException(string.Format("Invalid IPv6 Mobility option subfield {0}",
                                                                                                              optionSubfield.Name()));
                                                    }
                                                }
                                                break;

                                            case IpV6MobilityOptionType.BindingRefreshAdvice:
                                                var bindingRefreshAdvice = (IpV6MobilityOptionBindingRefreshAdvice)option;
                                                foreach (XElement optionSubfield in optionField.Fields())
                                                {
                                                    if (HandleCommonMobilityOptionSubfield(optionSubfield, option))
                                                        continue;

                                                    optionSubfield.AssertNoFields();
                                                    switch (optionSubfield.Name())
                                                    {
                                                        case "mip6.bra.interval":
                                                            optionSubfield.AssertShowDecimal(bindingRefreshAdvice.RefreshInterval);
                                                            break;

                                                        default:
                                                            throw new InvalidOperationException(string.Format("Invalid IPv6 Mobility option subfield {0}",
                                                                                                              optionSubfield.Name()));
                                                    }
                                                }
                                                break;

                                            case IpV6MobilityOptionType.PermanentHomeKeygenToken:
                                                var permanentHomeKeygenToken = (IpV6MobilityOptionPermanentHomeKeygenToken)option;
                                                foreach (XElement optionSubfield in optionField.Fields())
                                                {
                                                    if (HandleCommonMobilityOptionSubfield(optionSubfield, option))
                                                        continue;

                                                    optionSubfield.AssertNoFields();
                                                    switch (optionSubfield.Name())
                                                    {
                                                        case "mip6.phkt.phkt":
                                                            optionSubfield.AssertValue(permanentHomeKeygenToken.PermanentHomeKeygenToken);
                                                            break;

                                                        default:
                                                            throw new InvalidOperationException(string.Format("Invalid IPv6 Mobility option subfield {0}",
                                                                                                              optionSubfield.Name()));
                                                    }
                                                }
                                                break;

                                            case IpV6MobilityOptionType.Redirect:
                                                var redirect = (IpV6MobilityOptionRedirect)option;
                                                foreach (XElement optionSubfield in optionField.Fields())
                                                {
                                                    if (HandleCommonMobilityOptionSubfield(optionSubfield, option))
                                                        continue;

                                                    optionSubfield.AssertNoFields();
                                                    switch (optionSubfield.Name())
                                                    {
                                                        case "mip6.redir.k":
                                                            optionSubfield.AssertShowDecimal(redirect.LocalMobilityAddressIpV6 != null);
                                                            break;

                                                        case "mip6.redir.n":
                                                            optionSubfield.AssertShowDecimal(redirect.LocalMobilityAddressIpV4 != null);
                                                            break;

                                                        case "mip6.redir.reserved":
                                                            optionSubfield.AssertShowDecimal(0);
                                                            break;

                                                        case "mip6.redir.addr_r2lma_ipv4":
                                                            optionSubfield.AssertShow(redirect.LocalMobilityAddressIpV4.ToString());
                                                            break;

                                                        case "mip6.redir.addr_r2lma_ipv6":
                                                            optionSubfield.AssertValue(redirect.LocalMobilityAddressIpV6.Value.ToValue());
                                                            break;

                                                        default:
                                                            throw new InvalidOperationException(string.Format("Invalid IPv6 Mobility option subfield {0}",
                                                                                                              optionSubfield.Name()));
                                                    }
                                                }
                                                break;

                                            case IpV6MobilityOptionType.CareOfTest:
                                                var careOfTestOption = (IpV6MobilityOptionCareOfTest)option;
                                                foreach (XElement optionSubfield in optionField.Fields())
                                                {
                                                    if (HandleCommonMobilityOptionSubfield(optionSubfield, option))
                                                        continue;

                                                    optionSubfield.AssertNoFields();
                                                    switch (optionSubfield.Name())
                                                    {
                                                        case "mip6.mocot.co_keygen_tok":
                                                            optionSubfield.AssertValue(careOfTestOption.CareOfKeygenToken);
                                                            break;

                                                        default:
                                                            throw new InvalidOperationException(string.Format("Invalid IPv6 Mobility option subfield {0}",
                                                                                                              optionSubfield.Name()));
                                                    }
                                                }
                                                break;

                                            case IpV6MobilityOptionType.ReplayProtection:
                                                var replayProtection = (IpV6MobilityOptionReplayProtection)option;
                                                foreach (XElement optionSubfield in optionField.Fields())
                                                {
                                                    if (HandleCommonMobilityOptionSubfield(optionSubfield, option))
                                                        continue;

                                                    switch (optionSubfield.Name())
                                                    {
                                                        case "mip6.mseg_id.timestamp":
                                                            optionSubfield.AssertValue(replayProtection.Timestamp);
                                                            break;

                                                        default:
                                                            throw new InvalidOperationException(string.Format("Invalid IPv6 Mobility option subfield {0}",
                                                                                                              optionSubfield.Name()));
                                                    }
                                                }
                                                break;

                                            case IpV6MobilityOptionType.Authentication:
                                                var authentication = (IpV6MobilityOptionAuthentication)option;
                                                foreach (XElement optionSubfield in optionField.Fields())
                                                {
                                                    if (HandleCommonMobilityOptionSubfield(optionSubfield, option))
                                                        continue;

                                                    optionSubfield.AssertNoFields();
                                                    switch (optionSubfield.Name())
                                                    {
                                                        case "mip6.auth.subtype":
                                                            optionSubfield.AssertShowDecimal((byte)authentication.Subtype);
                                                            break;

                                                        case "mip6.auth.mobility_spi":
                                                            optionSubfield.AssertShowDecimal(authentication.MobilitySecurityParameterIndex);
                                                            break;

                                                        case "mip6.auth.auth_data":
                                                            optionSubfield.AssertValue(authentication.AuthenticationData);
                                                            break;

                                                        default:
                                                            throw new InvalidOperationException(string.Format("Invalid IPv6 Mobility option subfield {0}",
                                                                                                              optionSubfield.Name()));
                                                    }
                                                }
                                                break;

                                            case IpV6MobilityOptionType.HandoffIndicator:
                                                var handoffIndicator = (IpV6MobilityOptionHandoffIndicator)option;
                                                foreach (XElement optionSubfield in optionField.Fields())
                                                {
                                                    if (HandleCommonMobilityOptionSubfield(optionSubfield, option))
                                                        continue;

                                                    optionSubfield.AssertNoFields();
                                                    switch (optionSubfield.Name())
                                                    {
                                                        case "mip6.hi.reserved":
                                                            optionSubfield.AssertShowDecimal(0);
                                                            break;

                                                        case "mip6.hi":
                                                            optionSubfield.AssertShowDecimal((byte)handoffIndicator.HandoffIndicator);
                                                            break;

                                                        default:
                                                            throw new InvalidOperationException(string.Format("Invalid IPv6 Mobility option subfield {0}",
                                                                                                              optionSubfield.Name()));
                                                    }
                                                }
                                                break;

                                            case IpV6MobilityOptionType.IpV4DhcpSupportMode:
                                                var ipV4DhcpSupportMode = (IpV6MobilityOptionIpV4DhcpSupportMode)option;
                                                foreach (XElement optionSubfield in optionField.Fields())
                                                {
                                                    if (HandleCommonMobilityOptionSubfield(optionSubfield, option))
                                                        continue;

                                                    optionSubfield.AssertNoFields();
                                                    switch (optionSubfield.Name())
                                                    {
                                                        case "mip6.ipv4dsm.reserved":
                                                            optionSubfield.AssertShowDecimal(0);
                                                            break;

                                                        case "mip6.ipv4dsm.s_flag":
                                                            optionSubfield.AssertShowDecimal(ipV4DhcpSupportMode.IsServer);
                                                            break;

                                                        default:
                                                            throw new InvalidOperationException(string.Format("Invalid IPv6 Mobility option subfield {0}",
                                                                                                              optionSubfield.Name()));
                                                    }
                                                }
                                                break;

                                            case IpV6MobilityOptionType.DnsUpdate:
                                                var dnsUpdate = (IpV6MobilityOptionDnsUpdate)option;
                                                foreach (XElement optionSubfield in optionField.Fields())
                                                {
                                                    if (HandleCommonMobilityOptionSubfield(optionSubfield, option))
                                                        continue;

                                                    optionSubfield.AssertNoFields();
                                                    switch (optionSubfield.Name())
                                                    {
                                                        case "mip6.dnsu.status":
                                                            optionSubfield.AssertShowDecimal((byte)dnsUpdate.Status);
                                                            break;

                                                        case "mip6.dnsu.flag.r":
                                                            optionSubfield.AssertShowDecimal(dnsUpdate.Remove);
                                                            break;

                                                        case "mip6.dnsu.mn_id":
                                                            optionSubfield.AssertValue(dnsUpdate.MobileNodeIdentity);
                                                            break;

                                                        default:
                                                            throw new InvalidOperationException(string.Format("Invalid IPv6 Mobility option subfield {0}",
                                                                                                              optionSubfield.Name()));
                                                    }
                                                }
                                                break;

                                            case IpV6MobilityOptionType.LocalMobilityAnchorAddress:
                                                var localMobilityAnchorAddress = (IpV6MobilityOptionLocalMobilityAnchorAddress)option;
                                                foreach (XElement optionSubfield in optionField.Fields())
                                                {
                                                    if (HandleCommonMobilityOptionSubfield(optionSubfield, option))
                                                        continue;

                                                    optionSubfield.AssertNoFields();
                                                    switch (optionSubfield.Name())
                                                    {
                                                        case "mmip6.lmaa.opt_code":
                                                            optionSubfield.AssertShowDecimal((byte)localMobilityAnchorAddress.Code);
                                                            break;

                                                        case "mmip6.lmaa.reserved":
                                                            optionSubfield.AssertShowDecimal(0);
                                                            break;

                                                        case "mip6.lmaa.ipv6":
                                                            optionSubfield.AssertValue(localMobilityAnchorAddress.LocalMobilityAnchorAddressIpV6.Value.ToValue());
                                                            break;

                                                        case "mip6.lmaa.ipv4":
                                                            optionSubfield.AssertShow(localMobilityAnchorAddress.LocalMobilityAnchorAddressIpV4.Value.ToString());
                                                            break;

                                                        default:
                                                            throw new InvalidOperationException(string.Format("Invalid IPv6 Mobility option subfield {0}",
                                                                                                              optionSubfield.Name()));
                                                    }
                                                }
                                                break;

                                            case IpV6MobilityOptionType.ContextRequest:
                                                var contextRequest = (IpV6MobilityOptionContextRequest)option;
                                                optionField.AssertShow("Context Request" +
                                                                       (contextRequest.Requests.Any() ? "" : " (with option length = 2 bytes; should be >= 4)"));
                                                int requestIndex = 0;
                                                foreach (XElement optionSubfield in optionField.Fields())
                                                {
                                                    if (HandleCommonMobilityOptionSubfield(optionSubfield, option))
                                                        continue;

                                                    optionSubfield.AssertNoFields();
                                                    switch (optionSubfield.Name())
                                                    {
                                                        case "mip6.cr.reserved":
                                                            optionSubfield.AssertShowDecimal(0);
                                                            break;

                                                        case "mmip6.cr.req_type":
                                                            optionSubfield.AssertShowDecimal(contextRequest.Requests[requestIndex].RequestType);
                                                            break;

                                                        case "mmip6.cr.req_length":
                                                            optionSubfield.AssertShowDecimal(contextRequest.Requests[requestIndex].OptionLength);
                                                            if (contextRequest.Requests[requestIndex].OptionLength == 0)
                                                                ++requestIndex;
                                                            break;

                                                        case "mip6.vsm.vendorId":
                                                            optionSubfield.AssertValue(contextRequest.Requests[requestIndex].Option.Subsegment(0, 4));
                                                            break;

                                                        case "mip6.vsm.subtype":
                                                            optionSubfield.AssertValue(contextRequest.Requests[requestIndex].Option.Subsegment(4, 1));
                                                            ++requestIndex;
                                                            break;

                                                        case "":
                                                            optionSubfield.AssertValue(contextRequest.Requests[requestIndex].Option);
                                                            ++requestIndex;
                                                            break;

                                                        default:
                                                            throw new InvalidOperationException(string.Format("Invalid IPv6 Mobility option subfield {0}",
                                                                                                              optionSubfield.Name()));
                                                    }
                                                }
                                                break;

                                            case IpV6MobilityOptionType.AlternateIpV4CareOfAddress:
                                                var alternateIpV4CareOfAddress = (IpV6MobilityOptionAlternateIpV4CareOfAddress)option;
                                                foreach (XElement optionSubfield in optionField.Fields())
                                                {
                                                    if (HandleCommonMobilityOptionSubfield(optionSubfield, option))
                                                        continue;

                                                    optionSubfield.AssertNoFields();
                                                    switch (optionSubfield.Name())
                                                    {
                                                        case "mip6.alt_ip4":
                                                            optionSubfield.AssertShow(alternateIpV4CareOfAddress.AlternateCareOfAddress.ToString());
                                                            break;

                                                        default:
                                                            throw new InvalidOperationException(string.Format("Invalid IPv6 Mobility option subfield {0}",
                                                                                                              optionSubfield.Name()));
                                                    }
                                                }
                                                break;

                                            case IpV6MobilityOptionType.Signature:
                                                var signature = (IpV6MobilityOptionSignature)option;
                                                foreach (XElement optionSubfield in optionField.Fields())
                                                {
                                                    if (HandleCommonMobilityOptionSubfield(optionSubfield, option))
                                                        continue;

                                                    optionSubfield.AssertNoFields();
                                                    switch (optionSubfield.Name())
                                                    {
                                                        case "mip6.sign.sign":
                                                            optionSubfield.AssertValue(signature.Signature);
                                                            break;

                                                        default:
                                                            throw new InvalidOperationException(string.Format("Invalid IPv6 Mobility option subfield {0}",
                                                                                                              optionSubfield.Name()));
                                                    }
                                                }
                                                break;

                                            case IpV6MobilityOptionType.TransientBinding:
                                                optionField.AssertShow("Transient Binding(2 bytes)");
                                                foreach (XElement optionSubfield in optionField.Fields())
                                                {
                                                    if (HandleCommonMobilityOptionSubfield(optionSubfield, option))
                                                        continue;

                                                    switch (optionSubfield.Name())
                                                    {
                                                        case "_ws.expert":
                                                            break;

                                                        default:
                                                            throw new InvalidOperationException(string.Format("Invalid IPv6 Mobility option subfield {0}",
                                                                                                              optionSubfield.Name()));
                                                    }
                                                }
                                                break;

                                            case IpV6MobilityOptionType.Timestamp:
                                                var timestamp = (IpV6MobilityOptionTimestamp)option;
                                                foreach (XElement optionSubfield in optionField.Fields())
                                                {
                                                    if (HandleCommonMobilityOptionSubfield(optionSubfield, option))
                                                        continue;

                                                    optionSubfield.AssertNoFields();
                                                    switch (optionSubfield.Name())
                                                    {
                                                        case "mip6.timestamp_tmp":
                                                            optionSubfield.AssertValue(timestamp.Timestamp);
                                                            break;

                                                        default:
                                                            throw new InvalidOperationException(string.Format("Invalid IPv6 Mobility option subfield {0}",
                                                                                                              optionSubfield.Name()));
                                                    }
                                                }
                                                break;

                                            case IpV6MobilityOptionType.RestartCounter:
                                                var restartCounter = (IpV6MobilityOptionRestartCounter)option;
                                                foreach (XElement optionSubfield in optionField.Fields())
                                                {
                                                    if (HandleCommonMobilityOptionSubfield(optionSubfield, option))
                                                        continue;

                                                    optionSubfield.AssertNoFields();
                                                    switch (optionSubfield.Name())
                                                    {
                                                        case "mip6.rc":
                                                            optionSubfield.AssertShowDecimal(restartCounter.RestartCounter);
                                                            break;

                                                        default:
                                                            throw new InvalidOperationException(string.Format("Invalid IPv6 Mobility option subfield {0}",
                                                                                                              optionSubfield.Name()));
                                                    }
                                                }
                                                break;

                                            case IpV6MobilityOptionType.CryptographicallyGeneratedAddressParameters:
                                                var cryptographicallyGeneratedAddressParameters = (IpV6MobilityOptionCryptographicallyGeneratedAddressParameters)option;
                                                foreach (XElement optionSubfield in optionField.Fields())
                                                {
                                                    if (HandleCommonMobilityOptionSubfield(optionSubfield, option))
                                                        continue;

                                                    optionSubfield.AssertNoFields();
                                                    switch (optionSubfield.Name())
                                                    {
                                                        case "mip6.cgar.cga_par":
                                                            optionSubfield.AssertValue(cryptographicallyGeneratedAddressParameters.CryptographicallyGeneratedAddressParameters);
                                                            break;

                                                        default:
                                                            throw new InvalidOperationException(string.Format("Invalid IPv6 Mobility option subfield {0}",
                                                                                                              optionSubfield.Name()));
                                                    }
                                                }
                                                break;

                                            case IpV6MobilityOptionType.FlowIdentification:
                                                optionField.AssertShow("Flow Identification(" + (option.Length - 2) + " bytes)");
                                                foreach (XElement optionSubfield in optionField.Fields())
                                                {
                                                    if (HandleCommonMobilityOptionSubfield(optionSubfield, option))
                                                        continue;

                                                    switch (optionSubfield.Name())
                                                    {
                                                        case "_ws.expert":
                                                            break;

                                                        default:
                                                            throw new InvalidOperationException(string.Format("Invalid IPv6 Mobility option subfield {0}",
                                                                                                              optionSubfield.Name()));
                                                    }
                                                }
                                                break;

                                            case IpV6MobilityOptionType.NatDetection:
                                                optionField.AssertShow("NAT Detection");
                                                var natDetection = (IpV6MobilityOptionNatDetection)option;
                                                foreach (XElement optionSubfield in optionField.Fields())
                                                {
                                                    if (HandleCommonMobilityOptionSubfield(optionSubfield, option))
                                                        continue;

                                                    optionSubfield.AssertNoFields();
                                                    switch (optionSubfield.Name())
                                                    {
                                                        case "mip6.natd.f_flag":
                                                            optionSubfield.AssertShowDecimal(natDetection.UdpEncapsulationRequired);
                                                            break;

                                                        case "mip6.natd.reserved":
                                                            optionSubfield.AssertShowDecimal(0);
                                                            break;

                                                        case "mip6.natd.refresh_t":
                                                            optionSubfield.AssertShowDecimal(natDetection.RefreshTime);
                                                            break;

                                                        default:
                                                            throw new InvalidOperationException(string.Format("Invalid IPv6 Mobility option subfield {0}",
                                                                                                              optionSubfield.Name()));
                                                    }
                                                }
                                                break;

                                            case IpV6MobilityOptionType.FlowSummary:
                                                optionField.AssertShow("Flow Summary(" + (option.Length - 2) + " bytes)");
                                                foreach (XElement optionSubfield in optionField.Fields())
                                                {
                                                    if (HandleCommonMobilityOptionSubfield(optionSubfield, option))
                                                        continue;

                                                    switch (optionSubfield.Name())
                                                    {
                                                        case "_ws.expert":
                                                            break;

                                                        default:
                                                            throw new InvalidOperationException(string.Format("Invalid IPv6 Mobility option subfield {0}",
                                                                                                              optionSubfield.Name()));
                                                    }
                                                }
                                                break;

                                            case IpV6MobilityOptionType.Experimental:
                                                optionField.AssertShow("Experimental" +
                                                                       (option.Length == 2 ? " (with option length = 0 bytes; should be >= 1)" : ""));
                                                var experimental = (IpV6MobilityOptionExperimental)option;
                                                foreach (XElement optionSubfield in optionField.Fields())
                                                {
                                                    if (HandleCommonMobilityOptionSubfield(optionSubfield, option))
                                                        continue;

                                                    optionSubfield.AssertNoFields();
                                                    switch (optionSubfield.Name())
                                                    {
                                                        case "mip6.em.data":
                                                            optionSubfield.AssertValue(experimental.Data);
                                                            break;

                                                        default:
                                                            throw new InvalidOperationException(string.Format("Invalid IPv6 Mobility option subfield {0}",
                                                                                                              optionSubfield.Name()));
                                                    }
                                                }
                                                break;

                                            case IpV6MobilityOptionType.MobileAccessGatewayIpV6Address:
                                                optionField.AssertShow("MAG IPv6 Address(18 bytes)");

                                                // TODO: Dedup this code.
                                                foreach (XElement optionSubfield in optionField.Fields())
                                                {
                                                    if (HandleCommonMobilityOptionSubfield(optionSubfield, option))
                                                        continue;

                                                    switch (optionSubfield.Name())
                                                    {
                                                        case "_ws.expert":
                                                            break;

                                                        default:
                                                            throw new InvalidOperationException(string.Format("Invalid IPv6 Mobility option subfield {0}",
                                                                                                              optionSubfield.Name()));
                                                    }
                                                }
                                                break;

                                            case IpV6MobilityOptionType.CareOfTestInit:
                                                optionField.AssertShow("Care-of Test Init");
                                                foreach (XElement optionSubfield in optionField.Fields())
                                                {
                                                    Assert.IsTrue(HandleCommonMobilityOptionSubfield(optionSubfield, option));
                                                }
                                                break;

                                            case IpV6MobilityOptionType.MobileNodeLinkLocalAddressInterfaceIdentifier:
                                                optionField.AssertShow("Mobile Node Link-local Address Interface Identifier(10 bytes)");

                                                foreach (XElement optionSubfield in optionField.Fields())
                                                {
                                                    if (HandleCommonMobilityOptionSubfield(optionSubfield, option))
                                                        continue;

                                                    switch (optionSubfield.Name())
                                                    {
                                                        case "_ws.expert":
                                                            break;

                                                        default:
                                                            throw new InvalidOperationException(string.Format("Invalid IPv6 Mobility option subfield {0}",
                                                                                                              optionSubfield.Name()));
                                                    }
                                                }
                                                break;

                                            case IpV6MobilityOptionType.AlternateCareOfAddress:
                                                optionField.AssertShow("Alternate Care-of Address");
                                                var alternateCareOfAddress = (IpV6MobilityOptionAlternateCareOfAddress)option;
                                                foreach (XElement optionSubfield in optionField.Fields())
                                                {
                                                    if (HandleCommonMobilityOptionSubfield(optionSubfield, option))
                                                        continue;

                                                    optionSubfield.AssertNoFields();
                                                    switch (optionSubfield.Name())
                                                    {
                                                        case "mip6.acoa.acoa":
                                                            optionSubfield.AssertValue(alternateCareOfAddress.AlternateCareOfAddress.ToValue());
                                                            break;

                                                        default:
                                                            throw new InvalidOperationException(string.Format("Invalid IPv6 Mobility option subfield {0}",
                                                                                                              optionSubfield.Name()));
                                                    }
                                                }
                                                break;

                                            case IpV6MobilityOptionType.GreKey:
                                                var greKey = (IpV6MobilityOptionGreKey)option;
                                                optionField.AssertShow("GRE Key: " + greKey.GreKeyIdentifier);
                                                foreach (XElement optionSubfield in optionField.Fields())
                                                {
                                                    if (HandleCommonMobilityOptionSubfield(optionSubfield, option))
                                                        continue;

                                                    optionSubfield.AssertNoFields();
                                                    switch (optionSubfield.Name())
                                                    {
                                                        case "mip6.ipv4dra.reserved":
                                                            optionSubfield.AssertShowDecimal(0);
                                                            break;

                                                        case "mip6.gre_key":
                                                            optionSubfield.AssertShowDecimal(greKey.GreKeyIdentifier);
                                                            break;

                                                        default:
                                                            throw new InvalidOperationException(string.Format("Invalid IPv6 Mobility option subfield {0}",
                                                                                                              optionSubfield.Name()));
                                                    }
                                                }
                                                break;
                                            default:
                                                throw new InvalidOperationException(string.Format("Unsupported IPv6 mobility option type {0}", option.OptionType));
                                        }
                                        ++optionIndex;
                                        break;

                                    default:
                                        throw new InvalidOperationException(string.Format("Invalid ipv6 mobility header option field {0}", optionField.Name()));
                                }
                            }
                            break;

                        default:
                            field.AssertShow("Unknown MH Type");
                            Assert.IsTrue(mobilityHeader.MobilityHeaderType == IpV6MobilityHeaderType.Experimental ||
                                          mobilityHeader.MobilityHeaderType == IpV6MobilityHeaderType.HomeAgentSwitchMessage ||
                                          mobilityHeader.MobilityHeaderType == IpV6MobilityHeaderType.LocalizedRoutingInitiation ||
                                          mobilityHeader.MobilityHeaderType == IpV6MobilityHeaderType.LocalizedRoutingAcknowledgement);
                            field.AssertNoFields();
                            break;
                    }
                    break;

                default:
                    throw new InvalidOperationException(string.Format("Invalid ipv6 mobility header field {0}", field.Name()));
            }

            return true;
        }
        protected override bool CompareField(XElement field, Datagram datagram)
        {
            IgmpDatagram igmpDatagram = (IgmpDatagram)datagram;
            switch (field.Name())
            {
                case "igmp.version":
                    if (field.Show() == "0")
                        return false; // TODO: support IGMP version 0.

                    field.AssertShowDecimal(igmpDatagram.Version);
                    break;

                case "igmp.type":
                    field.AssertShowHex((byte)igmpDatagram.MessageType);
                    break;

                case "igmp.checksum":
                    field.AssertShowHex(igmpDatagram.Checksum);
                    break;

                case "igmp.maddr":
                    field.AssertShow(igmpDatagram.GroupAddress.ToString());
                    break;

                case "igmp.max_resp":
                    field.AssertShowDecimal((int)((igmpDatagram.MaxResponseTime.TotalSeconds + 0.05) * 10));
                    break;

                case "igmp.checksum_bad":
                    field.AssertShowDecimal(!igmpDatagram.IsChecksumCorrect);
                    break;

                case "igmp.num_grp_recs":
                    field.AssertShowDecimal(igmpDatagram.NumberOfGroupRecords);
                    break;

                case "":
                    switch (igmpDatagram.MessageType)
                    {
                        case IgmpMessageType.MembershipReportVersion3:
                            CompareIgmpGroupRecord(field, igmpDatagram.GroupRecords[_groupRecordIndex++]);
                            break;

                        case IgmpMessageType.MembershipQuery:
                            CompareDatagram(field, null, igmpDatagram);
                            break;

                        case IgmpMessageType.MulticastTraceRouteResponse:
                            // todo support IGMP traceroute http://www.ietf.org/proceedings/48/I-D/idmr-traceroute-ipm-07.txt.
                            break;

                        default:
                            if (typeof(IgmpMessageType).GetEnumValues<IgmpMessageType>().Contains(igmpDatagram.MessageType))
                                throw new InvalidOperationException("Invalid message type " + igmpDatagram.MessageType);

                            field.AssertValue(igmpDatagram.Skip(1));
//                                field.AssertShow(igmpDatagram.Skip(1));
                            break;
                    }

                    break;

                case "igmp.s":
                    field.AssertShowDecimal(igmpDatagram.IsSuppressRouterSideProcessing);
                    break;

                case "igmp.qrv":
                    field.AssertShowDecimal(igmpDatagram.QueryRobustnessVariable);
                    break;

                case "igmp.qqic":
                    field.AssertShowDecimal(igmpDatagram.QueryIntervalCode);
                    break;

                case "igmp.num_src":
                    field.AssertShowDecimal(igmpDatagram.NumberOfSources);
                    break;

                case "igmp.saddr":
                    field.AssertShow(igmpDatagram.SourceAddresses[_sourceAddressIndex++].ToString());
                    break;

                case "igmp.identifier":
                    // todo support IGMP version 0 and IGMP identifier.
                    break;

                case "igmp.mtrace.max_hops":
                case "igmp.mtrace.saddr":
                case "igmp.mtrace.raddr":
                case "igmp.mtrace.rspaddr":
                case "igmp.mtrace.resp_ttl":
                case "igmp.mtrace.q_id":
                    // todo support IGMP traceroute http://www.ietf.org/proceedings/48/I-D/idmr-traceroute-ipm-07.txt.
                    Assert.AreEqual(IgmpMessageType.MulticastTraceRouteResponse, igmpDatagram.MessageType);
                    break;

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

            return true;
        }
        private bool CompareResourceRecordData(XElement dataField, DnsResourceRecord resourceRecord)
        {
            var data = resourceRecord.Data;
            string dataFieldName = dataField.Name();
            string dataFieldShow = dataField.Show();
            string dataFieldShowUntilColon = dataFieldShow.Split(':')[0];
            switch (resourceRecord.DnsType)
            {
                case DnsType.A:
                    dataField.AssertNoFields();
                    switch (dataFieldName)
                    {
                        case "dns.a":
                            dataField.AssertShow(((DnsResourceDataIpV4)data).Data.ToString());
                            break;

                        default:
                            throw new InvalidOperationException("Invalid DNS data field name " + dataFieldName);
                    }
                    break;

                case DnsType.Ns:
                    dataField.AssertNoFields();
                    switch (dataFieldName)
                    {
                        case "dns.ns":
                            dataField.AssertShow(GetWiresharkDomainName(((DnsResourceDataDomainName)data).Data));
                            break;

                        default:
                            throw new InvalidOperationException("Invalid DNS data field name " + dataFieldName);
                    }
                    break;

                case DnsType.Mailbox:
                    dataField.AssertName("dns.mb");
                    dataField.AssertNoFields();
                    dataField.AssertShow(GetWiresharkDomainName(((DnsResourceDataDomainName)data).Data));
                    break;

                case DnsType.Md:
                    dataField.AssertName("dns.md");
                    dataField.AssertNoFields();
                    dataField.AssertShow(GetWiresharkDomainName(((DnsResourceDataDomainName)data).Data));
                    break;

                case DnsType.MailForwarder: 
                    dataField.AssertName("dns.mf");
                    dataField.AssertNoFields();
                    dataField.AssertShow(GetWiresharkDomainName(((DnsResourceDataDomainName)data).Data));
                    break;

                case DnsType.MailGroup:     // 8.
                    dataField.AssertName("dns.mg");
                    dataField.AssertShow(GetWiresharkDomainName(((DnsResourceDataDomainName)data).Data));
                    dataField.AssertNoFields();
                    break;

                case DnsType.MailRename:    // 9.
                    dataField.AssertName("dns.mr");
                    dataField.AssertShow(GetWiresharkDomainName(((DnsResourceDataDomainName)data).Data));
                    dataField.AssertNoFields();
                    break;

                case DnsType.CName:
                    dataField.AssertName("dns.cname");
                    dataField.AssertShow(GetWiresharkDomainName(((DnsResourceDataDomainName)data).Data));
                    dataField.AssertNoFields();
                    break;

                case DnsType.StartOfAuthority:
                    var startOfAuthority = (DnsResourceDataStartOfAuthority)data;
                    dataField.AssertNoFields();
                    switch (dataField.Name())
                    {
                        case "dns.soa.mname":
                            dataField.AssertShow(GetWiresharkDomainName(startOfAuthority.MainNameServer));
                            break;

                        case "dns.soa.rname":
                            dataField.AssertShow(GetWiresharkDomainName(startOfAuthority.ResponsibleMailbox));
                            break;

                        case "dns.soa.serial_number":
                            dataField.AssertShowDecimal(startOfAuthority.Serial.Value);
                            break;

                        case "dns.soa.refresh_interval":
                            dataField.AssertShowDecimal(startOfAuthority.Refresh);
                            break;

                        case "dns.soa.retry_interval":
                            dataField.AssertShowDecimal(startOfAuthority.Retry);
                            break;

                        case "dns.soa.expire_limit":
                            dataField.AssertShowDecimal(startOfAuthority.Expire);
                            break;

                        case "dns.soa.mininum_ttl":
                            dataField.AssertShowDecimal(startOfAuthority.MinimumTtl);
                            break;

                        default:
                            throw new InvalidOperationException("Invalid DNS data field " + dataField.Name());
                    }
                    break;

                case DnsType.WellKnownService:
                    var wksData = (DnsResourceDataWellKnownService)data;
                    dataField.AssertNoFields();
                    switch (dataField.Name())
                    {
                        case "dns.wks.address":
                            dataField.AssertShow(wksData.Address.ToString());
                            break;

                        case "dns.wks.protocol":
                            dataField.AssertShowDecimal((byte)wksData.Protocol);
                            break;

                        case "dns.wks.bits":
                            while (wksData.Bitmap[_wksBitmapIndex] == 0x00)
                                ++_wksBitmapIndex;
                            dataField.AssertShowDecimal(wksData.Bitmap[_wksBitmapIndex++]);
                            break;

                        default:
                            throw new InvalidOperationException("Invalid DNS data field " + dataField.Name());
                    }
                    break;

                case DnsType.Ptr:
                    dataField.AssertName("dns.ptr.domain_name");
                    dataField.AssertShow(GetWiresharkDomainName(((DnsResourceDataDomainName)data).Data));
                    dataField.AssertNoFields();
                    break;

                case DnsType.HInfo:
                    dataField.AssertNoFields();
                    var hInfoData = (DnsResourceDataHostInformation)data;
                    switch (dataFieldName)
                    {
                        case "dns.hinfo.cpu_length":
                            dataField.AssertShowDecimal(hInfoData.Cpu.Length);
                            break;

                        case "dns.hinfo.cpu":
                            dataField.AssertValue(hInfoData.Cpu);
                            break;

                        case "dns.hinfo.os_length":
                            dataField.AssertShowDecimal(hInfoData.OperatingSystem.Length);
                            break;

                        case "dns.hinfo.os":
                            dataField.AssertValue(hInfoData.OperatingSystem);
                            break;

                        default:
                            throw new InvalidOperationException("Invalid DNS data field " + dataFieldName);
                    }
                    break;

                case DnsType.MInfo:
                    dataField.AssertNoFields();
                    var mInfoData = (DnsResourceDataMailingListInfo)data;
                    switch (dataFieldName)
                    {
                        case "dns.minfo.r":
                            dataField.AssertShow(GetWiresharkDomainName(mInfoData.MailingList));
                            break;

                        case "dns.minfo.e":
                            dataField.AssertShow(GetWiresharkDomainName(mInfoData.ErrorMailbox));
                            break;

                        default:
                            throw new InvalidOperationException("Invalid DNS data field name " + dataFieldName);
                    }
                    break;

                case DnsType.MailExchange:
                    var mxData = (DnsResourceDataMailExchange)data;
                    dataField.AssertNoFields();
                    switch (dataFieldName)
                    {
                        case "dns.mx.preference":
                            dataField.AssertShowDecimal(mxData.Preference);
                            break;

                        case "dns.mx.mail_exchange":
                            dataField.AssertShow(GetWiresharkDomainName(mxData.MailExchangeHost));
                            break;

                        default:
                            throw new InvalidOperationException("Invalid DNS data field name " + dataFieldName);
                    }
                    break;

                case DnsType.Txt: // 16.
                    var txtData = (DnsResourceDataText)data;
                    dataField.AssertNoFields();
                    switch (dataField.Name())
                    {
                        case "dns.txt.length":
                            dataField.AssertShowDecimal(txtData.Text[_txtTypeIndex].Length);
                            break;

                        case "dns.txt":
                            dataField.AssertValue(txtData.Text[_txtTypeIndex]);
                            ++_txtTypeIndex;
                            break;

                        default:
                            throw new InvalidOperationException("Invalid DNS data field " + dataField.Name());
                    }
                    break;

                case DnsType.SenderPolicyFramework: // 99.
                    var spfData = (DnsResourceDataText)data;
                    dataField.AssertNoFields();
                    switch (dataField.Name())
                    {
                        case "dns.spf.length":
                            dataField.AssertShowDecimal(spfData.Text[_spfTypeIndex].Length);
                            break;

                        case "dns.spf":
                            dataField.AssertValue(spfData.Text[_spfTypeIndex]);
                            ++_spfTypeIndex;
                            break;

                        default:
                            throw new InvalidOperationException("Invalid DNS data field " + dataField.Name());
                    }
                    break;

                case DnsType.ResponsiblePerson:
                    var rpData = (DnsResourceDataResponsiblePerson)data;
                    dataField.AssertNoFields();
                    switch (dataFieldName)
                    {
                        case "dns.rp.mailbox":
                            dataField.AssertShow(GetWiresharkDomainName(rpData.Mailbox));
                            break;

                        case "dns.rp.txt_rr":
                            dataField.AssertShow(GetWiresharkDomainName(rpData.TextDomain));
                            break;

                        default:
                            throw new InvalidOperationException("Invalid DNS data field " + dataFieldName);
                    }
                    break;

                case DnsType.AfsDatabase:
                    var afsDbData = (DnsResourceDataAfsDatabase)data;
                    dataField.AssertNoFields();
                    switch (dataFieldName)
                    {
                        case "dns.afsdb.subtype":
                            dataField.AssertShowDecimal((ushort)afsDbData.Subtype);
                            break;

                        case "dns.afsdb.hostname":
                            dataField.AssertShow(GetWiresharkDomainName(afsDbData.HostName));
                            break;

                        default:
                            throw new InvalidOperationException("Invalid DNS data field " + dataFieldName);

                    }
                    break;

                case DnsType.X25:
                    var x25 = (DnsResourceDataString)data;
                    dataField.AssertNoFields();
                    switch (dataFieldName)
                    {
                        case "dns.x25.length":
                            dataField.AssertShowDecimal(x25.String.Length);
                            break;

                        case "dns.x25.psdn_address":
                            dataField.AssertValue(x25.String);
                            break;

                        default:
                            throw new InvalidOperationException("Invalid DNS data field " + dataFieldName);
                    }
                    break;

                case DnsType.Isdn:
                    var isdnData = (DnsResourceDataIsdn)data;
                    dataField.AssertNoFields();
                    switch (dataFieldName)
                    {
                        case "dns.idsn.length":
                            dataField.AssertShowDecimal(isdnData.IsdnAddress.Length);
                            break;

                        case "dns.idsn.address":
                            dataField.AssertValue(isdnData.IsdnAddress);
                            break;

                        case "dns.idsn.sa.length":
                            dataField.AssertShowDecimal(isdnData.Subaddress.Length);
                            break;

                        case "dns.idsn.sa.address":
                            dataField.AssertValue(isdnData.Subaddress);
                            break;

                        default:
                            throw new InvalidOperationException("Invalid DNS data field " + dataFieldName);
                    }
                    dataField.AssertNoFields();
                    break;

                case DnsType.RouteThrough:
                    dataField.AssertNoFields();
                    var rtData = (DnsResourceDataRouteThrough)data;
                    switch (dataFieldName)
                    {
                        case "dns.rt.subtype":
                            dataField.AssertShowDecimal(rtData.Preference);
                            break;

                        case "dns.rt.intermediate_host":
                            dataField.AssertShow(GetWiresharkDomainName(rtData.IntermediateHost));
                            break;

                        default:
                            throw new InvalidOperationException("Invalid DNS data field name " + dataFieldName);
                    }
                    break;

                case DnsType.NetworkServiceAccessPoint:
                    var nsapData = (DnsResourceDataNetworkServiceAccessPoint)data;

                    switch (dataFieldName)
                    {
                        case "dns.nsap.rdata":
                            byte[] nsapId = new byte[6];
                            nsapId.Write(0, nsapData.SystemIdentifier, Endianity.Big);
                            dataField.AssertValue(nsapData.AreaAddress.Concat(nsapId).Concat(nsapData.Selector));
                            break;

                        default:
                            throw new InvalidOperationException("Invalid DNS data field name " + dataFieldName);
                    }
                    dataField.AssertNoFields();
                    break;

                case DnsType.NetworkServiceAccessPointPointer:
                    dataField.AssertName("dns.nsap_ptr.owner");
                    dataField.AssertShow(GetWiresharkDomainName(((DnsResourceDataDomainName)data).Data));
                    dataField.AssertNoFields();
                    break;

                case DnsType.Key:
                    var keyData = (DnsResourceDataKey)data;
                    switch (dataFieldName)
                    {
                        case "dns.key.flags":
                            foreach (var flagField in dataField.Fields())
                            {
                                flagField.AssertNoFields();
                                int flagCount = GetFlagCount(flagField);
                                switch (flagCount)
                                {
                                    case 0:
                                        flagField.AssertShowDecimal(keyData.AuthenticationProhibited);
                                        break;

                                    case 1:
                                        flagField.AssertShowDecimal(keyData.ConfidentialityProhibited);
                                        break;

                                    case 2:
                                        flagField.AssertShowDecimal(keyData.Experimental);
                                        break;

                                    case 5:
                                        flagField.AssertShowDecimal(keyData.UserAssociated);
                                        break;

                                    case 6:
                                        flagField.AssertShowDecimal(keyData.NameType == DnsKeyNameType.NonZoneEntity);
                                        break;

                                    case 8:
                                        flagField.AssertShowDecimal(keyData.IpSec);
                                        break;

                                    case 9:
                                        flagField.AssertShowDecimal(keyData.Email);
                                        break;

                                    case 12:
                                        flagField.AssertShowDecimal((byte)keyData.Signatory);
                                        break;

                                    default:
                                        throw new InvalidOperationException("Invalid flag count " + flagCount);
                                }
                            }
                            break;

                        case "dns.key.protocol":
                            dataField.AssertNoFields();
                            dataField.AssertShowDecimal((byte)keyData.Protocol);
                            break;

                        case "dns.key.algorithm":
                            dataField.AssertNoFields();
                            dataField.AssertShowDecimal((byte)keyData.Algorithm);
                            break;

                        case "dns.key.key_id":
                            dataField.AssertNoFields();
                            dataField.AssertShowDecimal(keyData.KeyTag);
                            break;

                        case "dns.key.public_key":
                            dataField.AssertNoFields();
                            byte[] flagsExtension;
                            if (keyData.FlagsExtension == null)
                            {
                                flagsExtension = new byte[0];
                            }
                            else
                            {
                                flagsExtension = new byte[2];
                                flagsExtension.Write(0, keyData.FlagsExtension.Value, Endianity.Big);
                            }
                            dataField.AssertValue(flagsExtension.Concat(keyData.PublicKey));
                            break;

                        default:
                            throw new InvalidOperationException("Invalid DNS data field name " + dataFieldName);
                    }
                    break;

                case DnsType.Signature:   // 24.
                case DnsType.ResourceRecordSignature: // 46.
                    dataField.AssertNoFields();
                    var sigData = (DnsResourceDataSignature)data;
                    switch (dataFieldName)
                    {
                        case "dns.rrsig.type_covered":
                            dataField.AssertShowDecimal((ushort)sigData.TypeCovered);
                            break;

                        case "dns.rrsig.algorithm":
                            dataField.AssertShowDecimal((byte)sigData.Algorithm);
                            break;

                        case "dns.rrsig.labels":
                            dataField.AssertShowDecimal(sigData.Labels);
                            break;

                        case "dns.rrsig.original_ttl":
                            dataField.AssertShowDecimal(sigData.OriginalTtl);
                            break;

                        case "dns.rrsig.signature_expiration":
                            dataField.AssertValue(sigData.SignatureExpiration);
                            break;

                        case "dns.rrsig.signature_inception":
                            dataField.AssertValue(sigData.SignatureInception);
                            break;

                        case "dns.rrsig.key_tag":
                            dataField.AssertShowDecimal(sigData.KeyTag);
                            break;

                        case "dns.rrsig.signers_name":
                            dataField.AssertShow(GetWiresharkDomainName(sigData.SignersName));
                            break;

                        case "dns.rrsig.signature":
                            dataField.AssertValue(sigData.Signature);
                            break;

                        default:
                            throw new InvalidOperationException("Invalid DNS data field " + dataFieldName);
                    }
                    break;

                case DnsType.PointerX400:
                    var pxData = (DnsResourceDataX400Pointer)data;
                    switch (dataField.Name())
                    {
                        case "dns.px.preference":
                            dataField.AssertShowDecimal(pxData.Preference);
                            break;

                        case "dns.px.map822":
                            dataField.AssertShow(GetWiresharkDomainName(pxData.Map822));
                            break;

                        case "dns.px.map400":
                            dataField.AssertShow(GetWiresharkDomainName(pxData.MapX400));
                            break;

                        default:
                            throw new InvalidOperationException("Invalid DNS data field " + dataField.Name());
                    }
                    dataField.AssertNoFields();
                    break;

                case DnsType.GeographicalPosition:
                    dataField.AssertNoFields();
                    var gposData = (DnsResourceDataGeographicalPosition)data;
                    switch (dataFieldName)
                    {
                        case "dns.gpos.longitude_length":
                            dataField.AssertShowDecimal(gposData.Longitude.Length);
                            break;

                        case "dns.gpos.longitude":
                            dataField.AssertShow(gposData.Longitude);
                            break;

                        case "dns.gpos.latitude_length":
                            dataField.AssertShowDecimal(gposData.Latitude.Length);
                            break;

                        case "dns.gpos.latitude":
                            dataField.AssertShow(gposData.Latitude);
                            break;

                        case "dns.gpos.altitude_length":
                            dataField.AssertShowDecimal(gposData.Altitude.Length);
                            break;

                        case "dns.gpos.altitude":
                            dataField.AssertShow(gposData.Altitude);
                            break;

                        default:
                            throw new InvalidOperationException("Invalid DNS data field " + dataField.Name());
                    }
                    break;

                case DnsType.Aaaa:
                    dataField.AssertName("dns.aaaa");
                    dataField.AssertShow(GetWiresharkIpV6(((DnsResourceDataIpV6)data).Data));
                    dataField.AssertNoFields();
                    break;

                case DnsType.Location:
                    var locData = (DnsResourceDataLocationInformation)data;
                    dataField.AssertNoFields();
                    switch (dataFieldName)
                    {
                        case "dns.loc.version":
                            dataField.AssertShowDecimal(locData.Version);
                            break;

                        case "dns.loc.unknown_data":
                            Assert.AreNotEqual(0, locData.Version);
                            break;

                        case "dns.loc.size":
                            Assert.AreEqual(0, locData.Version);
                            string sizeValue = dataField.Showname().Split('(', ')')[1];
                            Assert.AreEqual(GetPrecisionValueString(locData.Size), sizeValue);
                            break;

                        case "dns.loc.horizontal_precision":
                            Assert.AreEqual(0, locData.Version);
                            string horizontalPrecisionValue = dataField.Showname().Split('(', ')')[1];
                            Assert.AreEqual(GetPrecisionValueString(locData.HorizontalPrecision), horizontalPrecisionValue);
                            break;

                        case "dns.loc.vertial_precision":
                            Assert.AreEqual(0, locData.Version);
                            string verticalPrecisionValue = dataField.Showname().Split('(', ')')[1];
                            Assert.AreEqual(GetPrecisionValueString(locData.VerticalPrecision), verticalPrecisionValue);
                            break;

                        case "dns.loc.latitude":
                            Assert.AreEqual(0, locData.Version);
                            dataField.AssertShowDecimal(locData.Latitude);
                            break;

                        case "dns.loc.longitude":
                            Assert.AreEqual(0, locData.Version);
                            dataField.AssertShowDecimal(locData.Longitude);
                            break;

                        case "dns.loc.altitude":
                            Assert.AreEqual(0, locData.Version);
                            dataField.AssertShowDecimal(locData.Altitude);
                            break;

                        default:
                            throw new InvalidOperationException("Invalid DNS data field " + dataFieldName);
                    }
                    break;

                case DnsType.NextDomain:
                    var nxtData = (DnsResourceDataNextDomain)data;
                    switch (dataField.Name())
                    {
                        case "dns.nxt.next_domain_name":
                            dataField.AssertShow(GetWiresharkDomainName(nxtData.NextDomainName));
                            break;

                        case "":
                            // TODO: Uncomment this when https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=10615 is fixed.
//                            DnsType actualType = nxtData.TypesExist.Skip(_nxtTypeIndex++).First();
//                            DnsType expectedType;
//                            if (!TryGetDnsType(dataFieldShow, out expectedType))
//                                throw new InvalidOperationException(string.Format("Can't parse DNS field {0} : {1}", dataFieldShow, actualType));
//                            Assert.AreEqual(expectedType, actualType);
                            return false;

                        default:
                            throw new InvalidOperationException("Invalid DNS data field " + dataField.Name());
                    }
                    dataField.AssertNoFields();
                    break;

                case DnsType.ServerSelection:
                    dataField.AssertNoFields();
                    var srvData = (DnsResourceDataServerSelection)data;
                    switch (dataFieldName)
                    {
                        case "dns.srv.priority":
                            dataField.AssertShowDecimal(srvData.Priority);
                            break;

                        case "dns.srv.weight":
                            dataField.AssertShowDecimal(srvData.Weight);
                            break;

                        case "dns.srv.port":
                            dataField.AssertShowDecimal(srvData.Port);
                            break;

                        case "dns.srv.target":
                            dataField.AssertShow(GetWiresharkDomainName(srvData.Target));
                            break;

                        default:
                            throw new InvalidOperationException("Invalid DNS data field " + dataFieldName);
                    }
                    break;

                case DnsType.NaPtr:
                    var naPtrData = (DnsResourceDataNamingAuthorityPointer)data;
                    dataField.AssertNoFields();
                    switch (dataFieldName)
                    {
                        case "dns.naptr.order":
                            dataField.AssertShowDecimal(naPtrData.Order);
                            break;

                        case "dns.naptr.preference":
                            dataField.AssertShowDecimal(naPtrData.Preference);
                            break;

                        case "dns.naptr.flags_length":
                            dataField.AssertShowDecimal(naPtrData.Flags.Length);
                            break;

                        case "dns.naptr.flags":
                            dataField.AssertValue(naPtrData.Flags);
                            break;

                        case "dns.naptr.service_length":
                            dataField.AssertShowDecimal(naPtrData.Services.Length);
                            break;

                        case "dns.naptr.service":
                            dataField.AssertValue(naPtrData.Services);
                            break;

                        case "dns.naptr.regex_length":
                            dataField.AssertShowDecimal(naPtrData.RegularExpression.Length);
                            break;

                        case "dns.naptr.regex":
                            dataField.AssertValue(naPtrData.RegularExpression);
                            break;

                        case "dns.naptr.replacement_length":
                            dataField.AssertShowDecimal(naPtrData.Replacement.NonCompressedLength);
                            break;

                        case "dns.naptr.replacement":
                            dataField.AssertShow(GetWiresharkDomainName(naPtrData.Replacement));
                            break;

                        default:
                            throw new InvalidOperationException("Invalid DNS data field " + dataFieldName);
                    }
                    break;

                case DnsType.KeyExchanger:
                    dataField.AssertNoFields();
                    var kxData = (DnsResourceDataKeyExchanger)data;
                    switch (dataFieldName)
                    {
                        case "dns.kx.preference":
                            dataField.AssertShowDecimal(kxData.Preference);
                            break;

                        case "dns.kx.key_exchange":
                            dataField.AssertShow(GetWiresharkDomainName(kxData.KeyExchangeHost));
                            break;

                        default:
                            throw new InvalidOperationException("Invalid DNS data field " + dataFieldName);
                    }
                    break;

                case DnsType.Cert:
                    dataField.AssertNoFields();
                    var certData = (DnsResourceDataCertificate)data;
                    switch (dataFieldName)
                    {
                        case "dns.cert.type":
                            dataField.AssertShowDecimal((ushort)certData.CertificateType);
                            break;

                        case "dns.cert.key_tag":
                            dataField.AssertShowDecimal(certData.KeyTag);
                            break;

                        case "dns.cert.algorithm":
                            dataField.AssertShowDecimal((byte)certData.Algorithm);
                            break;

                        case "dns.cert.certificate":
                            dataField.AssertValue(certData.Certificate);
                            break;

                        default:
                            throw new InvalidOperationException("Invalid DNS data field " + dataFieldName);
                    }
                    break;

                case DnsType.A6:
                    var a6Data = (DnsResourceDataA6)data;
                    switch (dataFieldName)
                    {
                        case "dns.a6.prefix_len":
                            dataField.AssertShowDecimal(a6Data.PrefixLength);
                            break;

                        case "dns.a6.address_suffix":
                            Assert.AreEqual(new IpV6Address(dataFieldShow), a6Data.AddressSuffix);
                            break;

                        case "dns.a6.prefix_name":
                            dataField.AssertShow(GetWiresharkDomainName(a6Data.PrefixName));
                            break;

                        default:
                            throw new InvalidOperationException("Invalid DNS data field " + dataFieldName);
                    }
                    dataField.AssertNoFields();
                    break;

                case DnsType.DName:
                    dataField.AssertName("dns.dname");
                    dataField.AssertShow(GetWiresharkDomainName(((DnsResourceDataDomainName)data).Data));
                    dataField.AssertNoFields();
                    break;

                case DnsType.Opt:
                    var optResourceRecord = (DnsOptResourceRecord)resourceRecord;
                    var optData = (DnsResourceDataOptions)data;
                    switch (dataFieldName)
                    {
                        case "dns.rr.udp_payload_size":
                            _optOptionIndex = 0;
                            dataField.AssertNoFields();
                            dataField.AssertShowDecimal(optResourceRecord.SendersUdpPayloadSize);
                            break;

                        case "dns.resp.ext_rcode":
                            dataField.AssertNoFields();
                            dataField.AssertShowDecimal(optResourceRecord.ExtendedReturnCode);
                            break;

                        case "dns.resp.edns0_version":
                            dataField.AssertNoFields();
                            dataField.AssertShowDecimal((byte)optResourceRecord.Version);
                            break;

                        case "dns.resp.z":
                            DnsOptFlags flags = optResourceRecord.Flags;
                            dataField.AssertShowDecimal((ushort)flags);
                            foreach (XElement subfield in dataField.Fields())
                            {
                                subfield.AssertNoFields();
                                switch (subfield.Name())
                                {
                                    case "dns.resp.z.do":
                                        subfield.AssertShowDecimal((flags & DnsOptFlags.DnsSecOk) == DnsOptFlags.DnsSecOk);
                                        break;

                                    case "dns.resp.z.reserved":
                                        subfield.AssertShowDecimal(0);
                                        break;

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

                        case "dns.opt":
                            foreach (XElement subfield in dataField.Fields())
                            {
                                DnsOption dnsOption = optData.Options.Options[_optOptionIndex];
                                var clientSubnet = dnsOption as DnsOptionClientSubnet;
                                switch (subfield.Name())
                                {
                                    case "dns.opt.code":
                                        subfield.AssertNoFields();
                                        subfield.AssertShowDecimal((ushort)dnsOption.Code);
                                        break;

                                    case "dns.opt.len":
                                        subfield.AssertShowDecimal(dnsOption.DataLength);
                                        if (subfield.Fields().Any())
                                        {
                                            Assert.AreEqual(1, subfield.Fields().Count());
                                            subfield.Fields().First().AssertName("_ws.expert");
                                        }
                                        break;

                                    case "dns.opt.data":
                                        subfield.AssertNoFields();
                                        switch (dnsOption.Code)
                                        {
                                            case DnsOptionCode.UpdateLease:
                                                subfield.AssertValue((uint)((DnsOptionUpdateLease)dnsOption).Lease);
                                                break;

                                            case DnsOptionCode.LongLivedQuery:
                                                byte[] expectedLongLivedQueryValue = new byte[dnsOption.DataLength];
                                                var longLivedQuery = (DnsOptionLongLivedQuery)dnsOption;
                                                int longLivedQueryOffset = 0;
                                                expectedLongLivedQueryValue.Write(ref longLivedQueryOffset, longLivedQuery.Version, Endianity.Big);
                                                expectedLongLivedQueryValue.Write(ref longLivedQueryOffset, (ushort)longLivedQuery.OpCode, Endianity.Big);
                                                expectedLongLivedQueryValue.Write(ref longLivedQueryOffset, (ushort)longLivedQuery.ErrorCode, Endianity.Big);
                                                expectedLongLivedQueryValue.Write(ref longLivedQueryOffset, longLivedQuery.Id, Endianity.Big);
                                                expectedLongLivedQueryValue.Write(ref longLivedQueryOffset, longLivedQuery.LeaseLife, Endianity.Big);
                                                subfield.AssertValue(expectedLongLivedQueryValue);
                                                break;

                                            case DnsOptionCode.ClientSubnet:
                                                byte[] expectedClientSubnetValue = new byte[dnsOption.DataLength];
                                                int clientSubnetOffset = 0;
                                                expectedClientSubnetValue.Write(ref clientSubnetOffset, (ushort)clientSubnet.Family, Endianity.Big);
                                                expectedClientSubnetValue.Write(ref clientSubnetOffset, clientSubnet.SourceNetmask);
                                                expectedClientSubnetValue.Write(ref clientSubnetOffset, clientSubnet.ScopeNetmask);
                                                expectedClientSubnetValue.Write(ref clientSubnetOffset, clientSubnet.Address);
                                                subfield.AssertValue(expectedClientSubnetValue);
                                                break;

                                            default:
                                                subfield.AssertValue(((DnsOptionAnything)dnsOption).Data);
                                                break;
                                        }
                                        if (dnsOption.Code != DnsOptionCode.ClientSubnet)
                                            ++_optOptionIndex;
                                        break;

                                    case "dns.opt.client.family":
                                        subfield.AssertNoFields();
                                        subfield.AssertShowDecimal((ushort)clientSubnet.Family);
                                        break;

                                    case "dns.opt.client.netmask":
                                        subfield.AssertNoFields();
                                        subfield.AssertShowDecimal(clientSubnet.SourceNetmask);
                                        break;

                                    case "dns.opt.client.scope":
                                        subfield.AssertNoFields();
                                        subfield.AssertShowDecimal(clientSubnet.ScopeNetmask);
                                        break;

                                    case "dns.opt.client.addr":
                                    case "dns.opt.client.addr4":
                                    case "dns.opt.client.addr6":
                                        subfield.AssertNoFields();
                                        if (clientSubnet.Address.Length <= 16)
                                        {
                                            subfield.AssertValue(clientSubnet.Address);
                                        }
                                        else
                                        {
                                            subfield.AssertValue(clientSubnet.Address.Take(16));
                                            // TODO: Remove this return when https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=10988 is fixed.
                                            return false;
                                        }
                                        ++_optOptionIndex;
                                        break;

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

                        default:
                            throw new InvalidOperationException("Invalid DNS data field name " + dataFieldName);
                    }
                    break;

                case DnsType.AddressPrefixList:
                    var aplData = (DnsResourceDataAddressPrefixList)data;
                    switch (dataFieldName)
                    {
                        case "dns.apl.address_family":
                            dataField.AssertNoFields();
                            dataField.AssertShowDecimal((ushort)aplData.Items[_aplItemIndex++].AddressFamily);

                            break;

                        case "dns.apl.coded_prefix":
                            dataField.AssertShowDecimal(aplData.Items[_aplItemIndex - 1].PrefixLength);
                            break;

                        case "dns.apl.negation":
                            dataField.AssertShowDecimal(aplData.Items[_aplItemIndex - 1].Negation);
                            break;

                        case "dns.apl.afdlength":
                            dataField.AssertShowDecimal(aplData.Items[_aplItemIndex - 1].AddressFamilyDependentPart.Length);
                            break;

                        case "dns.apl.afdpart.data":
                        case "dns.apl.afdpart.ipv4":
                        case "dns.apl.afdpart.ipv6":
                            if (dataFieldName != "dns.apl.afdpart.data")
                            {
                                Assert.AreEqual(dataFieldName == "dns.apl.afdpart.ipv4" ? AddressFamily.IpV4 : AddressFamily.IpV6,
                                                aplData.Items[_aplItemIndex - 1].AddressFamily);
                            }
                            dataField.AssertValue(aplData.Items[_aplItemIndex - 1].AddressFamilyDependentPart);
                            break;

                        default:
                            throw new InvalidOperationException("Invalid DNS data field name " + dataFieldName);
                    }
                    dataField.AssertNoFields();
                    break;

                case DnsType.DelegationSigner:  // 43.
                case DnsType.DnsSecLookAsideValidation: // 32769.
                    dataField.AssertNoFields();
                    var dsData = (DnsResourceDataDelegationSigner)data;
                    switch (dataFieldName)
                    {
                        case "dns.ds.key_id":
                            dataField.AssertShowDecimal(dsData.KeyTag);
                            break;

                        case "dns.ds.algorithm":
                            dataField.AssertShowDecimal((byte)dsData.Algorithm);
                            break;

                        case "dns.ds.digest_type":
                            dataField.AssertShowDecimal((byte)dsData.DigestType);
                            break;

                        case "dns.ds.digest":
                            dataField.AssertValue(dsData.Digest);
                            break;

                        default:
                            throw new InvalidOperationException("Invalid DNS data field name " + dataFieldName);
                    }
                    break;

                case DnsType.SshFingerprint:
                    var sshFpData = (DnsResourceDataSshFingerprint)data;
                    dataField.AssertNoFields();
                    switch (dataFieldName)
                    {
                        case "dns.sshfp.algorithm":
                            dataField.AssertShowDecimal((byte)sshFpData.Algorithm);
                            break;

                        case "dns.sshfp.fingerprint.type":
                            dataField.AssertShowDecimal((byte)sshFpData.FingerprintType);
                            break;

                        case "dns.sshfp.fingerprint":
                            dataField.AssertValue(sshFpData.Fingerprint);
                            break;

                        default:
                            throw new InvalidOperationException("Invalid DNS data field name " + dataFieldName);
                    }
                    break;

                case DnsType.IpSecKey:
                    dataField.AssertNoFields();
                    var ipSecKeyData = (DnsResourceDataIpSecKey)data;
                    switch (dataField.Name())
                    {
                        case "dns.ipseckey.gateway_precedence":
                            dataField.AssertShowDecimal(ipSecKeyData.Precedence);
                            break;

                        case "dns.ipseckey.gateway_type":
                            dataField.AssertShowDecimal((byte)ipSecKeyData.GatewayType);
                            break;

                        case "dns.ipseckey.gateway_algorithm":
                            dataField.AssertShowDecimal((byte)ipSecKeyData.Algorithm);
                            break;

                        case "dns.ipseckey.gateway_ipv4":
                            dataField.AssertShow(((DnsGatewayIpV4)ipSecKeyData.Gateway).Value.ToString());
                            break;

                        case "dns.ipseckey.gateway_ipv6":
                            dataField.AssertValue(((DnsGatewayIpV6)ipSecKeyData.Gateway).Value.ToValue());
                            break;

                        case "dns.ipseckey.gateway_dns":
                            dataField.AssertShow(GetWiresharkDomainName(((DnsGatewayDomainName)ipSecKeyData.Gateway).Value));
                            break;

                        case "dns.ipseckey.public_key":
                            dataField.AssertValue(ipSecKeyData.PublicKey);
                            break;

                        default:
                            throw new InvalidOperationException("Invalid DNS data field " + dataField.Name());
                    }
                    break;

                case DnsType.NSec:
                    var nSecData = (DnsResourceDataNextDomainSecure)data;
                    switch (dataField.Name())
                    {
                        case "dns.nsec.next_domain_name":
                            dataField.AssertShow(GetWiresharkDomainName(nSecData.NextDomainName));
                            break;

                        case "":
                            DnsType actualType = nSecData.TypesExist[_nSecTypeIndex++];
                            DnsType expectedType;
                            if (!TryGetDnsType(dataFieldShow, out expectedType))
                                throw new InvalidOperationException(string.Format("Failed parsing type from {0} : {1}", dataFieldShow, actualType));

                            Assert.AreEqual(expectedType, actualType);
                            break;

                        default:
                            throw new InvalidOperationException("Invalid DNS data field " + dataField.Name());
                    }
                    dataField.AssertNoFields();
                    break;

                case DnsType.DnsKey:
                    var dnsKeyData = (DnsResourceDataDnsKey)data;
                    switch (dataFieldName)
                    {
                        case "dns.dnskey.flags":
                            foreach (XElement subfield in dataField.Fields())
                            {
                                subfield.AssertNoFields();
                                switch (subfield.Name())
                                {
                                    case "dns.dnskey.flags.zone_key":
                                        subfield.AssertShowDecimal(dnsKeyData.ZoneKey);
                                        break;

                                    case "dns.dnskey.flags.key_revoked":
                                        subfield.AssertShowDecimal(dnsKeyData.Revoke);
                                        break;

                                    case "dns.dnskey.flags.secure_entry_point":
                                        subfield.AssertShowDecimal(dnsKeyData.SecureEntryPoint);
                                        break;

                                    case "dns.dnskey.flags.reserved":
                                        subfield.AssertShowDecimal(0);
                                        break;

                                    case "dns.dnskey.protocol":
                                        subfield.AssertShowDecimal(dnsKeyData.Protocol);
                                        break;

                                    case "dns.dnskey.algorithm":
                                        subfield.AssertShowDecimal((byte)dnsKeyData.Algorithm);
                                        break;

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

                        case "dns.dnskey.key_id":
                            dataField.AssertNoFields();
                            dataField.AssertShowDecimal(dnsKeyData.KeyTag);
                            break;

                        case "dns.dnskey.public_key":
                            dataField.AssertNoFields();
                            dataField.AssertValue(dnsKeyData.PublicKey);
                            break;
                            
                        default:
                            throw new InvalidOperationException("Invalid DNS resource data field name " + dataFieldName);
                    }
                    break;

                case DnsType.DynamicHostConfigurationId:
                    switch (dataFieldName)
                    {
                        case "dns.dhcid.rdata":
                            dataField.AssertValue(((DnsResourceDataAnything)data).Data);
                            break;

                        default:
                            throw new InvalidOperationException("Invalid DNS resource data field name " + dataFieldName);
                    }
                    dataField.AssertNoFields();
                    break;

                case DnsType.NSec3:
                    var nSec3Data = (DnsResourceDataNextDomainSecure3)data;
                    switch (dataFieldName)
                    {
                        case "dns.nsec3.algo":
                            dataField.AssertShowDecimal((byte)nSec3Data.HashAlgorithm);
                            dataField.AssertNoFields();
                            break;

                        case "dns.nsec3.flags":
                            dataField.AssertShowDecimal((byte)nSec3Data.Flags);
                            foreach (var flagField in dataField.Fields())
                            {
                                string flagFieldName = flagField.Name();
                                switch (flagFieldName)
                                {
                                    case "dns.nsec3.flags.opt_out":
                                        dataField.AssertShowDecimal((nSec3Data.Flags & DnsSecNSec3Flags.OptOut) == DnsSecNSec3Flags.OptOut);
                                        break;

                                    default:
                                        throw new InvalidOperationException("Invalid DNS resource data flag field name " + flagFieldName);
                                }
                            }
                            break;

                        case "dns.nsec3.iterations":
                            dataField.AssertShowDecimal(nSec3Data.Iterations);
                            dataField.AssertNoFields();
                            break;

                        case "dns.nsec3.salt_length":
                            dataField.AssertShowDecimal(nSec3Data.Salt.Length);
                            dataField.AssertNoFields();
                            break;

                        case "dns.nsec3.salt_value":
                            dataField.AssertValue(nSec3Data.Salt);
                            dataField.AssertNoFields();
                            break;

                        case "dns.nsec3.hash_length":
                            dataField.AssertShowDecimal(nSec3Data.NextHashedOwnerName.Length);
                            dataField.AssertNoFields();
                            break;

                        case "dns.nsec3.hash_value":
                            dataField.AssertValue(nSec3Data.NextHashedOwnerName);
                            dataField.AssertNoFields();
                            break;

                        case "":
                            DnsType expectedType = nSec3Data.TypesExist[_nSec3TypeIndex++];
                            Assert.IsTrue(dataField.Show().StartsWith("RR type in bit map: "));
                            if (dataField.Show().EndsWith(string.Format("({0})", (ushort)expectedType)))
                                dataField.AssertShow(string.Format("RR type in bit map: Unknown ({0})", (ushort)expectedType));
                            else
                                Assert.IsTrue(
                                    dataFieldShow.Replace("-", "").StartsWith("RR type in bit map: " + GetWiresharkDnsType(expectedType).Replace("-", "")),
                                    string.Format("{0} : {1}", dataFieldShow, GetWiresharkDnsType(expectedType)));
                            dataField.AssertNoFields();
                            break;

                        default:
                            throw new InvalidOperationException("Invalid DNS resource data field name " + dataFieldName);
                    }
                    break;

                case DnsType.NSec3Parameters:
                    var nSec3ParamData = (DnsResourceDataNextDomainSecure3Parameters)data;
                    switch (dataFieldName)
                    {
                        case "dns.nsec3.algo":
                            dataField.AssertShowDecimal((byte)nSec3ParamData.HashAlgorithm);
                            break;

                        case "dns.nsec3.flags":
                            dataField.AssertShowDecimal((byte)nSec3ParamData.Flags);
                            break;

                        case "dns.nsec3.iterations":
                            dataField.AssertShowDecimal(nSec3ParamData.Iterations);
                            break;

                        case "dns.nsec3.salt_length":
                            dataField.AssertShowDecimal(nSec3ParamData.Salt.Length);
                            break;

                        case "dns.nsec3.salt_value":
                            dataField.AssertShow(nSec3ParamData.Salt);
                            break;

                        default:
                            throw new InvalidOperationException("Invalid DNS resource data field name " + dataFieldName);
                    }
                    dataField.AssertNoFields();
                    break;

                case DnsType.Hip:
                    var hipData = (DnsResourceDataHostIdentityProtocol)data;
                    switch (dataFieldName)
                    {
                        case "dns.hip.hit":
                            dataField.AssertShow(hipData.HostIdentityTag);
                            break;

                        case "dns.hip.pk":
                            dataField.AssertShow(hipData.PublicKey);
                            break;

                        case "dns.hip.hit.length":
                            dataField.AssertShowDecimal(hipData.HostIdentityTag.Length);
                            break;

                        case "dns.hip.hit.pk.algo":
                            dataField.AssertShowDecimal((byte)hipData.PublicKeyAlgorithm);
                            break;

                        case "dns.hip.pk.length":
                            dataField.AssertShowDecimal(hipData.PublicKey.Length);
                            break;

                        case "dns.hip.rendezvous_server":
                            dataField.AssertShow(GetWiresharkDomainName(hipData.RendezvousServers[_hipRendezvousServersIndex++]));
                            break;

                        default:
                            throw new InvalidOperationException("Invalid DNS data field name " + dataFieldName);
                    }
                    dataField.AssertNoFields();
                    break;

                case DnsType.TKey:
                    dataField.AssertNoFields();
                    var tKeyData = (DnsResourceDataTransactionKey)data;
                    switch (dataFieldName)
                    {
                        case "dns.tkey.algo_name":
                            dataField.AssertShow(GetWiresharkDomainName(tKeyData.Algorithm));
                            break;

                        case "dns.tkey.signature_inception":
                            dataField.AssertValue(tKeyData.Inception);
                            break;

                        case "dns.tkey.signature_expiration":
                            dataField.AssertValue(tKeyData.Expiration);
                            break;

                        case "dns.tkey.mode":
                            dataField.AssertShowDecimal((ushort)tKeyData.Mode);
                            break;

                        case "dns.tkey.error":
                            dataField.AssertShowDecimal((ushort)tKeyData.Error);
                            break;

                        case "dns.tkey.key_size":
                            dataField.AssertShowDecimal(tKeyData.Key.Length);
                            break;

                        case "dns.tkey.key_data":
                            dataField.AssertValue(tKeyData.Key);
                            break;

                        case "dns.tkey.other_size":
                            dataField.AssertShowDecimal(tKeyData.Other.Length);
                            break;

                        case "dns.tkey.other_data":
                            dataField.AssertValue(tKeyData.Other);
                            break;

                        default:
                            throw new InvalidOperationException("Invalid DNS data field " + dataFieldName);
                    }
                    break;

                case DnsType.TransactionSignature:
                    var tSigData = (DnsResourceDataTransactionSignature)data;
                    switch (dataFieldName)
                    {
                        case "dns.tsig.algorithm_name":
                            dataField.AssertShow(GetWiresharkDomainName(tSigData.Algorithm));
                            dataField.AssertNoFields();
                            break;

                        case "":
                            switch (dataFieldShowUntilColon)
                            {
                                case "Time signed":
                                    dataField.AssertValue(tSigData.TimeSigned);
                                    break;

                                default:
                                    throw new InvalidOperationException("Invalid DNS data field " + dataFieldShow);
                            }
                            dataField.AssertNoFields();
                            break;

                        case "dns.tsig.fudge":
                            dataField.AssertShowDecimal(tSigData.Fudge);
                            dataField.AssertNoFields();
                            break;

                        case "dns.tsig.mac_size":
                            dataField.AssertShowDecimal(tSigData.MessageAuthenticationCode.Length);
                            dataField.AssertNoFields();
                            break;

                        case "dns.tsig.mac":
                            dataField.AssertShow("");
                            Assert.AreEqual(1, dataField.Fields().Count());
                            var tsigSubfield = dataField.Fields().First();
                            tsigSubfield.AssertName("_ws.expert");
                            break;

                        case "dns.tsig.original_id":
                            dataField.AssertShowDecimal(tSigData.OriginalId);
                            dataField.AssertNoFields();
                            break;

                        case "dns.tsig.error":
                            dataField.AssertShowDecimal((ushort)tSigData.Error);
                            dataField.AssertNoFields();
                            break;

                        case "dns.tsig.other_len":
                            dataField.AssertShowDecimal(tSigData.Other.Length);
                            dataField.AssertNoFields();
                            break;

                        case "dns.tsig.other_data":
                            dataField.AssertValue(tSigData.Other);
                            dataField.AssertNoFields();
                            break;

                        case "dns.tsig.time_signed":
                            dataField.AssertValue(tSigData.TimeSigned);
                            dataField.AssertNoFields();
                            break;

                        case "_ws.expert":
                            break;

                        default:
                            throw new InvalidOperationException("Invalid DNS data field name " + dataFieldName);
                    }
                    break;

                case DnsType.Null:
                    dataField.AssertNoFields();
                    dataField.AssertName("dns.null");
                    dataField.AssertValue(((DnsResourceDataAnything)data).Data);
                    break;

                case DnsType.CertificationAuthorityAuthorization:
                    var certificationAuthorityAuthorization = (DnsResourceDataCertificationAuthorityAuthorization)data;
                    switch (dataField.Name())
                    {
                        case "dns.caa.flags":
                            dataField.AssertShowDecimal((byte)certificationAuthorityAuthorization.Flags);
                            foreach (XElement subfield in dataField.Fields())
                            {
                                subfield.AssertNoFields();
                                switch (subfield.Name())
                                {
                                    case "dns.caa.flags.issuer_critical":
                                        subfield.AssertShowDecimal((certificationAuthorityAuthorization.Flags &
                                                                    DnsCertificationAuthorityAuthorizationFlags.Critical) ==
                                                                   DnsCertificationAuthorityAuthorizationFlags.Critical);
                                        break;

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

                            }
                            break;

                        case "dns.caa.unknown":
                        case "dns.caa.issue":
                            foreach (XElement subfield in dataField.Fields())
                            {
                                subfield.AssertNoFields();
                                switch (subfield.Name())
                                {
                                    case "dns.caa.tag_length":
                                        subfield.AssertShowDecimal(certificationAuthorityAuthorization.Tag.Length);
                                        break;

                                    case "dns.caa.tag":
                                        subfield.AssertValue(certificationAuthorityAuthorization.Tag);
                                        break;

                                    case "dns.caa.value":
                                        subfield.AssertValue(certificationAuthorityAuthorization.Value);
                                        break;

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

                            }
                            break;

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

                case DnsType.EId:                                 // 31.
                case DnsType.NimrodLocator:                       // 32.
                case DnsType.AsynchronousTransferModeAddress:     // 34.
                case DnsType.Sink:                                // 40.
                case DnsType.NInfo:                               // 56.
                case DnsType.RKey:                                // 57.
                case DnsType.TrustAnchorLink:                     // 58.
                case DnsType.ChildDelegationSigner:               // 59.
                case DnsType.UInfo:                               // 100.
                case DnsType.Uid:                                 // 101.
                case DnsType.Gid:                                 // 102.
                case DnsType.Unspecified:                         // 103.
                case DnsType.Ixfr:                                // 251.
                case DnsType.Axfr:                                // 252.
                case DnsType.MailB:                               // 253.
                case DnsType.MailA:                               // 254.
                case DnsType.Any:                                 // 255.
                case DnsType.Uri:                                 // 256.
                case DnsType.TrustAnchor:                         // 32768.
                default:
                    if (dataField.Name() == "_ws.expert")
                    {
                        dataField.AssertShowname("Expert Info (Note/Undecoded): Dissector for DNS Type (" + (ushort)resourceRecord.DnsType +
                                                 ") code not implemented, Contact Wireshark developers if you want this supported");
                    }
                    else
                    {
                        dataField.AssertName("dns.data");
                    }
                    break;
            }
            return true;
        }
        private void ValidateIpV6MobilityOptionIpV4HomeAddressField(XElement field, IIpV6MobilityOptionIpV4HomeAddress ipV4HomeAddress)
        {
            switch (field.Name())
            {
                case "mip6.ipv4ha.preflen":
                    field.AssertShowDecimal(ipV4HomeAddress.PrefixLength);
                    break;

                case "mip6.ipv4ha.ha":
                    field.AssertShow(ipV4HomeAddress.HomeAddress.ToString());
                    break;

                default:
                    throw new InvalidOperationException(string.Format("Invalid IpV6 IpV4 Home Address option field {0}", field.Name()));
            }
        }
        protected override bool CompareField(XElement field, Datagram datagram)
        {
            GreDatagram greDatagram = (GreDatagram)datagram;
            switch (field.Name())
            {
                case "gre.flags_and_version":
                    XElement[] innerFields = field.Fields().ToArray();
                    MoreAssert.IsInRange(8, 9, innerFields.Length);

                    int currentInnerFieldIndex = 0;
                    innerFields[currentInnerFieldIndex++].AssertShowDecimal(greDatagram.ChecksumPresent);
                    innerFields[currentInnerFieldIndex++].AssertShowDecimal(greDatagram.RoutingPresent);
                    innerFields[currentInnerFieldIndex++].AssertShowDecimal(greDatagram.KeyPresent);
                    innerFields[currentInnerFieldIndex++].AssertShowDecimal(greDatagram.SequenceNumberPresent);
                    innerFields[currentInnerFieldIndex++].AssertShowDecimal(greDatagram.StrictSourceRoute);
                    innerFields[currentInnerFieldIndex++].AssertShowDecimal(greDatagram.RecursionControl);
                    if (innerFields.Length == 9)
                    {
                        innerFields[currentInnerFieldIndex++].AssertShowDecimal(greDatagram.AcknowledgmentSequenceNumberPresent);
                        innerFields[currentInnerFieldIndex++].AssertShowDecimal(greDatagram.FutureUseBits);
                    }
                    else
                    {
                        byte futureUseBitsValue = (byte)((greDatagram.AcknowledgmentSequenceNumberPresent.ToInt() << 4) | greDatagram.FutureUseBits);
                        innerFields[currentInnerFieldIndex++].AssertShowDecimal(futureUseBitsValue);
                    }
                    innerFields[currentInnerFieldIndex].AssertShowDecimal((byte)greDatagram.Version);
                    break;

                case "data.len":
                    field.AssertShowDecimal(
                        greDatagram.Payload.Length + (greDatagram.AcknowledgmentSequenceNumberPresent &&
                                                      (greDatagram.Version != GreVersion.EnhancedGre || !greDatagram.SequenceNumberPresent)
                                                          ? 4
                                                          : 0), "GRE data.len");
                    field.AssertNoFields();
                    break;

                case "gre.checksum":
                    field.AssertShowDecimal(greDatagram.Checksum);
                    field.AssertNoFields();
                    break;

                case "gre.key.payload_length":
                    field.AssertShowDecimal(greDatagram.KeyPayloadLength);
                    field.AssertNoFields();
                    break;

                case "gre.key.call_id":
                    field.AssertShowDecimal(greDatagram.KeyCallId);
                    field.AssertNoFields();
                    break;

                case "gre.ack_number":
                    field.AssertShowDecimal(greDatagram.AcknowledgmentSequenceNumber);
                    field.AssertNoFields();
                    break;

                case "gre.sequence_number":
                    field.AssertShowDecimal(greDatagram.SequenceNumber);
                    field.AssertNoFields();
                    break;

                case "gre.offset":
                    field.AssertShowDecimal(greDatagram.RoutingOffset);
                    field.AssertNoFields();
                    break;

                case "gre.routing":
                    field.AssertShow("");
                    field.AssertNoFields();
                    break;

                case "gre.routing.address_family":
                    if (_routingEntryIndex == greDatagram.Routing.Count)
                        field.AssertShowDecimal(0);
                    else
                        field.AssertShowDecimal((ushort)greDatagram.Routing[_routingEntryIndex].AddressFamily);
                    field.AssertNoFields();
                    break;

                case "gre.routing.sre_offset":
                    if (_routingEntryIndex == greDatagram.Routing.Count)
                        field.AssertShowDecimal(0);
                    else
                        field.AssertShowDecimal(greDatagram.Routing[_routingEntryIndex].PayloadOffset);
                    field.AssertNoFields();
                    break;

                case "gre.routing.src_length":
                    if (_routingEntryIndex == greDatagram.Routing.Count)
                        field.AssertShowDecimal(0);
                    else
                        field.AssertShowDecimal(greDatagram.Routing[_routingEntryIndex].PayloadLength);
                    field.AssertNoFields();
                    break;

                case "gre.routing.information":
                    if (_routingEntryIndex != greDatagram.Routing.Count)
                    {
                        switch (greDatagram.Routing[_routingEntryIndex].AddressFamily)
                        {
                            case GreSourceRouteEntryAddressFamily.IpSourceRoute:
                                field.AssertValue(((GreSourceRouteEntryIp)greDatagram.Routing[_routingEntryIndex]).Addresses);
                                break;

                            case GreSourceRouteEntryAddressFamily.AsSourceRoute:
                                field.AssertValue(((GreSourceRouteEntryAs)greDatagram.Routing[_routingEntryIndex]).AsNumbers);
                                break;

                            default:
                                field.AssertValue(((GreSourceRouteEntryUnknown)greDatagram.Routing[_routingEntryIndex]).Data);
                                break;
                        }

                        ++_routingEntryIndex;
                    }
                    field.AssertNoFields();
                    break;

                case "gre.proto":
                    field.AssertShowDecimal((ushort)greDatagram.ProtocolType);
                    field.AssertNoFields();
                    break;

                case "gre.key":
                    field.AssertShowDecimal(greDatagram.Key);
                    field.AssertNoFields();
                    break;

                case "data":
                case "data.data":
                    field.AssertDataField(greDatagram.Payload);
                    break;

                default:
                    Assert.Fail("Invalid field name: " + field.Name());
                    break;
            }

            return true;
        }
        protected override bool CompareField(XElement field, Datagram datagram)
        {
            IcmpDatagram icmpDatagram = (IcmpDatagram)datagram;
            switch (field.Name())
            {
                case "icmp.type":
                    field.AssertShowDecimal((byte)icmpDatagram.MessageType);
                    field.AssertNoFields();
                    break;

                case "icmp.code":
                    field.AssertShowDecimal(icmpDatagram.Code);
                    field.AssertNoFields();
                    break;

                case "icmp.checksum_bad":
                    field.AssertShowDecimal(!icmpDatagram.IsChecksumCorrect);
                    field.AssertNoFields();
                    break;

                case "icmp.checksum":
                    field.AssertShowDecimal(icmpDatagram.Checksum);
                    field.AssertNoFields();
                    break;

                case "data":
                    var icmpIpV4PayloadDatagram = icmpDatagram as IcmpIpV4PayloadDatagram;
                    if (icmpIpV4PayloadDatagram != null)
                    {
                        if (!new[]
                                 {
                                     IpV4Protocol.IpComp, // TODO: Support IpComp.
                                     IpV4Protocol.Ax25, // TODO: Support Ax25.
                                     IpV4Protocol.FibreChannel, // TODO: Support FibreChannel.
                                 }.Contains(icmpIpV4PayloadDatagram.IpV4.Protocol))
                        {
                            if (icmpIpV4PayloadDatagram.IpV4.Protocol == IpV4Protocol.Udp)
                            {
                                // Uncomment this when https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=10990 is fixed.
                                //                                field.AssertDataField(casted1.IpV4.Udp.Payload);
                            }
                            else
                            {
                                // TODO: Remove this condition when https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=10991 and https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=10992 are fixed.
                                if (!(icmpIpV4PayloadDatagram is IcmpParameterProblemDatagram || icmpIpV4PayloadDatagram is IcmpRedirectDatagram))
                                    field.AssertDataField(icmpIpV4PayloadDatagram.IpV4.Payload);
                            }
                        }
                    }
                    else
                    {
                        field.AssertDataField(icmpDatagram.Payload);
                    }
                    break;

                case "":
                    switch (icmpDatagram.MessageType)
                    {
                        case IcmpMessageType.ParameterProblem:
                            if (field.Show() != "Unknown session type")
                                field.AssertShow("Pointer: " + ((IcmpParameterProblemDatagram)icmpDatagram).Pointer);
                            break;

                        case IcmpMessageType.RouterAdvertisement:
                            IcmpRouterAdvertisementDatagram routerAdvertisementDatagram = (IcmpRouterAdvertisementDatagram)icmpDatagram;
                            string fieldName = field.Show().Split(':')[0];
                            switch (fieldName)
                            {
                                case "Number of addresses":
                                    field.AssertShow(fieldName + ": " + routerAdvertisementDatagram.NumberOfAddresses);
                                    break;

                                case "Address entry size":
                                    field.AssertShow(fieldName + ": " + routerAdvertisementDatagram.AddressEntrySize);
                                    break;

                                case "Lifetime":
                                    TimeSpan actualLifetime = routerAdvertisementDatagram.Lifetime;
                                    StringBuilder actualLifetimeString = new StringBuilder(fieldName + ": ");
                                    if (actualLifetime.Hours != 0)
                                    {
                                        actualLifetimeString.Append(actualLifetime.Hours + " hour");
                                        if (actualLifetime.Hours != 1)
                                            actualLifetimeString.Append('s');
                                    }
                                    if (actualLifetime.Minutes != 0)
                                    {
                                        if (actualLifetime.Hours != 0)
                                            actualLifetimeString.Append(", ");
                                        actualLifetimeString.Append(actualLifetime.Minutes + " minute");
                                        if (actualLifetime.Minutes != 1)
                                            actualLifetimeString.Append('s');
                                    }
                                    if (actualLifetime.Seconds != 0)
                                    {
                                        if (actualLifetime.Hours != 0 || actualLifetime.Minutes != 0)
                                            actualLifetimeString.Append(", ");
                                        actualLifetimeString.Append(actualLifetime.Seconds + " second");
                                        if (actualLifetime.Seconds != 1)
                                            actualLifetimeString.Append('s');
                                    }
                                    break;

                                case "Router address":
                                    field.AssertShow(fieldName + ": " + routerAdvertisementDatagram.Entries[_routerIndex].RouterAddress);
                                    break;

                                case "Preference level":
                                    field.AssertShow(fieldName + ": " + routerAdvertisementDatagram.Entries[_routerIndex++].RouterAddressPreference);
                                    break;

                                default:
                                    throw new InvalidOperationException("Invalid icmp " + icmpDatagram.MessageType + " field " + fieldName);
                            }
                            break;
                    }
                    field.AssertNoFields();
                    break;

                case "icmp.ident":
                    ushort identifier = ((IcmpIdentifiedDatagram)icmpDatagram).Identifier;
                    field.AssertShowDecimal(field.Showname().StartsWith("Identifier (BE): ") ? identifier : identifier.ReverseEndianity());
                    field.AssertNoFields();
                    break;

                case "icmp.seq":
                    field.AssertShowDecimal(((IcmpIdentifiedDatagram)icmpDatagram).SequenceNumber);
                    field.AssertNoFields();
                    break;

                case "icmp.seq_le":
                    byte[] sequenceNumberBuffer = new byte[sizeof(ushort)];
                    sequenceNumberBuffer.Write(0, ((IcmpIdentifiedDatagram)icmpDatagram).SequenceNumber, Endianity.Big);
                    ushort lowerEndianSequenceNumber = sequenceNumberBuffer.ReadUShort(0, Endianity.Small);
                    field.AssertShowDecimal(lowerEndianSequenceNumber);
                    field.AssertNoFields();
                    break;

                case "icmp.redir_gw":
                    field.AssertShow(((IcmpRedirectDatagram)icmpDatagram).GatewayInternetAddress.ToString());
                    field.AssertNoFields();
                    break;

                case "icmp.mtu":
                    field.AssertShowDecimal(((IcmpDestinationUnreachableDatagram)icmpDatagram).NextHopMaximumTransmissionUnit);
                    field.AssertNoFields();
                    break;

                case "l2tp.l2_spec_def":
                    field.AssertShow("");
                    field.AssertNoFields();
                    break;

                case "icmp.resp_to":
                case "icmp.resptime":
                    break;

                // TODO: Remove this case when https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=10939 is fixed.
                case "icmp.length":
                    break;

                default:
                    if (!field.Name().StartsWith("lt2p.") &&
                        field.Name() != "pweth" &&
                        !field.Name().StartsWith("pweth."))
                        throw new InvalidOperationException("Invalid icmp field " + field.Name());
                    break;
            }

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

            switch (field.Name())
            {
                case "tcp.len":
                    if (tcpDatagram.Payload == null)
                    {
                        // todo seems like a bug in tshark https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=5235
                        break;
//                            field.AssertShowDecimal(tcpDatagram.Length);
                    }
                    else
                        field.AssertShowDecimal(tcpDatagram.Payload.Length);
                    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);
                    field.AssertNoFields();
                    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.AssertShow("0x" + flags.ToString("x" + 4 * sizeof(byte)));
                    foreach (var flagField in field.Fields())
                    {
                        switch (flagField.Name())
                        {
                            case "tcp.flags.cwr":
                                flagField.AssertShowDecimal(tcpDatagram.IsCongestionWindowReduced);
                                break;

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

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

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

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

                            case "tcp.flags.reset":
                                flagField.AssertShowDecimal(tcpDatagram.IsReset);
                                break;

                            case "tcp.flags.syn":
                                flagField.AssertShowDecimal(tcpDatagram.IsSynchronize);
                                break;

                            case "tcp.flags.fin":
                                flagField.AssertShowDecimal(tcpDatagram.IsFin);
                                break;
                        }
                        flagField.AssertNoFields();
                    }
                    break;

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

                case "tcp.checksum":
                    field.AssertShowHex(tcpDatagram.Checksum);
                    if (!ipV4Datagram.Options.IsBadForWireshark())
                    {
                        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.AssertShowDecimal(tcpDatagram.Checksum != 0 && ipV4Datagram.IsTransportChecksumCorrect);
                                    break;

                                case "tcp.checksum_bad":
                                    checksumField.AssertShowDecimal(tcpDatagram.Checksum != 0 && !ipV4Datagram.IsTransportChecksumCorrect);
                                    break;

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

                case "tcp.urgent_pointer":
                    field.AssertShowDecimal(tcpDatagram.UrgentPointer);
                    field.AssertNoFields();
                    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":
                case "":
                    field.AssertNoFields();
                    break;

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

            return true;
        }
        protected override bool CompareField(XElement field, Datagram datagram)
        {
            IpV4Datagram ipV4Datagram = (IpV4Datagram)datagram;
            switch (field.Name())
            {
                case "ip.version":
                    field.AssertShowDecimal(ipV4Datagram.Version);
                    field.AssertNoFields();
                    break;

                case "ip.hdr_len":
                    field.AssertShowDecimal(ipV4Datagram.HeaderLength);
                    field.AssertNoFields();
                    break;

                case "ip.dsfield":
                    field.AssertShowDecimal((int)ipV4Datagram.TypeOfService);
                    // TODO: Parse TypeOfService to Differentiated Services and ECN.
                    break;

                case "ip.len":
                    field.AssertShowDecimal(ipV4Datagram.TotalLength);
                    field.AssertNoFields();
                    break;

                case "ip.id":
                    field.AssertShowDecimal(ipV4Datagram.Identification);
                    field.AssertNoFields();
                    break;

                case "ip.flags":
                    field.AssertShowDecimal(((ushort)ipV4Datagram.Fragmentation.Options >> 13));
                    foreach (XElement subfield in field.Fields())
                    {
                        subfield.AssertNoFields();
                        switch (subfield.Name())
                        {
                            case "ip.flags.rb":
                                break;

                            case "ip.flags.df":
                                subfield.AssertShowDecimal((ipV4Datagram.Fragmentation.Options & IpV4FragmentationOptions.DoNotFragment) ==
                                                           IpV4FragmentationOptions.DoNotFragment);
                                break;

                            case "ip.flags.mf":
                                subfield.AssertShowDecimal((ipV4Datagram.Fragmentation.Options & IpV4FragmentationOptions.MoreFragments) ==
                                                           IpV4FragmentationOptions.MoreFragments);
                                break;

                            default:
                                throw new InvalidOperationException(string.Format("Invalid ip flags subfield {0}", subfield.Name()));
                        }
                    }
                    break;

                case "ip.frag_offset":
                    field.AssertShowDecimal(ipV4Datagram.Fragmentation.Offset);
                    field.AssertNoFields();
                    break;

                case "ip.ttl":
                    field.AssertShowDecimal(ipV4Datagram.Ttl);
                    foreach (XElement subfield in field.Fields())
                    {
                        switch (subfield.Name())
                        {
                            case "_ws.expert":
                                break;

                            default:
                                subfield.AssertNoFields();
                                throw new InvalidOperationException(string.Format("Invalid ip subfield {0}", subfield.Name()));
                        }
                    }
                    break;

                case "ip.proto":
                    field.AssertShowDecimal((byte)ipV4Datagram.Protocol);
                    field.AssertNoFields();
                    break;

                case "ip.checksum":
                    field.AssertShowDecimal(ipV4Datagram.HeaderChecksum);
                    if (field.Showname().EndsWith(" [not all data available]"))
                    {
                        Assert.IsFalse(ipV4Datagram.IsValid);
                        break;
                    }
                    foreach (var checksumField in field.Fields())
                    {
                        switch (checksumField.Name())
                        {
                            case "ip.checksum_good":
                                checksumField.AssertNoFields();
                                // TODO: Remove this case when https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=10579 is fixed.
                                if (field.Showname().EndsWith(" [in ICMP error packet]"))
                                    break;
                                checksumField.AssertShowDecimal(ipV4Datagram.IsHeaderChecksumCorrect);
                                break;

                            case "ip.checksum_bad":
                                if (ipV4Datagram.Length < IpV4Datagram.HeaderMinimumLength ||
                                    ipV4Datagram.Length < ipV4Datagram.HeaderLength ||
                                    // TODO: Remove this case when https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=10579 is fixed.
                                    field.Showname().EndsWith(" [in ICMP error packet]"))
                                    break;

                                checksumField.AssertShowDecimal(!ipV4Datagram.IsHeaderChecksumCorrect);
                                break;
                        }
                    }
                    break;

                case "ip.src":
                case "ip.src_host":
                    field.AssertShow(ipV4Datagram.Source.ToString());
                    field.AssertNoFields();
                    break;

                case "ip.dst":
                case "ip.dst_host":
                    // TODO: Remove this condition when https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=10959 is fixed or (worst case) when MTU Reply and CommercialSecurity options are supported.
                    if (ipV4Datagram.Options == null || !ipV4Datagram.Options.Any(option => option.OptionType == IpV4OptionType.MaximumTransmissionUnitReply ||
                                                                                            option.OptionType == IpV4OptionType.CommercialSecurity))
                    {
                        field.AssertShow(ipV4Datagram.Destination.ToString());
                    }
                    field.AssertNoFields();
                    break;

                case "ip.addr":
                case "ip.host":
                    // TODO: Remove this condition when https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=10959 is fixed or (worst case) when MTU Reply and CommercialSecurity options are supported.
                    if (ipV4Datagram.Options == null || !ipV4Datagram.Options.Any(option => option.OptionType == IpV4OptionType.MaximumTransmissionUnitReply ||
                                                                                            option.OptionType == IpV4OptionType.CommercialSecurity))
                    {
                        Assert.IsTrue(field.Show() == ipV4Datagram.Source.ToString() ||
                                      field.Show() == ipV4Datagram.Destination.ToString());
                    }
                    field.AssertNoFields();
                    break;

                case "ip.cur_rt":
                case "ip.cur_rt_host":
                    field.AssertShow(ipV4Datagram.CurrentDestination.ToString());
                    break;

                case "":
                    CompareIpV4Options(field, ipV4Datagram, ipV4Datagram.Options);
                    break;

                default:
                    throw new InvalidOperationException(string.Format("Invalid ip field {0}", field.Name()));
            }

            return true;
        }
        protected override bool CompareField(XElement field, Datagram datagram)
        {
            field.AssertNoFields();
            ArpDatagram arpDatagram = (ArpDatagram)datagram;
            switch (field.Name())
            {
                case "arp.hw.type":
                    field.AssertShowDecimal((ushort)arpDatagram.HardwareType);
                    break;

                case "arp.proto.type":
                    field.AssertShowDecimal((ushort)arpDatagram.ProtocolType);
                    break;

                case "arp.hw.size":
                    field.AssertShowDecimal(arpDatagram.HardwareLength);
                    break;

                case "arp.proto.size":
                    field.AssertShowDecimal(arpDatagram.ProtocolLength);
                    break;

                case "arp.opcode":
                    field.AssertShowDecimal((ushort)arpDatagram.Operation);
                    break;

                case "arp.src.hw":
                case "arp.src.hw_mac":
                    field.AssertShow(arpDatagram.SenderHardwareAddress);
                    break;

                case "arp.src.proto":
                    field.AssertShow(arpDatagram.SenderProtocolAddress);
                    break;

                case "arp.src.proto_ipv4":
                    field.AssertShow(arpDatagram.SenderProtocolIpV4Address.ToString());
                    break;

                case "arp.dst.hw":
                case "arp.dst.hw_mac":
                    field.AssertShow(arpDatagram.TargetHardwareAddress);
                    break;

                case "arp.dst.proto":
                    field.AssertShow(arpDatagram.TargetProtocolAddress);
                    break;

                case "arp.dst.proto_ipv4":
                    field.AssertShow(arpDatagram.TargetProtocolIpV4Address.ToString());
                    break;

                case "arp.isgratuitous":
                case "arp.dst.drarp_error_status":
                    // TODO: Support DRARP (RFC 1931).
                    break;

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

            return true;
        }
        protected override bool CompareField(XElement field, Datagram datagram)
        {
            IgmpDatagram igmpDatagram = (IgmpDatagram)datagram;
            switch (field.Name())
            {
                case "igmp.version":
                    field.AssertShowDecimal(Math.Max(igmpDatagram.Version, 0));
                    break;

                case "igmp.type":
                    field.AssertShowDecimal((byte)igmpDatagram.MessageType);
                    break;

                case "igmp.checksum":
                    field.AssertShowDecimal(igmpDatagram.Checksum);
                    break;

                case "igmp.maddr":
                    field.AssertShow(igmpDatagram.GroupAddress.ToString());
                    break;

                case "igmp.max_resp":
                    field.AssertShowDecimal((int)((igmpDatagram.MaxResponseTime.TotalSeconds + 0.05) * 10));
                    break;

                case "igmp.checksum_bad":
                    if (igmpDatagram.IsValid)
                        field.AssertShowDecimal(!igmpDatagram.IsChecksumCorrect);
                    break;

                case "igmp.num_grp_recs":
                    field.AssertShowDecimal(igmpDatagram.NumberOfGroupRecords);
                    break;

                case "":
                    switch (igmpDatagram.MessageType)
                    {
                        case IgmpMessageType.MembershipReportVersion3:
                            CompareIgmpGroupRecord(field, igmpDatagram.GroupRecords[_groupRecordIndex++]);
                            break;

                        case IgmpMessageType.MembershipQuery:
                            return CompareDatagram(field, null, igmpDatagram);

                        case IgmpMessageType.MulticastTraceRouteResponse:
                        case IgmpMessageType.MulticastTraceRoute:
                            // todo support IGMP traceroute http://www.ietf.org/proceedings/48/I-D/idmr-traceroute-ipm-07.txt.
                            break;

                        default:
                            switch (field.Show())
                            {
                                case "Data":
                                    if (field.Value().Length > 0)
                                    {
                                        // TODO: Change following https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=11582
                                        field.AssertValue(field.Value().Length / 2 == igmpDatagram.Length - 21 ? igmpDatagram.Skip(21) : igmpDatagram.Skip(1));
                                    }
                                    break;

                                default:
                                    if (typeof(IgmpMessageType).GetEnumValues<IgmpMessageType>().Contains(igmpDatagram.MessageType))
                                        throw new InvalidOperationException("Invalid message type " + igmpDatagram.MessageType);
                                    break;
                            }
                            break;
                    }

                    break;

                case "igmp.s":
                    field.AssertShowDecimal(igmpDatagram.IsSuppressRouterSideProcessing);
                    break;

                case "igmp.qrv":
                    field.AssertShowDecimal(igmpDatagram.QueryRobustnessVariable);
                    break;

                case "igmp.qqic":
                    field.AssertShowDecimal(igmpDatagram.QueryIntervalCode);
                    break;

                case "igmp.num_src":
                    field.AssertShowDecimal(igmpDatagram.NumberOfSources);
                    break;

                case "igmp.saddr":
                    field.AssertShow(igmpDatagram.SourceAddresses[_sourceAddressIndex++].ToString());
                    break;

                case "igmp.identifier":
                    field.AssertShowDecimal(igmpDatagram.Identifier);
                    break;

                case "igmp.access_key":
                    field.AssertValue(igmpDatagram.AccessKey);
                    break;

                case "igmp.reply":
                    field.AssertShowDecimal((byte)igmpDatagram.ReplyCode);
                    break;

                case "igmp.reply.pending":
                    field.AssertShowDecimal(igmpDatagram.RetryInThisManySeconds);
                    break;

                case "igmp.group_type":
                    field.AssertShowDecimal((byte)igmpDatagram.CreateGroupRequestCode);
                    break;

                case "igmp.mtrace.max_hops":
                case "igmp.mtrace.saddr":
                case "igmp.mtrace.raddr":
                case "igmp.mtrace.rspaddr":
                case "igmp.mtrace.resp_ttl":
                case "igmp.mtrace.q_id":
                    // todo support IGMP traceroute http://www.ietf.org/proceedings/48/I-D/idmr-traceroute-ipm-07.txt.
                    Assert.IsTrue(new[] { IgmpMessageType.MulticastTraceRouteResponse, IgmpMessageType.MulticastTraceRoute }.Contains(igmpDatagram.MessageType));
                    break;

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

            return true;
        }
        protected override bool CompareField(XElement field, Datagram datagram)
        {
            IpV4Datagram ipV4Datagram = (IpV4Datagram)datagram;
            switch (field.Name())
            {
                case "ip.version":
                    field.AssertShowDecimal(ipV4Datagram.Version);
                    break;

                case "ip.hdr_len":
                    field.AssertShowDecimal(ipV4Datagram.HeaderLength);
                    break;

                case "ip.dsfield":
                    field.AssertShowDecimal((int)ipV4Datagram.TypeOfService);
                    break;

                case "ip.len":
                    field.AssertShowDecimal(ipV4Datagram.TotalLength);
                    break;

                case "ip.id":
                    field.AssertShowHex(ipV4Datagram.Identification);
                    break;

                case "ip.flags":
                    field.AssertShowHex((byte)((ushort)ipV4Datagram.Fragmentation.Options >> 13));
                    break;

                case "ip.frag_offset":
                    field.AssertShowDecimal(ipV4Datagram.Fragmentation.Offset);
                    break;

                case "ip.ttl":
                    field.AssertShowDecimal(ipV4Datagram.Ttl);
                    break;

                case "ip.proto":
                    field.AssertShowDecimal((byte)ipV4Datagram.Protocol);
                    break;

                case "ip.checksum":
                    field.AssertShowHex(ipV4Datagram.HeaderChecksum);
                    foreach (var checksumField in field.Fields())
                    {
                        switch (checksumField.Name())
                        {
                            case "ip.checksum_good":
                                checksumField.AssertShowDecimal(ipV4Datagram.IsHeaderChecksumCorrect);
                                break;

                            case "ip.checksum_bad":
                                if (ipV4Datagram.Length < IpV4Datagram.HeaderMinimumLength ||
                                    ipV4Datagram.Length < ipV4Datagram.HeaderLength)
                                    break;

                                checksumField.AssertShowDecimal(!ipV4Datagram.IsHeaderChecksumCorrect);
                                break;
                        }
                    }
                    break;

                case "ip.src":
                case "ip.src_host":
                    field.AssertShow(ipV4Datagram.Source.ToString());
                    break;

                case "ip.dst":
                case "ip.dst_host":
                    if (field.Show() != ipV4Datagram.Destination.ToString())
                    {
                        // TODO: Remove this fallback once https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=7043 is fixed.
                        field.AssertShow(ipV4Datagram.CurrentDestination.ToString());
                        Assert.IsTrue(ipV4Datagram.Options.IsBadForWireshark(),
                                      string.Format("Expected destination: {0}. Destination: {1}. Current destination: {2}.", field.Show(),
                                                    ipV4Datagram.Destination, ipV4Datagram.CurrentDestination));
                    }
                    break;

                case "ip.addr":
                case "ip.host":
                    Assert.IsTrue(field.Show() == ipV4Datagram.Source.ToString() ||
                                  field.Show() == ipV4Datagram.Destination.ToString() ||
                                  // TODO: Remove this fallback once https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=7043 is fixed.
                                  field.Show() == ipV4Datagram.CurrentDestination.ToString() && ipV4Datagram.Options.IsBadForWireshark(),
                                  string.Format("Expected ip: {0}. ", field.Show()) +
                                  (ipV4Datagram.IsValid
                                       ? string.Format("Source: {0}. Destination: {1}. Current destination: {2}.", ipV4Datagram.Source,
                                                       ipV4Datagram.Destination, ipV4Datagram.CurrentDestination)
                                       : ""));
                    break;

                case "":
                    CompareIpV4Options(field, ipV4Datagram.Options);
                    break;

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

            return true;
        }
        protected override bool CompareField(XElement field, Datagram datagram)
        {
            IpV6Datagram ipV6Datagram = (IpV6Datagram)datagram;
            SkipAuthenticationHeaders(ipV6Datagram);
            int optionsIndex = 0;
            switch (field.Name())
            {
                case "ipv6.version":
                    // TODO: Remove this when https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=10706 is fixed.
                    if (field.Show() != ipV6Datagram.Version.ToString())
                        return false;
                    field.AssertShowDecimal(ipV6Datagram.Version);
                    foreach (XElement subfield in field.Fields())
                    {
                        switch (subfield.Name())
                        {
                            case "ip.version":
                                subfield.AssertShowDecimal(ipV6Datagram.Version);
                                break;

                            default:
                                throw new InvalidOperationException(string.Format("Invalid ipv6 version subfield {0}", subfield.Name()));
                        }
                    }
                    break;

                case "ipv6.class":
                    field.AssertShowDecimal(ipV6Datagram.TrafficClass);
                    break;

                case "ipv6.flow":
                    field.AssertShowDecimal(ipV6Datagram.FlowLabel);
                    field.AssertNoFields();
                    break;

                case "ipv6.plen":
                    field.AssertShowDecimal(ipV6Datagram.PayloadLength);
                    field.AssertNoFields();
                    break;

                case "ipv6.nxt":
                    field.AssertShowDecimal((byte)ipV6Datagram.NextHeader);
                    field.AssertNoFields();
                    break;

                case "ipv6.hlim":
                    field.AssertShowDecimal(ipV6Datagram.HopLimit);
                    field.AssertNoFields();
                    break;

                case "ipv6.src":
                case "ipv6.src_host":
                    field.AssertShow(ipV6Datagram.Source.GetWiresharkString());
                    field.AssertNoFields();
                    break;

                case "ipv6.src_6to4_gw_ipv4":
                case "ipv6.src_6to4_sla_id":
                case "ipv6.6to4_gw_ipv4":
                case "ipv6.6to4_sla_id":
                    field.AssertNoFields();
                    break;

                case "ipv6.dst":
                case "ipv6.dst_host":
                    field.AssertShow(ipV6Datagram.CurrentDestination.GetWiresharkString());
                    field.AssertNoFields();
                    break;

                case "ipv6.addr":
                case "ipv6.host":
                    Assert.IsTrue(field.Show() == ipV6Datagram.Source.GetWiresharkString() ||
                                  field.Show() == ipV6Datagram.CurrentDestination.GetWiresharkString());
                    field.AssertNoFields();
                    break;

                case "ipv6.hop_opt":
                    if (_currentExtensionHeaderIndex >= ipV6Datagram.ExtensionHeaders.Headers.Count)
                    {
                        Assert.IsFalse(ipV6Datagram.ExtensionHeaders.IsValid);
                        int maxLength = ipV6Datagram.Length - IpV6Datagram.HeaderLength - ipV6Datagram.ExtensionHeaders.BytesLength;
                        if (field.Fields().Any(subfield => subfield.Name() == "ipv6.opt.length"))
                        {
                            int length = int.Parse(field.Fields().First(subfield => subfield.Name() == "ipv6.opt.length").Show());
                            MoreAssert.IsBigger(maxLength, length);
                        }
                        else
                        {
                            Assert.AreEqual(6, maxLength);
                        }
                    }
                    else
                    {
                        IpV6ExtensionHeaderHopByHopOptions hopByHopOptions =
                            (IpV6ExtensionHeaderHopByHopOptions)ipV6Datagram.ExtensionHeaders[_currentExtensionHeaderIndex];
                        IncrementCurrentExtensionHeaderIndex(ipV6Datagram);
                        CompareOptions(field, ref optionsIndex, ipV6Datagram, hopByHopOptions);
                    }
                    break;

                case "ipv6.routing_hdr":
                    if (!ipV6Datagram.IsValid)
                        return false;
                    IpV6ExtensionHeaderRouting routing = (IpV6ExtensionHeaderRouting)ipV6Datagram.ExtensionHeaders[_currentExtensionHeaderIndex];
                        IpV6ExtensionHeaderRoutingProtocolLowPowerAndLossyNetworks routingProtocolLowPowerAndLossyNetworks =
                            routing as IpV6ExtensionHeaderRoutingProtocolLowPowerAndLossyNetworks;
                    int routingProtocolLowPowerAndLossyNetworksAddressIndex = 0;
                    IncrementCurrentExtensionHeaderIndex(ipV6Datagram);
                    int sourceRouteAddressIndex = 0;
                    foreach (var headerField in field.Fields())
                    {
                        switch (headerField.Name())
                        {
                            case "":
                                headerField.AssertNoFields();
                                ValidateExtensionHeaderUnnamedField(routing, headerField);
                                break;

                            case "ipv6.routing_hdr.type":
                                headerField.AssertNoFields();
                                headerField.AssertShowDecimal((byte)routing.RoutingType);
                                break;

                            case "ipv6.routing_hdr.left":
                                headerField.AssertNoFields();
                                headerField.AssertShowDecimal(routing.SegmentsLeft);
                                break;

                            case "ipv6.mipv6_home_address":
                                headerField.AssertNoFields();
                                IpV6ExtensionHeaderRoutingHomeAddress routingHomeAddress = (IpV6ExtensionHeaderRoutingHomeAddress)routing;
                                headerField.AssertShow(routingHomeAddress.HomeAddress.ToString("x"));
                                break;

                            case "ipv6.routing_hdr.addr":
                                headerField.AssertNoFields();
                                IpV6ExtensionHeaderRoutingSourceRoute routingSourceRoute = (IpV6ExtensionHeaderRoutingSourceRoute)routing;
                                headerField.AssertShow(routingSourceRoute.Addresses[sourceRouteAddressIndex++].ToString("x"));
                                break;

                            case "ipv6.routing_hdr.rpl.cmprI":
                                headerField.AssertNoFields();
                                headerField.AssertShowDecimal(routingProtocolLowPowerAndLossyNetworks.CommonPrefixLengthForNonLastAddresses);
                                break;

                            case "ipv6.routing_hdr.rpl.cmprE":
                                headerField.AssertNoFields();
                                headerField.AssertShowDecimal(routingProtocolLowPowerAndLossyNetworks.CommonPrefixLengthForLastAddress);
                                break;

                            case "ipv6.routing_hdr.rpl.pad":
                                headerField.AssertNoFields();
                                headerField.AssertShowDecimal(routingProtocolLowPowerAndLossyNetworks.PadSize);
                                break;

                            case "ipv6.routing_hdr.rpl.reserved":
                                headerField.AssertNoFields();
                                headerField.AssertShowDecimal(0);
                                break;

                            case "ipv6.routing_hdr.rpl.segments":
                                if (headerField.Fields().Any())
                                {
                                    headerField.AssertNumFields(1);
                                    headerField.Fields().First().AssertName("_ws.expert");
                                }
                                // TODO: Uncomment when https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=10560 is fixed.
            //                                headerField.AssertShowDecimal(routingProtocolLowPowerAndLossyNetworks.Addresses.Count);
                                break;

                            case "ipv6.routing_hdr.rpl.address":
                                headerField.AssertNoFields();
                                // TODO: Implement when https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=10560 is fixed.
                                break;

                            case "ipv6.routing_hdr.rpl.full_address":
                                headerField.AssertNoFields();
                                // TODO: Implement when https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=10673 is fixed.
                                ++routingProtocolLowPowerAndLossyNetworksAddressIndex;
                                break;

                            default:
                                throw new InvalidOperationException("Invalid IPv6 routing source route field " + headerField.Name());
                        }
                    }
                    break;

                case "ipv6.dst_opt":
                    if (_currentExtensionHeaderIndex >= ipV6Datagram.ExtensionHeaders.Headers.Count)
                    {
                        int expectedExtensionHeaderLength = (int.Parse(field.Fields().Skip(1).First().Value(), NumberStyles.HexNumber) + 1) * 8;
                        int actualMaxPossibleLength = ipV6Datagram.RealPayloadLength -
                                                   ipV6Datagram.ExtensionHeaders.Take(_currentExtensionHeaderIndex).Sum(
                                                       extensionHeader => extensionHeader.Length);
                        MoreAssert.IsSmaller(expectedExtensionHeaderLength, actualMaxPossibleLength);
                        return false;
                    }
                    IpV6ExtensionHeaderDestinationOptions destinationOptions = (IpV6ExtensionHeaderDestinationOptions)ipV6Datagram.ExtensionHeaders[_currentExtensionHeaderIndex];
                    IncrementCurrentExtensionHeaderIndex(ipV6Datagram);
                    CompareOptions(field, ref optionsIndex, ipV6Datagram, destinationOptions);
                    break;

                case "ipv6.shim6":
                    // TODO: Implement Shim6.
                    IpV4Protocol nextHeader = _currentExtensionHeaderIndex > 0
                                                  ? ipV6Datagram.ExtensionHeaders[_currentExtensionHeaderIndex - 1].NextHeader.Value
                                                  : ipV6Datagram.NextHeader;
                    Assert.IsTrue(nextHeader == IpV4Protocol.Shim6);
                    break;

                case "ipv6.unknown_hdr":
                    Assert.AreEqual(ipV6Datagram.ExtensionHeaders.Count(), _currentExtensionHeaderIndex);
                    // TODO: Fix according to https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=9996
                    return false;

                case "ipv6.src_sa_mac":
                case "ipv6.dst_sa_mac":
                case "ipv6.sa_mac":
                case "ipv6.dst_6to4_gw_ipv4":
                case "ipv6.dst_6to4_sla_id":
                    // TODO: Understand how these are calculated.
                    break;

                case "":
                    switch (field.Show())
                    {
                        case "Fragmentation Header":
                            if (_currentExtensionHeaderIndex >= ipV6Datagram.ExtensionHeaders.Headers.Count && !ipV6Datagram.IsValid)
                                return false;
                            IpV6ExtensionHeaderFragmentData fragmentData =
                                (IpV6ExtensionHeaderFragmentData)ipV6Datagram.ExtensionHeaders[_currentExtensionHeaderIndex];
                            IncrementCurrentExtensionHeaderIndex(ipV6Datagram);
                            foreach (var headerField in field.Fields())
                            {
                                switch (headerField.Name())
                                {
                                    case "ipv6.fragment.nxt":
                                        headerField.AssertValue((byte)fragmentData.NextHeader.Value);
                                        break;

                                    case "ipv6.fragment.offset":
                                        headerField.AssertShowDecimal(fragmentData.FragmentOffset);
                                        break;

                                    case "ipv6.fragment.more":
                                        headerField.AssertShowDecimal(fragmentData.MoreFragments);
                                        break;

                                    case "ipv6.fragment.id":
                                        headerField.AssertShowDecimal(fragmentData.Identification);
                                        break;

                                    case "ipv6.fragment.reserved_octet":
                                    case "ipv6.fragment.reserved_bits":
                                        headerField.AssertShowDecimal(0);
                                        break;

                                    default:
                                        throw new InvalidOperationException("Invalid ipv6 fragmentation field " + headerField.Name());
                                }
                            }
                            break;

                        default:
                            throw new InvalidOperationException(string.Format("Invalid ipv6 field {0}", field.Show()));
                    }
                    break;

                default:
                    throw new InvalidOperationException(string.Format("Invalid ipv6 field {0}", field.Name()));
            }

            return true;
        }
        private void CompareResourceRecordData(XElement dataField, DnsResourceRecord resourceRecord)
        {
            var data = resourceRecord.Data;
            string dataFieldName = dataField.Name();
            string dataFieldShow = dataField.Show();
            string dataFieldShowUntilColon = dataFieldShow.Split(':')[0];
            switch (resourceRecord.DnsType)
            {
                case DnsType.A:
                    switch (dataFieldName)
                    {
                        case "dns.resp.addr":
                            dataField.AssertShow(((DnsResourceDataIpV4)data).Data.ToString());
                            break;

                        default:
                            throw new InvalidOperationException("Invalid DNS data field name " + dataFieldName);
                    }
                    break;

                case DnsType.Ns:
                    dataField.AssertName("dns.resp.ns");
                    dataField.AssertShow(GetWiresharkDomainName(((DnsResourceDataDomainName)data).Data));
                    dataField.AssertNoFields();
                    break;

                case DnsType.Md:            // 3.
                case DnsType.MailForwarder: // 4.
                case DnsType.Mailbox:       // 7.
                case DnsType.MailGroup:     // 8.
                case DnsType.MailRename:    // 9.
                    dataField.AssertName("");
                    dataField.AssertShow("Host: " + GetWiresharkDomainName(((DnsResourceDataDomainName)data).Data));
                    dataField.AssertNoFields();
                    break;

                case DnsType.CName:
                    dataField.AssertName("dns.resp.primaryname");
                    dataField.AssertShow(GetWiresharkDomainName(((DnsResourceDataDomainName)data).Data));
                    dataField.AssertNoFields();
                    break;

                case DnsType.StartOfAuthority:
                    dataField.AssertName("");
                    var soaData = (DnsResourceDataStartOfAuthority)data;
                    switch (dataFieldShowUntilColon)
                    {
                        case "Primary name server":
                            dataField.AssertShow(dataFieldShowUntilColon + ": " + GetWiresharkDomainName(soaData.MainNameServer));
                            break;

                        case "Responsible authority's mailbox":
                            dataField.AssertShow(dataFieldShowUntilColon + ": " + GetWiresharkDomainName(soaData.ResponsibleMailbox));
                            break;

                        case "Serial number":
                            dataField.AssertShow(dataFieldShowUntilColon + ": " + soaData.Serial);
                            break;

                        case "Refresh interval":
                            dataField.AssertValue(soaData.Refresh);
                            break;

                        case "Retry interval":
                            dataField.AssertValue(soaData.Retry);
                            break;

                        case "Expiration limit":
                            dataField.AssertValue(soaData.Expire);
                            break;

                        case "Minimum TTL":
                            dataField.AssertValue(soaData.MinimumTtl);
                            break;

                        default:
                            throw new InvalidOperationException("Invalid DNS data field " + dataFieldShow);
                    }
                    dataField.AssertNoFields();
                    break;
                    
                case DnsType.Wks:
                    dataField.AssertName("");
                    var wksData = (DnsResourceDataWellKnownService)data;
                    switch (dataFieldShowUntilColon)
                    {
                        case "Addr":
                            dataField.AssertShow(dataFieldShowUntilColon + ": " + wksData.Address);
                            break;

                        case "Protocol":
                            dataField.AssertValue((byte)wksData.Protocol);
                            break;

                        case "Bits":
                            while (wksData.Bitmap[_wksBitmapIndex] == 0x00)
                                ++_wksBitmapIndex;
                            dataField.AssertValue(wksData.Bitmap[_wksBitmapIndex++]);
                            break;

                        default:
                            throw new InvalidOperationException("Invalid DNS data field " + dataFieldShow);
                    }
                    dataField.AssertNoFields();
                    break;

                case DnsType.Ptr:
                    dataField.AssertName("");
                    dataField.AssertShow("Domain name: " + GetWiresharkDomainName(((DnsResourceDataDomainName)data).Data));
                    dataField.AssertNoFields();
                    break;

                case DnsType.HInfo:
                    dataField.AssertName("");
                    var hInfoData = (DnsResourceDataHostInformation)data;
                    switch (dataFieldShowUntilColon)
                    {
                        case "CPU":
                            dataField.AssertValue(new[] {(byte)hInfoData.Cpu.Length}.Concat(hInfoData.Cpu));
                            break;

                        case "OS":
                            dataField.AssertValue(new[] {(byte)hInfoData.Os.Length}.Concat(hInfoData.Os));
                            break;

                        default:
                            throw new InvalidOperationException("Invalid DNS data field " + dataFieldShow);
                    }
                    dataField.AssertNoFields();
                    break;
                    
                case DnsType.MInfo:
                    dataField.AssertName("");
                    var mInfoData = (DnsResourceDataMailingListInfo)data;
                    switch (dataFieldShowUntilColon)
                    {
                        case "Responsible Mailbox":
                            dataField.AssertShow(dataFieldShowUntilColon + ": " + GetWiresharkDomainName(mInfoData.MailingList));
                            break;

                        case "Error Mailbox":
                            dataField.AssertShow(dataFieldShowUntilColon + ": " + GetWiresharkDomainName(mInfoData.ErrorMailbox));
                            break;

                        default:
                            throw new InvalidOperationException("Invalid DNS data field " + dataFieldShow);
                    }
                    dataField.AssertNoFields();
                    break;

                case DnsType.MailExchange:
                    var mxData = (DnsResourceDataMailExchange)data;
                    switch (dataFieldShowUntilColon)
                    {
                        case "Preference":
                            dataField.AssertShow(dataFieldShowUntilColon + ": " + mxData.Preference);
                            break;

                        case "Mail exchange":
                            dataField.AssertShow(dataFieldShowUntilColon + ": " + GetWiresharkDomainName(mxData.MailExchangeHost));
                            break;

                        default:
                            throw new InvalidOperationException("Invalid DNS data field " + dataFieldShow);
                    }
                    dataField.AssertNoFields();
                    break;

                case DnsType.Txt: // 16.
                case DnsType.Spf: // 99.
                    var txtData = (DnsResourceDataText)data;
                    dataField.AssertShow("Text: " + txtData.Text[_txtIndex++].Decode(EncodingExtensions.Iso88591).ToWiresharkLiteral(false, false));
                    dataField.AssertNoFields();
                    break;

                case DnsType.ResponsiblePerson:
                    dataField.AssertName("");
                    var rpData = (DnsResourceDataResponsiblePerson)data;
                    switch (dataFieldShowUntilColon)
                    {
                        case "Mailbox":
                            dataField.AssertShow(dataFieldShowUntilColon + ": " + GetWiresharkDomainName(rpData.Mailbox));
                            break;

                        case "TXT RR":
                            dataField.AssertShow(dataFieldShowUntilColon + ": " + GetWiresharkDomainName(rpData.TextDomain));
                            break;

                        default:
                            throw new InvalidOperationException("Invalid DNS data field " + dataFieldShow);
                    }
                    dataField.AssertNoFields();
                    break;

                case DnsType.AfsDatabase:
                    dataField.AssertName("");
                    var afsDbData = (DnsResourceDataAfsDatabase)data;
                    switch (dataFieldShowUntilColon)
                    {
                        case "Subtype":
                            dataField.AssertShow(dataFieldShowUntilColon + ": " + (ushort)afsDbData.Subtype);
                            break;

                        case "Hostname":
                            dataField.AssertShow(dataFieldShowUntilColon + ": " + GetWiresharkDomainName(afsDbData.HostName));
                            break;

                        default:
                            throw new InvalidOperationException("Invalid DNS data field " + dataFieldShow);

                    }
                    dataField.AssertNoFields();
                    break;

                case DnsType.X25:
                    dataField.AssertName("");
                    dataField.AssertShow("PSDN-Address: " + ((DnsResourceDataString)data).String.Decode(EncodingExtensions.Iso88591).ToWiresharkLiteral(false, false));
                    dataField.AssertNoFields();
                    break;

                case DnsType.Isdn:
                    dataField.AssertName("");
                    var isdnData = (DnsResourceDataIsdn)data;
                    switch (dataFieldShowUntilColon)
                    {
                        case "ISDN Address":
                            dataField.AssertShow(dataFieldShowUntilColon + ": " +
                                                 isdnData.IsdnAddress.Decode(EncodingExtensions.Iso88591).ToWiresharkLiteral(false, false));
                            break;

                        case "Subaddress":
                            dataField.AssertShow(dataFieldShowUntilColon + ": " +
                                                 isdnData.Subaddress.Decode(EncodingExtensions.Iso88591).ToWiresharkLiteral(false, false));
                            break;

                        default:
                            throw new InvalidOperationException("Invalid DNS data field " + dataFieldShow);
                    }
                    dataField.AssertNoFields();
                    break;

                case DnsType.RouteThrough:
                    dataField.AssertName("");
                    var rtData = (DnsResourceDataRouteThrough)data;
                    switch (dataFieldShowUntilColon)
                    {
                        case "Preference":
                            dataField.AssertShow(dataFieldShowUntilColon + ": " + rtData.Preference);
                            break;

                        case "Intermediate-Host":
                            dataField.AssertShow(dataFieldShowUntilColon + ": " + GetWiresharkDomainName(rtData.IntermediateHost));
                            break;

                        default:
                            throw new InvalidOperationException("Invalid DNS data field " + dataFieldShow);
                    }
                    dataField.AssertNoFields();
                    break;

                case DnsType.NetworkServiceAccessPoint:
                    var nsapData = (DnsResourceDataNetworkServiceAccessPoint)data;

                    switch (dataFieldName)
                    {
                        case "dns.nsap.rdata":
                            byte[] nsapId = new byte[6];
                            nsapId.Write(0, nsapData.SystemIdentifier, Endianity.Big);
                            dataField.AssertValue(nsapData.AreaAddress.Concat(nsapId).Concat(nsapData.Selector));
                            break;

                        default:
                            throw new InvalidOperationException("Invalid DNS data field name " + dataFieldName);
                    }
                    dataField.AssertNoFields();
                    break;

                case DnsType.NetworkServiceAccessPointPointer:
                    dataField.AssertName("");
                    dataField.AssertShow("Owner: " + GetWiresharkDomainName(((DnsResourceDataDomainName)data).Data));
                    dataField.AssertNoFields();
                    break;

                case DnsType.Key:
                    dataField.AssertName("");
                    var keyData = (DnsResourceDataKey)data;
                    switch (dataFieldShowUntilColon)
                    {
                        case "Flags":
                            foreach (var flagField in dataField.Fields())
                            {
                                int flagCount = GetFlagCount(flagField);
                                switch (flagCount)
                                {
                                    case 0:
                                        flagField.AssertShow(keyData.AuthenticationProhibited
                                                                 ? "1... .... .... .... = Key prohibited for authentication"
                                                                 : "0... .... .... .... = Key allowed for authentication");
                                        break;

                                    case 1:
                                        flagField.AssertShow(keyData.ConfidentialityProhibited
                                                                 ? ".1.. .... .... .... = Key prohibited for confidentiality"
                                                                 : ".0.. .... .... .... = Key allowed for confidentiality");
                                        break;

                                    case 2:
                                        flagField.AssertShow(keyData.Experimental
                                                                 ? "..1. .... .... .... = Key is experimental or optional"
                                                                 : "..0. .... .... .... = Key is required");
                                        break;

                                    case 5:
                                        flagField.AssertShow(keyData.UserAssociated
                                                                 ? ".... .1.. .... .... = Key is associated with a user"
                                                                 : ".... .0.. .... .... = Key is not associated with a user");
                                        break;

                                    case 6:
                                        flagField.AssertShow(keyData.NameType == DnsKeyNameType.NonZoneEntity
                                                                 ? ".... ..1. .... .... = Key is associated with the named entity"
                                                                 : ".... ..0. .... .... = Key is not associated with the named entity");
                                        break;

                                    case 8:
                                        flagField.AssertShow(keyData.IpSec
                                                                 ? ".... .... 1... .... = Key is valid for use with IPSEC"
                                                                 : ".... .... 0... .... = Key is not valid for use with IPSEC");
                                        break;

                                    case 9:
                                        flagField.AssertShow(keyData.Email
                                                                 ? ".... .... .1.. .... = Key is valid for use with MIME security multiparts"
                                                                 : ".... .... .0.. .... = Key is not valid for use with MIME security multiparts");
                                        break;

                                    case 12:
                                        Assert.AreEqual(flagField.Show().Substring(19), " = Signatory = " + (byte)keyData.Signatory);
                                        break;

                                    default:
                                        throw new InvalidOperationException("Invalid flag count " + flagCount);
                                }
                            }
                            break;

                        case "Protocol":
                            dataField.AssertShow(dataFieldShowUntilColon + ": " + (byte)keyData.Protocol);
                            dataField.AssertNoFields();
                            break;

                        case "Algorithm":
                            dataField.AssertValue((byte)keyData.Algorithm);
                            dataField.AssertNoFields();
                            break;

                        case "Key id":
                            // TODO: Calculate key tag.
                            dataField.AssertNoFields();
                            break;

                        case "Public key":
                            byte[] flagsExtension;
                            if (keyData.FlagsExtension == null)
                            {
                                flagsExtension = new byte[0];
                            } 
                            else
                            {
                                flagsExtension = new byte[2];
                                flagsExtension.Write(0, keyData.FlagsExtension.Value, Endianity.Big);
                            }
                            dataField.AssertValue(flagsExtension.Concat(keyData.PublicKey));
                            dataField.AssertNoFields();
                            break;

                        default:
                            throw new InvalidOperationException("Invalid DNS data field " + dataFieldShow);
                    }
                    break;

                case DnsType.Signature:   // 24.
                case DnsType.ResourceRecordSignature: // 46.
                    dataField.AssertName("");
                    var sigData = (DnsResourceDataSignature)data;
                    switch (dataFieldShowUntilColon)
                    {
                        case "Type covered":
                            dataField.AssertValue((ushort)sigData.TypeCovered);
                            break;

                        case "Algorithm":
                            dataField.AssertValue((byte)sigData.Algorithm);
                            break;

                        case "Labels":
                            dataField.AssertShow(dataFieldShowUntilColon + ": " + sigData.Labels);
                            break;

                        case "Original TTL":
                            dataField.AssertValue(sigData.OriginalTtl);
                            break;

                        case "Signature expiration":
                            dataField.AssertValue(sigData.SignatureExpiration);
                            break;

                        case "Time signed":
                            dataField.AssertValue(sigData.SignatureInception);
                            break;

                        case "Id of signing key(footprint)":
                            dataField.AssertShow(dataFieldShowUntilColon + ": " + sigData.KeyTag);
                            break;

                        case "Signer's name":
                            dataField.AssertShow(dataFieldShowUntilColon + ": " + GetWiresharkDomainName(sigData.SignersName));
                            break;

                        case "Signature":
                            dataField.AssertValue(sigData.Signature);
                            break;

                        default:
                            throw new InvalidOperationException("Invalid DNS data field " + dataFieldShow);
                    }
                    dataField.AssertNoFields();
                    break;

                case DnsType.PointerX400:
                    dataField.AssertName("");
                    var pxData = (DnsResourceDataX400Pointer)data;
                    switch (dataFieldShowUntilColon)
                    {
                        case "Preference":
                            dataField.AssertShow(dataFieldShowUntilColon + ": " + pxData.Preference);
                            break;

                        case "MAP822":
                            dataField.AssertShow(dataFieldShowUntilColon + ": " + GetWiresharkDomainName(pxData.Map822));
                            break;

                        case "MAPX400":
                            dataField.AssertShow(dataFieldShowUntilColon + ": " + GetWiresharkDomainName(pxData.MapX400));
                            break;

                        default:
                            throw new InvalidOperationException("Invalid DNS data field " + dataFieldShow);
                    }
                    dataField.AssertNoFields();
                    break;

                case DnsType.GPos:
                    dataField.AssertName("");
                    var gposData = (DnsResourceDataGeographicalPosition)data;
                    switch (dataFieldShowUntilColon)
                    {
                        case "Longitude":
                            dataField.AssertShow(dataFieldShowUntilColon + ": " + gposData.Longitude);
                            break;

                        case "Latitude":
                            dataField.AssertShow(dataFieldShowUntilColon + ": " + gposData.Latitude);
                            break;

                        case "Altitude":
                            dataField.AssertShow(dataFieldShowUntilColon + ": " + gposData.Altitude);
                            break;

                        default:
                            throw new InvalidOperationException("Invalid DNS data field " + dataFieldShow);
                    }
                    dataField.AssertNoFields();
                    break;

                case DnsType.Aaaa:
                    dataField.AssertName("");
                    dataField.AssertShow("Addr: " + GetWiresharkIpV6(((DnsResourceDataIpV6)data).Data));
                    break;

                case DnsType.Loc:
                    dataField.AssertName("");
                    var locData = (DnsResourceDataLocationInformation)data;
                    switch (dataFieldShowUntilColon)
                    {
                        case "Version":
                            dataField.AssertShow(dataFieldShowUntilColon + ": " + locData.Version);
                            break;

                        case "Data":
                            dataField.AssertShow("Data");
                            break;

                        case "Size":
                            dataField.AssertShow(dataFieldShowUntilColon + ": " + GetPrecisionValueString(locData.Size));
                            break;

                        case "Horizontal precision":
                            dataField.AssertShow(dataFieldShowUntilColon + ": " + GetPrecisionValueString(locData.HorizontalPrecision));
                            break;

                        case "Vertical precision":
                            dataField.AssertShow(dataFieldShowUntilColon + ": " + GetPrecisionValueString(locData.VerticalPrecision));
                            break;

                        case "Latitude":
                            dataField.AssertValue(locData.Latitude);
                            break;

                        case "Longitude":
                            dataField.AssertValue(locData.Longitude);
                            break;

                        case "Altitude":
                            dataField.AssertValue(locData.Altitude);
                            break;

                        default:
                            throw new InvalidOperationException("Invalid DNS data field " + dataFieldShowUntilColon);
                    }
                    dataField.AssertNoFields();
                    break;

                case DnsType.NextDomain:
                    dataField.AssertName("");
                    var nxtData = (DnsResourceDataNextDomain)data;
                    switch (dataFieldShowUntilColon)
                    {
                        case "Next domain name":
                            dataField.AssertShow(dataFieldShowUntilColon + ": " + GetWiresharkDomainName(nxtData.NextDomainName));
                            break;

                        case "RR type in bit map":
                            DnsType actualType = nxtData.TypesExist.Skip(_nxtTypeIndex++).First();
                            DnsType expectedType;
                            if (!TryGetDnsType(dataFieldShow, out expectedType))
                                throw new InvalidOperationException(string.Format("Can't parse DNS field {0} : {1}", dataFieldShow, actualType));
                            Assert.AreEqual(expectedType, actualType);
                            break;

                        default:
                            throw new InvalidOperationException("Invalid DNS data field " + dataFieldShow);
                    }
                    dataField.AssertNoFields();
                    break;

                case DnsType.ServerSelection:
                    dataField.AssertName("");
                    var srvData = (DnsResourceDataServerSelection)data;
                    switch (dataFieldShowUntilColon)
                    {
                        case "Priority":
                            dataField.AssertShow(dataFieldShowUntilColon + ": " + srvData.Priority);
                            break;

                        case "Weight":
                            dataField.AssertShow(dataFieldShowUntilColon + ": " + srvData.Weight);
                            break;

                        case "Port":
                            dataField.AssertShow(dataFieldShowUntilColon + ": " + srvData.Port);
                            break;

                        case "Target":
                            dataField.AssertShow(dataFieldShowUntilColon + ": " + GetWiresharkDomainName(srvData.Target));
                            break;

                        default:
                            throw new InvalidOperationException("Invalid DNS data field " + dataFieldShowUntilColon);
                    }
                    dataField.AssertNoFields();
                    break;

                case DnsType.NaPtr:
                    dataField.AssertName("");
                    var naPtrData = (DnsResourceDataNamingAuthorityPointer)data;
                    switch (dataFieldShowUntilColon)
                    {
                        case "Order":
                            dataField.AssertShow(dataFieldShowUntilColon + ": " + naPtrData.Order);
                            break;

                        case "Preference":
                            dataField.AssertShow(dataFieldShowUntilColon + ": " + naPtrData.Preference);
                            break;

                        case "Flags length":
                            dataField.AssertShow(dataFieldShowUntilColon + ": " + naPtrData.Flags.Length);
                            break;

                        case "Flags":
                            dataField.AssertValue(naPtrData.Flags);
                            break;

                        case "Service length":
                            dataField.AssertShow(dataFieldShowUntilColon + ": " + naPtrData.Services.Length);
                            break;

                        case "Service":
                            dataField.AssertValue(naPtrData.Services);
                            break;

                        case "Regex length":
                            dataField.AssertShow(dataFieldShowUntilColon + ": " + naPtrData.RegularExpression.Length);
                            break;

                        case "Regex":
                            dataField.AssertValue(naPtrData.RegularExpression);
                            break;

                        case "Replacement length":
                            dataField.AssertShow(dataFieldShowUntilColon + ": " + naPtrData.Replacement.NonCompressedLength);
                            break;

                        case "Replacement":
                            dataField.AssertShow(dataFieldShowUntilColon + ": " + GetWiresharkDomainName(naPtrData.Replacement));
                            break;

                        default:
                            throw new InvalidOperationException("Invalid DNS data field " + dataFieldShow);
                    }
                    dataField.AssertNoFields();
                    break;

                case DnsType.KeyExchanger:
                    dataField.AssertName("");
                    var kxData = (DnsResourceDataKeyExchanger)data;
                    switch (dataFieldShowUntilColon)
                    {
                        case "Preference":
                            dataField.AssertShow(dataFieldShowUntilColon + ": 0");
                            dataField.AssertValue(kxData.Preference);
                            break;

                        case "Key exchange":
                            dataField.AssertShow(dataFieldShowUntilColon + ": " + GetWiresharkDomainName(kxData.KeyExchangeHost));
                            break;

                        default:
                            throw new InvalidOperationException("Invalid DNS data field " + dataFieldShow);
                    }
                    dataField.AssertNoFields();
                    break;

                case DnsType.Cert:
                    dataField.AssertName("");
                    var certData = (DnsResourceDataCertificate)data;
                    switch (dataFieldShowUntilColon)
                    {
                        case "Type":
                            dataField.AssertValue((ushort)certData.CertificateType);
                            break;

                        case "Key footprint":
                            dataField.AssertValue(certData.KeyTag);
                            break;

                        case "Algorithm":
                            dataField.AssertValue((byte)certData.Algorithm);
                            break;

                        case "Public key":
                            dataField.AssertValue(certData.Certificate);
                            break;

                        default:
                            throw new InvalidOperationException("Invalid DNS data field " + dataFieldShow);
                    }
                    dataField.AssertNoFields();
                    break;
                    
                case DnsType.A6:
                    var a6Data = (DnsResourceDataA6)data;
                    switch (dataFieldShowUntilColon)
                    {
                        case "Prefix len":
                            dataField.AssertShow(dataFieldShowUntilColon + ": " + a6Data.PrefixLength);
                            break;

                        case "Address suffix":
                            Assert.AreEqual(new IpV6Address(dataFieldShow.Substring(dataFieldShowUntilColon.Length + 2)), a6Data.AddressSuffix);
                            break;

                        case "Prefix name":
                            dataField.AssertShow(dataFieldShowUntilColon + ": " + GetWiresharkDomainName(a6Data.PrefixName));
                            break;

                        default:
                            throw new InvalidOperationException("Invalid DNS data field " + dataFieldShow);
                    }
                    dataField.AssertNoFields();
                    break;
                
                case DnsType.DName:
                    dataField.AssertName("");
                    dataField.AssertShow("Target name: " + GetWiresharkDomainName(((DnsResourceDataDomainName)data).Data));
                    dataField.AssertNoFields();
                    break;

                case DnsType.Opt:
                    var optResourceRecord = (DnsOptResourceRecord)resourceRecord;
                    var optData = (DnsResourceDataOptions)data;
                    switch (dataFieldName)
                    {
                        case "":
                            switch (dataFieldShowUntilColon)
                            {
                                case "UDP payload size":
                                    dataField.AssertShow(dataFieldShowUntilColon + ": " + optResourceRecord.SendersUdpPayloadSize);
                                    dataField.AssertNoFields();
                                    break;

                                case "Higher bits in extended RCODE":
                                    dataField.AssertValue(optResourceRecord.ExtendedReturnCode);
                                    dataField.AssertNoFields();
                                    break;

                                case "EDNS0 version":
                                    dataField.AssertShow(dataFieldShowUntilColon + ": " + (byte)optResourceRecord.Version);
                                    dataField.AssertNoFields();
                                    break;

                                case "Z":
                                    ushort flags = (ushort)optResourceRecord.Flags;
                                    dataField.AssertValue(flags);
                                    if (dataField.Fields().Any())
                                    {
                                        dataField.AssertNumFields(2);
                                        dataField.Fields().First().AssertShow("Bit 0 (DO bit): 1 (Accepts DNSSEC security RRs)");
                                        // TODO - uncomment once https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=7045 is fixed.
                                        // dataField.Fields().Last().AssertShow("Bits 1-15: 0x" + (flags & 0x7FFF).ToString("x") + " (reserved)");
                                    }
                                    else
                                    {
                                        Assert.AreEqual<ushort>(0, (ushort)optResourceRecord.Flags);
                                    }
                                    break;

                                case "Data":
                                    Assert.AreEqual(dataField.Value().Length, 2 * optData.Options.Options.Sum(option => option.Length));
                                    dataField.AssertNoFields();
                                    break;

                                default:
                                    throw new InvalidOperationException("Invalid DNS data field " + dataFieldShow);
                            }
                            break;

                        case "dns.resp.len":
                            dataField.AssertShow("Data length: " + optData.Options.Options.Sum(option => option.DataLength));
                            dataField.AssertNoFields();
                            break;

                        default:
                            throw new InvalidOperationException("Invalid DNS data field name " + dataFieldName);
                    }
                    break;

                case DnsType.Apl:
                    var aplData = (DnsResourceDataAddressPrefixList)data;
                    switch (dataFieldName)
                    {
                        case "":
                            switch (dataFieldShowUntilColon)
                            {
                                case "Address Family":
                                    dataField.AssertValue((ushort)aplData.Items[_aplItemIndex++].AddressFamily);
                                    break;

                                case "IPv4 address":
                                case "IPv6 address":
                                    dataField.AssertValue(aplData.Items[_aplItemIndex - 1].AddressFamilyDependentPart);
                                    break;

                                default:
                                    throw new InvalidOperationException("Invalid DNS data field name " + dataFieldShowUntilColon);
                            }
                            dataField.AssertNoFields();
                            
                            break;

                        case "dns.apl.coded.prefix":
                            dataField.AssertShowDecimal(aplData.Items[_aplItemIndex - 1].PrefixLength);
                            break;

                        case "dns.apl.negation":
                            dataField.AssertShowDecimal(aplData.Items[_aplItemIndex - 1].Negation);
                            break;

                        case "dns.apl.afdlength":
                            dataField.AssertShowDecimal(aplData.Items[_aplItemIndex - 1].AddressFamilyDependentPart.Length);
                            break;

                        default:
                            throw new InvalidOperationException("Invalid DNS data field name " + dataFieldName);
                    }
                    dataField.AssertNoFields();
                    break;

                case DnsType.DelegationSigner:  // 43.
                case DnsType.DnsSecLookAsideValidation: // 32769.
                    dataField.AssertName("");
                    var dsData = (DnsResourceDataDelegationSigner)data;
                    switch (dataFieldShowUntilColon)
                    {
                        case "Key id":
                            dataField.AssertShow(dataFieldShowUntilColon + ": " + dsData.KeyTag.ToString("0000"));
                            break;

                        case "Algorithm":
                            dataField.AssertValue((byte)dsData.Algorithm);
                            break;

                        case "Digest type":
                            dataField.AssertValue((byte)dsData.DigestType);
                            break;

                        case "Public key":
                            dataField.AssertValue(dsData.Digest);
                            break;

                        default:
                            throw new InvalidOperationException("Invalid DNS data field " + dataFieldShow);
                    }
                    dataField.AssertNoFields();
                    break;

                case DnsType.SshFingerprint:
                    var sshFpData = (DnsResourceDataSshFingerprint)data;
                    switch (dataFieldName)
                    {
                        case "":
                            switch (dataFieldShowUntilColon)
                            {
                                case "Algorithm":
                                    dataField.AssertValue((byte)sshFpData.Algorithm);
                                    break;

                                case "Fingerprint type":
                                    dataField.AssertValue((byte)sshFpData.FingerprintType);
                                    break;

                                default:
                                    throw new InvalidOperationException("Invalid DNS data field " + dataFieldShow);
                            }
                            break;

                        case "dns.sshfp.fingerprint":
                            dataField.AssertValue(sshFpData.Fingerprint);
                            break;

                        default:
                            throw new InvalidOperationException("Invalid DNS data field name " + dataFieldName);
                    }
                    dataField.AssertNoFields();
                    break;

                case DnsType.IpSecKey:
                    dataField.AssertName("");
                    var ipSecKeyData = (DnsResourceDataIpSecKey)data;
                    switch (dataFieldShowUntilColon)
                    {
                        case "Gateway precedence":
                            dataField.AssertValue(ipSecKeyData.Precedence);
                            break;

                        case "Algorithm":
                            dataField.AssertValue((byte)ipSecKeyData.Algorithm);
                            break;

                        case "Gateway":
                            switch (ipSecKeyData.GatewayType)
                            {
                                case DnsGatewayType.None:
                                    dataField.AssertShow(dataFieldShowUntilColon + ": no gateway");
                                    break;

                                case DnsGatewayType.IpV4:
                                    dataField.AssertShow(dataFieldShowUntilColon + ": " + ((DnsGatewayIpV4)ipSecKeyData.Gateway).Value);
                                    break;

                                case DnsGatewayType.IpV6:
                                    dataField.AssertShow(dataFieldShowUntilColon + ": " + GetWiresharkIpV6(((DnsGatewayIpV6)ipSecKeyData.Gateway).Value));
                                    break;

                                case DnsGatewayType.DomainName:
                                    dataField.AssertShow(dataFieldShowUntilColon + ": " + GetWiresharkDomainName(((DnsGatewayDomainName)ipSecKeyData.Gateway).Value));
                                    break;

                                default:
                                    throw new InvalidOperationException("Invalid Gateway Type " + ipSecKeyData.GatewayType);
                            }
                            break;

                        case "Public key":
                            dataField.AssertValue(ipSecKeyData.PublicKey);
                            break;

                        default:
                            throw new InvalidOperationException("Invalid DNS data field " + dataFieldShow);
                    }
                    dataField.AssertNoFields();
                    break;

                case DnsType.NSec:
                    dataField.AssertName("");
                    var nSecData = (DnsResourceDataNextDomainSecure)data;
                    switch (dataFieldShowUntilColon)
                    {
                        case "Next domain name":
                            dataField.AssertShow(dataFieldShowUntilColon + ": " + GetWiresharkDomainName(nSecData.NextDomainName));
                            break;

                        case "RR type in bit map":
                            DnsType actualType = nSecData.TypesExist[_nSecTypeIndex++];
                            DnsType expectedType;
                            if (!TryGetDnsType(dataFieldShow, out expectedType))
                                throw new InvalidOperationException(string.Format("Failed parsing type from {0} : {1}", dataFieldShow, actualType));

                            Assert.AreEqual(expectedType, actualType);
                            break;

                        default:
                            throw new InvalidOperationException("Invalid DNS data field " + dataFieldShow);
                    }
                    dataField.AssertNoFields();
                    break;
                    
                case DnsType.DnsKey:
                    dataField.AssertName("");
                    var dnsKeyData = (DnsResourceDataDnsKey)data;
                    switch (dataFieldShowUntilColon)
                    {
                        case "Flags":
                            foreach (var flagField in dataField.Fields())
                            {
                                int flagCount = GetFlagCount(flagField);
                                switch (flagCount)
                                {
                                    case 7:
                                        flagField.AssertShow(dnsKeyData.ZoneKey
                                                                 ? ".... ...1 .... .... = This is the zone key for the specified zone"
                                                                 : ".... ...0 .... .... = This is not a zone key");
                                        break;

                                    case 8:
                                        flagField.AssertShow(dnsKeyData.Revoke
                                                                 ? ".... .... 1... .... = Key is revoked"
                                                                 : ".... .... 0... .... = Key is not revoked");
                                        break;

                                    case 15:
                                        flagField.AssertShow(dnsKeyData.SecureEntryPoint
                                                                 ? ".... .... .... ...1 = Key is a Key Signing Key"
                                                                 : ".... .... .... ...0 = Key is a Zone Signing Key");
                                        break;

                                    default:
                                        throw new InvalidOperationException("Invalid DNS data flag field " + flagField.Show());
                                }
                            }
                            break;

                        case "Protocol":
                            dataField.AssertShow(dataFieldShowUntilColon + ": " + dnsKeyData.Protocol);
                            dataField.AssertNoFields();
                            break;

                        case "Algorithm":
                            dataField.AssertValue((byte)dnsKeyData.Algorithm);
                            dataField.AssertNoFields();
                            break;

                        case "Key id":
                            // TODO: Calculate key tag.
                            dataField.AssertNoFields();
                            break;

                        case "Public key":
                            dataField.AssertValue(dnsKeyData.PublicKey);
                            dataField.AssertNoFields();
                            break;

                        default:
                            throw new InvalidOperationException("Invalid DNS data field " + dataFieldShow);
                    }
                    break;

                case DnsType.DynamicHostConfigurationId:
                    switch (dataFieldName)
                    {
                        case "dns.dhcid.rdata":
                            dataField.AssertValue(((DnsResourceDataAnything)data).Data);
                            break;

                        default:
                            throw new InvalidOperationException("Invalid DNS resource data field name " + dataFieldName);
                    }
                    dataField.AssertNoFields();
                    break;

                case DnsType.NSec3:
                    var nSec3Data = (DnsResourceDataNextDomainSecure3)data;
                    switch (dataFieldName)
                    {
                        case "dns.nsec3.algo":
                            dataField.AssertShowDecimal((byte)nSec3Data.HashAlgorithm);
                            dataField.AssertNoFields();
                            break;

                        case "dns.nsec3.flags":
                            dataField.AssertShowDecimal((byte)nSec3Data.Flags);
                            foreach (var flagField in dataField.Fields())
                            {
                                string flagFieldName = flagField.Name();
                                switch (flagFieldName)
                                {
                                    case "dns.nsec3.flags.opt_out":
                                        dataField.AssertShowDecimal((nSec3Data.Flags & DnsSecNSec3Flags.OptOut) == DnsSecNSec3Flags.OptOut);
                                        break;

                                    default:
                                        throw new InvalidOperationException("Invalid DNS resource data flag field name " + flagFieldName);
                                }
                            }
                            break;

                        case "dns.nsec3.iterations":
                            dataField.AssertShowDecimal(nSec3Data.Iterations);
                            dataField.AssertNoFields();
                            break;

                        case "dns.nsec3.salt_length":
                            dataField.AssertShowDecimal(nSec3Data.Salt.Length);
                            dataField.AssertNoFields();
                            break;

                        case "dns.nsec3.salt_value":
                            dataField.AssertValue(nSec3Data.Salt);
                            dataField.AssertNoFields();
                            break;

                        case "dns.nsec3.hash_length":
                            dataField.AssertShowDecimal(nSec3Data.NextHashedOwnerName.Length);
                            dataField.AssertNoFields();
                            break;

                        case "dns.nsec3.hash_value":
                            dataField.AssertValue(nSec3Data.NextHashedOwnerName);
                            dataField.AssertNoFields();
                            break;

                        case "":
                            DnsType expectedType = nSec3Data.TypesExist[_nSec3TypeIndex++];
                            Assert.IsTrue(dataField.Show().StartsWith("RR type in bit map: "));
                            if (dataField.Show().EndsWith(string.Format("({0})", (ushort)expectedType)))
                                dataField.AssertShow(string.Format("RR type in bit map: Unknown ({0})", (ushort)expectedType));
                            else
                                Assert.IsTrue(
                                    dataFieldShow.Replace("-", "").StartsWith("RR type in bit map: " + GetWiresharkDnsType(expectedType).Replace("-", "")),
                                    string.Format("{0} : {1}", dataFieldShow, GetWiresharkDnsType(expectedType)));
                            dataField.AssertNoFields();
                            break;

                        default:
                            throw new InvalidOperationException("Invalid DNS resource data field name " + dataFieldName);
                    }
                    break;

                case DnsType.NSec3Parameters:
                    var nSec3ParamData = (DnsResourceDataNextDomainSecure3Parameters)data;
                    switch (dataFieldName)
                    {
                        case "dns.nsec3.algo":
                            dataField.AssertShowDecimal((byte)nSec3ParamData.HashAlgorithm);
                            break;

                        case "dns.nsec3.flags":
                            dataField.AssertShowDecimal((byte)nSec3ParamData.Flags);
                            break;

                        case "dns.nsec3.iterations":
                            dataField.AssertShowDecimal(nSec3ParamData.Iterations);
                            break;

                        case "dns.nsec3.salt_length":
                            dataField.AssertShowDecimal(nSec3ParamData.Salt.Length);
                            break;

                        case "dns.nsec3.salt_value":
                            dataField.AssertShow(nSec3ParamData.Salt);
                            break;

                        default:
                            throw new InvalidOperationException("Invalid DNS resource data field name " + dataFieldName);
                    }
                    dataField.AssertNoFields();
                    break;

                case DnsType.Hip:
                    var hipData = (DnsResourceDataHostIdentityProtocol)data;
                    switch (dataFieldName)
                    {
                        case "":
                            switch (dataFieldShowUntilColon)
                            {
                                case "HIT length":
                                    dataField.AssertShow(dataFieldShowUntilColon + ": " + hipData.HostIdentityTag.Length);
                                    break;

                                case "PK algorithm":
                                    dataField.AssertValue((byte)hipData.PublicKeyAlgorithm);
                                    break;

                                case "PK length":
                                    dataField.AssertShow(dataFieldShowUntilColon + ": " + hipData.PublicKey.Length);
                                    break;

                                case "Rendezvous Server":
                                    dataField.AssertShow(dataFieldShowUntilColon + ": " +
                                                         GetWiresharkDomainName(hipData.RendezvousServers[_hipRendezvousServersIndex++]));
                                    break;

                                default:
                                    throw new InvalidOperationException("Invalid DNS data field " + dataFieldShow);
                            }
                            break;

                        case "dns.hip.hit":
                            dataField.AssertShow(hipData.HostIdentityTag);
                            break;

                        case "dns.hip.pk":
                            dataField.AssertShow(hipData.PublicKey);
                            break;

                        default:
                            throw new InvalidOperationException("Invalid DNS data field name " + dataFieldName);
                    }
                    dataField.AssertNoFields();
                    break;

                case DnsType.TKey:
                    dataField.AssertName("");
                    var tKeyData = (DnsResourceDataTransactionKey)data;
                    switch (dataFieldShowUntilColon)
                    {
                        case "Algorithm name":
                            dataField.AssertShow(dataFieldShowUntilColon + ": " + GetWiresharkDomainName(tKeyData.Algorithm));
                            break;

                        case "Signature inception":
                            dataField.AssertValue(tKeyData.Inception);
                            break;

                        case "Signature expiration":
                            dataField.AssertValue(tKeyData.Expiration);
                            break;

                        case "Mode":
                            dataField.AssertValue((ushort)tKeyData.Mode);
                            break;

                        case "Error":
                            dataField.AssertValue((ushort)tKeyData.Error);
                            break;

                        case "Key Size":
                            dataField.AssertShow(dataFieldShowUntilColon + ": " + tKeyData.Key.Length);
                            break;

                        case "Key Data":
                            dataField.AssertValue(tKeyData.Key);
                            break;

                        case "Other Size":
                            dataField.AssertShow(dataFieldShowUntilColon + ": " + tKeyData.Other.Length);
                            break;

                        case "Other Data":
                            dataField.AssertValue(tKeyData.Other);
                            break;

                        default:
                            throw new InvalidOperationException("Invalid DNS data field " + dataFieldShow);
                    }
                    dataField.AssertNoFields();
                    break;

                case DnsType.TransactionSignature:
                    var tSigData = (DnsResourceDataTransactionSignature)data;
                    switch (dataFieldName)
                    {
                        case "dns.tsig.algorithm_name":
                            dataField.AssertShow(GetWiresharkDomainName(tSigData.Algorithm));
                            dataField.AssertNoFields();
                            break;

                        case "":
                            switch (dataFieldShowUntilColon)
                            {
                                case "Time signed":
                                    dataField.AssertValue(tSigData.TimeSigned);
                                    break;

                                default:
                                    throw new InvalidOperationException("Invalid DNS data field " + dataFieldShow);
                            }
                            dataField.AssertNoFields();
                            break;

                        case "dns.tsig.fudge":
                            dataField.AssertShowDecimal(tSigData.Fudge);
                            dataField.AssertNoFields();
                            break;

                        case "dns.tsig.mac_size":
                            dataField.AssertShowDecimal(tSigData.MessageAuthenticationCode.Length);
                            dataField.AssertNoFields();
                            break;

                        case "dns.tsig.mac":
                            dataField.AssertShow("");
                            Assert.AreEqual(1, dataField.Fields().Count());
                            var tsigSubfield = dataField.Fields().First();
                                tsigSubfield.AssertShow("No dissector for algorithm:" + GetWiresharkDomainName(tSigData.Algorithm));
                            tsigSubfield.AssertValue(tSigData.MessageAuthenticationCode);
                            break;

                        case "dns.tsig.original_id":
                            dataField.AssertShowDecimal(tSigData.OriginalId);
                            dataField.AssertNoFields();
                            break;

                        case "dns.tsig.error":
                            dataField.AssertShowDecimal((ushort)tSigData.Error);
                            dataField.AssertNoFields();
                            break;

                        case "dns.tsig.other_len":
                            dataField.AssertShowDecimal(tSigData.Other.Length);
                            dataField.AssertNoFields();
                            break;

                        case "dns.tsig.other_data":
                            dataField.AssertValue(tSigData.Other);
                            dataField.AssertNoFields();
                            break;

                        default:
                            throw new InvalidOperationException("Invalid DNS data field name " + dataFieldName);
                    }
                    break;

                case DnsType.Null:                                // 10.
                case DnsType.EId:                                 // 31.
                case DnsType.NimrodLocator:                       // 32.
                case DnsType.AtmA:                                // 34.
                case DnsType.Sink:                                // 40.
                case DnsType.NInfo:                               // 56.
                case DnsType.RKey:                                // 57.
                case DnsType.TrustAnchorLink:                     // 58.
                case DnsType.Cds:                                 // 59.
                case DnsType.UInfo:                               // 100.
                case DnsType.Uid:                                 // 101.
                case DnsType.Gid:                                 // 102.
                case DnsType.Unspecified:                         // 103.
                case DnsType.Ixfr:                                // 251.
                case DnsType.Axfr:                                // 252.
                case DnsType.MailB:                               // 253.
                case DnsType.MailA:                               // 254.
                case DnsType.Any:                                 // 255.
                case DnsType.Uri:                                 // 256.
                case DnsType.CertificationAuthorityAuthorization: // 257.
                case DnsType.TrustAnchor:                         // 32768.
                default:
                    dataField.AssertName("");
                    dataField.AssertShow("Data");
                    dataField.AssertNoFields();
                    break;
            }
        }