// Copyright (c) 2008 The Board of Trustees of The Leland Stanford Junior University
// Copyright (c) 2011, 2012 Open Networking Foundation
// Copyright (c) 2012, 2013 Big Switch Networks, Inc.
// This library was generated by the LoxiGen Compiler.
// See the file LICENSE.txt which should have been included in the source distribution

// Automatically generated by LOXI from template of_class.java
// Do not modify

package org.projectfloodlight.openflow.protocol.ver10;

import org.projectfloodlight.openflow.protocol.*;
import org.projectfloodlight.openflow.protocol.action.*;
import org.projectfloodlight.openflow.protocol.actionid.*;
import org.projectfloodlight.openflow.protocol.bsntlv.*;
import org.projectfloodlight.openflow.protocol.errormsg.*;
import org.projectfloodlight.openflow.protocol.meterband.*;
import org.projectfloodlight.openflow.protocol.instruction.*;
import org.projectfloodlight.openflow.protocol.instructionid.*;
import org.projectfloodlight.openflow.protocol.match.*;
import org.projectfloodlight.openflow.protocol.oxm.*;
import org.projectfloodlight.openflow.protocol.queueprop.*;
import org.projectfloodlight.openflow.types.*;
import org.projectfloodlight.openflow.util.*;
import org.projectfloodlight.openflow.exceptions.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.List;
import com.google.common.collect.ImmutableList;
import java.util.Set;
import org.jboss.netty.buffer.ChannelBuffer;
import com.google.common.hash.PrimitiveSink;
import com.google.common.hash.Funnel;

class OFMatchV1Ver10 implements OFMatchV1 {
    private static final Logger logger = LoggerFactory.getLogger(OFMatchV1Ver10.class);
    // version: 1.0
    final static byte WIRE_VERSION = 1;
    final static int LENGTH = 40;

        private final static int DEFAULT_WILDCARDS = OFFlowWildcardsSerializerVer10.ALL_VAL;
        private final static OFPort DEFAULT_IN_PORT = OFPort.ZERO;
        private final static MacAddress DEFAULT_ETH_SRC = MacAddress.NONE;
        private final static MacAddress DEFAULT_ETH_DST = MacAddress.NONE;
        private final static OFVlanVidMatch DEFAULT_VLAN_VID = OFVlanVidMatch.NONE;
        private final static VlanPcp DEFAULT_VLAN_PCP = VlanPcp.NONE;
        private final static EthType DEFAULT_ETH_TYPE = EthType.NONE;
        private final static IpDscp DEFAULT_IP_DSCP = IpDscp.NONE;
        private final static IpProtocol DEFAULT_IP_PROTO = IpProtocol.NONE;
        private final static IPv4Address DEFAULT_IPV4_SRC = IPv4Address.NONE;
        private final static IPv4Address DEFAULT_IPV4_DST = IPv4Address.NONE;
        private final static TransportPort DEFAULT_TCP_SRC = TransportPort.NONE;
        private final static TransportPort DEFAULT_TCP_DST = TransportPort.NONE;

    // OF message fields
    private final int wildcards;
    private final OFPort inPort;
    private final MacAddress ethSrc;
    private final MacAddress ethDst;
    private final OFVlanVidMatch vlanVid;
    private final VlanPcp vlanPcp;
    private final EthType ethType;
    private final IpDscp ipDscp;
    private final IpProtocol ipProto;
    private final IPv4Address ipv4Src;
    private final IPv4Address ipv4Dst;
    private final TransportPort tcpSrc;
    private final TransportPort tcpDst;
//
    // Immutable default instance
    final static OFMatchV1Ver10 DEFAULT = new OFMatchV1Ver10(
        DEFAULT_WILDCARDS, DEFAULT_IN_PORT, DEFAULT_ETH_SRC, DEFAULT_ETH_DST, DEFAULT_VLAN_VID, DEFAULT_VLAN_PCP, DEFAULT_ETH_TYPE, DEFAULT_IP_DSCP, DEFAULT_IP_PROTO, DEFAULT_IPV4_SRC, DEFAULT_IPV4_DST, DEFAULT_TCP_SRC, DEFAULT_TCP_DST
    );

    // package private constructor - used by readers, builders, and factory
    OFMatchV1Ver10(int wildcards, OFPort inPort, MacAddress ethSrc, MacAddress ethDst, OFVlanVidMatch vlanVid, VlanPcp vlanPcp, EthType ethType, IpDscp ipDscp, IpProtocol ipProto, IPv4Address ipv4Src, IPv4Address ipv4Dst, TransportPort tcpSrc, TransportPort tcpDst) {
        this.wildcards = wildcards;
        this.inPort = inPort;
        this.ethSrc = ethSrc;
        this.ethDst = ethDst;
        this.vlanVid = vlanVid;
        this.vlanPcp = vlanPcp;
        this.ethType = ethType;
        this.ipDscp = ipDscp;
        this.ipProto = ipProto;
        this.ipv4Src = ipv4Src;
        this.ipv4Dst = ipv4Dst;
        this.tcpSrc = tcpSrc;
        this.tcpDst = tcpDst;
    }

    // Accessors for OF message fields
    @Override
    public int getWildcards() {
        return wildcards;
    }

    @Override
    public OFPort getInPort() {
        return inPort;
    }

    @Override
    public MacAddress getEthSrc() {
        return ethSrc;
    }

    @Override
    public MacAddress getEthDst() {
        return ethDst;
    }

    @Override
    public OFVlanVidMatch getVlanVid() {
        return vlanVid;
    }

    @Override
    public VlanPcp getVlanPcp() {
        return vlanPcp;
    }

    @Override
    public EthType getEthType() {
        return ethType;
    }

    @Override
    public IpDscp getIpDscp() {
        return ipDscp;
    }

    @Override
    public IpProtocol getIpProto() {
        return ipProto;
    }

    @Override
    public IPv4Address getIpv4Src() {
        return ipv4Src;
    }

    @Override
    public IPv4Address getIpv4Dst() {
        return ipv4Dst;
    }

    @Override
    public TransportPort getTcpSrc() {
        return tcpSrc;
    }

    @Override
    public TransportPort getTcpDst() {
        return tcpDst;
    }

    @Override
    public OFVersion getVersion() {
        return OFVersion.OF_10;
    }


    final public static int OFPFW_ALL = ((1 << 22) - 1);

    final public static int OFPFW_IN_PORT = 1 << 0; /* Switch input port. */
    final public static int OFPFW_DL_VLAN = 1 << 1; /* VLAN id. */
    final public static int OFPFW_DL_SRC = 1 << 2; /* Ethernet source address. */
    final public static int OFPFW_DL_DST = 1 << 3; /*
                                                    * Ethernet destination
                                                    * address.
                                                    */
    final public static int OFPFW_DL_TYPE = 1 << 4; /* Ethernet frame type. */
    final public static int OFPFW_NW_PROTO = 1 << 5; /* IP protocol. */
    final public static int OFPFW_TP_SRC = 1 << 6; /* TCP/UDP source port. */
    final public static int OFPFW_TP_DST = 1 << 7; /* TCP/UDP destination port. */

    /*
     * IP source address wildcard bit count. 0 is exact match, 1 ignores the
     * LSB, 2 ignores the 2 least-significant bits, ..., 32 and higher wildcard
     * the entire field. This is the *opposite* of the usual convention where
     * e.g. /24 indicates that 8 bits (not 24 bits) are wildcarded.
     */
    final public static int OFPFW_NW_SRC_SHIFT = 8;
    final public static int OFPFW_NW_SRC_BITS = 6;
    final public static int OFPFW_NW_SRC_MASK = ((1 << OFPFW_NW_SRC_BITS) - 1) << OFPFW_NW_SRC_SHIFT;
    final public static int OFPFW_NW_SRC_ALL = 32 << OFPFW_NW_SRC_SHIFT;

    /* IP destination address wildcard bit count. Same format as source. */
    final public static int OFPFW_NW_DST_SHIFT = 14;
    final public static int OFPFW_NW_DST_BITS = 6;
    final public static int OFPFW_NW_DST_MASK = ((1 << OFPFW_NW_DST_BITS) - 1) << OFPFW_NW_DST_SHIFT;
    final public static int OFPFW_NW_DST_ALL = 32 << OFPFW_NW_DST_SHIFT;

    final public static int OFPFW_DL_VLAN_PCP = 1 << 20; /* VLAN priority. */
    final public static int OFPFW_NW_TOS = 1 << 21; /* IP ToS (DSCP field, 6bits) */

    @SuppressWarnings("unchecked")
    @Override
    public <F extends OFValueType<F>> F get(MatchField<F> field)
            throws UnsupportedOperationException {
        if (isFullyWildcarded(field))
            return null;
        if (!field.arePrerequisitesOK(this))
            return null;

        Object result;
        switch (field.id) {
            case IN_PORT:
                result = inPort;
                break;
            case ETH_DST:
                result = ethDst;
                break;
            case ETH_SRC:
                result = ethSrc;
                break;
            case ETH_TYPE:
                result = ethType;
                break;
            case VLAN_VID:
                result = vlanVid;
                break;
            case VLAN_PCP:
                result = vlanPcp;
                break;
            case ARP_OP:
                result = ArpOpcode.of(ipProto.getIpProtocolNumber());
                break;
            case ARP_SPA:
                result = ipv4Src;
                break;
            case ARP_TPA:
                result = ipv4Dst;
                break;
            case IP_DSCP:
                result = ipDscp;
                break;
            case IP_PROTO:
                result = ipProto;
                break;
            case IPV4_SRC:
                result = ipv4Src;
                break;
            case IPV4_DST:
                result = ipv4Dst;
                break;
            case TCP_SRC:
                result = tcpSrc;
                break;
            case TCP_DST:
                result = tcpDst;
                break;
            case UDP_SRC:
                result = tcpSrc;
                break;
            case UDP_DST:
                result = tcpDst;
                break;
            case SCTP_SRC:
                result = tcpSrc;
                break;
            case SCTP_DST:
                result = tcpDst;
                break;
            case ICMPV4_TYPE:
                result = tcpSrc;
                break;
            case ICMPV4_CODE:
                result = tcpDst;
                break;
            // NOT SUPPORTED:
            default:
                throw new UnsupportedOperationException("OFMatch does not support matching on field " + field.getName());
        }
        return (F)result;
    }

    @SuppressWarnings("unchecked")
    @Override
    public <F extends OFValueType<F>> Masked<F> getMasked(MatchField<F> field)
            throws UnsupportedOperationException {
        if (!isPartiallyMasked(field))
            return null;
        if (!field.arePrerequisitesOK(this))
            return null;
        Object result;
        switch (field.id) {
            case ARP_SPA:
            case IPV4_SRC:
                int srcBitMask = (-1) << (32 - getIpv4SrcCidrMaskLen());
                result = IPv4AddressWithMask.of(ipv4Src, IPv4Address.of(srcBitMask));
                break;
            case ARP_TPA:
            case IPV4_DST:
                int dstBitMask = (-1) << (32 - getIpv4DstCidrMaskLen());

                result = IPv4AddressWithMask.of(ipv4Dst, IPv4Address.of(dstBitMask));
                break;
            default:
                throw new UnsupportedOperationException("OFMatch does not support masked matching on field " + field.getName());
        }
        return (Masked<F>)result;
    }

