Pull out inner-classes from Criteria to be independent classes

Make constructors of sub-types of Criterion package private for
limiting instantiation only from static factory methods in Criteria

Change-Id: I1fb1e9d003288a778a49e758549a92b66bf3cfdf
diff --git a/apps/mobility/src/main/java/org/onosproject/mobility/HostMobility.java b/apps/mobility/src/main/java/org/onosproject/mobility/HostMobility.java
index a28afdf..652233b 100644
--- a/apps/mobility/src/main/java/org/onosproject/mobility/HostMobility.java
+++ b/apps/mobility/src/main/java/org/onosproject/mobility/HostMobility.java
@@ -31,7 +31,7 @@
 import org.onosproject.net.device.DeviceService;
 import org.onosproject.net.flow.FlowRule;
 import org.onosproject.net.flow.FlowRuleService;
-import org.onosproject.net.flow.criteria.Criteria.EthCriterion;
+import org.onosproject.net.flow.criteria.EthCriterion;
 import org.onosproject.net.flow.criteria.Criterion;
 import org.onosproject.net.flow.criteria.Criterion.Type;
 import org.onosproject.net.host.HostEvent;
diff --git a/apps/sdnip/src/main/java/org/onosproject/sdnip/IntentSynchronizer.java b/apps/sdnip/src/main/java/org/onosproject/sdnip/IntentSynchronizer.java
index 8e089cd..e7e6a86 100644
--- a/apps/sdnip/src/main/java/org/onosproject/sdnip/IntentSynchronizer.java
+++ b/apps/sdnip/src/main/java/org/onosproject/sdnip/IntentSynchronizer.java
@@ -40,7 +40,7 @@
 import org.onosproject.net.flow.DefaultTrafficTreatment;
 import org.onosproject.net.flow.TrafficSelector;
 import org.onosproject.net.flow.TrafficTreatment;
-import org.onosproject.net.flow.criteria.Criteria.IPCriterion;
+import org.onosproject.net.flow.criteria.IPCriterion;
 import org.onosproject.net.flow.criteria.Criterion;
 import org.onosproject.net.host.HostService;
 import org.onosproject.net.intent.Intent;
diff --git a/core/api/src/main/java/org/onosproject/net/flow/criteria/Criteria.java b/core/api/src/main/java/org/onosproject/net/flow/criteria/Criteria.java
index a63e245..58d6c16 100644
--- a/core/api/src/main/java/org/onosproject/net/flow/criteria/Criteria.java
+++ b/core/api/src/main/java/org/onosproject/net/flow/criteria/Criteria.java
@@ -15,10 +15,6 @@
  */
 package org.onosproject.net.flow.criteria;
 
-import static com.google.common.base.MoreObjects.toStringHelper;
-
-import java.util.Objects;
-
 import org.onosproject.net.PortNumber;
 import org.onosproject.net.flow.criteria.Criterion.Type;
 import org.onlab.packet.IpPrefix;
@@ -380,1361 +376,6 @@
     }
 
     /**
-     * Implementation of input port criterion.
-     */
-    public static final class PortCriterion implements Criterion {
-        private final PortNumber port;
-        private final Type type;
-
-        /**
-         * Constructor.
-         *
-         * @param port the input port number to match
-         * @param type the match type. Should be either Type.IN_PORT or
-         * Type.IN_PHY_PORT
-         */
-        public PortCriterion(PortNumber port, Type type) {
-            this.port = port;
-            this.type = type;
-        }
-
-        @Override
-        public Type type() {
-            return this.type;
-        }
-
-        /**
-         * Gets the input port number to match.
-         *
-         * @return the input port number to match
-         */
-        public PortNumber port() {
-            return this.port;
-        }
-
-        @Override
-        public String toString() {
-            return toStringHelper(type().toString())
-                    .add("port", port).toString();
-        }
-
-        @Override
-        public int hashCode() {
-            return Objects.hash(type(), port);
-        }
-
-        @Override
-        public boolean equals(Object obj) {
-            if (this == obj) {
-                return true;
-            }
-            if (obj instanceof PortCriterion) {
-                PortCriterion that = (PortCriterion) obj;
-                return Objects.equals(port, that.port) &&
-                        Objects.equals(this.type(), that.type());
-            }
-            return false;
-        }
-    }
-
-    /**
-     * Implementation of Metadata criterion.
-     */
-    public static final class MetadataCriterion implements Criterion {
-        private final long metadata;
-
-        /**
-         * Constructor.
-         *
-         * @param metadata the metadata to match (64 bits data)
-         */
-        public MetadataCriterion(long metadata) {
-            this.metadata = metadata;
-        }
-
-        @Override
-        public Type type() {
-            return Type.METADATA;
-        }
-
-        /**
-         * Gets the metadata to match.
-         *
-         * @return the metadata to match (64 bits data)
-         */
-        public long metadata() {
-            return metadata;
-        }
-
-        @Override
-        public String toString() {
-            return toStringHelper(type().toString())
-                    .add("metadata", Long.toHexString(metadata))
-                    .toString();
-        }
-
-        @Override
-        public int hashCode() {
-            return Objects.hash(type(), metadata);
-        }
-
-        @Override
-        public boolean equals(Object obj) {
-            if (this == obj) {
-                return true;
-            }
-            if (obj instanceof MetadataCriterion) {
-                MetadataCriterion that = (MetadataCriterion) obj;
-                return Objects.equals(metadata, that.metadata) &&
-                        Objects.equals(this.type(), that.type());
-            }
-            return false;
-        }
-    }
-
-    /**
-     * Implementation of MAC address criterion.
-     */
-    public static final class EthCriterion implements Criterion {
-        private final MacAddress mac;
-        private final Type type;
-
-        /**
-         * Constructor.
-         *
-         * @param mac the source or destination MAC address to match
-         * @param type the match type. Should be either Type.ETH_DST or
-         * Type.ETH_SRC
-         */
-        public EthCriterion(MacAddress mac, Type type) {
-            this.mac = mac;
-            this.type = type;
-        }
-
-        @Override
-        public Type type() {
-            return this.type;
-        }
-
-        /**
-         * Gets the MAC address to match.
-         *
-         * @return the MAC address to match
-         */
-        public MacAddress mac() {
-            return this.mac;
-        }
-
-        @Override
-        public String toString() {
-            return toStringHelper(type().toString())
-                    .add("mac", mac).toString();
-        }
-
-        @Override
-        public int hashCode() {
-            return Objects.hash(type, mac);
-        }
-
-        @Override
-        public boolean equals(Object obj) {
-            if (this == obj) {
-                return true;
-            }
-            if (obj instanceof EthCriterion) {
-                EthCriterion that = (EthCriterion) obj;
-                return Objects.equals(mac, that.mac) &&
-                        Objects.equals(type, that.type);
-            }
-            return false;
-        }
-    }
-
-    /**
-     * Implementation of Ethernet type criterion (16 bits unsigned integer).
-     */
-    public static final class EthTypeCriterion implements Criterion {
-        private static final int MASK = 0xffff;
-        private final int ethType;              // Ethernet type value: 16 bits
-
-        /**
-         * Constructor.
-         *
-         * @param ethType the Ethernet frame type to match (16 bits unsigned
-         * integer)
-         */
-        public EthTypeCriterion(int ethType) {
-            this.ethType = ethType & MASK;
-        }
-
-        @Override
-        public Type type() {
-            return Type.ETH_TYPE;
-        }
-
-        /**
-         * Gets the Ethernet frame type to match.
-         *
-         * @return the Ethernet frame type to match (16 bits unsigned integer)
-         */
-        public int ethType() {
-            return ethType;
-        }
-
-        @Override
-        public String toString() {
-            return toStringHelper(type().toString())
-                    .add("ethType", Long.toHexString(ethType))
-                    .toString();
-        }
-
-        @Override
-        public int hashCode() {
-            return Objects.hash(type(), ethType);
-        }
-
-        @Override
-        public boolean equals(Object obj) {
-            if (this == obj) {
-                return true;
-            }
-            if (obj instanceof EthTypeCriterion) {
-                EthTypeCriterion that = (EthTypeCriterion) obj;
-                return Objects.equals(ethType, that.ethType) &&
-                        Objects.equals(this.type(), that.type());
-            }
-            return false;
-        }
-    }
-
-    /**
-     * Implementation of VLAN ID criterion.
-     */
-    public static final class VlanIdCriterion implements Criterion {
-        private final VlanId vlanId;
-
-        /**
-         * Constructor.
-         *
-         * @param vlanId the VLAN ID to match
-         */
-        public VlanIdCriterion(VlanId vlanId) {
-            this.vlanId = vlanId;
-        }
-
-        @Override
-        public Type type() {
-            return Type.VLAN_VID;
-        }
-
-        /**
-         * Gets the VLAN ID to match.
-         *
-         * @return the VLAN ID to match
-         */
-        public VlanId vlanId() {
-            return vlanId;
-        }
-
-        @Override
-        public String toString() {
-            return toStringHelper(type().toString())
-                    .add("vlanId", vlanId).toString();
-        }
-
-        @Override
-        public int hashCode() {
-            return Objects.hash(type(), vlanId);
-        }
-
-        @Override
-        public boolean equals(Object obj) {
-            if (this == obj) {
-                return true;
-            }
-            if (obj instanceof VlanIdCriterion) {
-                VlanIdCriterion that = (VlanIdCriterion) obj;
-                return Objects.equals(vlanId, that.vlanId) &&
-                        Objects.equals(this.type(), that.type());
-            }
-            return false;
-        }
-    }
-
-    /**
-     * Implementation of VLAN priority criterion (3 bits).
-     */
-    public static final class VlanPcpCriterion implements Criterion {
-        private static final byte MASK = 0x7;
-        private final byte vlanPcp;             // VLAN pcp value: 3 bits
-
-        /**
-         * Constructor.
-         *
-         * @param vlanPcp the VLAN priority to match (3 bits)
-         */
-        public VlanPcpCriterion(byte vlanPcp) {
-            this.vlanPcp = (byte) (vlanPcp & MASK);
-        }
-
-        @Override
-        public Type type() {
-            return Type.VLAN_PCP;
-        }
-
-        /**
-         * Gets the VLAN priority to match.
-         *
-         * @return the VLAN priority to match (3 bits)
-         */
-        public byte priority() {
-            return vlanPcp;
-        }
-
-        @Override
-        public String toString() {
-            return toStringHelper(type().toString())
-                .add("priority", Long.toHexString(vlanPcp)).toString();
-        }
-
-        @Override
-        public int hashCode() {
-            return Objects.hash(type(), vlanPcp);
-        }
-
-        @Override
-        public boolean equals(Object obj) {
-            if (this == obj) {
-                return true;
-            }
-            if (obj instanceof VlanPcpCriterion) {
-                VlanPcpCriterion that = (VlanPcpCriterion) obj;
-                return Objects.equals(vlanPcp, that.vlanPcp) &&
-                        Objects.equals(this.type(), that.type());
-            }
-            return false;
-        }
-    }
-
-    /**
-     * Implementation of IP DSCP (Differentiated Services Code Point)
-     * criterion (6 bits).
-     */
-    public static final class IPDscpCriterion implements Criterion {
-        private static final byte MASK = 0x3f;
-        private final byte ipDscp;              // IP DSCP value: 6 bits
-
-        /**
-         * Constructor.
-         *
-         * @param ipDscp the IP DSCP value to match
-         */
-        public IPDscpCriterion(byte ipDscp) {
-            this.ipDscp = (byte) (ipDscp & MASK);
-        }
-
-        @Override
-        public Type type() {
-            return Type.IP_DSCP;
-        }
-
-        /**
-         * Gets the IP DSCP value to match.
-         *
-         * @return the IP DSCP value to match
-         */
-        public byte ipDscp() {
-            return ipDscp;
-        }
-
-        @Override
-        public String toString() {
-            return toStringHelper(type().toString())
-                .add("ipDscp", Long.toHexString(ipDscp)).toString();
-        }
-
-        @Override
-        public int hashCode() {
-            return Objects.hash(type(), ipDscp);
-        }
-
-        @Override
-        public boolean equals(Object obj) {
-            if (this == obj) {
-                return true;
-            }
-            if (obj instanceof IPDscpCriterion) {
-                IPDscpCriterion that = (IPDscpCriterion) obj;
-                return Objects.equals(ipDscp, that.ipDscp) &&
-                        Objects.equals(this.type(), that.type());
-            }
-            return false;
-        }
-    }
-
-    /**
-     * Implementation of IP ECN (Explicit Congestion Notification) criterion
-     * (2 bits).
-     */
-    public static final class IPEcnCriterion implements Criterion {
-        private static final byte MASK = 0x3;
-        private final byte ipEcn;               // IP ECN value: 2 bits
-
-        /**
-         * Constructor.
-         *
-         * @param ipEcn the IP ECN value to match (2 bits)
-         */
-        public IPEcnCriterion(byte ipEcn) {
-            this.ipEcn = (byte) (ipEcn & MASK);
-        }
-
-        @Override
-        public Type type() {
-            return Type.IP_ECN;
-        }
-
-        /**
-         * Gets the IP ECN value to match.
-         *
-         * @return the IP ECN value to match (2 bits)
-         */
-        public byte ipEcn() {
-            return ipEcn;
-        }
-
-        @Override
-        public String toString() {
-            return toStringHelper(type().toString())
-                .add("ipEcn", Long.toHexString(ipEcn)).toString();
-        }
-
-        @Override
-        public int hashCode() {
-            return Objects.hash(type(), ipEcn);
-        }
-
-        @Override
-        public boolean equals(Object obj) {
-            if (this == obj) {
-                return true;
-            }
-            if (obj instanceof IPEcnCriterion) {
-                IPEcnCriterion that = (IPEcnCriterion) obj;
-                return Objects.equals(ipEcn, that.ipEcn) &&
-                        Objects.equals(this.type(), that.type());
-            }
-            return false;
-        }
-    }
-
-    /**
-     * Implementation of Internet Protocol Number criterion (8 bits unsigned)
-     * integer.
-     */
-    public static final class IPProtocolCriterion implements Criterion {
-        private static final short MASK = 0xff;
-        private final short proto;      // IP protocol number: 8 bits
-
-        /**
-         * Constructor.
-         *
-         * @param protocol the IP protocol (e.g., TCP=6, UDP=17) to match
-         * (8 bits unsigned integer)
-         */
-        public IPProtocolCriterion(short protocol) {
-            this.proto = (short) (protocol & MASK);
-        }
-
-        @Override
-        public Type type() {
-            return Type.IP_PROTO;
-        }
-
-        /**
-         * Gets the IP protocol to match.
-         *
-         * @return the IP protocol to match (8 bits unsigned integer)
-         */
-        public short protocol() {
-            return proto;
-        }
-
-        @Override
-        public String toString() {
-            return toStringHelper(type().toString())
-                    .add("protocol", proto).toString();
-        }
-
-        @Override
-        public int hashCode() {
-            return Objects.hash(type(), proto);
-        }
-
-        @Override
-        public boolean equals(Object obj) {
-            if (this == obj) {
-                return true;
-            }
-            if (obj instanceof IPProtocolCriterion) {
-                IPProtocolCriterion that = (IPProtocolCriterion) obj;
-                return Objects.equals(proto, that.proto);
-            }
-            return false;
-        }
-    }
-
-    /**
-     * Implementation of IP address criterion.
-     */
-    public static final class IPCriterion implements Criterion {
-        private final IpPrefix ip;
-        private final Type type;
-
-        /**
-         * Constructor.
-         *
-         * @param ip the IP prefix to match. Could be either IPv4 or IPv6
-         * @param type the match type. Should be one of the following:
-         * Type.IPV4_SRC, Type.IPV4_DST, Type.IPV6_SRC, Type.IPV6_DST
-         */
-        public IPCriterion(IpPrefix ip, Type type) {
-            this.ip = ip;
-            this.type = type;
-        }
-
-        @Override
-        public Type type() {
-            return this.type;
-        }
-
-        /**
-         * Gets the IP prefix to match.
-         *
-         * @return the IP prefix to match
-         */
-        public IpPrefix ip() {
-            return this.ip;
-        }
-
-        @Override
-        public String toString() {
-            return toStringHelper(type().toString())
-                    .add("ip", ip).toString();
-        }
-
-        @Override
-        public int hashCode() {
-            return Objects.hash(type, ip);
-        }
-
-        @Override
-        public boolean equals(Object obj) {
-            if (this == obj) {
-                return true;
-            }
-            if (obj instanceof IPCriterion) {
-                IPCriterion that = (IPCriterion) obj;
-                return Objects.equals(ip, that.ip) &&
-                        Objects.equals(type, that.type);
-            }
-            return false;
-        }
-    }
-
-    /**
-     * Implementation of TCP port criterion (16 bits unsigned integer).
-     */
-    public static final class TcpPortCriterion implements Criterion {
-        private static final int MASK = 0xffff;
-        private final int tcpPort;              // Port value: 16 bits
-        private final Type type;
-
-        /**
-         * Constructor.
-         *
-         * @param tcpPort the TCP port to match (16 bits unsigned integer)
-         * @param type the match type. Should be either Type.TCP_SRC or
-         * Type.TCP_DST
-         */
-        public TcpPortCriterion(int tcpPort, Type type) {
-            this.tcpPort = tcpPort & MASK;
-            this.type = type;
-        }
-
-        @Override
-        public Type type() {
-            return this.type;
-        }
-
-        /**
-         * Gets the TCP port to match.
-         *
-         * @return the TCP port to match (16 bits unsigned integer)
-         */
-        public int tcpPort() {
-            return this.tcpPort;
-        }
-
-        @Override
-        public String toString() {
-            return toStringHelper(type().toString())
-                .add("tcpPort", tcpPort).toString();
-        }
-
-        @Override
-        public int hashCode() {
-            return Objects.hash(type, tcpPort);
-        }
-
-        @Override
-        public boolean equals(Object obj) {
-            if (this == obj) {
-                return true;
-            }
-            if (obj instanceof TcpPortCriterion) {
-                TcpPortCriterion that = (TcpPortCriterion) obj;
-                return Objects.equals(tcpPort, that.tcpPort) &&
-                        Objects.equals(type, that.type);
-            }
-            return false;
-        }
-    }
-
-    /**
-     * Implementation of UDP port criterion (16 bits unsigned integer).
-     */
-    public static final class UdpPortCriterion implements Criterion {
-        private static final int MASK = 0xffff;
-        private final int udpPort;              // Port value: 16 bits
-        private final Type type;
-
-        /**
-         * Constructor.
-         *
-         * @param udpPort the UDP port to match (16 bits unsigned integer)
-         * @param type the match type. Should be either Type.UDP_SRC or
-         * Type.UDP_DST
-         */
-        public UdpPortCriterion(int udpPort, Type type) {
-            this.udpPort = udpPort & MASK;
-            this.type = type;
-        }
-
-        @Override
-        public Type type() {
-            return this.type;
-        }
-
-        /**
-         * Gets the UDP port to match.
-         *
-         * @return the UDP port to match (16 bits unsigned integer)
-         */
-        public int udpPort() {
-            return this.udpPort;
-        }
-
-        @Override
-        public String toString() {
-            return toStringHelper(type().toString())
-                .add("udpPort", udpPort).toString();
-        }
-
-        @Override
-        public int hashCode() {
-            return Objects.hash(type, udpPort);
-        }
-
-        @Override
-        public boolean equals(Object obj) {
-            if (this == obj) {
-                return true;
-            }
-            if (obj instanceof UdpPortCriterion) {
-                UdpPortCriterion that = (UdpPortCriterion) obj;
-                return Objects.equals(udpPort, that.udpPort) &&
-                        Objects.equals(type, that.type);
-            }
-            return false;
-        }
-    }
-
-    /**
-     * Implementation of SCTP port criterion (16 bits unsigned integer).
-     */
-    public static final class SctpPortCriterion implements Criterion {
-        private static final int MASK = 0xffff;
-        private final int sctpPort;             // Port value: 16 bits
-        private final Type type;
-
-        /**
-         * Constructor.
-         *
-         * @param sctpPort the SCTP port to match (16 bits unsigned integer)
-         * @param type the match type. Should be either Type.SCTP_SRC or
-         * Type.SCTP_DST
-         */
-        public SctpPortCriterion(int sctpPort, Type type) {
-            this.sctpPort = sctpPort & MASK;
-            this.type = type;
-        }
-
-        @Override
-        public Type type() {
-            return this.type;
-        }
-
-        /**
-         * Gets the SCTP port to match.
-         *
-         * @return the SCTP port to match (16 bits unsigned integer)
-         */
-        public int sctpPort() {
-            return this.sctpPort;
-        }
-
-        @Override
-        public String toString() {
-            return toStringHelper(type().toString())
-                .add("sctpPort", sctpPort).toString();
-        }
-
-        @Override
-        public int hashCode() {
-            return Objects.hash(type, sctpPort);
-        }
-
-        @Override
-        public boolean equals(Object obj) {
-            if (this == obj) {
-                return true;
-            }
-            if (obj instanceof SctpPortCriterion) {
-                SctpPortCriterion that = (SctpPortCriterion) obj;
-                return Objects.equals(sctpPort, that.sctpPort) &&
-                        Objects.equals(type, that.type);
-            }
-            return false;
-        }
-    }
-
-    /**
-     * Implementation of ICMP type criterion (8 bits unsigned integer).
-     */
-    public static final class IcmpTypeCriterion implements Criterion {
-        private static final short MASK = 0xff;
-        private final short icmpType;           // The ICMP type: 8 bits
-
-        /**
-         * Constructor.
-         *
-         * @param icmpType the ICMP type to match (8 bits unsigned integer)
-         */
-        public IcmpTypeCriterion(short icmpType) {
-            this.icmpType = (short) (icmpType & MASK);
-        }
-
-        @Override
-        public Type type() {
-            return Type.ICMPV4_TYPE;
-        }
-
-        /**
-         * Gets the ICMP type to match.
-         *
-         * @return the ICMP type to match (8 bits unsigned integer)
-         */
-        public short icmpType() {
-            return icmpType;
-        }
-
-        @Override
-        public String toString() {
-            return toStringHelper(type().toString())
-                .add("icmpType", icmpType).toString();
-        }
-
-        @Override
-        public int hashCode() {
-            return Objects.hash(type(), icmpType);
-        }
-
-        @Override
-        public boolean equals(Object obj) {
-            if (this == obj) {
-                return true;
-            }
-            if (obj instanceof IcmpTypeCriterion) {
-                IcmpTypeCriterion that = (IcmpTypeCriterion) obj;
-                return Objects.equals(icmpType, that.icmpType) &&
-                        Objects.equals(this.type(), that.type());
-            }
-            return false;
-        }
-    }
-
-    /**
-     * Implementation of ICMP code criterion (8 bits unsigned integer).
-     */
-    public static final class IcmpCodeCriterion implements Criterion {
-        private static final short MASK = 0xff;
-        private final short icmpCode;           // The ICMP code: 8 bits
-
-        /**
-         * Constructor.
-         *
-         * @param icmpCode the ICMP code to match (8 bits unsigned integer)
-         */
-        public IcmpCodeCriterion(short icmpCode) {
-            this.icmpCode = (short) (icmpCode & MASK);
-        }
-
-        @Override
-        public Type type() {
-            return Type.ICMPV4_CODE;
-        }
-
-        /**
-         * Gets the ICMP code to match.
-         *
-         * @return the ICMP code to match (8 bits unsigned integer)
-         */
-        public short icmpCode() {
-            return icmpCode;
-        }
-
-        @Override
-        public String toString() {
-            return toStringHelper(type().toString())
-                .add("icmpCode", icmpCode).toString();
-        }
-
-        @Override
-        public int hashCode() {
-            return Objects.hash(type(), icmpCode);
-        }
-
-        @Override
-        public boolean equals(Object obj) {
-            if (this == obj) {
-                return true;
-            }
-            if (obj instanceof IcmpCodeCriterion) {
-                IcmpCodeCriterion that = (IcmpCodeCriterion) obj;
-                return Objects.equals(icmpCode, that.icmpCode) &&
-                        Objects.equals(this.type(), that.type());
-            }
-            return false;
-        }
-    }
-
-    /**
-     * Implementation of IPv6 Flow Label (RFC 6437) criterion (20 bits unsigned
-     * integer).
-     */
-    public static final class IPv6FlowLabelCriterion implements Criterion {
-        private static final int MASK = 0xfffff;
-        private final int flowLabel;            // IPv6 flow label: 20 bits
-
-        /**
-         * Constructor.
-         *
-         * @param flowLabel the IPv6 flow label to match (20 bits)
-         */
-        public IPv6FlowLabelCriterion(int flowLabel) {
-            this.flowLabel = flowLabel & MASK;
-        }
-
-        @Override
-        public Type type() {
-            return Type.IPV6_FLABEL;
-        }
-
-        /**
-         * Gets the IPv6 flow label to match.
-         *
-         * @return the IPv6 flow label to match (20 bits)
-         */
-        public int flowLabel() {
-            return flowLabel;
-        }
-
-        @Override
-        public String toString() {
-            return toStringHelper(type().toString())
-                .add("flowLabel", Long.toHexString(flowLabel)).toString();
-        }
-
-        @Override
-        public int hashCode() {
-            return Objects.hash(type(), flowLabel);
-        }
-
-        @Override
-        public boolean equals(Object obj) {
-            if (this == obj) {
-                return true;
-            }
-            if (obj instanceof IPv6FlowLabelCriterion) {
-                IPv6FlowLabelCriterion that = (IPv6FlowLabelCriterion) obj;
-                return Objects.equals(flowLabel, that.flowLabel) &&
-                        Objects.equals(this.type(), that.type());
-            }
-            return false;
-        }
-    }
-
-    /**
-     * Implementation of ICMPv6 type criterion (8 bits unsigned integer).
-     */
-    public static final class Icmpv6TypeCriterion implements Criterion {
-        private static final short MASK = 0xff;
-        private final short icmpv6Type;         // ICMPv6 type: 8 bits
-
-        /**
-         * Constructor.
-         *
-         * @param icmpv6Type the ICMPv6 type to match (8 bits unsigned integer)
-         */
-        public Icmpv6TypeCriterion(short icmpv6Type) {
-            this.icmpv6Type = (short) (icmpv6Type & MASK);
-        }
-
-        @Override
-        public Type type() {
-            return Type.ICMPV6_TYPE;
-        }
-
-        /**
-         * Gets the ICMPv6 type to match.
-         *
-         * @return the ICMPv6 type to match (8 bits unsigned integer)
-         */
-        public short icmpv6Type() {
-            return icmpv6Type;
-        }
-
-        @Override
-        public String toString() {
-            return toStringHelper(type().toString())
-                .add("icmpv6Type", icmpv6Type).toString();
-        }
-
-        @Override
-        public int hashCode() {
-            return Objects.hash(type(), icmpv6Type);
-        }
-
-        @Override
-        public boolean equals(Object obj) {
-            if (this == obj) {
-                return true;
-            }
-            if (obj instanceof Icmpv6TypeCriterion) {
-                Icmpv6TypeCriterion that = (Icmpv6TypeCriterion) obj;
-                return Objects.equals(icmpv6Type, that.icmpv6Type) &&
-                        Objects.equals(this.type(), that.type());
-            }
-            return false;
-        }
-    }
-
-    /**
-     * Implementation of ICMPv6 code criterion (8 bits unsigned integer).
-     */
-    public static final class Icmpv6CodeCriterion implements Criterion {
-        private static final short MASK = 0xff;
-        private final short icmpv6Code;         // ICMPv6 code: 8 bits
-
-        /**
-         * Constructor.
-         *
-         * @param icmpv6Code the ICMPv6 code to match (8 bits unsigned integer)
-         */
-        public Icmpv6CodeCriterion(short icmpv6Code) {
-            this.icmpv6Code = (short) (icmpv6Code & MASK);
-        }
-
-        @Override
-        public Type type() {
-            return Type.ICMPV6_CODE;
-        }
-
-        /**
-         * Gets the ICMPv6 code to match.
-         *
-         * @return the ICMPv6 code to match (8 bits unsigned integer)
-         */
-        public short icmpv6Code() {
-            return icmpv6Code;
-        }
-
-        @Override
-        public String toString() {
-            return toStringHelper(type().toString())
-                .add("icmpv6Code", icmpv6Code).toString();
-        }
-
-        @Override
-        public int hashCode() {
-            return Objects.hash(type(), icmpv6Code);
-        }
-
-        @Override
-        public boolean equals(Object obj) {
-            if (this == obj) {
-                return true;
-            }
-            if (obj instanceof Icmpv6CodeCriterion) {
-                Icmpv6CodeCriterion that = (Icmpv6CodeCriterion) obj;
-                return Objects.equals(icmpv6Code, that.icmpv6Code) &&
-                        Objects.equals(this.type(), that.type());
-            }
-            return false;
-        }
-    }
-
-    /**
-     * Implementation of IPv6 Neighbor Discovery target address criterion.
-     */
-    public static final class IPv6NDTargetAddressCriterion
-                                implements Criterion {
-        private final Ip6Address targetAddress;
-
-        /**
-         * Constructor.
-         *
-         * @param targetAddress the IPv6 target address to match
-         */
-        public IPv6NDTargetAddressCriterion(Ip6Address targetAddress) {
-            this.targetAddress = targetAddress;
-        }
-
-        @Override
-        public Type type() {
-            return Type.IPV6_ND_TARGET;
-        }
-
-        /**
-         * Gets the IPv6 target address to match.
-         *
-         * @return the IPv6 target address to match
-         */
-        public Ip6Address targetAddress() {
-            return this.targetAddress;
-        }
-
-        @Override
-        public String toString() {
-            return toStringHelper(type().toString())
-                    .add("targetAddress", targetAddress).toString();
-        }
-
-        @Override
-        public int hashCode() {
-            return Objects.hash(type(), targetAddress);
-        }
-
-        @Override
-        public boolean equals(Object obj) {
-            if (this == obj) {
-                return true;
-            }
-            if (obj instanceof IPv6NDTargetAddressCriterion) {
-                IPv6NDTargetAddressCriterion that =
-                    (IPv6NDTargetAddressCriterion) obj;
-                return Objects.equals(targetAddress, that.targetAddress) &&
-                        Objects.equals(type(), that.type());
-            }
-            return false;
-        }
-    }
-
-    /**
-     * Implementation of IPv6 Neighbor Discovery link-layer address criterion.
-     */
-    public static final class IPv6NDLinkLayerAddressCriterion
-                                implements Criterion {
-        private final MacAddress mac;
-        private final Type type;
-
-        /**
-         * Constructor.
-         *
-         * @param mac the source or destination link-layer address to match
-         * @param type the match type. Should be either Type.IPV6_ND_SLL or
-         * Type.IPV6_ND_TLL
-         */
-        public IPv6NDLinkLayerAddressCriterion(MacAddress mac, Type type) {
-            this.mac = mac;
-            this.type = type;
-        }
-
-        @Override
-        public Type type() {
-            return this.type;
-        }
-
-        /**
-         * Gets the MAC link-layer address to match.
-         *
-         * @return the MAC link-layer address to match
-         */
-        public MacAddress mac() {
-            return this.mac;
-        }
-
-        @Override
-        public String toString() {
-            return toStringHelper(type().toString())
-                    .add("mac", mac).toString();
-        }
-
-        @Override
-        public int hashCode() {
-            return Objects.hash(type, mac);
-        }
-
-        @Override
-        public boolean equals(Object obj) {
-            if (this == obj) {
-                return true;
-            }
-            if (obj instanceof IPv6NDLinkLayerAddressCriterion) {
-                IPv6NDLinkLayerAddressCriterion that =
-                    (IPv6NDLinkLayerAddressCriterion) obj;
-                return Objects.equals(mac, that.mac) &&
-                        Objects.equals(type, that.type);
-            }
-            return false;
-        }
-    }
-
-    /**
-     * Implementation of MPLS tag criterion (20 bits).
-     */
-    public static final class MplsCriterion implements Criterion {
-        private static final int MASK = 0xfffff;
-        private final MplsLabel mplsLabel;
-
-        public MplsCriterion(MplsLabel mplsLabel) {
-            this.mplsLabel = mplsLabel;
-        }
-
-        @Override
-        public Type type() {
-            return Type.MPLS_LABEL;
-        }
-
-        public MplsLabel label() {
-            return mplsLabel;
-        }
-
-        @Override
-        public String toString() {
-            return toStringHelper(type().toString())
-                    .add("mpls", mplsLabel).toString();
-        }
-
-        @Override
-        public int hashCode() {
-            return Objects.hash(type(), mplsLabel);
-        }
-
-        @Override
-        public boolean equals(Object obj) {
-            if (this == obj) {
-                return true;
-            }
-            if (obj instanceof MplsCriterion) {
-                MplsCriterion that = (MplsCriterion) obj;
-                return Objects.equals(mplsLabel, that.mplsLabel) &&
-                        Objects.equals(this.type(), that.type());
-            }
-            return false;
-        }
-    }
-
-    /**
-     * Implementation of IPv6 Extension Header pseudo-field criterion
-     * (16 bits). Those are defined in Criterion.IPv6ExthdrFlags.
-     */
-    public static final class IPv6ExthdrFlagsCriterion implements Criterion {
-        private static final int MASK = 0xffff;
-        private final int exthdrFlags;          // IPv6 Exthdr flags: 16 bits
-
-        /**
-         * Constructor.
-         *
-         * @param exthdrFlags the IPv6 Extension Header pseudo-field flags
-         * to match (16 bits). Those are defined in Criterion.IPv6ExthdrFlags
-         */
-        public IPv6ExthdrFlagsCriterion(int exthdrFlags) {
-            this.exthdrFlags = exthdrFlags & MASK;
-        }
-
-        @Override
-        public Type type() {
-            return Type.IPV6_EXTHDR;
-        }
-
-        /**
-         * Gets the IPv6 Extension Header pseudo-field flags to match.
-         *
-         * @return the IPv6 Extension Header pseudo-field flags to match
-         * (16 bits). Those are defined in Criterion.IPv6ExthdrFlags
-         */
-        public int exthdrFlags() {
-            return exthdrFlags;
-        }
-
-        @Override
-        public String toString() {
-            return toStringHelper(type().toString())
-                .add("exthdrFlags", Long.toHexString(exthdrFlags)).toString();
-        }
-
-        @Override
-        public int hashCode() {
-            return Objects.hash(type(), exthdrFlags);
-        }
-
-        @Override
-        public boolean equals(Object obj) {
-            if (this == obj) {
-                return true;
-            }
-            if (obj instanceof IPv6ExthdrFlagsCriterion) {
-                IPv6ExthdrFlagsCriterion that = (IPv6ExthdrFlagsCriterion) obj;
-                return Objects.equals(exthdrFlags, that.exthdrFlags) &&
-                        Objects.equals(this.type(), that.type());
-            }
-            return false;
-        }
-    }
-
-    /**
-     * Implementation of lambda (wavelength) criterion (16 bits unsigned
-     * integer).
-     */
-    public static final class LambdaCriterion implements Criterion {
-        private static final int MASK = 0xffff;
-        private final int lambda;               // Lambda value: 16 bits
-        private final Type type;
-
-        /**
-         * Constructor.
-         *
-         * @param lambda the lambda (wavelength) to match (16 bits unsigned
-         * integer)
-         * @param type the match type. Should be Type.OCH_SIGID
-         */
-        public LambdaCriterion(int lambda, Type type) {
-            this.lambda = lambda & MASK;
-            this.type = type;
-        }
-
-        @Override
-        public Type type() {
-            return this.type;
-        }
-
-        /**
-         * Gets the lambda (wavelength) to match.
-         *
-         * @return the lambda (wavelength) to match (16 bits unsigned integer)
-         */
-        public int lambda() {
-            return lambda;
-        }
-
-        @Override
-        public String toString() {
-            return toStringHelper(type().toString())
-                .add("lambda", lambda).toString();
-        }
-
-        @Override
-        public int hashCode() {
-            return Objects.hash(type, lambda);
-        }
-
-        @Override
-        public boolean equals(Object obj) {
-            if (this == obj) {
-                return true;
-            }
-            if (obj instanceof LambdaCriterion) {
-                LambdaCriterion that = (LambdaCriterion) obj;
-                return Objects.equals(lambda, that.lambda) &&
-                        Objects.equals(type, that.type);
-            }
-            return false;
-        }
-    }
-
-    /**
-     * Implementation of optical signal type criterion (8 bits unsigned
-     * integer).
-     */
-    public static final class OpticalSignalTypeCriterion implements Criterion {
-        private static final short MASK = 0xff;
-        private final short signalType;         // Signal type value: 8 bits
-        private final Type type;
-
-        /**
-         * Constructor.
-         *
-         * @param signalType the optical signal type to match (8 bits unsigned
-         * integer)
-         * @param type the match type. Should be Type.OCH_SIGTYPE
-         */
-        public OpticalSignalTypeCriterion(short signalType, Type type) {
-            this.signalType = (short) (signalType & MASK);
-            this.type = type;
-        }
-
-        @Override
-        public Type type() {
-            return this.type;
-        }
-
-        /**
-         * Gets the optical signal type to match.
-         *
-         * @return the optical signal type to match (8 bits unsigned integer)
-         */
-        public short signalType() {
-            return signalType;
-        }
-
-        @Override
-        public String toString() {
-            return toStringHelper(type().toString())
-                .add("signalType", signalType).toString();
-        }
-
-        @Override
-        public int hashCode() {
-            return Objects.hash(type, signalType);
-        }
-
-        @Override
-        public boolean equals(Object obj) {
-            if (this == obj) {
-                return true;
-            }
-            if (obj instanceof OpticalSignalTypeCriterion) {
-                OpticalSignalTypeCriterion that = (OpticalSignalTypeCriterion) obj;
-                return Objects.equals(signalType, that.signalType) &&
-                        Objects.equals(type, that.type);
-            }
-            return false;
-        }
-    }
-
-    /**
      * Dummy Criterion used with @see{FilteringObjective}.
      */
     private static class DummyCriterion implements Criterion {
diff --git a/core/api/src/main/java/org/onosproject/net/flow/criteria/EthCriterion.java b/core/api/src/main/java/org/onosproject/net/flow/criteria/EthCriterion.java
new file mode 100644
index 0000000..b73e58b
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/flow/criteria/EthCriterion.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.net.flow.criteria;
+
+import org.onlab.packet.MacAddress;
+
+import java.util.Objects;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+
+/**
+ * Implementation of MAC address criterion.
+ */
+public final class EthCriterion implements Criterion {
+    private final MacAddress mac;
+    private final Type type;
+
+    /**
+     * Constructor.
+     *
+     * @param mac the source or destination MAC address to match
+     * @param type the match type. Should be either Type.ETH_DST or
+     * Type.ETH_SRC
+     */
+    EthCriterion(MacAddress mac, Type type) {
+        this.mac = mac;
+        this.type = type;
+    }
+
+    @Override
+    public Type type() {
+        return this.type;
+    }
+
+    /**
+     * Gets the MAC address to match.
+     *
+     * @return the MAC address to match
+     */
+    public MacAddress mac() {
+        return this.mac;
+    }
+
+    @Override
+    public String toString() {
+        return toStringHelper(type().toString())
+                .add("mac", mac).toString();
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(type, mac);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof EthCriterion) {
+            EthCriterion that = (EthCriterion) obj;
+            return Objects.equals(mac, that.mac) &&
+                    Objects.equals(type, that.type);
+        }
+        return false;
+    }
+}
diff --git a/core/api/src/main/java/org/onosproject/net/flow/criteria/EthTypeCriterion.java b/core/api/src/main/java/org/onosproject/net/flow/criteria/EthTypeCriterion.java
new file mode 100644
index 0000000..22ab445
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/flow/criteria/EthTypeCriterion.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.net.flow.criteria;
+
+import java.util.Objects;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+
+/**
+ * Implementation of Ethernet type criterion (16 bits unsigned integer).
+ */
+public final class EthTypeCriterion implements Criterion {
+    private static final int MASK = 0xffff;
+    private final int ethType;              // Ethernet type value: 16 bits
+
+    /**
+     * Constructor.
+     *
+     * @param ethType the Ethernet frame type to match (16 bits unsigned
+     * integer)
+     */
+    EthTypeCriterion(int ethType) {
+        this.ethType = ethType & MASK;
+    }
+
+    @Override
+    public Type type() {
+        return Type.ETH_TYPE;
+    }
+
+    /**
+     * Gets the Ethernet frame type to match.
+     *
+     * @return the Ethernet frame type to match (16 bits unsigned integer)
+     */
+    public int ethType() {
+        return ethType;
+    }
+
+    @Override
+    public String toString() {
+        return toStringHelper(type().toString())
+                .add("ethType", Long.toHexString(ethType))
+                .toString();
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(type(), ethType);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof EthTypeCriterion) {
+            EthTypeCriterion that = (EthTypeCriterion) obj;
+            return Objects.equals(ethType, that.ethType) &&
+                    Objects.equals(this.type(), that.type());
+        }
+        return false;
+    }
+}
diff --git a/core/api/src/main/java/org/onosproject/net/flow/criteria/IPCriterion.java b/core/api/src/main/java/org/onosproject/net/flow/criteria/IPCriterion.java
new file mode 100644
index 0000000..bf67d1a
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/flow/criteria/IPCriterion.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.net.flow.criteria;
+
+import org.onlab.packet.IpPrefix;
+
+import java.util.Objects;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+
+/**
+ * Implementation of IP address criterion.
+ */
+public final class IPCriterion implements Criterion {
+    private final IpPrefix ip;
+    private final Type type;
+
+    /**
+     * Constructor.
+     *
+     * @param ip the IP prefix to match. Could be either IPv4 or IPv6
+     * @param type the match type. Should be one of the following:
+     * Type.IPV4_SRC, Type.IPV4_DST, Type.IPV6_SRC, Type.IPV6_DST
+     */
+    IPCriterion(IpPrefix ip, Type type) {
+        this.ip = ip;
+        this.type = type;
+    }
+
+    @Override
+    public Type type() {
+        return this.type;
+    }
+
+    /**
+     * Gets the IP prefix to match.
+     *
+     * @return the IP prefix to match
+     */
+    public IpPrefix ip() {
+        return this.ip;
+    }
+
+    @Override
+    public String toString() {
+        return toStringHelper(type().toString())
+                .add("ip", ip).toString();
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(type, ip);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof IPCriterion) {
+            IPCriterion that = (IPCriterion) obj;
+            return Objects.equals(ip, that.ip) &&
+                    Objects.equals(type, that.type);
+        }
+        return false;
+    }
+}
diff --git a/core/api/src/main/java/org/onosproject/net/flow/criteria/IPDscpCriterion.java b/core/api/src/main/java/org/onosproject/net/flow/criteria/IPDscpCriterion.java
new file mode 100644
index 0000000..86d04c9
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/flow/criteria/IPDscpCriterion.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.net.flow.criteria;
+
+import java.util.Objects;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+
+/**
+ * Implementation of IP DSCP (Differentiated Services Code Point)
+ * criterion (6 bits).
+ */
+public final class IPDscpCriterion implements Criterion {
+    private static final byte MASK = 0x3f;
+    private final byte ipDscp;              // IP DSCP value: 6 bits
+
+    /**
+     * Constructor.
+     *
+     * @param ipDscp the IP DSCP value to match
+     */
+    IPDscpCriterion(byte ipDscp) {
+        this.ipDscp = (byte) (ipDscp & MASK);
+    }
+
+    @Override
+    public Type type() {
+        return Type.IP_DSCP;
+    }
+
+    /**
+     * Gets the IP DSCP value to match.
+     *
+     * @return the IP DSCP value to match
+     */
+    public byte ipDscp() {
+        return ipDscp;
+    }
+
+    @Override
+    public String toString() {
+        return toStringHelper(type().toString())
+            .add("ipDscp", Long.toHexString(ipDscp)).toString();
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(type(), ipDscp);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof IPDscpCriterion) {
+            IPDscpCriterion that = (IPDscpCriterion) obj;
+            return Objects.equals(ipDscp, that.ipDscp) &&
+                    Objects.equals(this.type(), that.type());
+        }
+        return false;
+    }
+}
diff --git a/core/api/src/main/java/org/onosproject/net/flow/criteria/IPEcnCriterion.java b/core/api/src/main/java/org/onosproject/net/flow/criteria/IPEcnCriterion.java
new file mode 100644
index 0000000..d403955
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/flow/criteria/IPEcnCriterion.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.net.flow.criteria;
+
+import java.util.Objects;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+
+/**
+ * Implementation of IP ECN (Explicit Congestion Notification) criterion
+ * (2 bits).
+ */
+public final class IPEcnCriterion implements Criterion {
+    private static final byte MASK = 0x3;
+    private final byte ipEcn;               // IP ECN value: 2 bits
+
+    /**
+     * Constructor.
+     *
+     * @param ipEcn the IP ECN value to match (2 bits)
+     */
+    IPEcnCriterion(byte ipEcn) {
+        this.ipEcn = (byte) (ipEcn & MASK);
+    }
+
+    @Override
+    public Type type() {
+        return Type.IP_ECN;
+    }
+
+    /**
+     * Gets the IP ECN value to match.
+     *
+     * @return the IP ECN value to match (2 bits)
+     */
+    public byte ipEcn() {
+        return ipEcn;
+    }
+
+    @Override
+    public String toString() {
+        return toStringHelper(type().toString())
+            .add("ipEcn", Long.toHexString(ipEcn)).toString();
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(type(), ipEcn);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof IPEcnCriterion) {
+            IPEcnCriterion that = (IPEcnCriterion) obj;
+            return Objects.equals(ipEcn, that.ipEcn) &&
+                    Objects.equals(this.type(), that.type());
+        }
+        return false;
+    }
+}
diff --git a/core/api/src/main/java/org/onosproject/net/flow/criteria/IPProtocolCriterion.java b/core/api/src/main/java/org/onosproject/net/flow/criteria/IPProtocolCriterion.java
new file mode 100644
index 0000000..3457e0f
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/flow/criteria/IPProtocolCriterion.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.net.flow.criteria;
+
+import java.util.Objects;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+
+/**
+ * Implementation of Internet Protocol Number criterion (8 bits unsigned)
+ * integer.
+ */
+public final class IPProtocolCriterion implements Criterion {
+    private static final short MASK = 0xff;
+    private final short proto;      // IP protocol number: 8 bits
+
+    /**
+     * Constructor.
+     *
+     * @param protocol the IP protocol (e.g., TCP=6, UDP=17) to match
+     * (8 bits unsigned integer)
+     */
+    IPProtocolCriterion(short protocol) {
+        this.proto = (short) (protocol & MASK);
+    }
+
+    @Override
+    public Type type() {
+        return Type.IP_PROTO;
+    }
+
+    /**
+     * Gets the IP protocol to match.
+     *
+     * @return the IP protocol to match (8 bits unsigned integer)
+     */
+    public short protocol() {
+        return proto;
+    }
+
+    @Override
+    public String toString() {
+        return toStringHelper(type().toString())
+                .add("protocol", proto).toString();
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(type(), proto);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof IPProtocolCriterion) {
+            IPProtocolCriterion that = (IPProtocolCriterion) obj;
+            return Objects.equals(proto, that.proto);
+        }
+        return false;
+    }
+}
diff --git a/core/api/src/main/java/org/onosproject/net/flow/criteria/IPv6ExthdrFlagsCriterion.java b/core/api/src/main/java/org/onosproject/net/flow/criteria/IPv6ExthdrFlagsCriterion.java
new file mode 100644
index 0000000..c9d7a3ce
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/flow/criteria/IPv6ExthdrFlagsCriterion.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.net.flow.criteria;
+
+import java.util.Objects;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+
+/**
+ * Implementation of IPv6 Extension Header pseudo-field criterion
+ * (16 bits). Those are defined in Criterion.IPv6ExthdrFlags.
+ */
+public final class IPv6ExthdrFlagsCriterion implements Criterion {
+    private static final int MASK = 0xffff;
+    private final int exthdrFlags;          // IPv6 Exthdr flags: 16 bits
+
+    /**
+     * Constructor.
+     *
+     * @param exthdrFlags the IPv6 Extension Header pseudo-field flags
+     * to match (16 bits). Those are defined in Criterion.IPv6ExthdrFlags
+     */
+    IPv6ExthdrFlagsCriterion(int exthdrFlags) {
+        this.exthdrFlags = exthdrFlags & MASK;
+    }
+
+    @Override
+    public Type type() {
+        return Type.IPV6_EXTHDR;
+    }
+
+    /**
+     * Gets the IPv6 Extension Header pseudo-field flags to match.
+     *
+     * @return the IPv6 Extension Header pseudo-field flags to match
+     * (16 bits). Those are defined in Criterion.IPv6ExthdrFlags
+     */
+    public int exthdrFlags() {
+        return exthdrFlags;
+    }
+
+    @Override
+    public String toString() {
+        return toStringHelper(type().toString())
+            .add("exthdrFlags", Long.toHexString(exthdrFlags)).toString();
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(type(), exthdrFlags);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof IPv6ExthdrFlagsCriterion) {
+            IPv6ExthdrFlagsCriterion that = (IPv6ExthdrFlagsCriterion) obj;
+            return Objects.equals(exthdrFlags, that.exthdrFlags) &&
+                    Objects.equals(this.type(), that.type());
+        }
+        return false;
+    }
+}
diff --git a/core/api/src/main/java/org/onosproject/net/flow/criteria/IPv6FlowLabelCriterion.java b/core/api/src/main/java/org/onosproject/net/flow/criteria/IPv6FlowLabelCriterion.java
new file mode 100644
index 0000000..4ac0194
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/flow/criteria/IPv6FlowLabelCriterion.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.net.flow.criteria;
+
+import java.util.Objects;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+
+/**
+ * Implementation of IPv6 Flow Label (RFC 6437) criterion (20 bits unsigned
+ * integer).
+ */
+public final class IPv6FlowLabelCriterion implements Criterion {
+    private static final int MASK = 0xfffff;
+    private final int flowLabel;            // IPv6 flow label: 20 bits
+
+    /**
+     * Constructor.
+     *
+     * @param flowLabel the IPv6 flow label to match (20 bits)
+     */
+    IPv6FlowLabelCriterion(int flowLabel) {
+        this.flowLabel = flowLabel & MASK;
+    }
+
+    @Override
+    public Type type() {
+        return Type.IPV6_FLABEL;
+    }
+
+    /**
+     * Gets the IPv6 flow label to match.
+     *
+     * @return the IPv6 flow label to match (20 bits)
+     */
+    public int flowLabel() {
+        return flowLabel;
+    }
+
+    @Override
+    public String toString() {
+        return toStringHelper(type().toString())
+            .add("flowLabel", Long.toHexString(flowLabel)).toString();
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(type(), flowLabel);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof IPv6FlowLabelCriterion) {
+            IPv6FlowLabelCriterion that = (IPv6FlowLabelCriterion) obj;
+            return Objects.equals(flowLabel, that.flowLabel) &&
+                    Objects.equals(this.type(), that.type());
+        }
+        return false;
+    }
+}
diff --git a/core/api/src/main/java/org/onosproject/net/flow/criteria/IPv6NDLinkLayerAddressCriterion.java b/core/api/src/main/java/org/onosproject/net/flow/criteria/IPv6NDLinkLayerAddressCriterion.java
new file mode 100644
index 0000000..bf72d15
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/flow/criteria/IPv6NDLinkLayerAddressCriterion.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.net.flow.criteria;
+
+import org.onlab.packet.MacAddress;
+
+import java.util.Objects;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+
+/**
+ * Implementation of IPv6 Neighbor Discovery link-layer address criterion.
+ */
+public final class IPv6NDLinkLayerAddressCriterion implements Criterion {
+    private final MacAddress mac;
+    private final Type type;
+
+    /**
+     * Constructor.
+     *
+     * @param mac the source or destination link-layer address to match
+     * @param type the match type. Should be either Type.IPV6_ND_SLL or
+     * Type.IPV6_ND_TLL
+     */
+    IPv6NDLinkLayerAddressCriterion(MacAddress mac, Type type) {
+        this.mac = mac;
+        this.type = type;
+    }
+
+    @Override
+    public Type type() {
+        return this.type;
+    }
+
+    /**
+     * Gets the MAC link-layer address to match.
+     *
+     * @return the MAC link-layer address to match
+     */
+    public MacAddress mac() {
+        return this.mac;
+    }
+
+    @Override
+    public String toString() {
+        return toStringHelper(type().toString())
+                .add("mac", mac).toString();
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(type, mac);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof IPv6NDLinkLayerAddressCriterion) {
+            IPv6NDLinkLayerAddressCriterion that =
+                (IPv6NDLinkLayerAddressCriterion) obj;
+            return Objects.equals(mac, that.mac) &&
+                    Objects.equals(type, that.type);
+        }
+        return false;
+    }
+}
diff --git a/core/api/src/main/java/org/onosproject/net/flow/criteria/IPv6NDTargetAddressCriterion.java b/core/api/src/main/java/org/onosproject/net/flow/criteria/IPv6NDTargetAddressCriterion.java
new file mode 100644
index 0000000..4c6d92d
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/flow/criteria/IPv6NDTargetAddressCriterion.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.net.flow.criteria;
+
+import org.onlab.packet.Ip6Address;
+
+import java.util.Objects;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+
+/**
+ * Implementation of IPv6 Neighbor Discovery target address criterion.
+ */
+public final class IPv6NDTargetAddressCriterion implements Criterion {
+    private final Ip6Address targetAddress;
+
+    /**
+     * Constructor.
+     *
+     * @param targetAddress the IPv6 target address to match
+     */
+    IPv6NDTargetAddressCriterion(Ip6Address targetAddress) {
+        this.targetAddress = targetAddress;
+    }
+
+    @Override
+    public Type type() {
+        return Type.IPV6_ND_TARGET;
+    }
+
+    /**
+     * Gets the IPv6 target address to match.
+     *
+     * @return the IPv6 target address to match
+     */
+    public Ip6Address targetAddress() {
+        return this.targetAddress;
+    }
+
+    @Override
+    public String toString() {
+        return toStringHelper(type().toString())
+                .add("targetAddress", targetAddress).toString();
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(type(), targetAddress);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof IPv6NDTargetAddressCriterion) {
+            IPv6NDTargetAddressCriterion that =
+                (IPv6NDTargetAddressCriterion) obj;
+            return Objects.equals(targetAddress, that.targetAddress) &&
+                    Objects.equals(type(), that.type());
+        }
+        return false;
+    }
+}
diff --git a/core/api/src/main/java/org/onosproject/net/flow/criteria/IcmpCodeCriterion.java b/core/api/src/main/java/org/onosproject/net/flow/criteria/IcmpCodeCriterion.java
new file mode 100644
index 0000000..4470eea
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/flow/criteria/IcmpCodeCriterion.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.net.flow.criteria;
+
+import java.util.Objects;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+
+/**
+ * Implementation of ICMP code criterion (8 bits unsigned integer).
+ */
+public final class IcmpCodeCriterion implements Criterion {
+    private static final short MASK = 0xff;
+    private final short icmpCode;           // The ICMP code: 8 bits
+
+    /**
+     * Constructor.
+     *
+     * @param icmpCode the ICMP code to match (8 bits unsigned integer)
+     */
+    IcmpCodeCriterion(short icmpCode) {
+        this.icmpCode = (short) (icmpCode & MASK);
+    }
+
+    @Override
+    public Type type() {
+        return Type.ICMPV4_CODE;
+    }
+
+    /**
+     * Gets the ICMP code to match.
+     *
+     * @return the ICMP code to match (8 bits unsigned integer)
+     */
+    public short icmpCode() {
+        return icmpCode;
+    }
+
+    @Override
+    public String toString() {
+        return toStringHelper(type().toString())
+            .add("icmpCode", icmpCode).toString();
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(type(), icmpCode);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof IcmpCodeCriterion) {
+            IcmpCodeCriterion that = (IcmpCodeCriterion) obj;
+            return Objects.equals(icmpCode, that.icmpCode) &&
+                    Objects.equals(this.type(), that.type());
+        }
+        return false;
+    }
+}
diff --git a/core/api/src/main/java/org/onosproject/net/flow/criteria/IcmpTypeCriterion.java b/core/api/src/main/java/org/onosproject/net/flow/criteria/IcmpTypeCriterion.java
new file mode 100644
index 0000000..f67c8f5
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/flow/criteria/IcmpTypeCriterion.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.net.flow.criteria;
+
+import java.util.Objects;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+
+/**
+ * Implementation of ICMP type criterion (8 bits unsigned integer).
+ */
+public final class IcmpTypeCriterion implements Criterion {
+    private static final short MASK = 0xff;
+    private final short icmpType;           // The ICMP type: 8 bits
+
+    /**
+     * Constructor.
+     *
+     * @param icmpType the ICMP type to match (8 bits unsigned integer)
+     */
+    IcmpTypeCriterion(short icmpType) {
+        this.icmpType = (short) (icmpType & MASK);
+    }
+
+    @Override
+    public Type type() {
+        return Type.ICMPV4_TYPE;
+    }
+
+    /**
+     * Gets the ICMP type to match.
+     *
+     * @return the ICMP type to match (8 bits unsigned integer)
+     */
+    public short icmpType() {
+        return icmpType;
+    }
+
+    @Override
+    public String toString() {
+        return toStringHelper(type().toString())
+            .add("icmpType", icmpType).toString();
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(type(), icmpType);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof IcmpTypeCriterion) {
+            IcmpTypeCriterion that = (IcmpTypeCriterion) obj;
+            return Objects.equals(icmpType, that.icmpType) &&
+                    Objects.equals(this.type(), that.type());
+        }
+        return false;
+    }
+}
diff --git a/core/api/src/main/java/org/onosproject/net/flow/criteria/Icmpv6CodeCriterion.java b/core/api/src/main/java/org/onosproject/net/flow/criteria/Icmpv6CodeCriterion.java
new file mode 100644
index 0000000..a510d7f
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/flow/criteria/Icmpv6CodeCriterion.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.net.flow.criteria;
+
+import java.util.Objects;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+
+/**
+ * Implementation of ICMPv6 code criterion (8 bits unsigned integer).
+ */
+public final class Icmpv6CodeCriterion implements Criterion {
+    private static final short MASK = 0xff;
+    private final short icmpv6Code;         // ICMPv6 code: 8 bits
+
+    /**
+     * Constructor.
+     *
+     * @param icmpv6Code the ICMPv6 code to match (8 bits unsigned integer)
+     */
+    Icmpv6CodeCriterion(short icmpv6Code) {
+        this.icmpv6Code = (short) (icmpv6Code & MASK);
+    }
+
+    @Override
+    public Type type() {
+        return Type.ICMPV6_CODE;
+    }
+
+    /**
+     * Gets the ICMPv6 code to match.
+     *
+     * @return the ICMPv6 code to match (8 bits unsigned integer)
+     */
+    public short icmpv6Code() {
+        return icmpv6Code;
+    }
+
+    @Override
+    public String toString() {
+        return toStringHelper(type().toString())
+            .add("icmpv6Code", icmpv6Code).toString();
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(type(), icmpv6Code);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof Icmpv6CodeCriterion) {
+            Icmpv6CodeCriterion that = (Icmpv6CodeCriterion) obj;
+            return Objects.equals(icmpv6Code, that.icmpv6Code) &&
+                    Objects.equals(this.type(), that.type());
+        }
+        return false;
+    }
+}
diff --git a/core/api/src/main/java/org/onosproject/net/flow/criteria/Icmpv6TypeCriterion.java b/core/api/src/main/java/org/onosproject/net/flow/criteria/Icmpv6TypeCriterion.java
new file mode 100644
index 0000000..7650244
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/flow/criteria/Icmpv6TypeCriterion.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.net.flow.criteria;
+
+import java.util.Objects;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+
+/**
+ * Implementation of ICMPv6 type criterion (8 bits unsigned integer).
+ */
+public final class Icmpv6TypeCriterion implements Criterion {
+    private static final short MASK = 0xff;
+    private final short icmpv6Type;         // ICMPv6 type: 8 bits
+
+    /**
+     * Constructor.
+     *
+     * @param icmpv6Type the ICMPv6 type to match (8 bits unsigned integer)
+     */
+    Icmpv6TypeCriterion(short icmpv6Type) {
+        this.icmpv6Type = (short) (icmpv6Type & MASK);
+    }
+
+    @Override
+    public Type type() {
+        return Type.ICMPV6_TYPE;
+    }
+
+    /**
+     * Gets the ICMPv6 type to match.
+     *
+     * @return the ICMPv6 type to match (8 bits unsigned integer)
+     */
+    public short icmpv6Type() {
+        return icmpv6Type;
+    }
+
+    @Override
+    public String toString() {
+        return toStringHelper(type().toString())
+            .add("icmpv6Type", icmpv6Type).toString();
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(type(), icmpv6Type);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof Icmpv6TypeCriterion) {
+            Icmpv6TypeCriterion that = (Icmpv6TypeCriterion) obj;
+            return Objects.equals(icmpv6Type, that.icmpv6Type) &&
+                    Objects.equals(this.type(), that.type());
+        }
+        return false;
+    }
+}
diff --git a/core/api/src/main/java/org/onosproject/net/flow/criteria/LambdaCriterion.java b/core/api/src/main/java/org/onosproject/net/flow/criteria/LambdaCriterion.java
new file mode 100644
index 0000000..c5752be
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/flow/criteria/LambdaCriterion.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.net.flow.criteria;
+
+import java.util.Objects;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+
+/**
+ * Implementation of lambda (wavelength) criterion (16 bits unsigned
+ * integer).
+ */
+public final class LambdaCriterion implements Criterion {
+    private static final int MASK = 0xffff;
+    private final int lambda;               // Lambda value: 16 bits
+    private final Type type;
+
+    /**
+     * Constructor.
+     *
+     * @param lambda the lambda (wavelength) to match (16 bits unsigned
+     * integer)
+     * @param type the match type. Should be Type.OCH_SIGID
+     */
+    LambdaCriterion(int lambda, Type type) {
+        this.lambda = lambda & MASK;
+        this.type = type;
+    }
+
+    @Override
+    public Type type() {
+        return this.type;
+    }
+
+    /**
+     * Gets the lambda (wavelength) to match.
+     *
+     * @return the lambda (wavelength) to match (16 bits unsigned integer)
+     */
+    public int lambda() {
+        return lambda;
+    }
+
+    @Override
+    public String toString() {
+        return toStringHelper(type().toString())
+            .add("lambda", lambda).toString();
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(type, lambda);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof LambdaCriterion) {
+            LambdaCriterion that = (LambdaCriterion) obj;
+            return Objects.equals(lambda, that.lambda) &&
+                    Objects.equals(type, that.type);
+        }
+        return false;
+    }
+}
diff --git a/core/api/src/main/java/org/onosproject/net/flow/criteria/MetadataCriterion.java b/core/api/src/main/java/org/onosproject/net/flow/criteria/MetadataCriterion.java
new file mode 100644
index 0000000..9957840
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/flow/criteria/MetadataCriterion.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.net.flow.criteria;
+
+import java.util.Objects;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+
+/**
+ * Implementation of Metadata criterion.
+ */
+public final class MetadataCriterion implements Criterion {
+    private final long metadata;
+
+    /**
+     * Constructor.
+     *
+     * @param metadata the metadata to match (64 bits data)
+     */
+    MetadataCriterion(long metadata) {
+        this.metadata = metadata;
+    }
+
+    @Override
+    public Type type() {
+        return Type.METADATA;
+    }
+
+    /**
+     * Gets the metadata to match.
+     *
+     * @return the metadata to match (64 bits data)
+     */
+    public long metadata() {
+        return metadata;
+    }
+
+    @Override
+    public String toString() {
+        return toStringHelper(type().toString())
+                .add("metadata", Long.toHexString(metadata))
+                .toString();
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(type(), metadata);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof MetadataCriterion) {
+            MetadataCriterion that = (MetadataCriterion) obj;
+            return Objects.equals(metadata, that.metadata) &&
+                    Objects.equals(this.type(), that.type());
+        }
+        return false;
+    }
+}
diff --git a/core/api/src/main/java/org/onosproject/net/flow/criteria/MplsCriterion.java b/core/api/src/main/java/org/onosproject/net/flow/criteria/MplsCriterion.java
new file mode 100644
index 0000000..e971965
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/flow/criteria/MplsCriterion.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.net.flow.criteria;
+
+import org.onlab.packet.MplsLabel;
+
+import java.util.Objects;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+
+/**
+ * Implementation of MPLS tag criterion (20 bits).
+ */
+public final class MplsCriterion implements Criterion {
+    private static final int MASK = 0xfffff;
+    private final MplsLabel mplsLabel;
+
+    MplsCriterion(MplsLabel mplsLabel) {
+        this.mplsLabel = mplsLabel;
+    }
+
+    @Override
+    public Type type() {
+        return Type.MPLS_LABEL;
+    }
+
+    public MplsLabel label() {
+        return mplsLabel;
+    }
+
+    @Override
+    public String toString() {
+        return toStringHelper(type().toString())
+                .add("mpls", mplsLabel).toString();
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(type(), mplsLabel);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof MplsCriterion) {
+            MplsCriterion that = (MplsCriterion) obj;
+            return Objects.equals(mplsLabel, that.mplsLabel) &&
+                    Objects.equals(this.type(), that.type());
+        }
+        return false;
+    }
+}
diff --git a/core/api/src/main/java/org/onosproject/net/flow/criteria/OpticalSignalTypeCriterion.java b/core/api/src/main/java/org/onosproject/net/flow/criteria/OpticalSignalTypeCriterion.java
new file mode 100644
index 0000000..6c24212
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/flow/criteria/OpticalSignalTypeCriterion.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.net.flow.criteria;
+
+import java.util.Objects;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+
+/**
+ * Implementation of optical signal type criterion (8 bits unsigned
+ * integer).
+ */
+public final class OpticalSignalTypeCriterion implements Criterion {
+    private static final short MASK = 0xff;
+    private final short signalType;         // Signal type value: 8 bits
+    private final Type type;
+
+    /**
+     * Constructor.
+     *
+     * @param signalType the optical signal type to match (8 bits unsigned
+     * integer)
+     * @param type the match type. Should be Type.OCH_SIGTYPE
+     */
+    OpticalSignalTypeCriterion(short signalType, Type type) {
+        this.signalType = (short) (signalType & MASK);
+        this.type = type;
+    }
+
+    @Override
+    public Type type() {
+        return this.type;
+    }
+
+    /**
+     * Gets the optical signal type to match.
+     *
+     * @return the optical signal type to match (8 bits unsigned integer)
+     */
+    public short signalType() {
+        return signalType;
+    }
+
+    @Override
+    public String toString() {
+        return toStringHelper(type().toString())
+            .add("signalType", signalType).toString();
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(type, signalType);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof OpticalSignalTypeCriterion) {
+            OpticalSignalTypeCriterion that = (OpticalSignalTypeCriterion) obj;
+            return Objects.equals(signalType, that.signalType) &&
+                    Objects.equals(type, that.type);
+        }
+        return false;
+    }
+}
diff --git a/core/api/src/main/java/org/onosproject/net/flow/criteria/PortCriterion.java b/core/api/src/main/java/org/onosproject/net/flow/criteria/PortCriterion.java
new file mode 100644
index 0000000..ec07536
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/flow/criteria/PortCriterion.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.net.flow.criteria;
+
+import org.onosproject.net.PortNumber;
+
+import java.util.Objects;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+
+/**
+ * Implementation of input port criterion.
+ */
+public final class PortCriterion implements Criterion {
+    private final PortNumber port;
+    private final Type type;
+
+    /**
+     * Constructor.
+     *
+     * @param port the input port number to match
+     * @param type the match type. Should be either Type.IN_PORT or
+     * Type.IN_PHY_PORT
+     */
+    PortCriterion(PortNumber port, Type type) {
+        this.port = port;
+        this.type = type;
+    }
+
+    @Override
+    public Type type() {
+        return this.type;
+    }
+
+    /**
+     * Gets the input port number to match.
+     *
+     * @return the input port number to match
+     */
+    public PortNumber port() {
+        return this.port;
+    }
+
+    @Override
+    public String toString() {
+        return toStringHelper(type().toString())
+                .add("port", port).toString();
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(type(), port);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof PortCriterion) {
+            PortCriterion that = (PortCriterion) obj;
+            return Objects.equals(port, that.port) &&
+                    Objects.equals(this.type(), that.type());
+        }
+        return false;
+    }
+}
diff --git a/core/api/src/main/java/org/onosproject/net/flow/criteria/SctpPortCriterion.java b/core/api/src/main/java/org/onosproject/net/flow/criteria/SctpPortCriterion.java
new file mode 100644
index 0000000..8e965c9
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/flow/criteria/SctpPortCriterion.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.net.flow.criteria;
+
+import java.util.Objects;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+
+/**
+ * Implementation of SCTP port criterion (16 bits unsigned integer).
+ */
+public final class SctpPortCriterion implements Criterion {
+    private static final int MASK = 0xffff;
+    private final int sctpPort;             // Port value: 16 bits
+    private final Type type;
+
+    /**
+     * Constructor.
+     *
+     * @param sctpPort the SCTP port to match (16 bits unsigned integer)
+     * @param type the match type. Should be either Type.SCTP_SRC or
+     * Type.SCTP_DST
+     */
+    SctpPortCriterion(int sctpPort, Type type) {
+        this.sctpPort = sctpPort & MASK;
+        this.type = type;
+    }
+
+    @Override
+    public Type type() {
+        return this.type;
+    }
+
+    /**
+     * Gets the SCTP port to match.
+     *
+     * @return the SCTP port to match (16 bits unsigned integer)
+     */
+    public int sctpPort() {
+        return this.sctpPort;
+    }
+
+    @Override
+    public String toString() {
+        return toStringHelper(type().toString())
+            .add("sctpPort", sctpPort).toString();
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(type, sctpPort);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof SctpPortCriterion) {
+            SctpPortCriterion that = (SctpPortCriterion) obj;
+            return Objects.equals(sctpPort, that.sctpPort) &&
+                    Objects.equals(type, that.type);
+        }
+        return false;
+    }
+}
diff --git a/core/api/src/main/java/org/onosproject/net/flow/criteria/TcpPortCriterion.java b/core/api/src/main/java/org/onosproject/net/flow/criteria/TcpPortCriterion.java
new file mode 100644
index 0000000..74d3e5c
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/flow/criteria/TcpPortCriterion.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.net.flow.criteria;
+
+import java.util.Objects;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+
+/**
+ * Implementation of TCP port criterion (16 bits unsigned integer).
+ */
+public final class TcpPortCriterion implements Criterion {
+    private static final int MASK = 0xffff;
+    private final int tcpPort;              // Port value: 16 bits
+    private final Type type;
+
+    /**
+     * Constructor.
+     *
+     * @param tcpPort the TCP port to match (16 bits unsigned integer)
+     * @param type the match type. Should be either Type.TCP_SRC or
+     * Type.TCP_DST
+     */
+    TcpPortCriterion(int tcpPort, Type type) {
+        this.tcpPort = tcpPort & MASK;
+        this.type = type;
+    }
+
+    @Override
+    public Type type() {
+        return this.type;
+    }
+
+    /**
+     * Gets the TCP port to match.
+     *
+     * @return the TCP port to match (16 bits unsigned integer)
+     */
+    public int tcpPort() {
+        return this.tcpPort;
+    }
+
+    @Override
+    public String toString() {
+        return toStringHelper(type().toString())
+            .add("tcpPort", tcpPort).toString();
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(type, tcpPort);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof TcpPortCriterion) {
+            TcpPortCriterion that = (TcpPortCriterion) obj;
+            return Objects.equals(tcpPort, that.tcpPort) &&
+                    Objects.equals(type, that.type);
+        }
+        return false;
+    }
+}
diff --git a/core/api/src/main/java/org/onosproject/net/flow/criteria/UdpPortCriterion.java b/core/api/src/main/java/org/onosproject/net/flow/criteria/UdpPortCriterion.java
new file mode 100644
index 0000000..12f31b5
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/flow/criteria/UdpPortCriterion.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.net.flow.criteria;
+
+import java.util.Objects;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+
+/**
+ * Implementation of UDP port criterion (16 bits unsigned integer).
+ */
+public final class UdpPortCriterion implements Criterion {
+    private static final int MASK = 0xffff;
+    private final int udpPort;              // Port value: 16 bits
+    private final Type type;
+
+    /**
+     * Constructor.
+     *
+     * @param udpPort the UDP port to match (16 bits unsigned integer)
+     * @param type the match type. Should be either Type.UDP_SRC or
+     * Type.UDP_DST
+     */
+    UdpPortCriterion(int udpPort, Type type) {
+        this.udpPort = udpPort & MASK;
+        this.type = type;
+    }
+
+    @Override
+    public Type type() {
+        return this.type;
+    }
+
+    /**
+     * Gets the UDP port to match.
+     *
+     * @return the UDP port to match (16 bits unsigned integer)
+     */
+    public int udpPort() {
+        return this.udpPort;
+    }
+
+    @Override
+    public String toString() {
+        return toStringHelper(type().toString())
+            .add("udpPort", udpPort).toString();
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(type, udpPort);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof UdpPortCriterion) {
+            UdpPortCriterion that = (UdpPortCriterion) obj;
+            return Objects.equals(udpPort, that.udpPort) &&
+                    Objects.equals(type, that.type);
+        }
+        return false;
+    }
+}
diff --git a/core/api/src/main/java/org/onosproject/net/flow/criteria/VlanIdCriterion.java b/core/api/src/main/java/org/onosproject/net/flow/criteria/VlanIdCriterion.java
new file mode 100644
index 0000000..17d0bcd
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/flow/criteria/VlanIdCriterion.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.net.flow.criteria;
+
+import org.onlab.packet.VlanId;
+
+import java.util.Objects;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+
+/**
+ * Implementation of VLAN ID criterion.
+ */
+public final class VlanIdCriterion implements Criterion {
+    private final VlanId vlanId;
+
+    /**
+     * Constructor.
+     *
+     * @param vlanId the VLAN ID to match
+     */
+    VlanIdCriterion(VlanId vlanId) {
+        this.vlanId = vlanId;
+    }
+
+    @Override
+    public Type type() {
+        return Type.VLAN_VID;
+    }
+
+    /**
+     * Gets the VLAN ID to match.
+     *
+     * @return the VLAN ID to match
+     */
+    public VlanId vlanId() {
+        return vlanId;
+    }
+
+    @Override
+    public String toString() {
+        return toStringHelper(type().toString())
+                .add("vlanId", vlanId).toString();
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(type(), vlanId);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof VlanIdCriterion) {
+            VlanIdCriterion that = (VlanIdCriterion) obj;
+            return Objects.equals(vlanId, that.vlanId) &&
+                    Objects.equals(this.type(), that.type());
+        }
+        return false;
+    }
+}
diff --git a/core/api/src/main/java/org/onosproject/net/flow/criteria/VlanPcpCriterion.java b/core/api/src/main/java/org/onosproject/net/flow/criteria/VlanPcpCriterion.java
new file mode 100644
index 0000000..78e73d6
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/flow/criteria/VlanPcpCriterion.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.net.flow.criteria;
+
+import java.util.Objects;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+
+/**
+ * Implementation of VLAN priority criterion (3 bits).
+ */
+public final class VlanPcpCriterion implements Criterion {
+    private static final byte MASK = 0x7;
+    private final byte vlanPcp;             // VLAN pcp value: 3 bits
+
+    /**
+     * Constructor.
+     *
+     * @param vlanPcp the VLAN priority to match (3 bits)
+     */
+    VlanPcpCriterion(byte vlanPcp) {
+        this.vlanPcp = (byte) (vlanPcp & MASK);
+    }
+
+    @Override
+    public Type type() {
+        return Type.VLAN_PCP;
+    }
+
+    /**
+     * Gets the VLAN priority to match.
+     *
+     * @return the VLAN priority to match (3 bits)
+     */
+    public byte priority() {
+        return vlanPcp;
+    }
+
+    @Override
+    public String toString() {
+        return toStringHelper(type().toString())
+            .add("priority", Long.toHexString(vlanPcp)).toString();
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(type(), vlanPcp);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof VlanPcpCriterion) {
+            VlanPcpCriterion that = (VlanPcpCriterion) obj;
+            return Objects.equals(vlanPcp, that.vlanPcp) &&
+                    Objects.equals(this.type(), that.type());
+        }
+        return false;
+    }
+}
diff --git a/core/api/src/test/java/org/onosproject/net/flow/criteria/CriteriaTest.java b/core/api/src/test/java/org/onosproject/net/flow/criteria/CriteriaTest.java
index beb96e8..ff80032 100644
--- a/core/api/src/test/java/org/onosproject/net/flow/criteria/CriteriaTest.java
+++ b/core/api/src/test/java/org/onosproject/net/flow/criteria/CriteriaTest.java
@@ -254,30 +254,30 @@
      */
     @Test
     public void testCriteriaImmutability() {
-        assertThatClassIsImmutable(Criteria.PortCriterion.class);
-        assertThatClassIsImmutable(Criteria.MetadataCriterion.class);
-        assertThatClassIsImmutable(Criteria.EthCriterion.class);
-        assertThatClassIsImmutable(Criteria.EthTypeCriterion.class);
-        assertThatClassIsImmutable(Criteria.VlanIdCriterion.class);
-        assertThatClassIsImmutable(Criteria.VlanPcpCriterion.class);
-        assertThatClassIsImmutable(Criteria.IPDscpCriterion.class);
-        assertThatClassIsImmutable(Criteria.IPEcnCriterion.class);
-        assertThatClassIsImmutable(Criteria.IPProtocolCriterion.class);
-        assertThatClassIsImmutable(Criteria.IPCriterion.class);
-        assertThatClassIsImmutable(Criteria.TcpPortCriterion.class);
-        assertThatClassIsImmutable(Criteria.UdpPortCriterion.class);
-        assertThatClassIsImmutable(Criteria.SctpPortCriterion.class);
-        assertThatClassIsImmutable(Criteria.IcmpTypeCriterion.class);
-        assertThatClassIsImmutable(Criteria.IcmpCodeCriterion.class);
-        assertThatClassIsImmutable(Criteria.IPv6FlowLabelCriterion.class);
-        assertThatClassIsImmutable(Criteria.Icmpv6TypeCriterion.class);
-        assertThatClassIsImmutable(Criteria.Icmpv6CodeCriterion.class);
-        assertThatClassIsImmutable(Criteria.IPv6NDTargetAddressCriterion.class);
-        assertThatClassIsImmutable(Criteria.IPv6NDLinkLayerAddressCriterion.class);
-        assertThatClassIsImmutable(Criteria.MplsCriterion.class);
-        assertThatClassIsImmutable(Criteria.IPv6ExthdrFlagsCriterion.class);
-        assertThatClassIsImmutable(Criteria.LambdaCriterion.class);
-        assertThatClassIsImmutable(Criteria.OpticalSignalTypeCriterion.class);
+        assertThatClassIsImmutable(PortCriterion.class);
+        assertThatClassIsImmutable(MetadataCriterion.class);
+        assertThatClassIsImmutable(EthCriterion.class);
+        assertThatClassIsImmutable(EthTypeCriterion.class);
+        assertThatClassIsImmutable(VlanIdCriterion.class);
+        assertThatClassIsImmutable(VlanPcpCriterion.class);
+        assertThatClassIsImmutable(IPDscpCriterion.class);
+        assertThatClassIsImmutable(IPEcnCriterion.class);
+        assertThatClassIsImmutable(IPProtocolCriterion.class);
+        assertThatClassIsImmutable(IPCriterion.class);
+        assertThatClassIsImmutable(TcpPortCriterion.class);
+        assertThatClassIsImmutable(UdpPortCriterion.class);
+        assertThatClassIsImmutable(SctpPortCriterion.class);
+        assertThatClassIsImmutable(IcmpTypeCriterion.class);
+        assertThatClassIsImmutable(IcmpCodeCriterion.class);
+        assertThatClassIsImmutable(IPv6FlowLabelCriterion.class);
+        assertThatClassIsImmutable(Icmpv6TypeCriterion.class);
+        assertThatClassIsImmutable(Icmpv6CodeCriterion.class);
+        assertThatClassIsImmutable(IPv6NDTargetAddressCriterion.class);
+        assertThatClassIsImmutable(IPv6NDLinkLayerAddressCriterion.class);
+        assertThatClassIsImmutable(MplsCriterion.class);
+        assertThatClassIsImmutable(IPv6ExthdrFlagsCriterion.class);
+        assertThatClassIsImmutable(LambdaCriterion.class);
+        assertThatClassIsImmutable(OpticalSignalTypeCriterion.class);
     }
 
     // PortCriterion class