    @Override
    public boolean supports(MatchField<?> field) {
        switch (field.id) {
            case IN_PORT:
            case ETH_DST:
            case ETH_SRC:
            case ETH_TYPE:
            case VLAN_VID:
            case VLAN_PCP:
            case ARP_OP:
            case ARP_SPA:
            case ARP_TPA:
            case IP_DSCP:
            case IP_PROTO:
            case IPV4_SRC:
            case IPV4_DST:
            case TCP_SRC:
            case TCP_DST:
            case UDP_SRC:
            case UDP_DST:
            case SCTP_SRC:
            case SCTP_DST:
            case ICMPV4_TYPE:
            case ICMPV4_CODE:
                return true;
            default:
                return false;
        }
    }

    @Override
    public boolean supportsMasked(MatchField<?> field) {
        switch (field.id) {
            case ARP_SPA:
            case ARP_TPA:
            case IPV4_SRC:
            case IPV4_DST:
                return true;
            default:
                return false;
        }
    }

    @Override
    public boolean isExact(MatchField<?> field) {
        if (!field.arePrerequisitesOK(this))
            return false;

        switch (field.id) {
            case IN_PORT:
                return (this.wildcards & OFPFW_IN_PORT) == 0;
            case ETH_DST:
                return (this.wildcards & OFPFW_DL_DST) == 0;
            case ETH_SRC:
                return (this.wildcards & OFPFW_DL_SRC) == 0;
            case ETH_TYPE:
                return (this.wildcards & OFPFW_DL_TYPE) == 0;
            case VLAN_VID:
                return (this.wildcards & OFPFW_DL_VLAN) == 0;
            case VLAN_PCP:
                return (this.wildcards & OFPFW_DL_VLAN_PCP) == 0;
            case ARP_OP:
                return (this.wildcards & OFPFW_NW_PROTO) == 0;
            case ARP_SPA:
                return this.getIpv4SrcCidrMaskLen() >= 32;
            case ARP_TPA:
                return this.getIpv4DstCidrMaskLen() >= 32;
            case IP_DSCP:
                return (this.wildcards & OFPFW_NW_TOS) == 0;
            case IP_PROTO:
                return (this.wildcards & OFPFW_NW_PROTO) == 0;
            case IPV4_SRC:
                return this.getIpv4SrcCidrMaskLen() >= 32;
            case IPV4_DST:
                return this.getIpv4DstCidrMaskLen() >= 32;
            case TCP_SRC:
                return (this.wildcards & OFPFW_TP_SRC) == 0;
            case TCP_DST:
                return (this.wildcards & OFPFW_TP_DST) == 0;
            case UDP_SRC:
                return (this.wildcards & OFPFW_TP_SRC) == 0;
            case UDP_DST:
                return (this.wildcards & OFPFW_TP_DST) == 0;
            case SCTP_SRC:
                return (this.wildcards & OFPFW_TP_SRC) == 0;
            case SCTP_DST:
                return (this.wildcards & OFPFW_TP_DST) == 0;
            case ICMPV4_TYPE:
                return (this.wildcards & OFPFW_TP_SRC) == 0;
            case ICMPV4_CODE:
                return (this.wildcards & OFPFW_TP_DST) == 0;
            default:
                throw new UnsupportedOperationException("OFMatch does not support matching on field " + field.getName());
        }
    }

    /**
     * Parse this match's wildcard fields and return the number of significant
     * bits in the IP destination field. NOTE: this returns the number of bits
     * that are fixed, i.e., like CIDR, not the number of bits that are free
     * like OpenFlow encodes.
     *
     * @return A number between 0 (matches all IPs) and 32 (exact match)
     */
    public int getIpv4DstCidrMaskLen() {
        return Math.max(32 - ((wildcards & OFPFW_NW_DST_MASK) >> OFPFW_NW_DST_SHIFT),
                        0);
    }

    /**
     * Parse this match's wildcard fields and return the number of significant
     * bits in the IP destination field. NOTE: this returns the number of bits
     * that are fixed, i.e., like CIDR, not the number of bits that are free
     * like OpenFlow encodes.
     *
     * @return A number between 0 (matches all IPs) and 32 (exact match)
     */
    public int getIpv4SrcCidrMaskLen() {
        return Math.max(32 - ((wildcards & OFPFW_NW_SRC_MASK) >> OFPFW_NW_SRC_SHIFT),
                        0);
    }


    @Override
    public boolean isFullyWildcarded(MatchField<?> field) {
        if (!field.arePrerequisitesOK(this))
            return true;

        switch (field.id) {
            case IN_PORT:
                return (this.wildcards & OFPFW_IN_PORT) != 0;
            case ETH_DST:
                return (this.wildcards & OFPFW_DL_DST) != 0;
            case ETH_SRC:
                return (this.wildcards & OFPFW_DL_SRC) != 0;
            case ETH_TYPE:
                return (this.wildcards & OFPFW_DL_TYPE) != 0;
            case VLAN_VID:
                return (this.wildcards & OFPFW_DL_VLAN) != 0;
            case VLAN_PCP:
                return (this.wildcards & OFPFW_DL_VLAN_PCP) != 0;
            case ARP_OP:
                return (this.wildcards & OFPFW_NW_PROTO) != 0;
            case ARP_SPA:
                return this.getIpv4SrcCidrMaskLen() <= 0;
            case ARP_TPA:
                return this.getIpv4DstCidrMaskLen() <= 0;
            case IP_DSCP:
                return (this.wildcards & OFPFW_NW_TOS) != 0;
            case IP_PROTO:
                return (this.wildcards & OFPFW_NW_PROTO) != 0;
            case TCP_SRC:
                return (this.wildcards & OFPFW_TP_SRC) != 0;
            case TCP_DST:
                return (this.wildcards & OFPFW_TP_DST) != 0;
            case UDP_SRC:
                return (this.wildcards & OFPFW_TP_SRC) != 0;
            case UDP_DST:
                return (this.wildcards & OFPFW_TP_DST) != 0;
            case SCTP_SRC:
                return (this.wildcards & OFPFW_TP_SRC) != 0;
            case SCTP_DST:
                return (this.wildcards & OFPFW_TP_DST) != 0;
            case ICMPV4_TYPE:
                return (this.wildcards & OFPFW_TP_SRC) != 0;
            case ICMPV4_CODE:
                return (this.wildcards & OFPFW_TP_DST) != 0;
            case IPV4_SRC:
                return this.getIpv4SrcCidrMaskLen() <= 0;
            case IPV4_DST:
                return this.getIpv4DstCidrMaskLen() <= 0;
            default:
                throw new UnsupportedOperationException("OFMatch does not support matching on field " + field.getName());
        }
    }

    @Override
    public boolean isPartiallyMasked(MatchField<?> field) {
        if (!field.arePrerequisitesOK(this))
            return false;

        switch (field.id) {
            case ARP_SPA:
            case IPV4_SRC:
                int srcCidrLen = getIpv4SrcCidrMaskLen();
                return srcCidrLen > 0 && srcCidrLen < 32;
            case ARP_TPA:
            case IPV4_DST:
                int dstCidrLen = getIpv4DstCidrMaskLen();
                return dstCidrLen > 0 && dstCidrLen < 32;
            default:
                return false;
        }
    }

    @Override
    public Iterable<MatchField<?>> getMatchFields() {
        ImmutableList.Builder<MatchField<?>> builder = ImmutableList.builder();
        if ((wildcards & OFPFW_IN_PORT) == 0)
            builder.add(MatchField.IN_PORT);
        if ((wildcards & OFPFW_DL_VLAN) == 0)
            builder.add(MatchField.VLAN_VID);
        if ((wildcards & OFPFW_DL_SRC) == 0)
            builder.add(MatchField.ETH_SRC);
        if ((wildcards & OFPFW_DL_DST) == 0)
            builder.add(MatchField.ETH_DST);
        if ((wildcards & OFPFW_DL_TYPE) == 0)
            builder.add(MatchField.ETH_TYPE);
        if ((wildcards & OFPFW_NW_PROTO) == 0) {
            if (ethType == EthType.ARP) {
                builder.add(MatchField.ARP_OP);
            } else if (ethType == EthType.IPv4) {
                builder.add(MatchField.IP_PROTO);
            } else {
                throw new UnsupportedOperationException(
                        "Unsupported Ethertype for matching on network protocol " + ethType);
            }
        }
        if ((wildcards & OFPFW_TP_SRC) == 0) {
            if (ipProto == IpProtocol.UDP) {
                builder.add(MatchField.UDP_SRC);
            } else if (ipProto == IpProtocol.TCP) {
                builder.add(MatchField.TCP_SRC);
            } else if (ipProto == IpProtocol.SCTP) {
                builder.add(MatchField.SCTP_SRC);
            } else {
                throw new UnsupportedOperationException(
                        "Unsupported IP protocol for matching on source port " + ipProto);
            }
        }
        if ((wildcards & OFPFW_TP_DST) == 0) {
            if (ipProto == IpProtocol.UDP) {
                builder.add(MatchField.UDP_DST);
            } else if (ipProto == IpProtocol.TCP) {
                builder.add(MatchField.TCP_DST);
            } else if (ipProto == IpProtocol.SCTP) {
                builder.add(MatchField.SCTP_DST);
            } else {
                throw new UnsupportedOperationException(
                        "Unsupported IP protocol for matching on destination port " + ipProto);
            }
        }
        if (((wildcards & OFPFW_NW_SRC_MASK) >> OFPFW_NW_SRC_SHIFT) < 32) {
            if (ethType == EthType.ARP) {
                builder.add(MatchField.ARP_SPA);
            } else if (ethType == EthType.IPv4) {
                builder.add(MatchField.IPV4_SRC);
            } else {
                throw new UnsupportedOperationException(
                        "Unsupported Ethertype for matching on source IP " + ethType);
            }
        }
        if (((wildcards & OFPFW_NW_DST_MASK) >> OFPFW_NW_DST_SHIFT) < 32) {
            if (ethType == EthType.ARP) {
                builder.add(MatchField.ARP_TPA);
            } else if (ethType == EthType.IPv4) {
                builder.add(MatchField.IPV4_DST);
            } else {
                throw new UnsupportedOperationException(
                        "Unsupported Ethertype for matching on destination IP " + ethType);
            }
        }
        if ((wildcards & OFPFW_DL_VLAN_PCP) == 0)
            builder.add(MatchField.VLAN_PCP);
        if ((wildcards & OFPFW_NW_TOS) == 0)
            builder.add(MatchField.IP_DSCP);
        return builder.build();
    }

    public OFMatchV1.Builder createBuilder() {
        return new BuilderWithParent(this);
    }

    static class BuilderWithParent implements OFMatchV1.Builder {
        final OFMatchV1Ver10 parentMessage;