@@ -289,10 +289,10 @@
     public void testMatchInPortMethod() {
         PortNumber p1 = portNumber(1);
         Criterion matchInPort = Criteria.matchInPort(p1);
-        Criteria.PortCriterion portCriterion =
+        PortCriterion portCriterion =
                 checkAndConvert(matchInPort,
                                 Criterion.Type.IN_PORT,
-                                Criteria.PortCriterion.class);
+                                PortCriterion.class);
         assertThat(portCriterion.port(), is(equalTo(p1)));
     }
 
@@ -303,10 +303,10 @@
     public void testMatchInPhyPortMethod() {
         PortNumber p1 = portNumber(1);
         Criterion matchInPhyPort = Criteria.matchInPhyPort(p1);
-        Criteria.PortCriterion portCriterion =
+        PortCriterion portCriterion =
                 checkAndConvert(matchInPhyPort,
                                 Criterion.Type.IN_PHY_PORT,
-                                Criteria.PortCriterion.class);
+                                PortCriterion.class);
         assertThat(portCriterion.port(), is(equalTo(p1)));
     }
 
@@ -335,10 +335,10 @@
     public void testMatchMetadataMethod() {
         Long metadata = 12L;
         Criterion matchMetadata = Criteria.matchMetadata(metadata);
-        Criteria.MetadataCriterion metadataCriterion =
+        MetadataCriterion metadataCriterion =
                 checkAndConvert(matchMetadata,
                                 Criterion.Type.METADATA,
-                                Criteria.MetadataCriterion.class);
+                                MetadataCriterion.class);
         assertThat(metadataCriterion.metadata(), is(equalTo(metadata)));
     }
 
@@ -361,10 +361,10 @@
     @Test
     public void testMatchEthDstMethod() {
         Criterion matchEthDst = Criteria.matchEthDst(mac1);
-        Criteria.EthCriterion ethCriterion =
+        EthCriterion ethCriterion =
                 checkAndConvert(matchEthDst,
                         Criterion.Type.ETH_DST,
-                        Criteria.EthCriterion.class);
+                        EthCriterion.class);
         assertThat(ethCriterion.mac(), is(equalTo(mac1)));
     }
 
@@ -374,10 +374,10 @@
     @Test
     public void testMatchEthSrcMethod() {
         Criterion matchEthSrc = Criteria.matchEthSrc(mac1);
-        Criteria.EthCriterion ethCriterion =
+        EthCriterion ethCriterion =
                 checkAndConvert(matchEthSrc,
                                 Criterion.Type.ETH_SRC,
-                                Criteria.EthCriterion.class);
+                                EthCriterion.class);
         assertThat(ethCriterion.mac(), is(mac1));
     }
 
@@ -401,10 +401,10 @@
     public void testMatchEthTypeMethod() {
         int ethType = 12;
         Criterion matchEthType = Criteria.matchEthType(ethType);
-        Criteria.EthTypeCriterion ethTypeCriterion =
+        EthTypeCriterion ethTypeCriterion =
                 checkAndConvert(matchEthType,
                                 Criterion.Type.ETH_TYPE,
-                                Criteria.EthTypeCriterion.class);
+                                EthTypeCriterion.class);
         assertThat(ethTypeCriterion.ethType(), is(equalTo(ethType)));
     }
 