        // OF message fields
        private boolean wildcardsSet;
        private int wildcards;
        private boolean inPortSet;
        private OFPort inPort;
        private boolean ethSrcSet;
        private MacAddress ethSrc;
        private boolean ethDstSet;
        private MacAddress ethDst;
        private boolean vlanVidSet;
        private OFVlanVidMatch vlanVid;
        private boolean vlanPcpSet;
        private VlanPcp vlanPcp;
        private boolean ethTypeSet;
        private EthType ethType;
        private boolean ipDscpSet;
        private IpDscp ipDscp;
        private boolean ipProtoSet;
        private IpProtocol ipProto;
        private boolean ipv4SrcSet;
        private IPv4Address ipv4Src;
        private boolean ipv4DstSet;
        private IPv4Address ipv4Dst;
        private boolean tcpSrcSet;
        private TransportPort tcpSrc;
        private boolean tcpDstSet;
        private TransportPort tcpDst;

        BuilderWithParent(OFMatchV1Ver10 parentMessage) {
            this.parentMessage = parentMessage;
        }

    @Override
    public int getWildcards() {
        return wildcards;
    }

    @Override
    public OFMatchV1.Builder setWildcards(int wildcards) {
        this.wildcards = wildcards;
        this.wildcardsSet = true;
        return this;
    }
    @Override
    public OFPort getInPort() {
        return inPort;
    }

    @Override
    public OFMatchV1.Builder setInPort(OFPort inPort) {
        this.inPort = inPort;
        this.inPortSet = true;
        return this;
    }
    @Override
    public MacAddress getEthSrc() {
        return ethSrc;
    }

    @Override
    public OFMatchV1.Builder setEthSrc(MacAddress ethSrc) {
        this.ethSrc = ethSrc;
        this.ethSrcSet = true;
        return this;
    }
    @Override
    public MacAddress getEthDst() {
        return ethDst;
    }

    @Override
    public OFMatchV1.Builder setEthDst(MacAddress ethDst) {
        this.ethDst = ethDst;
        this.ethDstSet = true;
        return this;
    }
    @Override
    public OFVlanVidMatch getVlanVid() {
        return vlanVid;
    }

    @Override
    public OFMatchV1.Builder setVlanVid(OFVlanVidMatch vlanVid) {
        this.vlanVid = vlanVid;
        this.vlanVidSet = true;
        return this;
    }
    @Override
    public VlanPcp getVlanPcp() {
        return vlanPcp;
    }

    @Override
    public OFMatchV1.Builder setVlanPcp(VlanPcp vlanPcp) {
        this.vlanPcp = vlanPcp;
        this.vlanPcpSet = true;
        return this;
    }
    @Override
    public EthType getEthType() {
        return ethType;
    }

    @Override
    public OFMatchV1.Builder setEthType(EthType ethType) {
        this.ethType = ethType;
        this.ethTypeSet = true;
        return this;
    }
    @Override
    public IpDscp getIpDscp() {
        return ipDscp;
    }

    @Override
    public OFMatchV1.Builder setIpDscp(IpDscp ipDscp) {
        this.ipDscp = ipDscp;
        this.ipDscpSet = true;
        return this;
    }
    @Override
    public IpProtocol getIpProto() {
        return ipProto;
    }

    @Override
    public OFMatchV1.Builder setIpProto(IpProtocol ipProto) {
        this.ipProto = ipProto;
        this.ipProtoSet = true;
        return this;
    }
    @Override
    public IPv4Address getIpv4Src() {
        return ipv4Src;
    }

    @Override
    public OFMatchV1.Builder setIpv4Src(IPv4Address ipv4Src) {
        this.ipv4Src = ipv4Src;
        this.ipv4SrcSet = true;
        return this;
    }
    @Override
    public IPv4Address getIpv4Dst() {
        return ipv4Dst;
    }

    @Override
    public OFMatchV1.Builder setIpv4Dst(IPv4Address ipv4Dst) {
        this.ipv4Dst = ipv4Dst;
        this.ipv4DstSet = true;
        return this;
    }
    @Override
    public TransportPort getTcpSrc() {
        return tcpSrc;
    }

    @Override
    public OFMatchV1.Builder setTcpSrc(TransportPort tcpSrc) {
        this.tcpSrc = tcpSrc;
        this.tcpSrcSet = true;
        return this;
    }
    @Override
    public TransportPort getTcpDst() {
        return tcpDst;
    }

    @Override
    public OFMatchV1.Builder setTcpDst(TransportPort tcpDst) {
        this.tcpDst = tcpDst;
        this.tcpDstSet = true;
        return this;
    }
    @Override
    public OFVersion getVersion() {
        return OFVersion.OF_10;
    }



        @Override
        public OFMatchV1 build() {
                int wildcards = this.wildcardsSet ? this.wildcards : parentMessage.wildcards;
                OFPort inPort = this.inPortSet ? this.inPort : parentMessage.inPort;
                if(inPort == null)
                    throw new NullPointerException("Property inPort must not be null");
                MacAddress ethSrc = this.ethSrcSet ? this.ethSrc : parentMessage.ethSrc;
                if(ethSrc == null)
                    throw new NullPointerException("Property ethSrc must not be null");
                MacAddress ethDst = this.ethDstSet ? this.ethDst : parentMessage.ethDst;
                if(ethDst == null)
                    throw new NullPointerException("Property ethDst must not be null");
                OFVlanVidMatch vlanVid = this.vlanVidSet ? this.vlanVid : parentMessage.vlanVid;
                if(vlanVid == null)
                    throw new NullPointerException("Property vlanVid must not be null");
                VlanPcp vlanPcp = this.vlanPcpSet ? this.vlanPcp : parentMessage.vlanPcp;
                if(vlanPcp == null)
                    throw new NullPointerException("Property vlanPcp must not be null");
                EthType ethType = this.ethTypeSet ? this.ethType : parentMessage.ethType;
                if(ethType == null)
                    throw new NullPointerException("Property ethType must not be null");
                IpDscp ipDscp = this.ipDscpSet ? this.ipDscp : parentMessage.ipDscp;
                if(ipDscp == null)
                    throw new NullPointerException("Property ipDscp must not be null");
                IpProtocol ipProto = this.ipProtoSet ? this.ipProto : parentMessage.ipProto;
                if(ipProto == null)
                    throw new NullPointerException("Property ipProto must not be null");
                IPv4Address ipv4Src = this.ipv4SrcSet ? this.ipv4Src : parentMessage.ipv4Src;
                if(ipv4Src == null)
                    throw new NullPointerException("Property ipv4Src must not be null");
                IPv4Address ipv4Dst = this.ipv4DstSet ? this.ipv4Dst : parentMessage.ipv4Dst;
                if(ipv4Dst == null)
                    throw new NullPointerException("Property ipv4Dst must not be null");
                TransportPort tcpSrc = this.tcpSrcSet ? this.tcpSrc : parentMessage.tcpSrc;
                if(tcpSrc == null)
                    throw new NullPointerException("Property tcpSrc must not be null");
                TransportPort tcpDst = this.tcpDstSet ? this.tcpDst : parentMessage.tcpDst;
                if(tcpDst == null)
                    throw new NullPointerException("Property tcpDst must not be null");

                //
            // normalize match fields according to current OpenVSwitch behavior. When prerequisites for a field are not met
            // e.g., eth_type is not set to 0x800, OVS sets the value of corresponding ignored fields (e.g.,
            // ip_src, tcp_dst) to 0, and sets the wildcard bit to 1.
            if(ethType.equals(EthType.IPv4)) {
                // IP
                if(ipProto.equals(IpProtocol.TCP) || ipProto.equals(IpProtocol.UDP) || ipProto.equals(IpProtocol.ICMP)) {
                    // fully speced, wildcards and all values are fine
                    // normalize 32-63 ipv4 src 'mask' to a full bitmask
                    if((wildcards & OFPFW_NW_SRC_ALL) != 0)
                        wildcards |= OFPFW_NW_SRC_MASK;

                    // normalize 32-63 ipv4 dst 'mask' to a full bitmask
                    if((wildcards & OFPFW_NW_DST_ALL) != 0)
                        wildcards |= OFPFW_NW_DST_MASK;

                } else {
                    // normalize 32-63 ipv4 src 'mask' to a full bitmask
                    if((wildcards & OFPFW_NW_SRC_ALL) != 0)
                        wildcards |= OFPFW_NW_SRC_MASK;

                    // normalize 32-63 ipv4 dst 'mask' to a full bitmask
                    if((wildcards & OFPFW_NW_DST_ALL) != 0)
                        wildcards |= OFPFW_NW_DST_MASK;

                    // not TCP/UDP/ICMP -> Clear TP wildcards for the wire
                    wildcards |= (OFPFW_TP_SRC | OFPFW_TP_DST);
                    tcpSrc = TransportPort.NONE;
                    tcpDst = TransportPort.NONE;
                }
            } else if (ethType.equals(EthType.ARP)) {
                // normalize 32-63 ipv4 src 'mask' to a full bitmask
                if((wildcards & OFPFW_NW_SRC_ALL) != 0)
                    wildcards |= OFPFW_NW_SRC_MASK;

                // normalize 32-63 ipv4 dst 'mask' to a full bitmask
                if((wildcards & OFPFW_NW_DST_ALL) != 0)
                    wildcards |= OFPFW_NW_DST_MASK;

                // ARP: clear NW_TOS / TP wildcards for the wire
                wildcards |= ( OFPFW_NW_TOS | OFPFW_TP_SRC | OFPFW_TP_DST);
                ipDscp = IpDscp.NONE;
                tcpSrc = TransportPort.NONE;
                tcpDst = TransportPort.NONE;
            } else {
                // not even IP. Clear NW/TP wildcards for the wire
                wildcards |= ( OFPFW_NW_TOS | OFPFW_NW_PROTO | OFPFW_NW_SRC_MASK | OFPFW_NW_DST_MASK | OFPFW_TP_SRC | OFPFW_TP_DST);
                ipDscp = IpDscp.NONE;
                ipProto = IpProtocol.NONE;
                ipv4Src = IPv4Address.NONE;
                ipv4Dst = IPv4Address.NONE;
                tcpSrc = TransportPort.NONE;
                tcpDst = TransportPort.NONE;
            }
                return new OFMatchV1Ver10(
                    wildcards,
                    inPort,
                    ethSrc,
                    ethDst,
                    vlanVid,
                    vlanPcp,
                    ethType,
                    ipDscp,
                    ipProto,
                    ipv4Src,
                    ipv4Dst,
                    tcpSrc,
                    tcpDst
                );
        }
        @SuppressWarnings("unchecked")
        @Override
        public <F extends OFValueType<F>> F get(MatchField<F> field)
                throws UnsupportedOperationException {
            if (isFullyWildcarded(field))
                return null;

            Object result;
            switch (field.id) {
                case IN_PORT:
                    result = inPort;
                    break;
                case ETH_DST:
                    result = ethDst;
                    break;
                case ETH_SRC:
                    result = ethSrc;
                    break;
                case ETH_TYPE:
                    result = ethType;
                    break;
                case VLAN_VID:
                    result = vlanVid;
                    break;
                case VLAN_PCP:
                    result = vlanPcp;
                    break;
                case ARP_OP:
                    result = ArpOpcode.of(ipProto.getIpProtocolNumber());
                    break;
                case ARP_SPA:
                    result = ipv4Src;
                    break;
                case ARP_TPA:
                    result = ipv4Dst;
                    break;
                case IP_DSCP:
                    result = ipDscp;
                    break;
                case IP_PROTO:
                    result = ipProto;
                    break;
                case IPV4_SRC:
                    result = ipv4Src;
                    break;
                case IPV4_DST:
                    result = ipv4Dst;
                    break;
                case TCP_SRC:
                    result = tcpSrc;
                    break;
                case TCP_DST:
                    result = tcpDst;
                    break;
                case UDP_SRC:
                    result = tcpSrc;
                    break;
                case UDP_DST:
                    result = tcpDst;
                    break;
                case SCTP_SRC:
                    result = tcpSrc;
                    break;
                case SCTP_DST:
                    result = tcpDst;
                    break;
                case ICMPV4_TYPE:
                    result = tcpSrc;
                    break;
                case ICMPV4_CODE:
                    result = tcpDst;
                    break;
                // NOT SUPPORTED:
                default:
                    throw new UnsupportedOperationException("OFMatch does not support matching on field " + field.getName());
            }
            return (F)result;
        }