@@ -427,10 +427,10 @@
     @Test
     public void testMatchVlanIdMethod() {
         Criterion matchVlanId = Criteria.matchVlanId(vlanId1);
-        Criteria.VlanIdCriterion vlanIdCriterion =
+        VlanIdCriterion vlanIdCriterion =
                 checkAndConvert(matchVlanId,
                         Criterion.Type.VLAN_VID,
-                        Criteria.VlanIdCriterion.class);
+                        VlanIdCriterion.class);
         assertThat(vlanIdCriterion.vlanId(), is(equalTo(vlanId1)));
     }
 
@@ -453,10 +453,10 @@
     @Test
     public void testMatchVlanPcpMethod() {
         Criterion matchVlanPcp = Criteria.matchVlanPcp(vlanPcp1);
-        Criteria.VlanPcpCriterion vlanPcpCriterion =
+        VlanPcpCriterion vlanPcpCriterion =
                 checkAndConvert(matchVlanPcp,
                         Criterion.Type.VLAN_PCP,
-                        Criteria.VlanPcpCriterion.class);
+                        VlanPcpCriterion.class);
         assertThat(vlanPcpCriterion.priority(), is(equalTo(vlanPcp1)));
     }
 
@@ -479,10 +479,10 @@
     @Test
     public void testMatchIPDscpMethod() {
         Criterion matchIPDscp = Criteria.matchIPDscp(ipDscp1);
-        Criteria.IPDscpCriterion ipDscpCriterion =
+        IPDscpCriterion ipDscpCriterion =
                 checkAndConvert(matchIPDscp,
                         Criterion.Type.IP_DSCP,
-                        Criteria.IPDscpCriterion.class);
+                        IPDscpCriterion.class);
         assertThat(ipDscpCriterion.ipDscp(), is(equalTo(ipDscp1)));
     }
 
@@ -505,10 +505,10 @@
     @Test
     public void testMatchIPEcnMethod() {
         Criterion matchIPEcn = Criteria.matchIPEcn(ipEcn1);
-        Criteria.IPEcnCriterion ipEcnCriterion =
+        IPEcnCriterion ipEcnCriterion =
                 checkAndConvert(matchIPEcn,
                         Criterion.Type.IP_ECN,
-                        Criteria.IPEcnCriterion.class);
+                        IPEcnCriterion.class);
         assertThat(ipEcnCriterion.ipEcn(), is(equalTo(ipEcn1)));
     }
 
@@ -531,10 +531,10 @@
     @Test
     public void testMatchIpProtocolMethod() {
         Criterion matchIPProtocol = Criteria.matchIPProtocol(protocol1);
-        Criteria.IPProtocolCriterion ipProtocolCriterion =
+        IPProtocolCriterion ipProtocolCriterion =
                 checkAndConvert(matchIPProtocol,
                         Criterion.Type.IP_PROTO,
-                        Criteria.IPProtocolCriterion.class);
+                        IPProtocolCriterion.class);
         assertThat(ipProtocolCriterion.protocol(), is(equalTo(protocol1)));
     }
 
@@ -557,10 +557,10 @@
     @Test
     public void testMatchIPSrcMethod() {
         Criterion matchIpSrc = Criteria.matchIPSrc(ip1);
-        Criteria.IPCriterion ipCriterion =
+        IPCriterion ipCriterion =
                 checkAndConvert(matchIpSrc,
                                 Criterion.Type.IPV4_SRC,
-                                Criteria.IPCriterion.class);
+                                IPCriterion.class);
         assertThat(ipCriterion.ip(), is(ip1));
     }
 
@@ -570,10 +570,10 @@
     @Test
     public void testMatchIPDstMethod() {
         Criterion matchIPDst = Criteria.matchIPDst(ip1);
-        Criteria.IPCriterion ipCriterion =
+        IPCriterion ipCriterion =
                 checkAndConvert(matchIPDst,
                         Criterion.Type.IPV4_DST,
-                        Criteria.IPCriterion.class);
+                        IPCriterion.class);
         assertThat(ipCriterion.ip(), is(equalTo(ip1)));
     }
 
@@ -583,10 +583,10 @@
     @Test
     public void testMatchIPv6SrcMethod() {
         Criterion matchIpv6Src = Criteria.matchIPv6Src(ipv61);
-        Criteria.IPCriterion ipCriterion =
+        IPCriterion ipCriterion =
                 checkAndConvert(matchIpv6Src,
                         Criterion.Type.IPV6_SRC,
-                        Criteria.IPCriterion.class);
+                        IPCriterion.class);
         assertThat(ipCriterion.ip(), is(ipv61));
     }
 
@@ -596,10 +596,10 @@
     @Test
     public void testMatchIPv6DstMethod() {
         Criterion matchIPv6Dst = Criteria.matchIPv6Dst(ipv61);
-        Criteria.IPCriterion ipCriterion =
+        IPCriterion ipCriterion =
                 checkAndConvert(matchIPv6Dst,
                         Criterion.Type.IPV6_DST,
-                        Criteria.IPCriterion.class);
+                        IPCriterion.class);
         assertThat(ipCriterion.ip(), is(equalTo(ipv61)));
     }
 
@@ -627,10 +627,10 @@
     @Test
     public void testMatchTcpSrcMethod() {
         Criterion matchTcpSrc = Criteria.matchTcpSrc(1);
-        Criteria.TcpPortCriterion tcpPortCriterion =
+        TcpPortCriterion tcpPortCriterion =
                 checkAndConvert(matchTcpSrc,
                                 Criterion.Type.TCP_SRC,
-                                Criteria.TcpPortCriterion.class);
+                                TcpPortCriterion.class);
         assertThat(tcpPortCriterion.tcpPort(), is(equalTo(1)));
     }
 
@@ -640,10 +640,10 @@
     @Test
     public void testMatchTcpDstMethod() {
         Criterion matchTcpDst = Criteria.matchTcpDst(1);
-        Criteria.TcpPortCriterion tcpPortCriterion =
+        TcpPortCriterion tcpPortCriterion =
                 checkAndConvert(matchTcpDst,
                         Criterion.Type.TCP_DST,
-                        Criteria.TcpPortCriterion.class);
+                        TcpPortCriterion.class);
         assertThat(tcpPortCriterion.tcpPort(), is(equalTo(1)));
     }
 
@@ -666,10 +666,10 @@
     @Test
     public void testMatchUdpSrcMethod() {
         Criterion matchUdpSrc = Criteria.matchUdpSrc(1);
-        Criteria.UdpPortCriterion udpPortCriterion =
+        UdpPortCriterion udpPortCriterion =
                 checkAndConvert(matchUdpSrc,
                                 Criterion.Type.UDP_SRC,
-                                Criteria.UdpPortCriterion.class);
+                                UdpPortCriterion.class);
         assertThat(udpPortCriterion.udpPort(), is(equalTo(1)));
     }
 
@@ -679,10 +679,10 @@
     @Test
     public void testMatchUdpDstMethod() {
         Criterion matchUdpDst = Criteria.matchUdpDst(1);
-        Criteria.UdpPortCriterion udpPortCriterion =
+        UdpPortCriterion udpPortCriterion =
                 checkAndConvert(matchUdpDst,
                         Criterion.Type.UDP_DST,
-                        Criteria.UdpPortCriterion.class);
+                        UdpPortCriterion.class);
         assertThat(udpPortCriterion.udpPort(), is(equalTo(1)));
     }
 
@@ -705,10 +705,10 @@
     @Test
     public void testMatchSctpSrcMethod() {
         Criterion matchSctpSrc = Criteria.matchSctpSrc(1);
-        Criteria.SctpPortCriterion sctpPortCriterion =
+        SctpPortCriterion sctpPortCriterion =
                 checkAndConvert(matchSctpSrc,
                                 Criterion.Type.SCTP_SRC,
-                                Criteria.SctpPortCriterion.class);
+                                SctpPortCriterion.class);
         assertThat(sctpPortCriterion.sctpPort(), is(equalTo(1)));
     }
 
@@ -718,10 +718,10 @@
     @Test
     public void testMatchSctpDstMethod() {
         Criterion matchSctpDst = Criteria.matchSctpDst(1);
-        Criteria.SctpPortCriterion sctpPortCriterion =
+        SctpPortCriterion sctpPortCriterion =
                 checkAndConvert(matchSctpDst,
                         Criterion.Type.SCTP_DST,
-                        Criteria.SctpPortCriterion.class);
+                        SctpPortCriterion.class);
         assertThat(sctpPortCriterion.sctpPort(), is(equalTo(1)));
     }
 
@@ -745,10 +745,10 @@
     public void testMatchIcmpTypeMethod() {
         short icmpType = 12;
         Criterion matchIcmpType = Criteria.matchIcmpType(icmpType);
-        Criteria.IcmpTypeCriterion icmpTypeCriterion =
+        IcmpTypeCriterion icmpTypeCriterion =
                 checkAndConvert(matchIcmpType,
                                 Criterion.Type.ICMPV4_TYPE,
-                                Criteria.IcmpTypeCriterion.class);
+                                IcmpTypeCriterion.class);
         assertThat(icmpTypeCriterion.icmpType(), is(equalTo(icmpType)));
     }
 
@@ -772,10 +772,10 @@
     public void testMatchIcmpCodeMethod() {
         short icmpCode = 12;
         Criterion matchIcmpCode = Criteria.matchIcmpCode(icmpCode);
-        Criteria.IcmpCodeCriterion icmpCodeCriterion =
+        IcmpCodeCriterion icmpCodeCriterion =
                 checkAndConvert(matchIcmpCode,
                                 Criterion.Type.ICMPV4_CODE,
-                                Criteria.IcmpCodeCriterion.class);
+                                IcmpCodeCriterion.class);
         assertThat(icmpCodeCriterion.icmpCode(), is(equalTo(icmpCode)));
     }
 
@@ -799,10 +799,10 @@
     public void testMatchIPv6FlowLabelMethod() {
         int flowLabel = 12;
         Criterion matchFlowLabel = Criteria.matchIPv6FlowLabel(flowLabel);
-        Criteria.IPv6FlowLabelCriterion flowLabelCriterion =
+        IPv6FlowLabelCriterion flowLabelCriterion =
                 checkAndConvert(matchFlowLabel,
                                 Criterion.Type.IPV6_FLABEL,
-                                Criteria.IPv6FlowLabelCriterion.class);
+                                IPv6FlowLabelCriterion.class);
         assertThat(flowLabelCriterion.flowLabel(), is(equalTo(flowLabel)));
     }
 
@@ -826,10 +826,10 @@
     public void testMatchIcmpv6TypeMethod() {
         short icmpv6Type = 12;
         Criterion matchIcmpv6Type = Criteria.matchIcmpv6Type(icmpv6Type);
-        Criteria.Icmpv6TypeCriterion icmpv6TypeCriterion =
+        Icmpv6TypeCriterion icmpv6TypeCriterion =
                 checkAndConvert(matchIcmpv6Type,
                                 Criterion.Type.ICMPV6_TYPE,
-                                Criteria.Icmpv6TypeCriterion.class);
+                                Icmpv6TypeCriterion.class);
         assertThat(icmpv6TypeCriterion.icmpv6Type(), is(equalTo(icmpv6Type)));
     }
 