        @SuppressWarnings("unchecked")
        @Override
        public <F extends OFValueType<F>> Masked<F> getMasked(MatchField<F> field)
                throws UnsupportedOperationException {
            if (!isPartiallyMasked(field))
                return null;
            Object result;
            switch (field.id) {
                case IPV4_SRC:
                case ARP_SPA:
                    int srcBitMask = (-1) << (32 - getIpv4SrcCidrMaskLen());
                    result = IPv4AddressWithMask.of(ipv4Src, IPv4Address.of(srcBitMask));
                    break;
                case IPV4_DST:
                case ARP_TPA:
                    int dstMaskedBits = Math.min(32, (wildcards & OFPFW_NW_DST_MASK) >> OFPFW_NW_DST_SHIFT);
                    int dstBitMask = (-1) << (32 - getIpv4DstCidrMaskLen());

                    result = IPv4AddressWithMask.of(ipv4Dst, IPv4Address.of(dstBitMask));
                    break;
                default:
                    throw new UnsupportedOperationException("OFMatch does not support masked matching on field " + field.getName());
            }
            return (Masked<F>)result;
        }

        @Override
        public boolean supports(MatchField<?> field) {
            switch (field.id) {
                case IN_PORT:
                case ETH_DST:
                case ETH_SRC:
                case ETH_TYPE:
                case VLAN_VID:
                case VLAN_PCP:
                case ARP_OP:
                case ARP_SPA:
                case ARP_TPA:
                case IP_DSCP:
                case IP_PROTO:
                case IPV4_SRC:
                case IPV4_DST:
                case TCP_SRC:
                case TCP_DST:
                case UDP_SRC:
                case UDP_DST:
                case SCTP_SRC:
                case SCTP_DST:
                case ICMPV4_TYPE:
                case ICMPV4_CODE:
                    return true;
                default:
                    return false;
            }
        }

        @Override
        public boolean supportsMasked(MatchField<?> field) {
            switch (field.id) {
                case ARP_SPA:
                case ARP_TPA:
                case IPV4_SRC:
                case IPV4_DST:
                    return true;
                default:
                    return false;
            }
        }

        @Override
        public boolean isExact(MatchField<?> field) {
            switch (field.id) {
                case IN_PORT:
                    return (this.wildcards & OFPFW_IN_PORT) == 0;
                case ETH_DST:
                    return (this.wildcards & OFPFW_DL_DST) == 0;
                case ETH_SRC:
                    return (this.wildcards & OFPFW_DL_SRC) == 0;
                case ETH_TYPE:
                    return (this.wildcards & OFPFW_DL_TYPE) == 0;
                case VLAN_VID:
                    return (this.wildcards & OFPFW_DL_VLAN) == 0;
                case VLAN_PCP:
                    return (this.wildcards & OFPFW_DL_VLAN_PCP) == 0;
                case ARP_OP:
                    return (this.wildcards & OFPFW_NW_PROTO) == 0;
                case ARP_SPA:
                    return this.getIpv4SrcCidrMaskLen() >= 32;
                case ARP_TPA:
                    return this.getIpv4DstCidrMaskLen() >= 32;
                case IP_DSCP:
                    return (this.wildcards & OFPFW_NW_TOS) == 0;
                case IP_PROTO:
                    return (this.wildcards & OFPFW_NW_PROTO) == 0;
                case IPV4_SRC:
                    return this.getIpv4SrcCidrMaskLen() >= 32;
                case IPV4_DST:
                    return this.getIpv4DstCidrMaskLen() >= 32;
                case TCP_SRC:
                    return (this.wildcards & OFPFW_TP_SRC) == 0;
                case TCP_DST:
                    return (this.wildcards & OFPFW_TP_DST) == 0;
                case UDP_SRC:
                    return (this.wildcards & OFPFW_TP_SRC) == 0;
                case UDP_DST:
                    return (this.wildcards & OFPFW_TP_DST) == 0;
                case SCTP_SRC:
                    return (this.wildcards & OFPFW_TP_SRC) == 0;
                case SCTP_DST:
                    return (this.wildcards & OFPFW_TP_DST) == 0;
                case ICMPV4_TYPE:
                    return (this.wildcards & OFPFW_TP_SRC) == 0;
                case ICMPV4_CODE:
                    return (this.wildcards & OFPFW_TP_DST) == 0;
                default:
                    throw new UnsupportedOperationException("OFMatch does not support matching on field " + field.getName());
            }
        }

        /**
         * Parse this match's wildcard fields and return the number of significant
         * bits in the IP destination field. NOTE: this returns the number of bits
         * that are fixed, i.e., like CIDR, not the number of bits that are free
         * like OpenFlow encodes.
         *
         * @return A number between 0 (matches all IPs) and 32 (exact match)
         */
        public int getIpv4DstCidrMaskLen() {
            return Math.max(32 - ((wildcards & OFPFW_NW_DST_MASK) >> OFPFW_NW_DST_SHIFT),
                            0);
        }

        /**
         * Parse this match's wildcard fields and return the number of significant
         * bits in the IP destination field. NOTE: this returns the number of bits
         * that are fixed, i.e., like CIDR, not the number of bits that are free
         * like OpenFlow encodes.
         *
         * @return A number between 0 (matches all IPs) and 32 (exact match)
         */
        public int getIpv4SrcCidrMaskLen() {
            return Math.max(32 - ((wildcards & OFPFW_NW_SRC_MASK) >> OFPFW_NW_SRC_SHIFT),
                            0);
        }


        @Override
        public boolean isFullyWildcarded(MatchField<?> field) {
            switch (field.id) {
                case IN_PORT:
                    return (this.wildcards & OFPFW_IN_PORT) != 0;
                case ETH_DST:
                    return (this.wildcards & OFPFW_DL_DST) != 0;
                case ETH_SRC:
                    return (this.wildcards & OFPFW_DL_SRC) != 0;
                case ETH_TYPE:
                    return (this.wildcards & OFPFW_DL_TYPE) != 0;
                case VLAN_VID:
                    return (this.wildcards & OFPFW_DL_VLAN) != 0;
                case VLAN_PCP:
                    return (this.wildcards & OFPFW_DL_VLAN_PCP) != 0;
                case ARP_OP:
                    return (this.wildcards & OFPFW_NW_PROTO) != 0;
                case ARP_SPA:
                    return this.getIpv4SrcCidrMaskLen() <= 0;
                case ARP_TPA:
                    return this.getIpv4DstCidrMaskLen() <= 0;
                case IP_DSCP:
                    return (this.wildcards & OFPFW_NW_TOS) != 0;
                case IP_PROTO:
                    return (this.wildcards & OFPFW_NW_PROTO) != 0;
                case TCP_SRC:
                    return (this.wildcards & OFPFW_TP_SRC) != 0;
                case TCP_DST:
                    return (this.wildcards & OFPFW_TP_DST) != 0;
                case UDP_SRC:
                    return (this.wildcards & OFPFW_TP_SRC) != 0;
                case UDP_DST:
                    return (this.wildcards & OFPFW_TP_DST) != 0;
                case SCTP_SRC:
                    return (this.wildcards & OFPFW_TP_SRC) != 0;
                case SCTP_DST:
                    return (this.wildcards & OFPFW_TP_DST) != 0;
                case ICMPV4_TYPE:
                    return (this.wildcards & OFPFW_TP_SRC) != 0;
                case ICMPV4_CODE:
                    return (this.wildcards & OFPFW_TP_DST) != 0;
                case IPV4_SRC:
                    return this.getIpv4SrcCidrMaskLen() <= 0;
                case IPV4_DST:
                    return this.getIpv4DstCidrMaskLen() <= 0;
                default:
                    throw new UnsupportedOperationException("OFMatch does not support matching on field " + field.getName());
            }
        }

        @Override
        public boolean isPartiallyMasked(MatchField<?> field) {
            switch (field.id) {
                case ARP_SPA:
                case IPV4_SRC:
                    int srcCidrLen = getIpv4SrcCidrMaskLen();
                    return srcCidrLen > 0 && srcCidrLen < 32;
                case ARP_TPA:
                case IPV4_DST:
                    int dstCidrLen = getIpv4DstCidrMaskLen();
                    return dstCidrLen > 0 && dstCidrLen < 32;
                default:
                    throw new UnsupportedOperationException("OFMatch does not support masked matching on field " + field.getName());
            }
        }

        private final void initWildcards() {
            if(!wildcardsSet) {
                wildcards = parentMessage.wildcards;
                wildcardsSet = true;
            }
        }