@@ -853,10 +853,10 @@
     public void testMatchIcmpv6CodeMethod() {
         short icmpv6Code = 12;
         Criterion matchIcmpv6Code = Criteria.matchIcmpv6Code(icmpv6Code);
-        Criteria.Icmpv6CodeCriterion icmpv6CodeCriterion =
+        Icmpv6CodeCriterion icmpv6CodeCriterion =
                 checkAndConvert(matchIcmpv6Code,
                                 Criterion.Type.ICMPV6_CODE,
-                                Criteria.Icmpv6CodeCriterion.class);
+                                Icmpv6CodeCriterion.class);
         assertThat(icmpv6CodeCriterion.icmpv6Code(), is(equalTo(icmpv6Code)));
     }
 
@@ -880,10 +880,10 @@
     public void testMatchIPv6NDTargetAddressMethod() {
         Criterion matchTargetAddress =
             Criteria.matchIPv6NDTargetAddress(ip6TargetAddress1);
-        Criteria.IPv6NDTargetAddressCriterion targetAddressCriterion =
+        IPv6NDTargetAddressCriterion targetAddressCriterion =
                 checkAndConvert(matchTargetAddress,
                                 Criterion.Type.IPV6_ND_TARGET,
-                                Criteria.IPv6NDTargetAddressCriterion.class);
+                                IPv6NDTargetAddressCriterion.class);
         assertThat(targetAddressCriterion.targetAddress(),
                    is(ip6TargetAddress1));
     }
@@ -909,10 +909,10 @@
     public void testMatchIPv6NDSourceLinkLayerAddressMethod() {
         Criterion matchSrcLlAddr =
             Criteria.matchIPv6NDSourceLinkLayerAddress(llMac1);
-        Criteria.IPv6NDLinkLayerAddressCriterion srcLlCriterion =
+        IPv6NDLinkLayerAddressCriterion srcLlCriterion =
                 checkAndConvert(matchSrcLlAddr,
                         Criterion.Type.IPV6_ND_SLL,
-                        Criteria.IPv6NDLinkLayerAddressCriterion.class);
+                        IPv6NDLinkLayerAddressCriterion.class);
         assertThat(srcLlCriterion.mac(), is(equalTo(llMac1)));
     }
 
@@ -923,10 +923,10 @@
     public void testMatchIPv6NDTargetLinkLayerAddressMethod() {
         Criterion matchTargetLlAddr =
             Criteria.matchIPv6NDTargetLinkLayerAddress(llMac1);
-        Criteria.IPv6NDLinkLayerAddressCriterion targetLlCriterion =
+        IPv6NDLinkLayerAddressCriterion targetLlCriterion =
                 checkAndConvert(matchTargetLlAddr,
                         Criterion.Type.IPV6_ND_TLL,
-                        Criteria.IPv6NDLinkLayerAddressCriterion.class);
+                        IPv6NDLinkLayerAddressCriterion.class);
         assertThat(targetLlCriterion.mac(), is(equalTo(llMac1)));
     }
 
@@ -954,10 +954,10 @@
     @Test
     public void testMatchMplsLabelMethod() {
         Criterion matchMplsLabel = Criteria.matchMplsLabel(mpls1);
-        Criteria.MplsCriterion mplsCriterion =
+        MplsCriterion mplsCriterion =
                 checkAndConvert(matchMplsLabel,
                         Criterion.Type.MPLS_LABEL,
-                        Criteria.MplsCriterion.class);
+                        MplsCriterion.class);
         assertThat(mplsCriterion.label(), is(equalTo(mpls1)));
     }
 
@@ -981,10 +981,10 @@
     public void testMatchIPv6ExthdrFlagsMethod() {
         Criterion matchExthdrFlags =
             Criteria.matchIPv6ExthdrFlags(ipv6ExthdrFlags1);
-        Criteria.IPv6ExthdrFlagsCriterion exthdrFlagsCriterion =
+        IPv6ExthdrFlagsCriterion exthdrFlagsCriterion =
                 checkAndConvert(matchExthdrFlags,
                         Criterion.Type.IPV6_EXTHDR,
-                        Criteria.IPv6ExthdrFlagsCriterion.class);
+                        IPv6ExthdrFlagsCriterion.class);
         assertThat(exthdrFlagsCriterion.exthdrFlags(),
                    is(equalTo(ipv6ExthdrFlags1)));
     }
@@ -1009,10 +1009,10 @@
     @Test
     public void testMatchLambdaMethod() {
         Criterion matchLambda = Criteria.matchLambda(lambda1);
-        Criteria.LambdaCriterion lambdaCriterion =
+        LambdaCriterion lambdaCriterion =
                 checkAndConvert(matchLambda,
                         Criterion.Type.OCH_SIGID,
-                        Criteria.LambdaCriterion.class);
+                        LambdaCriterion.class);
         assertThat(lambdaCriterion.lambda(), is(equalTo(lambda1)));
     }
 
@@ -1035,10 +1035,10 @@
     @Test
     public void testMatchOpticalSignalTypeMethod() {
         Criterion matchLambda = Criteria.matchOpticalSignalType(signalLambda1);
-        Criteria.OpticalSignalTypeCriterion opticalSignalTypeCriterion =
+        OpticalSignalTypeCriterion opticalSignalTypeCriterion =
                 checkAndConvert(matchLambda,
                         Criterion.Type.OCH_SIGTYPE,
-                        Criteria.OpticalSignalTypeCriterion.class);
+                        OpticalSignalTypeCriterion.class);
         assertThat(opticalSignalTypeCriterion.signalType(), is(equalTo(signalLambda1)));
     }
 
diff --git a/core/common/src/main/java/org/onosproject/codec/impl/CriterionCodec.java b/core/common/src/main/java/org/onosproject/codec/impl/CriterionCodec.java
index 57cff66..899ade5 100644
--- a/core/common/src/main/java/org/onosproject/codec/impl/CriterionCodec.java
+++ b/core/common/src/main/java/org/onosproject/codec/impl/CriterionCodec.java
@@ -19,8 +19,31 @@
 
 import org.onosproject.codec.CodecContext;
 import org.onosproject.codec.JsonCodec;
-import org.onosproject.net.flow.criteria.Criteria;
 import org.onosproject.net.flow.criteria.Criterion;
+import org.onosproject.net.flow.criteria.EthCriterion;
+import org.onosproject.net.flow.criteria.EthTypeCriterion;
+import org.onosproject.net.flow.criteria.IPCriterion;
+import org.onosproject.net.flow.criteria.IPDscpCriterion;
+import org.onosproject.net.flow.criteria.IPEcnCriterion;
+import org.onosproject.net.flow.criteria.IPProtocolCriterion;
+import org.onosproject.net.flow.criteria.IPv6ExthdrFlagsCriterion;
+import org.onosproject.net.flow.criteria.IPv6FlowLabelCriterion;
+import org.onosproject.net.flow.criteria.IPv6NDLinkLayerAddressCriterion;
+import org.onosproject.net.flow.criteria.IPv6NDTargetAddressCriterion;
+import org.onosproject.net.flow.criteria.IcmpCodeCriterion;
+import org.onosproject.net.flow.criteria.IcmpTypeCriterion;
+import org.onosproject.net.flow.criteria.Icmpv6CodeCriterion;
+import org.onosproject.net.flow.criteria.Icmpv6TypeCriterion;
+import org.onosproject.net.flow.criteria.LambdaCriterion;
+import org.onosproject.net.flow.criteria.MetadataCriterion;
+import org.onosproject.net.flow.criteria.MplsCriterion;
+import org.onosproject.net.flow.criteria.OpticalSignalTypeCriterion;
+import org.onosproject.net.flow.criteria.PortCriterion;
+import org.onosproject.net.flow.criteria.SctpPortCriterion;
+import org.onosproject.net.flow.criteria.TcpPortCriterion;
+import org.onosproject.net.flow.criteria.UdpPortCriterion;
+import org.onosproject.net.flow.criteria.VlanIdCriterion;
+import org.onosproject.net.flow.criteria.VlanPcpCriterion;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -107,7 +130,7 @@
     private static class FormatInPort implements CriterionTypeFormatter {
         @Override
         public ObjectNode formatCriterion(ObjectNode root, Criterion criterion) {
-            final Criteria.PortCriterion portCriterion = (Criteria.PortCriterion) criterion;
+            final PortCriterion portCriterion = (PortCriterion) criterion;
             return root.put("port", portCriterion.port().toLong());
         }
     }
@@ -115,8 +138,8 @@
     private static class FormatMetadata implements CriterionTypeFormatter {
         @Override
         public ObjectNode formatCriterion(ObjectNode root, Criterion criterion) {
-            final Criteria.MetadataCriterion metadataCriterion =
-                    (Criteria.MetadataCriterion) criterion;
+            final MetadataCriterion metadataCriterion =
+                    (MetadataCriterion) criterion;
             return root.put("metadata", metadataCriterion.metadata());
         }
     }
@@ -124,7 +147,7 @@
     private static class FormatEth implements CriterionTypeFormatter {
         @Override
         public ObjectNode formatCriterion(ObjectNode root, Criterion criterion) {
-            final Criteria.EthCriterion ethCriterion = (Criteria.EthCriterion) criterion;
+            final EthCriterion ethCriterion = (EthCriterion) criterion;
             return root.put("mac", ethCriterion.mac().toString());
         }
     }
@@ -132,8 +155,8 @@
     private static class FormatEthType implements CriterionTypeFormatter {
         @Override
         public ObjectNode formatCriterion(ObjectNode root, Criterion criterion) {
-            final Criteria.EthTypeCriterion ethTypeCriterion =
-                    (Criteria.EthTypeCriterion) criterion;
+            final EthTypeCriterion ethTypeCriterion =
+                    (EthTypeCriterion) criterion;
             return root.put("ethType", ethTypeCriterion.ethType());
         }
     }
@@ -141,8 +164,8 @@
     private static class FormatVlanVid implements CriterionTypeFormatter {
         @Override
         public ObjectNode formatCriterion(ObjectNode root, Criterion criterion) {
-            final Criteria.VlanIdCriterion vlanIdCriterion =
-                    (Criteria.VlanIdCriterion) criterion;
+            final VlanIdCriterion vlanIdCriterion =
+                    (VlanIdCriterion) criterion;
             return root.put("vlanId", vlanIdCriterion.vlanId().toShort());
         }
     }
@@ -150,8 +173,8 @@
     private static class FormatVlanPcp implements CriterionTypeFormatter {
             @Override
             public ObjectNode formatCriterion(ObjectNode root, Criterion criterion) {
-                final Criteria.VlanPcpCriterion vlanPcpCriterion =
-                        (Criteria.VlanPcpCriterion) criterion;
+                final VlanPcpCriterion vlanPcpCriterion =
+                        (VlanPcpCriterion) criterion;
                 return root.put("priority", vlanPcpCriterion.priority());
             }
     }
@@ -159,8 +182,8 @@
     private static class FormatIpDscp implements CriterionTypeFormatter {
             @Override
             public ObjectNode formatCriterion(ObjectNode root, Criterion criterion) {
-                final Criteria.IPDscpCriterion ipDscpCriterion =
-                        (Criteria.IPDscpCriterion) criterion;
+                final IPDscpCriterion ipDscpCriterion =
+                        (IPDscpCriterion) criterion;
                 return root.put("ipDscp", ipDscpCriterion.ipDscp());
             }
     }
@@ -168,8 +191,8 @@
     private static class FormatIpEcn implements CriterionTypeFormatter {
             @Override
             public ObjectNode formatCriterion(ObjectNode root, Criterion criterion) {
-                final Criteria.IPEcnCriterion ipEcnCriterion =
-                        (Criteria.IPEcnCriterion) criterion;
+                final IPEcnCriterion ipEcnCriterion =
+                        (IPEcnCriterion) criterion;
                 return root.put("ipEcn", ipEcnCriterion.ipEcn());
             }
     }
@@ -177,8 +200,8 @@
     private static class FormatIpProto implements CriterionTypeFormatter {
         @Override
         public ObjectNode formatCriterion(ObjectNode root, Criterion criterion) {
-            final Criteria.IPProtocolCriterion iPProtocolCriterion =
-                    (Criteria.IPProtocolCriterion) criterion;
+            final IPProtocolCriterion iPProtocolCriterion =
+                    (IPProtocolCriterion) criterion;
             return root.put("protocol", iPProtocolCriterion.protocol());
         }
     }
@@ -186,7 +209,7 @@
     private static class FormatIp implements CriterionTypeFormatter {
             @Override
             public ObjectNode formatCriterion(ObjectNode root, Criterion criterion) {
-                final Criteria.IPCriterion iPCriterion = (Criteria.IPCriterion) criterion;
+                final IPCriterion iPCriterion = (IPCriterion) criterion;
                 return root.put("ip", iPCriterion.ip().toString());
         }
     }
@@ -194,8 +217,8 @@
     private static class FormatTcp implements CriterionTypeFormatter {
             @Override
             public ObjectNode formatCriterion(ObjectNode root, Criterion criterion) {
-                final Criteria.TcpPortCriterion tcpPortCriterion =
-                        (Criteria.TcpPortCriterion) criterion;
+                final TcpPortCriterion tcpPortCriterion =
+                        (TcpPortCriterion) criterion;
                 return root.put("tcpPort", tcpPortCriterion.tcpPort());
             }
     }
@@ -203,8 +226,8 @@
     private static class FormatUdp implements CriterionTypeFormatter {
             @Override
             public ObjectNode formatCriterion(ObjectNode root, Criterion criterion) {
-                final Criteria.UdpPortCriterion udpPortCriterion =
-                        (Criteria.UdpPortCriterion) criterion;
+                final UdpPortCriterion udpPortCriterion =
+                        (UdpPortCriterion) criterion;
                 return root.put("udpPort", udpPortCriterion.udpPort());
             }
     }
@@ -212,8 +235,8 @@
     private static class FormatSctp implements CriterionTypeFormatter {
         @Override
         public ObjectNode formatCriterion(ObjectNode root, Criterion criterion) {
-            final Criteria.SctpPortCriterion sctpPortCriterion =
-                    (Criteria.SctpPortCriterion) criterion;
+            final SctpPortCriterion sctpPortCriterion =
+                    (SctpPortCriterion) criterion;
             return root.put("sctpPort", sctpPortCriterion.sctpPort());
         }
     }
@@ -221,8 +244,8 @@
     private static class FormatIcmpV4Type implements CriterionTypeFormatter {
         @Override
         public ObjectNode formatCriterion(ObjectNode root, Criterion criterion) {
-            final Criteria.IcmpTypeCriterion icmpTypeCriterion =
-                    (Criteria.IcmpTypeCriterion) criterion;
+            final IcmpTypeCriterion icmpTypeCriterion =
+                    (IcmpTypeCriterion) criterion;
             return root.put("icmpType", icmpTypeCriterion.icmpType());
         }
     }
@@ -230,8 +253,8 @@
     private static class FormatIcmpV4Code implements CriterionTypeFormatter {
         @Override
         public ObjectNode formatCriterion(ObjectNode root, Criterion criterion) {
-            final Criteria.IcmpCodeCriterion icmpCodeCriterion =
-                    (Criteria.IcmpCodeCriterion) criterion;
+            final IcmpCodeCriterion icmpCodeCriterion =
+                    (IcmpCodeCriterion) criterion;
             return root.put("icmpCode", icmpCodeCriterion.icmpCode());
         }
     }
@@ -239,8 +262,8 @@
     private static class FormatIpV6FLabel implements CriterionTypeFormatter {
         @Override
         public ObjectNode formatCriterion(ObjectNode root, Criterion criterion) {
-            final Criteria.IPv6FlowLabelCriterion ipv6FlowLabelCriterion =
-                    (Criteria.IPv6FlowLabelCriterion) criterion;
+            final IPv6FlowLabelCriterion ipv6FlowLabelCriterion =
+                    (IPv6FlowLabelCriterion) criterion;
             return root.put("flowLabel", ipv6FlowLabelCriterion.flowLabel());
         }
     }
@@ -248,8 +271,8 @@
     private static class FormatIcmpV6Type implements CriterionTypeFormatter {
         @Override
         public ObjectNode formatCriterion(ObjectNode root, Criterion criterion) {
-            final Criteria.Icmpv6TypeCriterion icmpv6TypeCriterion =
-                    (Criteria.Icmpv6TypeCriterion) criterion;
+            final Icmpv6TypeCriterion icmpv6TypeCriterion =
+                    (Icmpv6TypeCriterion) criterion;
             return root.put("icmpv6Type", icmpv6TypeCriterion.icmpv6Type());
         }
     }
@@ -257,8 +280,8 @@
     private static class FormatIcmpV6Code implements CriterionTypeFormatter {
         @Override
         public ObjectNode formatCriterion(ObjectNode root, Criterion criterion) {
-            final Criteria.Icmpv6CodeCriterion icmpv6CodeCriterion =
-                    (Criteria.Icmpv6CodeCriterion) criterion;
+            final Icmpv6CodeCriterion icmpv6CodeCriterion =
+                    (Icmpv6CodeCriterion) criterion;
             return root.put("icmpv6Code", icmpv6CodeCriterion.icmpv6Code());
         }
     }
@@ -266,8 +289,8 @@
     private static class FormatV6NDTarget implements CriterionTypeFormatter {
         @Override
         public ObjectNode formatCriterion(ObjectNode root, Criterion criterion) {
-            final Criteria.IPv6NDTargetAddressCriterion ipv6NDTargetAddressCriterion
-                = (Criteria.IPv6NDTargetAddressCriterion) criterion;
+            final IPv6NDTargetAddressCriterion ipv6NDTargetAddressCriterion
+                = (IPv6NDTargetAddressCriterion) criterion;
             return root.put("targetAddress", ipv6NDTargetAddressCriterion.targetAddress().toString());
         }
     }
@@ -275,8 +298,8 @@
     private static class FormatV6NDTll implements CriterionTypeFormatter {
         @Override
         public ObjectNode formatCriterion(ObjectNode root, Criterion criterion) {
-            final Criteria.IPv6NDLinkLayerAddressCriterion ipv6NDLinkLayerAddressCriterion
-                = (Criteria.IPv6NDLinkLayerAddressCriterion) criterion;
+            final IPv6NDLinkLayerAddressCriterion ipv6NDLinkLayerAddressCriterion
+                = (IPv6NDLinkLayerAddressCriterion) criterion;
             return root.put("mac", ipv6NDLinkLayerAddressCriterion.mac().toString());
         }
     }
@@ -284,8 +307,8 @@
     private static class FormatMplsLabel implements CriterionTypeFormatter {
         @Override
         public ObjectNode formatCriterion(ObjectNode root, Criterion criterion) {
-            final Criteria.MplsCriterion mplsCriterion =
-                    (Criteria.MplsCriterion) criterion;
+            final MplsCriterion mplsCriterion =
+                    (MplsCriterion) criterion;
             return root.put("label", mplsCriterion.label().toInt());
         }
     }