        @Override
        public <F extends OFValueType<F>> Match.Builder setExact(MatchField<F> field,
                F value) {
            initWildcards();
            Object val = value;
            switch (field.id) {
                case ETH_DST:
                    setEthDst((MacAddress) value);
                    wildcards &= ~OFPFW_DL_DST;
                    break;
                case ETH_SRC:
                    setEthSrc((MacAddress) value);
                    wildcards &= ~OFPFW_DL_SRC;
                    break;
                case ETH_TYPE:
                    setEthType((EthType) value);
                    wildcards &= ~OFPFW_DL_TYPE;
                    break;
                case ICMPV4_CODE:
                    setTcpDst(TransportPort.of(((ICMPv4Code)value).getCode()));
                    wildcards &= ~OFPFW_TP_DST;
                    break;
                case ICMPV4_TYPE:
                    setTcpSrc(TransportPort.of(((ICMPv4Type)value).getType()));
                    wildcards &= ~OFPFW_TP_SRC;
                    break;
                case IN_PORT:
                    setInPort((OFPort) value);
                    wildcards &= ~OFPFW_IN_PORT;
                    break;
                case ARP_OP:
                    setIpProto(IpProtocol.of((short)((ArpOpcode)value).getOpcode()));
                    wildcards &= ~OFPFW_NW_PROTO;
                    break;
                case ARP_TPA:
                case IPV4_DST:
                    setIpv4Dst((IPv4Address) value);
                    wildcards &= ~OFPFW_NW_DST_MASK;
                    break;
                case ARP_SPA:
                case IPV4_SRC:
                    setIpv4Src((IPv4Address) value);
                    wildcards &= ~OFPFW_NW_SRC_MASK;
                    break;
                case IP_DSCP:
                    setIpDscp((IpDscp) value);
                    wildcards &= ~OFPFW_NW_TOS;
                    break;
                case IP_PROTO:
                    setIpProto((IpProtocol) value);
                    wildcards &= ~OFPFW_NW_PROTO;
                    break;
                case SCTP_DST:
                    setTcpDst((TransportPort) value);
                    wildcards &= ~OFPFW_TP_DST;
                    break;
                case SCTP_SRC:
                    setTcpSrc((TransportPort) value);
                    wildcards &= ~OFPFW_TP_SRC;
                    break;
                case TCP_DST:
                    setTcpDst((TransportPort) value);
                    wildcards &= ~OFPFW_TP_DST;
                    break;
                case TCP_SRC:
                    setTcpSrc((TransportPort) value);
                    wildcards &= ~OFPFW_TP_SRC;
                    break;
                case UDP_DST:
                    setTcpDst((TransportPort) value);
                    wildcards &= ~OFPFW_TP_DST;
                    break;
                case UDP_SRC:
                    setTcpSrc((TransportPort) value);
                    wildcards &= ~OFPFW_TP_SRC;
                    break;
                case VLAN_PCP:
                    setVlanPcp((VlanPcp) value);
                    wildcards &= ~OFPFW_DL_VLAN_PCP;
                    break;
                case VLAN_VID:
                    setVlanVid((OFVlanVidMatch) value);
                    wildcards &= ~OFPFW_DL_VLAN;
                    break;
                default:
                    throw new UnsupportedOperationException(
                            "OFMatch does not support matching on field " + field.getName());
            }
            return this;
        }

        @Override
        public <F extends OFValueType<F>> Match.Builder setMasked(MatchField<F> field,
                F value, F mask) {
            initWildcards();
            switch (field.id) {
                case ARP_SPA:
                case ARP_TPA:
                case IPV4_DST:
                case IPV4_SRC:
                    Object valObj = value;
                    Object masObj = mask;
                    IPv4Address ip = ((IPv4Address)valObj);
                    int maskval = ((IPv4Address)masObj).getInt();
                    if (Integer.bitCount(~maskval + 1) != 1)
                        throw new UnsupportedOperationException("OFMatch only supports CIDR masks for IPv4");
                    int maskLen = 32 - Integer.bitCount(maskval);
                    switch(field.id) {
                        case ARP_TPA:
                        case IPV4_DST:
                            setIpv4Dst(ip);
                            wildcards = (wildcards &~OFPFW_NW_DST_MASK) | (maskLen << OFPFW_NW_DST_SHIFT);
                            break;
                        case ARP_SPA:
                        case IPV4_SRC:
                            setIpv4Src(ip);
                            wildcards = (wildcards &~OFPFW_NW_SRC_MASK) | (maskLen << OFPFW_NW_SRC_SHIFT);
                            break;
                        default:
                            // Cannot really get here
                            break;
                    }
                    break;
                default:
                    throw new UnsupportedOperationException("OFMatch does not support masked matching on field " + field.getName());
            }
            return this;
        }

        @Override
        public <F extends OFValueType<F>> Match.Builder setMasked(MatchField<F> field, Masked<F> valueWithMask)
                                                                       throws UnsupportedOperationException {
            return this.setMasked(field, valueWithMask.getValue(), valueWithMask.getMask());
        }

        @Override
        public <F extends OFValueType<F>> Match.Builder wildcard(MatchField<F> field) {
            initWildcards();
            switch (field.id) {
                case ETH_DST:
                    setEthDst(MacAddress.NONE);
                    wildcards |= OFPFW_DL_DST;
                    break;
                case ETH_SRC:
                    setEthSrc(MacAddress.NONE);
                    wildcards |= OFPFW_DL_SRC;
                    break;
                case ETH_TYPE:
                    setEthType(EthType.NONE);
                    wildcards |= OFPFW_DL_TYPE;
                    break;
                case ICMPV4_CODE:
                case TCP_DST:
                case UDP_DST:
                case SCTP_DST:
                    setTcpDst(TransportPort.NONE);
                    wildcards |= OFPFW_TP_DST;
                    break;
                case ICMPV4_TYPE:
                case TCP_SRC:
                case UDP_SRC:
                case SCTP_SRC:
                    setTcpSrc(TransportPort.NONE);
                    wildcards |= OFPFW_TP_SRC;
                    break;
                case IN_PORT:
                    setInPort(OFPort.of(0)); // NOTE: not 'NONE' -- that is 0xFF for ports
                    wildcards |= OFPFW_IN_PORT;
                    break;
                case ARP_TPA:
                case IPV4_DST:
                    setIpv4Dst(IPv4Address.NONE);
                    wildcards |= OFPFW_NW_DST_MASK;
                    break;
                case ARP_SPA:
                case IPV4_SRC:
                    setIpv4Src(IPv4Address.NONE);
                    wildcards |= OFPFW_NW_SRC_MASK;
                    break;
                case IP_DSCP:
                    setIpDscp(IpDscp.NONE);
                    wildcards |= OFPFW_NW_TOS;
                    break;
                case IP_PROTO:
                    setIpProto(IpProtocol.NONE);
                    wildcards |= OFPFW_NW_PROTO;
                    break;
                case VLAN_PCP:
                    setVlanPcp(VlanPcp.NONE);
                    wildcards |= OFPFW_DL_VLAN_PCP;
                    break;
                case VLAN_VID:
                    setVlanVid(OFVlanVidMatch.NONE);
                    wildcards |= OFPFW_DL_VLAN;
                    break;
                default:
                    throw new UnsupportedOperationException("OFMatch does not support matching on field " + field.getName());
            }
            return this;
        }

    }

    static class Builder implements OFMatchV1.Builder {
        // OF message fields
        private boolean wildcardsSet;
        private int wildcards;
        private boolean inPortSet;
        private OFPort inPort;
        private boolean ethSrcSet;
        private MacAddress ethSrc;
        private boolean ethDstSet;
        private MacAddress ethDst;
        private boolean vlanVidSet;
        private OFVlanVidMatch vlanVid;
        private boolean vlanPcpSet;
        private VlanPcp vlanPcp;
        private boolean ethTypeSet;
        private EthType ethType;
        private boolean ipDscpSet;
        private IpDscp ipDscp;
        private boolean ipProtoSet;
        private IpProtocol ipProto;
        private boolean ipv4SrcSet;
        private IPv4Address ipv4Src;
        private boolean ipv4DstSet;
        private IPv4Address ipv4Dst;
        private boolean tcpSrcSet;
        private TransportPort tcpSrc;
        private boolean tcpDstSet;
        private TransportPort tcpDst;

    @Override
    public int getWildcards() {
        return wildcards;
    }

    @Override
    public OFMatchV1.Builder setWildcards(int wildcards) {
        this.wildcards = wildcards;
        this.wildcardsSet = true;
        return this;
    }
    @Override
    public OFPort getInPort() {
        return inPort;
    }

    @Override
    public OFMatchV1.Builder setInPort(OFPort inPort) {
        this.inPort = inPort;
        this.inPortSet = true;
        return this;
    }
    @Override
    public MacAddress getEthSrc() {
        return ethSrc;
    }

    @Override
    public OFMatchV1.Builder setEthSrc(MacAddress ethSrc) {
        this.ethSrc = ethSrc;
        this.ethSrcSet = true;
        return this;
    }
    @Override
    public MacAddress getEthDst() {
        return ethDst;
    }

    @Override
    public OFMatchV1.Builder setEthDst(MacAddress ethDst) {
        this.ethDst = ethDst;
        this.ethDstSet = true;
        return this;
    }
    @Override
    public OFVlanVidMatch getVlanVid() {
        return vlanVid;
    }

    @Override
    public OFMatchV1.Builder setVlanVid(OFVlanVidMatch vlanVid) {
        this.vlanVid = vlanVid;
        this.vlanVidSet = true;
        return this;
    }
    @Override
    public VlanPcp getVlanPcp() {
        return vlanPcp;
    }

    @Override
    public OFMatchV1.Builder setVlanPcp(VlanPcp vlanPcp) {
        this.vlanPcp = vlanPcp;
        this.vlanPcpSet = true;
        return this;
    }
    @Override
    public EthType getEthType() {
        return ethType;
    }

    @Override
    public OFMatchV1.Builder setEthType(EthType ethType) {
        this.ethType = ethType;
        this.ethTypeSet = true;
        return this;
    }
    @Override
    public IpDscp getIpDscp() {
        return ipDscp;
    }

    @Override
    public OFMatchV1.Builder setIpDscp(IpDscp ipDscp) {
        this.ipDscp = ipDscp;
        this.ipDscpSet = true;
        return this;
    }
    @Override
    public IpProtocol getIpProto() {
        return ipProto;
    }

    @Override
    public OFMatchV1.Builder setIpProto(IpProtocol ipProto) {
        this.ipProto = ipProto;
        this.ipProtoSet = true;
        return this;
    }
    @Override
    public IPv4Address getIpv4Src() {
        return ipv4Src;
    }

    @Override
    public OFMatchV1.Builder setIpv4Src(IPv4Address ipv4Src) {
        this.ipv4Src = ipv4Src;
        this.ipv4SrcSet = true;
        return this;
    }
    @Override
    public IPv4Address getIpv4Dst() {
        return ipv4Dst;
    }

    @Override
    public OFMatchV1.Builder setIpv4Dst(IPv4Address ipv4Dst) {
        this.ipv4Dst = ipv4Dst;
        this.ipv4DstSet = true;
        return this;
    }
    @Override
    public TransportPort getTcpSrc() {
        return tcpSrc;
    }

    @Override
    public OFMatchV1.Builder setTcpSrc(TransportPort tcpSrc) {
        this.tcpSrc = tcpSrc;
        this.tcpSrcSet = true;
        return this;
    }
    @Override
    public TransportPort getTcpDst() {
        return tcpDst;
    }

    @Override
    public OFMatchV1.Builder setTcpDst(TransportPort tcpDst) {
        this.tcpDst = tcpDst;
        this.tcpDstSet = true;
        return this;
    }
    @Override
    public OFVersion getVersion() {
        return OFVersion.OF_10;
    }

//
        @Override
        public OFMatchV1 build() {
            int wildcards = this.wildcardsSet ? this.wildcards : DEFAULT_WILDCARDS;
            OFPort inPort = this.inPortSet ? this.inPort : DEFAULT_IN_PORT;
            if(inPort == null)
                throw new NullPointerException("Property inPort must not be null");
            MacAddress ethSrc = this.ethSrcSet ? this.ethSrc : DEFAULT_ETH_SRC;
            if(ethSrc == null)
                throw new NullPointerException("Property ethSrc must not be null");
            MacAddress ethDst = this.ethDstSet ? this.ethDst : DEFAULT_ETH_DST;
            if(ethDst == null)
                throw new NullPointerException("Property ethDst must not be null");
            OFVlanVidMatch vlanVid = this.vlanVidSet ? this.vlanVid : DEFAULT_VLAN_VID;
            if(vlanVid == null)
                throw new NullPointerException("Property vlanVid must not be null");
            VlanPcp vlanPcp = this.vlanPcpSet ? this.vlanPcp : DEFAULT_VLAN_PCP;
            if(vlanPcp == null)
                throw new NullPointerException("Property vlanPcp must not be null");
            EthType ethType = this.ethTypeSet ? this.ethType : DEFAULT_ETH_TYPE;
            if(ethType == null)
                throw new NullPointerException("Property ethType must not be null");
            IpDscp ipDscp = this.ipDscpSet ? this.ipDscp : DEFAULT_IP_DSCP;
            if(ipDscp == null)
                throw new NullPointerException("Property ipDscp must not be null");
            IpProtocol ipProto = this.ipProtoSet ? this.ipProto : DEFAULT_IP_PROTO;
            if(ipProto == null)
                throw new NullPointerException("Property ipProto must not be null");
            IPv4Address ipv4Src = this.ipv4SrcSet ? this.ipv4Src : DEFAULT_IPV4_SRC;
            if(ipv4Src == null)
                throw new NullPointerException("Property ipv4Src must not be null");
            IPv4Address ipv4Dst = this.ipv4DstSet ? this.ipv4Dst : DEFAULT_IPV4_DST;
            if(ipv4Dst == null)
                throw new NullPointerException("Property ipv4Dst must not be null");
            TransportPort tcpSrc = this.tcpSrcSet ? this.tcpSrc : DEFAULT_TCP_SRC;
            if(tcpSrc == null)
                throw new NullPointerException("Property tcpSrc must not be null");
            TransportPort tcpDst = this.tcpDstSet ? this.tcpDst : DEFAULT_TCP_DST;
            if(tcpDst == null)
                throw new NullPointerException("Property tcpDst must not be null");

            // normalize match fields according to current OpenVSwitch behavior. When prerequisites for a field are not met
            // e.g., eth_type is not set to 0x800, OVS sets the value of corresponding ignored fields (e.g.,
            // ip_src, tcp_dst) to 0, and sets the wildcard bit to 1.
            if(ethType.equals(EthType.IPv4)) {
                // IP
                if(ipProto.equals(IpProtocol.TCP) || ipProto.equals(IpProtocol.UDP) || ipProto.equals(IpProtocol.ICMP)) {
                    // fully speced, wildcards and all values are fine
                    // normalize 32-63 ipv4 src 'mask' to a full bitmask
                    if((wildcards & OFPFW_NW_SRC_ALL) != 0)
                        wildcards |= OFPFW_NW_SRC_MASK;

                    // normalize 32-63 ipv4 dst 'mask' to a full bitmask
                    if((wildcards & OFPFW_NW_DST_ALL) != 0)
                        wildcards |= OFPFW_NW_DST_MASK;

                } else {
                    // normalize 32-63 ipv4 src 'mask' to a full bitmask
                    if((wildcards & OFPFW_NW_SRC_ALL) != 0)
                        wildcards |= OFPFW_NW_SRC_MASK;

                    // normalize 32-63 ipv4 dst 'mask' to a full bitmask
                    if((wildcards & OFPFW_NW_DST_ALL) != 0)
                        wildcards |= OFPFW_NW_DST_MASK;

                    // not TCP/UDP/ICMP -> Clear TP wildcards for the wire
                    wildcards |= (OFPFW_TP_SRC | OFPFW_TP_DST);
                    tcpSrc = TransportPort.NONE;
                    tcpDst = TransportPort.NONE;
                }
            } else if (ethType.equals(EthType.ARP)) {
                // normalize 32-63 ipv4 src 'mask' to a full bitmask
                if((wildcards & OFPFW_NW_SRC_ALL) != 0)
                    wildcards |= OFPFW_NW_SRC_MASK;

                // normalize 32-63 ipv4 dst 'mask' to a full bitmask
                if((wildcards & OFPFW_NW_DST_ALL) != 0)
                    wildcards |= OFPFW_NW_DST_MASK;

                // ARP: clear NW_TOS / TP wildcards for the wire
                wildcards |= ( OFPFW_NW_TOS | OFPFW_TP_SRC | OFPFW_TP_DST);
                ipDscp = IpDscp.NONE;
                tcpSrc = TransportPort.NONE;
                tcpDst = TransportPort.NONE;
            } else {
                // not even IP. Clear NW/TP wildcards for the wire
                wildcards |= ( OFPFW_NW_TOS | OFPFW_NW_PROTO | OFPFW_NW_SRC_MASK | OFPFW_NW_DST_MASK | OFPFW_TP_SRC | OFPFW_TP_DST);
                ipDscp = IpDscp.NONE;
                ipProto = IpProtocol.NONE;
                ipv4Src = IPv4Address.NONE;
                ipv4Dst = IPv4Address.NONE;
                tcpSrc = TransportPort.NONE;
                tcpDst = TransportPort.NONE;
            }

            return new OFMatchV1Ver10(
                    wildcards,
                    inPort,
                    ethSrc,
                    ethDst,
                    vlanVid,
                    vlanPcp,
                    ethType,
                    ipDscp,
                    ipProto,
                    ipv4Src,
                    ipv4Dst,
                    tcpSrc,
                    tcpDst
                );
        }
        @SuppressWarnings("unchecked")
        @Override
        public <F extends OFValueType<F>> F get(MatchField<F> field)
                throws UnsupportedOperationException {
            if (isFullyWildcarded(field))
                return null;

            Object result;
            switch (field.id) {
                case IN_PORT:
                    result = inPort;
                    break;
                case ETH_DST:
                    result = ethDst;
                    break;
                case ETH_SRC:
                    result = ethSrc;
                    break;
                case ETH_TYPE:
                    result = ethType;
                    break;
                case VLAN_VID:
                    result = vlanVid;
                    break;
                case VLAN_PCP:
                    result = vlanPcp;
                    break;
                case ARP_OP:
                    result = ArpOpcode.of(ipProto.getIpProtocolNumber());
                    break;
                case ARP_SPA:
                    result = ipv4Src;
                    break;
                case ARP_TPA:
                    result = ipv4Dst;
                    break;
                case IP_DSCP:
                    result = ipDscp;
                    break;
                case IP_PROTO:
                    result = ipProto;
                    break;
                case IPV4_SRC:
                    result = ipv4Src;
                    break;
                case IPV4_DST:
                    result = ipv4Dst;
                    break;
                case TCP_SRC:
                    result = tcpSrc;
                    break;
                case TCP_DST:
                    result = tcpDst;
                    break;
                case UDP_SRC:
                    result = tcpSrc;
                    break;
                case UDP_DST:
                    result = tcpDst;
                    break;
                case SCTP_SRC:
                    result = tcpSrc;
                    break;
                case SCTP_DST:
                    result = tcpDst;
                    break;
                case ICMPV4_TYPE:
                    result = tcpSrc;
                    break;
                case ICMPV4_CODE:
                    result = tcpDst;
                    break;
                // NOT SUPPORTED:
                default:
                    throw new UnsupportedOperationException("OFMatch does not support matching on field " + field.getName());
            }
            return (F)result;
        }

        @SuppressWarnings("unchecked")
        @Override
        public <F extends OFValueType<F>> Masked<F> getMasked(MatchField<F> field)
                throws UnsupportedOperationException {
            if (!isPartiallyMasked(field))
                return null;
            Object result;
            switch (field.id) {
                case IPV4_SRC:
                case ARP_SPA:
                    int srcBitMask = (-1) << (32 - getIpv4SrcCidrMaskLen());
                    result = IPv4AddressWithMask.of(ipv4Src, IPv4Address.of(srcBitMask));
                    break;
                case IPV4_DST:
                case ARP_TPA:
                    int dstMaskedBits = Math.min(32, (wildcards & OFPFW_NW_DST_MASK) >> OFPFW_NW_DST_SHIFT);
                    int dstBitMask = (-1) << (32 - getIpv4DstCidrMaskLen());

                    result = IPv4AddressWithMask.of(ipv4Dst, IPv4Address.of(dstBitMask));
                    break;
                default:
                    throw new UnsupportedOperationException("OFMatch does not support masked matching on field " + field.getName());
            }
            return (Masked<F>)result;
        }

        @Override
        public boolean supports(MatchField<?> field) {
            switch (field.id) {
                case IN_PORT:
                case ETH_DST:
                case ETH_SRC:
                case ETH_TYPE:
                case VLAN_VID:
                case VLAN_PCP:
                case ARP_OP:
                case ARP_SPA:
                case ARP_TPA:
                case IP_DSCP:
                case IP_PROTO:
                case IPV4_SRC:
                case IPV4_DST:
                case TCP_SRC:
                case TCP_DST:
                case UDP_SRC:
                case UDP_DST:
                case SCTP_SRC:
                case SCTP_DST:
                case ICMPV4_TYPE:
                case ICMPV4_CODE:
                    return true;
                default:
                    return false;
            }
        }

        @Override
        public boolean supportsMasked(MatchField<?> field) {
            switch (field.id) {
                case ARP_SPA:
                case ARP_TPA:
                case IPV4_SRC:
                case IPV4_DST:
                    return true;
                default:
                    return false;
            }
        }

        @Override
        public boolean isExact(MatchField<?> field) {
            switch (field.id) {
                case IN_PORT:
                    return (this.wildcards & OFPFW_IN_PORT) == 0;
                case ETH_DST:
                    return (this.wildcards & OFPFW_DL_DST) == 0;
                case ETH_SRC:
                    return (this.wildcards & OFPFW_DL_SRC) == 0;
                case ETH_TYPE:
                    return (this.wildcards & OFPFW_DL_TYPE) == 0;
                case VLAN_VID:
                    return (this.wildcards & OFPFW_DL_VLAN) == 0;
                case VLAN_PCP:
                    return (this.wildcards & OFPFW_DL_VLAN_PCP) == 0;
                case ARP_OP:
                    return (this.wildcards & OFPFW_NW_PROTO) == 0;
                case ARP_SPA:
                    return this.getIpv4SrcCidrMaskLen() >= 32;
                case ARP_TPA:
                    return this.getIpv4DstCidrMaskLen() >= 32;
                case IP_DSCP:
                    return (this.wildcards & OFPFW_NW_TOS) == 0;
                case IP_PROTO:
                    return (this.wildcards & OFPFW_NW_PROTO) == 0;
                case IPV4_SRC:
                    return this.getIpv4SrcCidrMaskLen() >= 32;
                case IPV4_DST:
                    return this.getIpv4DstCidrMaskLen() >= 32;
                case TCP_SRC:
                    return (this.wildcards & OFPFW_TP_SRC) == 0;
                case TCP_DST:
                    return (this.wildcards & OFPFW_TP_DST) == 0;
                case UDP_SRC:
                    return (this.wildcards & OFPFW_TP_SRC) == 0;
                case UDP_DST:
                    return (this.wildcards & OFPFW_TP_DST) == 0;
                case SCTP_SRC:
                    return (this.wildcards & OFPFW_TP_SRC) == 0;
                case SCTP_DST:
                    return (this.wildcards & OFPFW_TP_DST) == 0;
                case ICMPV4_TYPE:
                    return (this.wildcards & OFPFW_TP_SRC) == 0;
                case ICMPV4_CODE:
                    return (this.wildcards & OFPFW_TP_DST) == 0;
                default:
                    throw new UnsupportedOperationException("OFMatch does not support matching on field " + field.getName());
            }
        }