@@ -293,8 +316,8 @@
     private static class FormatIpV6Exthdr implements CriterionTypeFormatter {
         @Override
         public ObjectNode formatCriterion(ObjectNode root, Criterion criterion) {
-            final Criteria.IPv6ExthdrFlagsCriterion exthdrCriterion =
-                    (Criteria.IPv6ExthdrFlagsCriterion) criterion;
+            final IPv6ExthdrFlagsCriterion exthdrCriterion =
+                    (IPv6ExthdrFlagsCriterion) criterion;
             return root.put("exthdrFlags", exthdrCriterion.exthdrFlags());
         }
     }
@@ -302,8 +325,8 @@
     private static class FormatOchSigId implements CriterionTypeFormatter {
         @Override
         public ObjectNode formatCriterion(ObjectNode root, Criterion criterion) {
-            final Criteria.LambdaCriterion lambdaCriterion =
-                    (Criteria.LambdaCriterion) criterion;
+            final LambdaCriterion lambdaCriterion =
+                    (LambdaCriterion) criterion;
             return root.put("lambda", lambdaCriterion.lambda());
         }
     }
@@ -311,8 +334,8 @@
     private static class FormatOchSigType implements CriterionTypeFormatter {
         @Override
         public ObjectNode formatCriterion(ObjectNode root, Criterion criterion) {
-            final Criteria.OpticalSignalTypeCriterion opticalSignalTypeCriterion =
-                    (Criteria.OpticalSignalTypeCriterion) criterion;
+            final OpticalSignalTypeCriterion opticalSignalTypeCriterion =
+                    (OpticalSignalTypeCriterion) criterion;
             return root.put("signalType", opticalSignalTypeCriterion.signalType());
         }
     }
diff --git a/core/common/src/test/java/org/onosproject/codec/impl/CriterionJsonMatcher.java b/core/common/src/test/java/org/onosproject/codec/impl/CriterionJsonMatcher.java
index beb9545..6db66e4 100644
--- a/core/common/src/test/java/org/onosproject/codec/impl/CriterionJsonMatcher.java
+++ b/core/common/src/test/java/org/onosproject/codec/impl/CriterionJsonMatcher.java
@@ -17,10 +17,33 @@
 
 import org.hamcrest.Description;
 import org.hamcrest.TypeSafeDiagnosingMatcher;
-import org.onosproject.net.flow.criteria.Criteria;
 import org.onosproject.net.flow.criteria.Criterion;
 
 import com.fasterxml.jackson.databind.JsonNode;
+import org.onosproject.net.flow.criteria.EthCriterion;
+import org.onosproject.net.flow.criteria.EthTypeCriterion;
+import org.onosproject.net.flow.criteria.IPCriterion;
+import org.onosproject.net.flow.criteria.IPDscpCriterion;
+import org.onosproject.net.flow.criteria.IPEcnCriterion;
+import org.onosproject.net.flow.criteria.IPProtocolCriterion;
+import org.onosproject.net.flow.criteria.IPv6ExthdrFlagsCriterion;
+import org.onosproject.net.flow.criteria.IPv6FlowLabelCriterion;
+import org.onosproject.net.flow.criteria.IPv6NDLinkLayerAddressCriterion;
+import org.onosproject.net.flow.criteria.IPv6NDTargetAddressCriterion;
+import org.onosproject.net.flow.criteria.IcmpCodeCriterion;
+import org.onosproject.net.flow.criteria.IcmpTypeCriterion;
+import org.onosproject.net.flow.criteria.Icmpv6CodeCriterion;
+import org.onosproject.net.flow.criteria.Icmpv6TypeCriterion;
+import org.onosproject.net.flow.criteria.LambdaCriterion;
+import org.onosproject.net.flow.criteria.MetadataCriterion;
+import org.onosproject.net.flow.criteria.MplsCriterion;
+import org.onosproject.net.flow.criteria.OpticalSignalTypeCriterion;
+import org.onosproject.net.flow.criteria.PortCriterion;
+import org.onosproject.net.flow.criteria.SctpPortCriterion;
+import org.onosproject.net.flow.criteria.TcpPortCriterion;
+import org.onosproject.net.flow.criteria.UdpPortCriterion;
+import org.onosproject.net.flow.criteria.VlanIdCriterion;
+import org.onosproject.net.flow.criteria.VlanPcpCriterion;
 
 /**
  * Hamcrest matcher for criterion objects.
@@ -57,7 +80,7 @@
      * @param criterion criterion to match
      * @return true if the JSON matches the criterion, false otherwise.
      */