        /**
         * Parse this match's wildcard fields and return the number of significant
         * bits in the IP destination field. NOTE: this returns the number of bits
         * that are fixed, i.e., like CIDR, not the number of bits that are free
         * like OpenFlow encodes.
         *
         * @return A number between 0 (matches all IPs) and 32 (exact match)
         */
        public int getIpv4DstCidrMaskLen() {
            return Math.max(32 - ((wildcards & OFPFW_NW_DST_MASK) >> OFPFW_NW_DST_SHIFT),
                            0);
        }

        /**
         * Parse this match's wildcard fields and return the number of significant
         * bits in the IP destination field. NOTE: this returns the number of bits
         * that are fixed, i.e., like CIDR, not the number of bits that are free
         * like OpenFlow encodes.
         *
         * @return A number between 0 (matches all IPs) and 32 (exact match)
         */
        public int getIpv4SrcCidrMaskLen() {
            return Math.max(32 - ((wildcards & OFPFW_NW_SRC_MASK) >> OFPFW_NW_SRC_SHIFT),
                            0);
        }


        @Override
        public boolean isFullyWildcarded(MatchField<?> field) {
            switch (field.id) {
                case IN_PORT:
                    return (this.wildcards & OFPFW_IN_PORT) != 0;
                case ETH_DST:
                    return (this.wildcards & OFPFW_DL_DST) != 0;
                case ETH_SRC:
                    return (this.wildcards & OFPFW_DL_SRC) != 0;
                case ETH_TYPE:
                    return (this.wildcards & OFPFW_DL_TYPE) != 0;
                case VLAN_VID:
                    return (this.wildcards & OFPFW_DL_VLAN) != 0;
                case VLAN_PCP:
                    return (this.wildcards & OFPFW_DL_VLAN_PCP) != 0;
                case ARP_OP:
                    return (this.wildcards & OFPFW_NW_PROTO) != 0;
                case ARP_SPA:
                    return this.getIpv4SrcCidrMaskLen() <= 0;
                case ARP_TPA:
                    return this.getIpv4DstCidrMaskLen() <= 0;
                case IP_DSCP:
                    return (this.wildcards & OFPFW_NW_TOS) != 0;
                case IP_PROTO:
                    return (this.wildcards & OFPFW_NW_PROTO) != 0;
                case TCP_SRC:
                    return (this.wildcards & OFPFW_TP_SRC) != 0;
                case TCP_DST:
                    return (this.wildcards & OFPFW_TP_DST) != 0;
                case UDP_SRC:
                    return (this.wildcards & OFPFW_TP_SRC) != 0;
                case UDP_DST:
                    return (this.wildcards & OFPFW_TP_DST) != 0;
                case SCTP_SRC:
                    return (this.wildcards & OFPFW_TP_SRC) != 0;
                case SCTP_DST:
                    return (this.wildcards & OFPFW_TP_DST) != 0;
                case ICMPV4_TYPE:
                    return (this.wildcards & OFPFW_TP_SRC) != 0;
                case ICMPV4_CODE:
                    return (this.wildcards & OFPFW_TP_DST) != 0;
                case IPV4_SRC:
                    return this.getIpv4SrcCidrMaskLen() <= 0;
                case IPV4_DST:
                    return this.getIpv4DstCidrMaskLen() <= 0;
                default:
                    throw new UnsupportedOperationException("OFMatch does not support matching on field " + field.getName());
            }
        }

        @Override
        public boolean isPartiallyMasked(MatchField<?> field) {
            switch (field.id) {
                case ARP_SPA:
                case IPV4_SRC:
                    int srcCidrLen = getIpv4SrcCidrMaskLen();
                    return srcCidrLen > 0 && srcCidrLen < 32;
                case ARP_TPA:
                case IPV4_DST:
                    int dstCidrLen = getIpv4DstCidrMaskLen();
                    return dstCidrLen > 0 && dstCidrLen < 32;
                default:
                    throw new UnsupportedOperationException("OFMatch does not support masked matching on field " + field.getName());
            }
        }

        private final void initWildcards() {
            if(!wildcardsSet) {
                wildcards = OFPFW_ALL;
                wildcardsSet = true;
            }
        }

        @Override
        public <F extends OFValueType<F>> Match.Builder setExact(MatchField<F> field,
                F value) {
            initWildcards();
            Object val = value;
            switch (field.id) {
                case ETH_DST:
                    setEthDst((MacAddress) value);
                    wildcards &= ~OFPFW_DL_DST;
                    break;
                case ETH_SRC:
                    setEthSrc((MacAddress) value);
                    wildcards &= ~OFPFW_DL_SRC;
                    break;
                case ETH_TYPE:
                    setEthType((EthType) value);
                    wildcards &= ~OFPFW_DL_TYPE;
                    break;
                case ICMPV4_CODE:
                    setTcpDst(TransportPort.of(((ICMPv4Code)value).getCode()));
                    wildcards &= ~OFPFW_TP_DST;
                    break;
                case ICMPV4_TYPE:
                    setTcpSrc(TransportPort.of(((ICMPv4Type)value).getType()));
                    wildcards &= ~OFPFW_TP_SRC;
                    break;
                case IN_PORT:
                    setInPort((OFPort) value);
                    wildcards &= ~OFPFW_IN_PORT;
                    break;
                case ARP_OP:
                    setIpProto(IpProtocol.of((short)((ArpOpcode)value).getOpcode()));
                    wildcards &= ~OFPFW_NW_PROTO;
                    break;
                case ARP_TPA:
                case IPV4_DST:
                    setIpv4Dst((IPv4Address) value);
                    wildcards &= ~OFPFW_NW_DST_MASK;
                    break;
                case ARP_SPA:
                case IPV4_SRC:
                    setIpv4Src((IPv4Address) value);
                    wildcards &= ~OFPFW_NW_SRC_MASK;
                    break;
                case IP_DSCP:
                    setIpDscp((IpDscp) value);
                    wildcards &= ~OFPFW_NW_TOS;
                    break;
                case IP_PROTO:
                    setIpProto((IpProtocol) value);
                    wildcards &= ~OFPFW_NW_PROTO;
                    break;
                case SCTP_DST:
                    setTcpDst((TransportPort) value);
                    wildcards &= ~OFPFW_TP_DST;
                    break;
                case SCTP_SRC:
                    setTcpSrc((TransportPort) value);
                    wildcards &= ~OFPFW_TP_SRC;
                    break;
                case TCP_DST:
                    setTcpDst((TransportPort) value);
                    wildcards &= ~OFPFW_TP_DST;
                    break;
                case TCP_SRC:
                    setTcpSrc((TransportPort) value);
                    wildcards &= ~OFPFW_TP_SRC;
                    break;
                case UDP_DST:
                    setTcpDst((TransportPort) value);
                    wildcards &= ~OFPFW_TP_DST;
                    break;
                case UDP_SRC:
                    setTcpSrc((TransportPort) value);
                    wildcards &= ~OFPFW_TP_SRC;
                    break;
                case VLAN_PCP:
                    setVlanPcp((VlanPcp) value);
                    wildcards &= ~OFPFW_DL_VLAN_PCP;
                    break;
                case VLAN_VID:
                    setVlanVid((OFVlanVidMatch) value);
                    wildcards &= ~OFPFW_DL_VLAN;
                    break;
                default:
                    throw new UnsupportedOperationException(
                            "OFMatch does not support matching on field " + field.getName());
            }
            return this;
        }

        @Override
        public <F extends OFValueType<F>> Match.Builder setMasked(MatchField<F> field,
                F value, F mask) {
            initWildcards();
            switch (field.id) {
                case ARP_SPA:
                case ARP_TPA:
                case IPV4_DST:
                case IPV4_SRC:
                    Object valObj = value;
                    Object masObj = mask;
                    IPv4Address ip = ((IPv4Address)valObj);
                    int maskval = ((IPv4Address)masObj).getInt();
                    if (Integer.bitCount(~maskval + 1) != 1)
                        throw new UnsupportedOperationException("OFMatch only supports CIDR masks for IPv4");
                    int maskLen = 32 - Integer.bitCount(maskval);
                    switch(field.id) {
                        case ARP_TPA:
                        case IPV4_DST:
                            setIpv4Dst(ip);
                            wildcards = (wildcards &~OFPFW_NW_DST_MASK) | (maskLen << OFPFW_NW_DST_SHIFT);
                            break;
                        case ARP_SPA:
                        case IPV4_SRC:
                            setIpv4Src(ip);
                            wildcards = (wildcards &~OFPFW_NW_SRC_MASK) | (maskLen << OFPFW_NW_SRC_SHIFT);
                            break;
                        default:
                            // Cannot really get here
                            break;
                    }
                    break;
                default:
                    throw new UnsupportedOperationException("OFMatch does not support masked matching on field " + field.getName());
            }
            return this;
        }

        @Override
        public <F extends OFValueType<F>> Match.Builder setMasked(MatchField<F> field, Masked<F> valueWithMask)
                                                                       throws UnsupportedOperationException {
            return this.setMasked(field, valueWithMask.getValue(), valueWithMask.getMask());
        }

        @Override
        public <F extends OFValueType<F>> Match.Builder wildcard(MatchField<F> field) {
            initWildcards();
            switch (field.id) {
                case ETH_DST:
                    setEthDst(MacAddress.NONE);
                    wildcards |= OFPFW_DL_DST;
                    break;
                case ETH_SRC:
                    setEthSrc(MacAddress.NONE);
                    wildcards |= OFPFW_DL_SRC;
                    break;
                case ETH_TYPE:
                    setEthType(EthType.NONE);
                    wildcards |= OFPFW_DL_TYPE;
                    break;
                case ICMPV4_CODE:
                case TCP_DST:
                case UDP_DST:
                case SCTP_DST:
                    setTcpDst(TransportPort.NONE);
                    wildcards |= OFPFW_TP_DST;
                    break;
                case ICMPV4_TYPE:
                case TCP_SRC:
                case UDP_SRC:
                case SCTP_SRC:
                    setTcpSrc(TransportPort.NONE);
                    wildcards |= OFPFW_TP_SRC;
                    break;
                case IN_PORT:
                    setInPort(OFPort.of(0)); // NOTE: not 'NONE' -- that is 0xFF for ports
                    wildcards |= OFPFW_IN_PORT;
                    break;
                case ARP_TPA:
                case IPV4_DST:
                    setIpv4Dst(IPv4Address.NONE);
                    wildcards |= OFPFW_NW_DST_MASK;
                    break;
                case ARP_SPA:
                case IPV4_SRC:
                    setIpv4Src(IPv4Address.NONE);
                    wildcards |= OFPFW_NW_SRC_MASK;
                    break;
                case IP_DSCP:
                    setIpDscp(IpDscp.NONE);
                    wildcards |= OFPFW_NW_TOS;
                    break;
                case IP_PROTO:
                    setIpProto(IpProtocol.NONE);
                    wildcards |= OFPFW_NW_PROTO;
                    break;
                case VLAN_PCP:
                    setVlanPcp(VlanPcp.NONE);
                    wildcards |= OFPFW_DL_VLAN_PCP;
                    break;
                case VLAN_VID:
                    setVlanVid(OFVlanVidMatch.NONE);
                    wildcards |= OFPFW_DL_VLAN;
                    break;
                default:
                    throw new UnsupportedOperationException("OFMatch does not support matching on field " + field.getName());
            }
            return this;
        }

    }


    final static Reader READER = new Reader();
    static class Reader implements OFMessageReader<OFMatchV1> {
        @Override
        public OFMatchV1 readFrom(ChannelBuffer bb) throws OFParseError {
            int wildcards = bb.readInt();
            OFPort inPort = OFPort.read2Bytes(bb);
            MacAddress ethSrc = MacAddress.read6Bytes(bb);
            MacAddress ethDst = MacAddress.read6Bytes(bb);
            OFVlanVidMatch vlanVid = OFVlanVidMatch.read2BytesOF10(bb);
            VlanPcp vlanPcp = VlanPcp.readByte(bb);
            // pad: 1 bytes
            bb.skipBytes(1);
            EthType ethType = EthType.read2Bytes(bb);
            IpDscp ipDscp = IpDscp.readByte(bb);
            IpProtocol ipProto = IpProtocol.readByte(bb);
            // pad: 2 bytes
            bb.skipBytes(2);
            IPv4Address ipv4Src = IPv4Address.read4Bytes(bb);
            IPv4Address ipv4Dst = IPv4Address.read4Bytes(bb);
            TransportPort tcpSrc = TransportPort.read2Bytes(bb);
            TransportPort tcpDst = TransportPort.read2Bytes(bb);

            // normalize match fields according to current OpenVSwitch behavior. When prerequisites for a field are not met
            // e.g., eth_type is not set to 0x800, OVS sets the value of corresponding ignored fields (e.g.,
            // ip_src, tcp_dst) to 0, and sets the wildcard bit to 1.
            if(ethType.equals(EthType.IPv4)) {
                // IP
                if(ipProto.equals(IpProtocol.TCP) || ipProto.equals(IpProtocol.UDP) || ipProto.equals(IpProtocol.ICMP)) {
                    // fully speced, wildcards and all values are fine
                    // normalize 32-63 ipv4 src 'mask' to a full bitmask
                    if((wildcards & OFPFW_NW_SRC_ALL) != 0)
                        wildcards |= OFPFW_NW_SRC_MASK;

                    // normalize 32-63 ipv4 dst 'mask' to a full bitmask
                    if((wildcards & OFPFW_NW_DST_ALL) != 0)
                        wildcards |= OFPFW_NW_DST_MASK;

                } else {
                    // normalize 32-63 ipv4 src 'mask' to a full bitmask
                    if((wildcards & OFPFW_NW_SRC_ALL) != 0)
                        wildcards |= OFPFW_NW_SRC_MASK;

                    // normalize 32-63 ipv4 dst 'mask' to a full bitmask
                    if((wildcards & OFPFW_NW_DST_ALL) != 0)
                        wildcards |= OFPFW_NW_DST_MASK;

                    // not TCP/UDP/ICMP -> Clear TP wildcards for the wire
                    wildcards |= (OFPFW_TP_SRC | OFPFW_TP_DST);
                    tcpSrc = TransportPort.NONE;
                    tcpDst = TransportPort.NONE;
                }
            } else if (ethType.equals(EthType.ARP)) {
                // normalize 32-63 ipv4 src 'mask' to a full bitmask
                if((wildcards & OFPFW_NW_SRC_ALL) != 0)
                    wildcards |= OFPFW_NW_SRC_MASK;

                // normalize 32-63 ipv4 dst 'mask' to a full bitmask
                if((wildcards & OFPFW_NW_DST_ALL) != 0)
                    wildcards |= OFPFW_NW_DST_MASK;

                // ARP: clear NW_TOS / TP wildcards for the wire
                wildcards |= ( OFPFW_NW_TOS | OFPFW_TP_SRC | OFPFW_TP_DST);
                ipDscp = IpDscp.NONE;
                tcpSrc = TransportPort.NONE;
                tcpDst = TransportPort.NONE;
            } else {
                // not even IP. Clear NW/TP wildcards for the wire
                wildcards |= ( OFPFW_NW_TOS | OFPFW_NW_PROTO | OFPFW_NW_SRC_MASK | OFPFW_NW_DST_MASK | OFPFW_TP_SRC | OFPFW_TP_DST);
                ipDscp = IpDscp.NONE;
                ipProto = IpProtocol.NONE;
                ipv4Src = IPv4Address.NONE;
                ipv4Dst = IPv4Address.NONE;
                tcpSrc = TransportPort.NONE;
                tcpDst = TransportPort.NONE;
            }
            OFMatchV1Ver10 matchV1Ver10 = new OFMatchV1Ver10(
                    wildcards,
                      inPort,
                      ethSrc,
                      ethDst,
                      vlanVid,
                      vlanPcp,
                      ethType,
                      ipDscp,
                      ipProto,
                      ipv4Src,
                      ipv4Dst,
                      tcpSrc,
                      tcpDst
                    );
            if(logger.isTraceEnabled())
                logger.trace("readFrom - read={}", matchV1Ver10);
            return matchV1Ver10;
        }
    }

    public void putTo(PrimitiveSink sink) {
        FUNNEL.funnel(this, sink);
    }

    final static OFMatchV1Ver10Funnel FUNNEL = new OFMatchV1Ver10Funnel();
    static class OFMatchV1Ver10Funnel implements Funnel<OFMatchV1Ver10> {
        private static final long serialVersionUID = 1L;
        @Override
        public void funnel(OFMatchV1Ver10 message, PrimitiveSink sink) {
            sink.putInt(message.wildcards);
            message.inPort.putTo(sink);
            message.ethSrc.putTo(sink);
            message.ethDst.putTo(sink);
            message.vlanVid.putTo(sink);
            message.vlanPcp.putTo(sink);
            // skip pad (1 bytes)
            message.ethType.putTo(sink);
            message.ipDscp.putTo(sink);
            message.ipProto.putTo(sink);
            // skip pad (2 bytes)
            message.ipv4Src.putTo(sink);
            message.ipv4Dst.putTo(sink);
            message.tcpSrc.putTo(sink);
            message.tcpDst.putTo(sink);
        }
    }


    public void writeTo(ChannelBuffer bb) {
        WRITER.write(bb, this);
    }

    final static Writer WRITER = new Writer();
    static class Writer implements OFMessageWriter<OFMatchV1Ver10> {
        @Override
        public void write(ChannelBuffer bb, OFMatchV1Ver10 message) {
            bb.writeInt(message.wildcards);
            message.inPort.write2Bytes(bb);
            message.ethSrc.write6Bytes(bb);
            message.ethDst.write6Bytes(bb);
            message.vlanVid.write2BytesOF10(bb);
            message.vlanPcp.writeByte(bb);
            // pad: 1 bytes
            bb.writeZero(1);
            message.ethType.write2Bytes(bb);
            message.ipDscp.writeByte(bb);
            message.ipProto.writeByte(bb);
            // pad: 2 bytes
            bb.writeZero(2);
            message.ipv4Src.write4Bytes(bb);
            message.ipv4Dst.write4Bytes(bb);
            message.tcpSrc.write2Bytes(bb);
            message.tcpDst.write2Bytes(bb);


        }
    }

    @Override
    public String toString() {
        StringBuilder b = new StringBuilder("OFMatchV1Ver10(");
        boolean first = true;
        for(MatchField<?> field : getMatchFields()) {
            if(first)
                first = false;
            else
                b.append(", ");
            String name = field.getName();
            b.append(name).append('=').append(this.get(field));
            if(isPartiallyMasked(field)) {
                b.append('/').append(this.getMasked(field).getMask());
            }
        }
        b.append(")");
        return b.toString();
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        OFMatchV1Ver10 other = (OFMatchV1Ver10) obj;

        if( wildcards != other.wildcards)
            return false;
        if (inPort == null) {
            if (other.inPort != null)
                return false;
        } else if (!inPort.equals(other.inPort))
            return false;
        if (ethSrc == null) {
            if (other.ethSrc != null)
                return false;
        } else if (!ethSrc.equals(other.ethSrc))
            return false;
        if (ethDst == null) {
            if (other.ethDst != null)
                return false;
        } else if (!ethDst.equals(other.ethDst))
            return false;
        if (vlanVid == null) {
            if (other.vlanVid != null)
                return false;
        } else if (!vlanVid.equals(other.vlanVid))
            return false;
        if (vlanPcp == null) {
            if (other.vlanPcp != null)
                return false;
        } else if (!vlanPcp.equals(other.vlanPcp))
            return false;
        if (ethType == null) {
            if (other.ethType != null)
                return false;
        } else if (!ethType.equals(other.ethType))
            return false;
        if (ipDscp == null) {
            if (other.ipDscp != null)
                return false;
        } else if (!ipDscp.equals(other.ipDscp))
            return false;
        if (ipProto == null) {
            if (other.ipProto != null)
                return false;
        } else if (!ipProto.equals(other.ipProto))
            return false;
        if (ipv4Src == null) {
            if (other.ipv4Src != null)
                return false;
        } else if (!ipv4Src.equals(other.ipv4Src))
            return false;
        if (ipv4Dst == null) {
            if (other.ipv4Dst != null)
                return false;
        } else if (!ipv4Dst.equals(other.ipv4Dst))
            return false;
        if (tcpSrc == null) {
            if (other.tcpSrc != null)
                return false;
        } else if (!tcpSrc.equals(other.tcpSrc))
            return false;
        if (tcpDst == null) {
            if (other.tcpDst != null)
                return false;
        } else if (!tcpDst.equals(other.tcpDst))
            return false;
        return true;
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;

        result = prime * result + wildcards;
        result = prime * result + ((inPort == null) ? 0 : inPort.hashCode());
        result = prime * result + ((ethSrc == null) ? 0 : ethSrc.hashCode());
        result = prime * result + ((ethDst == null) ? 0 : ethDst.hashCode());
        result = prime * result + ((vlanVid == null) ? 0 : vlanVid.hashCode());
        result = prime * result + ((vlanPcp == null) ? 0 : vlanPcp.hashCode());
        result = prime * result + ((ethType == null) ? 0 : ethType.hashCode());
        result = prime * result + ((ipDscp == null) ? 0 : ipDscp.hashCode());
        result = prime * result + ((ipProto == null) ? 0 : ipProto.hashCode());
        result = prime * result + ((ipv4Src == null) ? 0 : ipv4Src.hashCode());
        result = prime * result + ((ipv4Dst == null) ? 0 : ipv4Dst.hashCode());
        result = prime * result + ((tcpSrc == null) ? 0 : tcpSrc.hashCode());
        result = prime * result + ((tcpDst == null) ? 0 : tcpDst.hashCode());
        return result;
    }

}