-    private boolean matchCriterion(Criteria.PortCriterion criterion) {
+    private boolean matchCriterion(PortCriterion criterion) {
         final long port = criterion.port().toLong();
         final long jsonPort = jsonCriterion.get("port").asLong();
         if (port != jsonPort) {
@@ -73,7 +96,7 @@
      * @param criterion criterion to match
      * @return true if the JSON matches the criterion, false otherwise.
      */
-    private boolean matchCriterion(Criteria.MetadataCriterion criterion) {
+    private boolean matchCriterion(MetadataCriterion criterion) {
         final long metadata = criterion.metadata();
         final long jsonMetadata = jsonCriterion.get("metadata").asLong();
         if (metadata != jsonMetadata) {
@@ -90,7 +113,7 @@
      * @param criterion criterion to match
      * @return true if the JSON matches the criterion, false otherwise.
      */
-    private boolean matchCriterion(Criteria.EthCriterion criterion) {
+    private boolean matchCriterion(EthCriterion criterion) {
         final String mac = criterion.mac().toString();
         final String jsonMac = jsonCriterion.get("mac").textValue();
         if (!mac.equals(jsonMac)) {
@@ -106,7 +129,7 @@
      * @param criterion criterion to match
      * @return true if the JSON matches the criterion, false otherwise.
      */
-    private boolean matchCriterion(Criteria.EthTypeCriterion criterion) {
+    private boolean matchCriterion(EthTypeCriterion criterion) {
         final int ethType = criterion.ethType();
         final int jsonEthType = jsonCriterion.get("ethType").intValue();
         if (ethType != jsonEthType) {
@@ -123,7 +146,7 @@
      * @param criterion criterion to match
      * @return true if the JSON matches the criterion, false otherwise.
      */
-    private boolean matchCriterion(Criteria.VlanIdCriterion criterion) {
+    private boolean matchCriterion(VlanIdCriterion criterion) {
         final short vlanId = criterion.vlanId().toShort();
         final short jsonVlanId = jsonCriterion.get("vlanId").shortValue();
         if (vlanId != jsonVlanId) {
@@ -139,7 +162,7 @@
      * @param criterion criterion to match
      * @return true if the JSON matches the criterion, false otherwise.
      */
-    private boolean matchCriterion(Criteria.VlanPcpCriterion criterion) {
+    private boolean matchCriterion(VlanPcpCriterion criterion) {
         final byte priority = criterion.priority();
         final byte jsonPriority =
                 (byte) jsonCriterion.get("priority").shortValue();
@@ -156,7 +179,7 @@
      * @param criterion criterion to match
      * @return true if the JSON matches the criterion, false otherwise.
      */
-    private boolean matchCriterion(Criteria.IPDscpCriterion criterion) {
+    private boolean matchCriterion(IPDscpCriterion criterion) {
         final byte ipDscp = criterion.ipDscp();
         final byte jsonIpDscp = (byte) jsonCriterion.get("ipDscp").shortValue();
         if (ipDscp != jsonIpDscp) {
@@ -172,7 +195,7 @@
      * @param criterion criterion to match
      * @return true if the JSON matches the criterion, false otherwise.
      */
-    private boolean matchCriterion(Criteria.IPEcnCriterion criterion) {
+    private boolean matchCriterion(IPEcnCriterion criterion) {
         final byte ipEcn = criterion.ipEcn();
         final byte jsonIpEcn = (byte) jsonCriterion.get("ipEcn").shortValue();
         if (ipEcn != jsonIpEcn) {
@@ -188,7 +211,7 @@
      * @param criterion criterion to match
      * @return true if the JSON matches the criterion, false otherwise.
      */
-    private boolean matchCriterion(Criteria.IPProtocolCriterion criterion) {
+    private boolean matchCriterion(IPProtocolCriterion criterion) {
         final short protocol = criterion.protocol();
         final short jsonProtocol = jsonCriterion.get("protocol").shortValue();
         if (protocol != jsonProtocol) {
@@ -205,7 +228,7 @@
      * @param criterion criterion to match
      * @return true if the JSON matches the criterion, false otherwise.
      */
-    private boolean matchCriterion(Criteria.IPCriterion criterion) {
+    private boolean matchCriterion(IPCriterion criterion) {
         final String ip = criterion.ip().toString();
         final String jsonIp = jsonCriterion.get("ip").textValue();
         if (!ip.equals(jsonIp)) {
@@ -221,7 +244,7 @@
      * @param criterion criterion to match
      * @return true if the JSON matches the criterion, false otherwise.
      */
-    private boolean matchCriterion(Criteria.TcpPortCriterion criterion) {
+    private boolean matchCriterion(TcpPortCriterion criterion) {
         final int tcpPort = criterion.tcpPort();
         final int jsonTcpPort = jsonCriterion.get("tcpPort").intValue();
         if (tcpPort != jsonTcpPort) {
@@ -238,7 +261,7 @@
      * @param criterion criterion to match
      * @return true if the JSON matches the criterion, false otherwise.
      */
-    private boolean matchCriterion(Criteria.UdpPortCriterion criterion) {
+    private boolean matchCriterion(UdpPortCriterion criterion) {
         final int udpPort = criterion.udpPort();
         final int jsonUdpPort = jsonCriterion.get("udpPort").intValue();
         if (udpPort != jsonUdpPort) {
@@ -255,7 +278,7 @@
      * @param criterion criterion to match
      * @return true if the JSON matches the criterion, false otherwise.
      */
-    private boolean matchCriterion(Criteria.SctpPortCriterion criterion) {
+    private boolean matchCriterion(SctpPortCriterion criterion) {
         final int sctpPort = criterion.sctpPort();
         final int jsonSctpPort = jsonCriterion.get("sctpPort").intValue();
         if (sctpPort != jsonSctpPort) {
@@ -272,7 +295,7 @@
      * @param criterion criterion to match
      * @return true if the JSON matches the criterion, false otherwise.
      */
-    private boolean matchCriterion(Criteria.IcmpTypeCriterion criterion) {
+    private boolean matchCriterion(IcmpTypeCriterion criterion) {
         final short icmpType = criterion.icmpType();
         final short jsonIcmpType = jsonCriterion.get("icmpType").shortValue();
         if (icmpType != jsonIcmpType) {
@@ -289,7 +312,7 @@
      * @param criterion criterion to match
      * @return true if the JSON matches the criterion, false otherwise.
      */
-    private boolean matchCriterion(Criteria.IcmpCodeCriterion criterion) {
+    private boolean matchCriterion(IcmpCodeCriterion criterion) {
         final short icmpCode = criterion.icmpCode();
         final short jsonIcmpCode = jsonCriterion.get("icmpCode").shortValue();
         if (icmpCode != jsonIcmpCode) {
@@ -306,7 +329,7 @@
      * @param criterion criterion to match
      * @return true if the JSON matches the criterion, false otherwise.
      */
-    private boolean matchCriterion(Criteria.IPv6FlowLabelCriterion criterion) {
+    private boolean matchCriterion(IPv6FlowLabelCriterion criterion) {
         final int flowLabel = criterion.flowLabel();
         final int jsonFlowLabel = jsonCriterion.get("flowLabel").intValue();
         if (flowLabel != jsonFlowLabel) {
@@ -323,7 +346,7 @@
      * @param criterion criterion to match
      * @return true if the JSON matches the criterion, false otherwise.
      */
-    private boolean matchCriterion(Criteria.Icmpv6TypeCriterion criterion) {
+    private boolean matchCriterion(Icmpv6TypeCriterion criterion) {
         final short icmpv6Type = criterion.icmpv6Type();
         final short jsonIcmpv6Type =
                 jsonCriterion.get("icmpv6Type").shortValue();
@@ -341,7 +364,7 @@
      * @param criterion criterion to match
      * @return true if the JSON matches the criterion, false otherwise.
      */
-    private boolean matchCriterion(Criteria.Icmpv6CodeCriterion criterion) {
+    private boolean matchCriterion(Icmpv6CodeCriterion criterion) {
         final short icmpv6Code = criterion.icmpv6Code();
         final short jsonIcmpv6Code =
                 jsonCriterion.get("icmpv6Code").shortValue();
@@ -359,7 +382,7 @@
      * @param criterion criterion to match
      * @return true if the JSON matches the criterion, false otherwise.
      */
-    private boolean matchCriterion(Criteria.IPv6NDTargetAddressCriterion criterion) {
+    private boolean matchCriterion(IPv6NDTargetAddressCriterion criterion) {
         final String targetAddress =
                 criterion.targetAddress().toString();
         final String jsonTargetAddress =
@@ -378,7 +401,7 @@
      * @param criterion criterion to match
      * @return true if the JSON matches the criterion, false otherwise.
      */
-    private boolean matchCriterion(Criteria.IPv6NDLinkLayerAddressCriterion criterion) {
+    private boolean matchCriterion(IPv6NDLinkLayerAddressCriterion criterion) {
         final String llAddress =
                 criterion.mac().toString();
         final String jsonLlAddress =
@@ -396,7 +419,7 @@
      * @param criterion criterion to match
      * @return true if the JSON matches the criterion, false otherwise.
      */
-    private boolean matchCriterion(Criteria.MplsCriterion criterion) {
+    private boolean matchCriterion(MplsCriterion criterion) {
         final int label = criterion.label().toInt();
         final int jsonLabel = jsonCriterion.get("label").intValue();
         if (label != jsonLabel) {
@@ -412,7 +435,7 @@
      * @param criterion criterion to match
      * @return true if the JSON matches the criterion, false otherwise.
      */
-    private boolean matchCriterion(Criteria.IPv6ExthdrFlagsCriterion criterion) {
+    private boolean matchCriterion(IPv6ExthdrFlagsCriterion criterion) {
         final int exthdrFlags = criterion.exthdrFlags();
         final int jsonExthdrFlags =
                 jsonCriterion.get("exthdrFlags").intValue();
@@ -430,7 +453,7 @@
      * @param criterion criterion to match
      * @return true if the JSON matches the criterion, false otherwise.
      */
-    private boolean matchCriterion(Criteria.LambdaCriterion criterion) {
+    private boolean matchCriterion(LambdaCriterion criterion) {
         final int lambda = criterion.lambda();
         final int jsonLambda = jsonCriterion.get("lambda").intValue();
         if (lambda != jsonLambda) {
@@ -446,7 +469,7 @@
      * @param criterion criterion to match
      * @return true if the JSON matches the criterion, false otherwise.
      */
-    private boolean matchCriterion(Criteria.OpticalSignalTypeCriterion criterion) {
+    private boolean matchCriterion(OpticalSignalTypeCriterion criterion) {
         final short signalType = criterion.signalType();
         final short jsonSignalType = jsonCriterion.get("signalType").shortValue();
         if (signalType != jsonSignalType) {
@@ -472,88 +495,88 @@
 
             case IN_PORT:
             case IN_PHY_PORT:
-                return matchCriterion((Criteria.PortCriterion) criterion);
+                return matchCriterion((PortCriterion) criterion);
 
             case METADATA:
-                return matchCriterion((Criteria.MetadataCriterion) criterion);
+                return matchCriterion((MetadataCriterion) criterion);
 
             case ETH_DST:
             case ETH_SRC:
-                return matchCriterion((Criteria.EthCriterion) criterion);
+                return matchCriterion((EthCriterion) criterion);
 
             case ETH_TYPE:
-                return matchCriterion((Criteria.EthTypeCriterion) criterion);
+                return matchCriterion((EthTypeCriterion) criterion);
 
             case VLAN_VID:
-                return matchCriterion((Criteria.VlanIdCriterion) criterion);
+                return matchCriterion((VlanIdCriterion) criterion);
 
             case VLAN_PCP:
-                return matchCriterion((Criteria.VlanPcpCriterion) criterion);
+                return matchCriterion((VlanPcpCriterion) criterion);
 
             case IP_DSCP:
-                return matchCriterion((Criteria.IPDscpCriterion) criterion);
+                return matchCriterion((IPDscpCriterion) criterion);
 
             case IP_ECN:
-                return matchCriterion((Criteria.IPEcnCriterion) criterion);
+                return matchCriterion((IPEcnCriterion) criterion);
 
             case IP_PROTO:
-                return matchCriterion((Criteria.IPProtocolCriterion) criterion);
+                return matchCriterion((IPProtocolCriterion) criterion);
 
             case IPV4_SRC:
             case IPV4_DST:
             case IPV6_SRC:
             case IPV6_DST:
-                return matchCriterion((Criteria.IPCriterion) criterion);
+                return matchCriterion((IPCriterion) criterion);
 
             case TCP_SRC:
             case TCP_DST:
-                return matchCriterion((Criteria.TcpPortCriterion) criterion);
+                return matchCriterion((TcpPortCriterion) criterion);
 
             case UDP_SRC:
             case UDP_DST:
-                return matchCriterion((Criteria.UdpPortCriterion) criterion);
+                return matchCriterion((UdpPortCriterion) criterion);
 
             case SCTP_SRC:
             case SCTP_DST:
-                return matchCriterion((Criteria.SctpPortCriterion) criterion);
+                return matchCriterion((SctpPortCriterion) criterion);
 
             case ICMPV4_TYPE:
-                return matchCriterion((Criteria.IcmpTypeCriterion) criterion);
+                return matchCriterion((IcmpTypeCriterion) criterion);
 
             case ICMPV4_CODE:
-                return matchCriterion((Criteria.IcmpCodeCriterion) criterion);
+                return matchCriterion((IcmpCodeCriterion) criterion);
 
             case IPV6_FLABEL:
-                return matchCriterion((Criteria.IPv6FlowLabelCriterion) criterion);
+                return matchCriterion((IPv6FlowLabelCriterion) criterion);
 
             case ICMPV6_TYPE:
-                return matchCriterion((Criteria.Icmpv6TypeCriterion) criterion);
+                return matchCriterion((Icmpv6TypeCriterion) criterion);
 
             case ICMPV6_CODE:
-                return matchCriterion((Criteria.Icmpv6CodeCriterion) criterion);
+                return matchCriterion((Icmpv6CodeCriterion) criterion);
 
             case IPV6_ND_TARGET:
                 return matchCriterion(
-                        (Criteria.IPv6NDTargetAddressCriterion) criterion);
+                        (IPv6NDTargetAddressCriterion) criterion);
 
             case IPV6_ND_SLL:
             case IPV6_ND_TLL:
                 return matchCriterion(
-                        (Criteria.IPv6NDLinkLayerAddressCriterion) criterion);
+                        (IPv6NDLinkLayerAddressCriterion) criterion);
 
             case MPLS_LABEL:
-                return matchCriterion((Criteria.MplsCriterion) criterion);
+                return matchCriterion((MplsCriterion) criterion);
 
             case IPV6_EXTHDR:
                 return matchCriterion(
-                        (Criteria.IPv6ExthdrFlagsCriterion) criterion);
+                        (IPv6ExthdrFlagsCriterion) criterion);
 
             case OCH_SIGID:
-                return matchCriterion((Criteria.LambdaCriterion) criterion);
+                return matchCriterion((LambdaCriterion) criterion);
 
             case OCH_SIGTYPE:
                 return matchCriterion(
-                        (Criteria.OpticalSignalTypeCriterion) criterion);
+                        (OpticalSignalTypeCriterion) criterion);
 
             default:
                 // Don't know how to format this type
diff --git a/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/MplsPathIntentCompiler.java b/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/MplsPathIntentCompiler.java
index 4558ce0..557365d 100644
--- a/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/MplsPathIntentCompiler.java
+++ b/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/MplsPathIntentCompiler.java
@@ -34,8 +34,8 @@
 import org.onosproject.net.flow.FlowRule;
 import org.onosproject.net.flow.TrafficSelector;
 import org.onosproject.net.flow.TrafficTreatment;
-import org.onosproject.net.flow.criteria.Criteria;
 import org.onosproject.net.flow.criteria.Criterion;
+import org.onosproject.net.flow.criteria.EthTypeCriterion;
 import org.onosproject.net.intent.FlowRuleIntent;
 import org.onosproject.net.intent.Intent;
 import org.onosproject.net.intent.IntentCompiler;
@@ -241,8 +241,8 @@
             // if the ingress ethertype is defined, the egress traffic
             // will be use that value, otherwise the IPv4 ethertype is used.
             Criterion c = intent.selector().getCriterion(Criterion.Type.ETH_TYPE);
-            if (c != null && c instanceof Criteria.EthTypeCriterion) {
-                Criteria.EthTypeCriterion ethertype = (Criteria.EthTypeCriterion) c;
+            if (c != null && c instanceof EthTypeCriterion) {
+                EthTypeCriterion ethertype = (EthTypeCriterion) c;
                 treat.popMpls((short) ethertype.ethType());
             } else {
                 treat.popMpls(Ethernet.TYPE_IPV4);
diff --git a/core/store/serializers/src/main/java/org/onosproject/store/serializers/KryoNamespaces.java b/core/store/serializers/src/main/java/org/onosproject/store/serializers/KryoNamespaces.java
index 7b17109..17eb374 100644
--- a/core/store/serializers/src/main/java/org/onosproject/store/serializers/KryoNamespaces.java
+++ b/core/store/serializers/src/main/java/org/onosproject/store/serializers/KryoNamespaces.java
@@ -73,8 +73,31 @@
 import org.onosproject.net.flow.FlowRuleBatchRequest;
 import org.onosproject.net.flow.FlowRuleExtPayLoad;
 import org.onosproject.net.flow.StoredFlowEntry;
-import org.onosproject.net.flow.criteria.Criteria;
 import org.onosproject.net.flow.criteria.Criterion;
+import org.onosproject.net.flow.criteria.EthCriterion;
+import org.onosproject.net.flow.criteria.EthTypeCriterion;
+import org.onosproject.net.flow.criteria.IPCriterion;
+import org.onosproject.net.flow.criteria.IPDscpCriterion;
+import org.onosproject.net.flow.criteria.IPEcnCriterion;
+import org.onosproject.net.flow.criteria.IPProtocolCriterion;
+import org.onosproject.net.flow.criteria.IPv6ExthdrFlagsCriterion;
+import org.onosproject.net.flow.criteria.IPv6FlowLabelCriterion;
+import org.onosproject.net.flow.criteria.IPv6NDLinkLayerAddressCriterion;
+import org.onosproject.net.flow.criteria.IPv6NDTargetAddressCriterion;
+import org.onosproject.net.flow.criteria.IcmpCodeCriterion;
+import org.onosproject.net.flow.criteria.IcmpTypeCriterion;
+import org.onosproject.net.flow.criteria.Icmpv6CodeCriterion;
+import org.onosproject.net.flow.criteria.Icmpv6TypeCriterion;
+import org.onosproject.net.flow.criteria.LambdaCriterion;
+import org.onosproject.net.flow.criteria.MetadataCriterion;
+import org.onosproject.net.flow.criteria.MplsCriterion;
+import org.onosproject.net.flow.criteria.OpticalSignalTypeCriterion;
+import org.onosproject.net.flow.criteria.PortCriterion;
+import org.onosproject.net.flow.criteria.SctpPortCriterion;
+import org.onosproject.net.flow.criteria.TcpPortCriterion;
+import org.onosproject.net.flow.criteria.UdpPortCriterion;
+import org.onosproject.net.flow.criteria.VlanIdCriterion;
+import org.onosproject.net.flow.criteria.VlanPcpCriterion;
 import org.onosproject.net.flow.instructions.Instructions;
 import org.onosproject.net.flow.instructions.L0ModificationInstruction;
 import org.onosproject.net.flow.instructions.L2ModificationInstruction;
@@ -234,30 +257,30 @@
                     FlowEntry.FlowEntryState.class,
                     FlowId.class,
                     DefaultTrafficSelector.class,
-                    Criteria.PortCriterion.class,
-                    Criteria.MetadataCriterion.class,
-                    Criteria.EthCriterion.class,
-                    Criteria.EthTypeCriterion.class,
-                    Criteria.VlanIdCriterion.class,
-                    Criteria.VlanPcpCriterion.class,
-                    Criteria.IPDscpCriterion.class,
-                    Criteria.IPEcnCriterion.class,
-                    Criteria.IPProtocolCriterion.class,
-                    Criteria.IPCriterion.class,
-                    Criteria.TcpPortCriterion.class,
-                    Criteria.UdpPortCriterion.class,
-                    Criteria.SctpPortCriterion.class,
-                    Criteria.IcmpTypeCriterion.class,
-                    Criteria.IcmpCodeCriterion.class,
-                    Criteria.IPv6FlowLabelCriterion.class,
-                    Criteria.Icmpv6TypeCriterion.class,
-                    Criteria.Icmpv6CodeCriterion.class,
-                    Criteria.IPv6NDTargetAddressCriterion.class,
-                    Criteria.IPv6NDLinkLayerAddressCriterion.class,
-                    Criteria.MplsCriterion.class,
-                    Criteria.IPv6ExthdrFlagsCriterion.class,
-                    Criteria.LambdaCriterion.class,
-                    Criteria.OpticalSignalTypeCriterion.class,
+                    PortCriterion.class,
+                    MetadataCriterion.class,
+                    EthCriterion.class,
+                    EthTypeCriterion.class,
+                    VlanIdCriterion.class,
+                    VlanPcpCriterion.class,
+                    IPDscpCriterion.class,
+                    IPEcnCriterion.class,
+                    IPProtocolCriterion.class,
+                    IPCriterion.class,
+                    TcpPortCriterion.class,
+                    UdpPortCriterion.class,
+                    SctpPortCriterion.class,
+                    IcmpTypeCriterion.class,
+                    IcmpCodeCriterion.class,
+                    IPv6FlowLabelCriterion.class,
+                    Icmpv6TypeCriterion.class,
+                    Icmpv6CodeCriterion.class,
+                    IPv6NDTargetAddressCriterion.class,
+                    IPv6NDLinkLayerAddressCriterion.class,
+                    MplsCriterion.class,
+                    IPv6ExthdrFlagsCriterion.class,
+                    LambdaCriterion.class,
+                    OpticalSignalTypeCriterion.class,
                     Criterion.class,
                     Criterion.Type.class,
                     DefaultTrafficTreatment.class,
diff --git a/drivers/src/main/java/org/onosproject/driver/pipeline/OVSCorsaPipeline.java b/drivers/src/main/java/org/onosproject/driver/pipeline/OVSCorsaPipeline.java
index d92e9ca..a92dbe1 100644
--- a/drivers/src/main/java/org/onosproject/driver/pipeline/OVSCorsaPipeline.java
+++ b/drivers/src/main/java/org/onosproject/driver/pipeline/OVSCorsaPipeline.java
@@ -44,6 +44,12 @@
 import org.onosproject.net.flow.TrafficTreatment;
 import org.onosproject.net.flow.criteria.Criteria;
 import org.onosproject.net.flow.criteria.Criterion;
+import org.onosproject.net.flow.criteria.EthCriterion;
+import org.onosproject.net.flow.criteria.EthTypeCriterion;
+import org.onosproject.net.flow.criteria.IPCriterion;
+import org.onosproject.net.flow.criteria.IPProtocolCriterion;
+import org.onosproject.net.flow.criteria.PortCriterion;
+import org.onosproject.net.flow.criteria.VlanIdCriterion;
 import org.onosproject.net.flowobjective.FilteringObjective;
 import org.onosproject.net.flowobjective.FlowObjectiveStore;
 import org.onosproject.net.flowobjective.ForwardingObjective;
@@ -245,8 +251,8 @@
         log.debug("Processing versatile forwarding objective");
         TrafficSelector selector = fwd.selector();
 
-        Criteria.EthTypeCriterion ethType =
-                (Criteria.EthTypeCriterion) selector.getCriterion(Criterion.Type.ETH_TYPE);
+        EthTypeCriterion ethType =
+                (EthTypeCriterion) selector.getCriterion(Criterion.Type.ETH_TYPE);
         if (ethType == null) {
             log.error("Versatile forwarding objective must include ethType");
             fail(fwd, ObjectiveError.UNKNOWN);
@@ -263,11 +269,11 @@
             fail(fwd, ObjectiveError.UNSUPPORTED);
             return Collections.emptySet();
         } else if (ethType.ethType() == Ethernet.TYPE_IPV4) {
-            Criteria.IPCriterion ipSrc = (Criteria.IPCriterion) selector
+            IPCriterion ipSrc = (IPCriterion) selector
                     .getCriterion(Criterion.Type.IPV4_SRC);
-            Criteria.IPCriterion ipDst = (Criteria.IPCriterion) selector
+            IPCriterion ipDst = (IPCriterion) selector
                     .getCriterion(Criterion.Type.IPV4_DST);
-            Criteria.IPProtocolCriterion ipProto = (Criteria.IPProtocolCriterion) selector
+            IPProtocolCriterion ipProto = (IPProtocolCriterion) selector
                     .getCriterion(Criterion.Type.IP_PROTO);
             if (ipSrc != null) {
                 log.warn("Driver does not currently handle matching Src IP");
@@ -296,8 +302,8 @@
     private Collection<FlowRule> processSpecific(ForwardingObjective fwd) {
         log.debug("Processing specific forwarding objective");
         TrafficSelector selector = fwd.selector();
-        Criteria.EthTypeCriterion ethType =
-                (Criteria.EthTypeCriterion) selector.getCriterion(Criterion.Type.ETH_TYPE);
+        EthTypeCriterion ethType =
+                (EthTypeCriterion) selector.getCriterion(Criterion.Type.ETH_TYPE);
         if (ethType == null || ethType.ethType() != Ethernet.TYPE_IPV4) {
             fail(fwd, ObjectiveError.UNSUPPORTED);
             return Collections.emptySet();
@@ -307,7 +313,7 @@
                 DefaultTrafficSelector.builder()
                         .matchEthType(Ethernet.TYPE_IPV4)
                         .matchIPDst(
-                                ((Criteria.IPCriterion)
+                                ((IPCriterion)
                                         selector.getCriterion(Criterion.Type.IPV4_DST)).ip())
                         .build();
 
@@ -351,10 +357,10 @@
                                              ApplicationId applicationId) {
         // This driver only processes filtering criteria defined with switch
         // ports as the key
-        Criteria.PortCriterion p;
+        PortCriterion p;
         if (!filt.key().equals(Criteria.dummy()) &&
                 filt.key().type() == Criterion.Type.IN_PORT) {
-            p = (Criteria.PortCriterion) filt.key();
+            p = (PortCriterion) filt.key();
         } else {
             log.warn("No key defined in filtering objective from app: {}. Not"
                     + "processing filtering objective", applicationId);
@@ -365,7 +371,7 @@
         FlowRuleOperations.Builder ops = FlowRuleOperations.builder();
         for (Criterion c : filt.conditions()) {
             if (c.type() == Criterion.Type.ETH_DST) {
-                Criteria.EthCriterion e = (Criteria.EthCriterion) c;
+                EthCriterion e = (EthCriterion) c;
                 log.debug("adding rule for MAC: {}", e.mac());
                 TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
                 TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
@@ -381,7 +387,7 @@
                         .forTable(MAC_TABLE).build();
                 ops =  install ? ops.add(rule) : ops.remove(rule);
             } else if (c.type() == Criterion.Type.VLAN_VID) {
-                Criteria.VlanIdCriterion v = (Criteria.VlanIdCriterion) c;
+                VlanIdCriterion v = (VlanIdCriterion) c;
                 log.debug("adding rule for VLAN: {}", v.vlanId());
                 TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
                 TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
@@ -399,7 +405,7 @@
                         .forTable(VLAN_TABLE).build();
                 ops = install ? ops.add(rule) : ops.remove(rule);
             } else if (c.type() == Criterion.Type.IPV4_DST) {
-                Criteria.IPCriterion ip = (Criteria.IPCriterion) c;
+                IPCriterion ip = (IPCriterion) c;
                 log.debug("adding rule for IP: {}", ip.ip());
                 TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
                 TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
diff --git a/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/FlowModBuilder.java b/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/FlowModBuilder.java
index 8609a25..108dbf8 100644
--- a/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/FlowModBuilder.java
+++ b/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/FlowModBuilder.java
@@ -22,28 +22,30 @@
 import org.onlab.packet.VlanId;
 import org.onosproject.net.flow.FlowRule;
 import org.onosproject.net.flow.TrafficSelector;
-import org.onosproject.net.flow.criteria.Criteria;
-import org.onosproject.net.flow.criteria.Criteria.EthCriterion;
-import org.onosproject.net.flow.criteria.Criteria.EthTypeCriterion;
-import org.onosproject.net.flow.criteria.Criteria.IPCriterion;
-import org.onosproject.net.flow.criteria.Criteria.IPDscpCriterion;
-import org.onosproject.net.flow.criteria.Criteria.IPEcnCriterion;
-import org.onosproject.net.flow.criteria.Criteria.IPProtocolCriterion;
-import org.onosproject.net.flow.criteria.Criteria.IPv6FlowLabelCriterion;
-import org.onosproject.net.flow.criteria.Criteria.IPv6NDLinkLayerAddressCriterion;
-import org.onosproject.net.flow.criteria.Criteria.IPv6NDTargetAddressCriterion;
-import org.onosproject.net.flow.criteria.Criteria.IcmpCodeCriterion;
-import org.onosproject.net.flow.criteria.Criteria.IcmpTypeCriterion;
-import org.onosproject.net.flow.criteria.Criteria.Icmpv6CodeCriterion;
-import org.onosproject.net.flow.criteria.Criteria.Icmpv6TypeCriterion;
-import org.onosproject.net.flow.criteria.Criteria.LambdaCriterion;
-import org.onosproject.net.flow.criteria.Criteria.MetadataCriterion;
-import org.onosproject.net.flow.criteria.Criteria.PortCriterion;
-import org.onosproject.net.flow.criteria.Criteria.SctpPortCriterion;
-import org.onosproject.net.flow.criteria.Criteria.TcpPortCriterion;
-import org.onosproject.net.flow.criteria.Criteria.UdpPortCriterion;
-import org.onosproject.net.flow.criteria.Criteria.VlanIdCriterion;
-import org.onosproject.net.flow.criteria.Criteria.VlanPcpCriterion;
+import org.onosproject.net.flow.criteria.EthCriterion;
+import org.onosproject.net.flow.criteria.EthTypeCriterion;
+import org.onosproject.net.flow.criteria.IPCriterion;
+import org.onosproject.net.flow.criteria.IPDscpCriterion;
+import org.onosproject.net.flow.criteria.IPEcnCriterion;
+import org.onosproject.net.flow.criteria.IPProtocolCriterion;
+import org.onosproject.net.flow.criteria.IPv6ExthdrFlagsCriterion;
+import org.onosproject.net.flow.criteria.IPv6FlowLabelCriterion;
+import org.onosproject.net.flow.criteria.IPv6NDLinkLayerAddressCriterion;
+import org.onosproject.net.flow.criteria.IPv6NDTargetAddressCriterion;
+import org.onosproject.net.flow.criteria.IcmpCodeCriterion;
+import org.onosproject.net.flow.criteria.IcmpTypeCriterion;
+import org.onosproject.net.flow.criteria.Icmpv6CodeCriterion;
+import org.onosproject.net.flow.criteria.Icmpv6TypeCriterion;
+import org.onosproject.net.flow.criteria.LambdaCriterion;
+import org.onosproject.net.flow.criteria.MetadataCriterion;
+import org.onosproject.net.flow.criteria.MplsCriterion;
+import org.onosproject.net.flow.criteria.OpticalSignalTypeCriterion;
+import org.onosproject.net.flow.criteria.PortCriterion;
+import org.onosproject.net.flow.criteria.SctpPortCriterion;
+import org.onosproject.net.flow.criteria.TcpPortCriterion;
+import org.onosproject.net.flow.criteria.UdpPortCriterion;
+import org.onosproject.net.flow.criteria.VlanIdCriterion;
+import org.onosproject.net.flow.criteria.VlanPcpCriterion;
 import org.onosproject.net.flow.criteria.Criterion;
 import org.projectfloodlight.openflow.protocol.OFFactory;
 import org.projectfloodlight.openflow.protocol.OFFlowAdd;
@@ -362,12 +364,12 @@
                         MacAddress.of(llAddressCriterion.mac().toLong()));
                 break;
             case MPLS_LABEL:
-                Criteria.MplsCriterion mp = (Criteria.MplsCriterion) c;
+                MplsCriterion mp = (MplsCriterion) c;
                 mBuilder.setExact(MatchField.MPLS_LABEL, U32.of(mp.label().toInt()));
                 break;
             case IPV6_EXTHDR:
-                Criteria.IPv6ExthdrFlagsCriterion exthdrFlagsCriterion =
-                    (Criteria.IPv6ExthdrFlagsCriterion) c;
+                IPv6ExthdrFlagsCriterion exthdrFlagsCriterion =
+                    (IPv6ExthdrFlagsCriterion) c;
                 mBuilder.setExact(MatchField.IPV6_EXTHDR,
                                   U16.of(exthdrFlagsCriterion.exthdrFlags()));
                 break;
@@ -378,8 +380,8 @@
                                             (short) lc.lambda(), (short) 1));
                 break;
             case OCH_SIGTYPE:
-                Criteria.OpticalSignalTypeCriterion sc =
-                        (Criteria.OpticalSignalTypeCriterion) c;
+                OpticalSignalTypeCriterion sc =
+                        (OpticalSignalTypeCriterion) c;
                 mBuilder.setExact(MatchField.OCH_SIGTYPE,
                                   U8.of(sc.signalType()));
                 break;