ONOS-7066 ONOS-7067 PI abstractions refactoring and P4Info model parser

Includes changes previously reviewed in #15607, #15877, and #15955.

Change-Id: Ie2ff62e415f2099832ebfe05961a879b7b188fc3
diff --git a/core/api/src/test/java/org/onosproject/net/pi/runtime/PiActionGroupMemberTest.java b/core/api/src/test/java/org/onosproject/net/pi/runtime/PiActionGroupMemberTest.java
index c9e53ee..020d575 100644
--- a/core/api/src/test/java/org/onosproject/net/pi/runtime/PiActionGroupMemberTest.java
+++ b/core/api/src/test/java/org/onosproject/net/pi/runtime/PiActionGroupMemberTest.java
@@ -18,6 +18,8 @@
 
 import com.google.common.testing.EqualsTester;
 import org.junit.Test;
+import org.onosproject.net.pi.model.PiActionId;
+import org.onosproject.net.pi.model.PiActionParamId;
 
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.Matchers.is;
@@ -32,22 +34,22 @@
  */
 public class PiActionGroupMemberTest {
 
-    final PiActionGroupMemberId piActionGroupMemberId = PiActionGroupMemberId.of(10);
-    final PiAction piAction = PiAction.builder().withId(PiActionId.of(MOD_NW_DST))
+    private final PiActionGroupMemberId piActionGroupMemberId = PiActionGroupMemberId.of(10);
+    private final PiAction piAction = PiAction.builder().withId(PiActionId.of(MOD_NW_DST))
             .withParameter(new PiActionParam(PiActionParamId.of(DST_ADDR), copyFrom(0x0a010101)))
             .build();
 
-    final PiActionGroupMember piActionGroupMember1 = PiActionGroupMember.builder()
+    private final PiActionGroupMember piActionGroupMember1 = PiActionGroupMember.builder()
             .withId(piActionGroupMemberId)
             .withAction(piAction)
             .withWeight(10)
             .build();
-    final PiActionGroupMember sameAsPiActionGroupMember1 = PiActionGroupMember.builder()
+    private final PiActionGroupMember sameAsPiActionGroupMember1 = PiActionGroupMember.builder()
             .withId(piActionGroupMemberId)
             .withAction(piAction)
             .withWeight(10)
             .build();
-    final PiActionGroupMember piActionGroupMember2 = PiActionGroupMember.builder()
+    private final PiActionGroupMember piActionGroupMember2 = PiActionGroupMember.builder()
             .withId(piActionGroupMemberId)
             .withAction(piAction)
             .withWeight(20)
diff --git a/core/api/src/test/java/org/onosproject/net/pi/runtime/PiActionGroupTest.java b/core/api/src/test/java/org/onosproject/net/pi/runtime/PiActionGroupTest.java
index 0da15e4..6672d91 100644
--- a/core/api/src/test/java/org/onosproject/net/pi/runtime/PiActionGroupTest.java
+++ b/core/api/src/test/java/org/onosproject/net/pi/runtime/PiActionGroupTest.java
@@ -20,6 +20,9 @@
 import com.google.common.testing.EqualsTester;
 import org.apache.commons.collections.CollectionUtils;
 import org.junit.Test;
+import org.onosproject.net.pi.model.PiActionGroupType;
+import org.onosproject.net.pi.model.PiActionId;
+import org.onosproject.net.pi.model.PiActionParamId;
 
 import java.util.Collection;
 
@@ -37,36 +40,36 @@
  */
 public class PiActionGroupTest {
 
-    final PiActionGroupMemberId piActionGroupMemberId = PiActionGroupMemberId.of(10);
-    final PiAction piAction = PiAction.builder().withId(PiActionId.of(MOD_NW_DST))
+    private final PiActionGroupMemberId piActionGroupMemberId = PiActionGroupMemberId.of(10);
+    private final PiAction piAction = PiAction.builder().withId(PiActionId.of(MOD_NW_DST))
             .withParameter(new PiActionParam(PiActionParamId.of(DST_ADDR), copyFrom(0x0a010101)))
             .build();
 
-    final PiActionGroupMember piActionGroupMember = PiActionGroupMember.builder()
+    private final PiActionGroupMember piActionGroupMember = PiActionGroupMember.builder()
             .withId(piActionGroupMemberId)
             .withAction(piAction)
             .withWeight(10)
             .build();
-    PiActionGroupId piActionGroupId = PiActionGroupId.of(10);
-    PiActionGroup piActionGroup1 = PiActionGroup.builder()
+    private PiActionGroupId piActionGroupId = PiActionGroupId.of(10);
+    private PiActionGroup piActionGroup1 = PiActionGroup.builder()
             .addMember(piActionGroupMember)
             .withId(piActionGroupId)
-            .withType(PiActionGroup.Type.SELECT)
+            .withType(PiActionGroupType.SELECT)
             .withActionProfileId(ACTION_PROF_ID)
             .build();
 
-    PiActionGroup sameAsPiActionGroup1 = PiActionGroup.builder()
+    private PiActionGroup sameAsPiActionGroup1 = PiActionGroup.builder()
             .addMember(piActionGroupMember)
             .withId(piActionGroupId)
-            .withType(PiActionGroup.Type.SELECT)
+            .withType(PiActionGroupType.SELECT)
             .withActionProfileId(ACTION_PROF_ID)
             .build();
 
-    PiActionGroupId piActionGroupId2 = PiActionGroupId.of(20);
-    PiActionGroup piActionGroup2 = PiActionGroup.builder()
+    private PiActionGroupId piActionGroupId2 = PiActionGroupId.of(20);
+    private PiActionGroup piActionGroup2 = PiActionGroup.builder()
             .addMember(piActionGroupMember)
             .withId(piActionGroupId2)
-            .withType(PiActionGroup.Type.SELECT)
+            .withType(PiActionGroupType.SELECT)
             .withActionProfileId(ACTION_PROF_ID)
             .build();
 
@@ -102,7 +105,7 @@
         piActionGroupMembers.add(piActionGroupMember);
         assertThat(piActionGroup1, is(notNullValue()));
         assertThat(piActionGroup1.id(), is(piActionGroupId));
-        assertThat(piActionGroup1.type(), is(PiActionGroup.Type.SELECT));
+        assertThat(piActionGroup1.type(), is(PiActionGroupType.SELECT));
         assertThat("Incorrect members value",
                    CollectionUtils.isEqualCollection(piActionGroup1.members(), piActionGroupMembers));
     }
diff --git a/core/api/src/test/java/org/onosproject/net/pi/runtime/PiActionIdTest.java b/core/api/src/test/java/org/onosproject/net/pi/runtime/PiActionIdTest.java
index 72e27af..262a50f 100644
--- a/core/api/src/test/java/org/onosproject/net/pi/runtime/PiActionIdTest.java
+++ b/core/api/src/test/java/org/onosproject/net/pi/runtime/PiActionIdTest.java
@@ -18,6 +18,7 @@
 
 import com.google.common.testing.EqualsTester;
 import org.junit.Test;
+import org.onosproject.net.pi.model.PiActionId;
 
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.Matchers.is;
@@ -60,9 +61,8 @@
      */
     @Test
     public void testConstruction() {
-        final String id = DEC_TTL;
-        final PiActionId actionId = PiActionId.of(id);
+        final PiActionId actionId = PiActionId.of(DEC_TTL);
         assertThat(actionId, is(notNullValue()));
-        assertThat(actionId.name(), is(id));
+        assertThat(actionId.id(), is(DEC_TTL));
     }
 }
diff --git a/core/api/src/test/java/org/onosproject/net/pi/runtime/PiActionParamIdTest.java b/core/api/src/test/java/org/onosproject/net/pi/runtime/PiActionParamIdTest.java
index b24adf0..c2793e7 100644
--- a/core/api/src/test/java/org/onosproject/net/pi/runtime/PiActionParamIdTest.java
+++ b/core/api/src/test/java/org/onosproject/net/pi/runtime/PiActionParamIdTest.java
@@ -18,6 +18,7 @@
 
 import com.google.common.testing.EqualsTester;
 import org.junit.Test;
+import org.onosproject.net.pi.model.PiActionParamId;
 
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.Matchers.is;
@@ -60,8 +61,8 @@
     @Test
     public void testConstruction() {
         final String param = SRC_ADDR;
-        final PiActionParamId actionParamId = PiActionParamId.of(SRC_ADDR);
+        final PiActionParamId actionParamId = PiActionParamId.of(param);
         assertThat(actionParamId, is(notNullValue()));
-        assertThat(actionParamId.name(), is(param));
+        assertThat(actionParamId.id(), is(param));
     }
 }
diff --git a/core/api/src/test/java/org/onosproject/net/pi/runtime/PiActionParamTest.java b/core/api/src/test/java/org/onosproject/net/pi/runtime/PiActionParamTest.java
index e8181b4..993c5e2 100644
--- a/core/api/src/test/java/org/onosproject/net/pi/runtime/PiActionParamTest.java
+++ b/core/api/src/test/java/org/onosproject/net/pi/runtime/PiActionParamTest.java
@@ -19,6 +19,7 @@
 import com.google.common.testing.EqualsTester;
 import org.junit.Test;
 import org.onlab.util.ImmutableByteSequence;
+import org.onosproject.net.pi.model.PiActionParamId;
 
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.Matchers.is;
@@ -32,11 +33,11 @@
  * Unit tests for PiActionParam class.
  */
 public class PiActionParamTest {
-    ImmutableByteSequence value1 = copyFrom(0x0a010101);
-    ImmutableByteSequence value2 = copyFrom(0x0a010102);
-    final PiActionParam piActionParam1 = new PiActionParam(PiActionParamId.of(DST_ADDR), value1);
-    final PiActionParam sameAsPiActionParam1 = new PiActionParam(PiActionParamId.of(DST_ADDR), value1);
-    final PiActionParam piActionParam2 = new PiActionParam(PiActionParamId.of(DST_ADDR), value2);
+    private ImmutableByteSequence value1 = copyFrom(0x0a010101);
+    private ImmutableByteSequence value2 = copyFrom(0x0a010102);
+    private final PiActionParam piActionParam1 = new PiActionParam(PiActionParamId.of(DST_ADDR), value1);
+    private final PiActionParam sameAsPiActionParam1 = new PiActionParam(PiActionParamId.of(DST_ADDR), value1);
+    private final PiActionParam piActionParam2 = new PiActionParam(PiActionParamId.of(DST_ADDR), value2);
 
     /**
      * Checks that the PiActionParam class is immutable.
diff --git a/core/api/src/test/java/org/onosproject/net/pi/runtime/PiActionTest.java b/core/api/src/test/java/org/onosproject/net/pi/runtime/PiActionTest.java
index 86f8686..9a69ab3 100644
--- a/core/api/src/test/java/org/onosproject/net/pi/runtime/PiActionTest.java
+++ b/core/api/src/test/java/org/onosproject/net/pi/runtime/PiActionTest.java
@@ -19,7 +19,8 @@
 import com.google.common.collect.Lists;
 import com.google.common.testing.EqualsTester;
 import org.junit.Test;
-
+import org.onosproject.net.pi.model.PiActionId;
+import org.onosproject.net.pi.model.PiActionParamId;
 
 import java.util.Collection;
 
@@ -35,13 +36,13 @@
  * Unit tests for PiAction class.
  */
 public class PiActionTest {
-    final PiAction piAction1 = PiAction.builder().withId(PiActionId.of(MOD_NW_DST))
+    private final PiAction piAction1 = PiAction.builder().withId(PiActionId.of(MOD_NW_DST))
             .withParameter(new PiActionParam(PiActionParamId.of(DST_ADDR), copyFrom(0x0a010101)))
             .build();
-    final PiAction sameAsPiAction1 = PiAction.builder().withId(PiActionId.of(MOD_NW_DST))
+    private final PiAction sameAsPiAction1 = PiAction.builder().withId(PiActionId.of(MOD_NW_DST))
             .withParameter(new PiActionParam(PiActionParamId.of(DST_ADDR), copyFrom(0x0a010101)))
             .build();
-    final PiAction piAction2 = PiAction.builder().withId(PiActionId.of("set_egress_port_0")).build();
+    private final PiAction piAction2 = PiAction.builder().withId(PiActionId.of("set_egress_port_0")).build();
 
     /**
      * Checks that the PiAction class is immutable.
diff --git a/core/api/src/test/java/org/onosproject/net/pi/runtime/PiConstantsTest.java b/core/api/src/test/java/org/onosproject/net/pi/runtime/PiConstantsTest.java
index 86f713d..158baab 100644
--- a/core/api/src/test/java/org/onosproject/net/pi/runtime/PiConstantsTest.java
+++ b/core/api/src/test/java/org/onosproject/net/pi/runtime/PiConstantsTest.java
@@ -15,30 +15,36 @@
  */
 package org.onosproject.net.pi.runtime;
 
+import org.onosproject.net.pi.model.PiActionProfileId;
+
 /**
- * Unit tests for PiActionId class.
+ * Constants for Pi* unit tests.
  */
 public final class PiConstantsTest {
-    private PiConstantsTest() {
-    }
-    public static final String MOD_NW_DST = "mod_nw_dst";
-    public static final String DEC_TTL = "dec_ttl";
-    public static final String MOD_VLAN_VID = "mod_vlan_vid";
+
+    static final String DOT = ".";
+    static final String MOD_NW_DST = "mod_nw_dst";
+    static final String DEC_TTL = "dec_ttl";
+    static final String MOD_VLAN_VID = "mod_vlan_vid";
     public static final String DROP = "drop";
 
-    public static final String IPV4_HEADER_NAME = "ipv4_t";
-    public static final String ETH_HEADER_NAME = "ethernet_t";
-    public static final String VLAN_HEADER_NAME = "vlan_tag_t";
+    static final String IPV4_HEADER_NAME = "ipv4_t";
+    static final String ETH_HEADER_NAME = "ethernet_t";
+    static final String VLAN_HEADER_NAME = "vlan_tag_t";
 
     public static final String ETH_TYPE = "etherType";
     public static final String DST_ADDR = "dstAddr";
-    public static final String SRC_ADDR = "srcAddr";
-    public static final String VID = "vid";
+    static final String SRC_ADDR = "srcAddr";
+    static final String VID = "vid";
     public static final String PORT = "port";
 
-    public static final String EGRESS_PORT = "egress_port";
-    public static final String INGRESS_PORT = "ingress_port";
+    static final String EGRESS_PORT = "egress_port";
+    static final String INGRESS_PORT = "ingress_port";
 
-    public static final PiActionProfileId ACTION_PROF_ID =
+    static final PiActionProfileId ACTION_PROF_ID =
             PiActionProfileId.of("Test action profile");
+
+    private PiConstantsTest() {
+        // Hides constructor.
+    }
 }
diff --git a/core/api/src/test/java/org/onosproject/net/pi/runtime/PiPacketMetadataIdTest.java b/core/api/src/test/java/org/onosproject/net/pi/runtime/PiControlMetadataIdTest.java
similarity index 62%
rename from core/api/src/test/java/org/onosproject/net/pi/runtime/PiPacketMetadataIdTest.java
rename to core/api/src/test/java/org/onosproject/net/pi/runtime/PiControlMetadataIdTest.java
index a2ee50f..d65ef2e 100644
--- a/core/api/src/test/java/org/onosproject/net/pi/runtime/PiPacketMetadataIdTest.java
+++ b/core/api/src/test/java/org/onosproject/net/pi/runtime/PiControlMetadataIdTest.java
@@ -18,6 +18,7 @@
 
 import com.google.common.testing.EqualsTester;
 import org.junit.Test;
+import org.onosproject.net.pi.model.PiControlMetadataId;
 
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.Matchers.is;
@@ -27,21 +28,21 @@
 import static org.onosproject.net.pi.runtime.PiConstantsTest.INGRESS_PORT;
 
 /**
- * Unit tests for PiPacketMetadataId class.
+ * Unit tests for PiControlMetadataId class.
  */
-public class PiPacketMetadataIdTest {
+public class PiControlMetadataIdTest {
 
-    final PiPacketMetadataId piPacketMetadataId1 = PiPacketMetadataId.of(EGRESS_PORT);
-    final PiPacketMetadataId sameAsPiPacketMetadataId1 = PiPacketMetadataId.of(EGRESS_PORT);
-    final PiPacketMetadataId piPacketMetadataId2 = PiPacketMetadataId.of(INGRESS_PORT);
+    final PiControlMetadataId piControlMetadataId1 = PiControlMetadataId.of(EGRESS_PORT);
+    final PiControlMetadataId sameAsPiControlMetadataId1 = PiControlMetadataId.of(EGRESS_PORT);
+    final PiControlMetadataId piControlMetadataId2 = PiControlMetadataId.of(INGRESS_PORT);
 
     /**
-     * Checks that the PiPacketMetadataId class is immutable.
+     * Checks that the PiControlMetadataId class is immutable.
      */
     @Test
     public void testImmutability() {
 
-        assertThatClassIsImmutable(PiPacketMetadataId.class);
+        assertThatClassIsImmutable(PiControlMetadataId.class);
     }
 
     /**
@@ -51,18 +52,17 @@
     public void testEquals() {
 
         new EqualsTester()
-                .addEqualityGroup(piPacketMetadataId1, sameAsPiPacketMetadataId1)
-                .addEqualityGroup(piPacketMetadataId2)
+                .addEqualityGroup(piControlMetadataId1, sameAsPiControlMetadataId1)
+                .addEqualityGroup(piControlMetadataId2)
                 .testEquals();
     }
 
     /**
-     * Checks the methods of PiPacketMetadataId.
+     * Checks the methods of PiControlMetadataId.
      */
     @Test
     public void testMethods() {
-
-        assertThat(piPacketMetadataId1, is(notNullValue()));
-        assertThat(piPacketMetadataId1.name(), is(EGRESS_PORT));
+        assertThat(piControlMetadataId1, is(notNullValue()));
+        assertThat(piControlMetadataId1.id(), is(EGRESS_PORT));
     }
 }
diff --git a/core/api/src/test/java/org/onosproject/net/pi/runtime/PiControlMetadataTest.java b/core/api/src/test/java/org/onosproject/net/pi/runtime/PiControlMetadataTest.java
new file mode 100644
index 0000000..ab80fd6
--- /dev/null
+++ b/core/api/src/test/java/org/onosproject/net/pi/runtime/PiControlMetadataTest.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * 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.pi.runtime;
+
+import com.google.common.testing.EqualsTester;
+import org.junit.Test;
+import org.onosproject.net.pi.model.PiControlMetadataId;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.notNullValue;
+import static org.onlab.junit.ImmutableClassChecker.assertThatClassIsImmutable;
+import static org.onlab.util.ImmutableByteSequence.copyFrom;
+import static org.onosproject.net.pi.runtime.PiConstantsTest.EGRESS_PORT;
+
+/**
+ * Unit tests for PiControlMetadata class.
+ */
+public class PiControlMetadataTest {
+
+    final PiControlMetadataId piControlMetadataId = PiControlMetadataId.of(EGRESS_PORT);
+
+    final PiControlMetadata piControlMetadata1 = PiControlMetadata.builder()
+            .withId(piControlMetadataId)
+            .withValue(copyFrom(0x10))
+            .build();
+    final PiControlMetadata sameAsPiControlMetadata1 = PiControlMetadata.builder()
+            .withId(piControlMetadataId)
+            .withValue(copyFrom(0x10))
+            .build();
+    final PiControlMetadata piControlMetadata2 = PiControlMetadata.builder()
+            .withId(piControlMetadataId)
+            .withValue(copyFrom(0x20))
+            .build();
+
+    /**
+     * Checks that the PiControlMetadata class is immutable.
+     */
+    @Test
+    public void testImmutability() {
+
+        assertThatClassIsImmutable(PiControlMetadata.class);
+    }
+
+    /**
+     * Checks the operation of equals(), hashCode() and toString() methods.
+     */
+    @Test
+    public void testEquals() {
+
+        new EqualsTester()
+                .addEqualityGroup(piControlMetadata1, sameAsPiControlMetadata1)
+                .addEqualityGroup(piControlMetadata2)
+                .testEquals();
+    }
+
+    /**
+     * Checks the methods of PiControlMetadata.
+     */
+    @Test
+    public void testMethods() {
+
+        assertThat(piControlMetadata1, is(notNullValue()));
+        assertThat(piControlMetadata1.id(), is(PiControlMetadataId.of(EGRESS_PORT)));
+        assertThat(piControlMetadata1.value(), is(copyFrom(0x10)));
+    }
+}
diff --git a/core/api/src/test/java/org/onosproject/net/pi/runtime/PiExactFieldMatchTest.java b/core/api/src/test/java/org/onosproject/net/pi/runtime/PiExactFieldMatchTest.java
index af331c6..38b6765 100644
--- a/core/api/src/test/java/org/onosproject/net/pi/runtime/PiExactFieldMatchTest.java
+++ b/core/api/src/test/java/org/onosproject/net/pi/runtime/PiExactFieldMatchTest.java
@@ -19,6 +19,7 @@
 import com.google.common.testing.EqualsTester;
 import org.junit.Test;
 import org.onlab.util.ImmutableByteSequence;
+import org.onosproject.net.pi.model.PiMatchFieldId;
 import org.onosproject.net.pi.model.PiMatchType;
 
 import static org.hamcrest.MatcherAssert.assertThat;
@@ -26,6 +27,7 @@
 import static org.hamcrest.Matchers.notNullValue;
 import static org.onlab.junit.ImmutableClassChecker.assertThatClassIsImmutable;
 import static org.onlab.util.ImmutableByteSequence.copyFrom;
+import static org.onosproject.net.pi.runtime.PiConstantsTest.DOT;
 import static org.onosproject.net.pi.runtime.PiConstantsTest.ETH_HEADER_NAME;
 import static org.onosproject.net.pi.runtime.PiConstantsTest.ETH_TYPE;
 
@@ -33,12 +35,13 @@
  * Unit tests for PiExactFieldMatch class.
  */
 public class PiExactFieldMatchTest {
-    final ImmutableByteSequence value1 = copyFrom(0x0800);
-    final ImmutableByteSequence value2 = copyFrom(0x0806);
-    final PiHeaderFieldId piHeaderField = PiHeaderFieldId.of(ETH_HEADER_NAME, ETH_TYPE);
-    PiExactFieldMatch piExactFieldMatch1 = new PiExactFieldMatch(piHeaderField, value1);
-    PiExactFieldMatch sameAsPiExactFieldMatch1 = new PiExactFieldMatch(piHeaderField, value1);
-    PiExactFieldMatch piExactFieldMatch2 = new PiExactFieldMatch(piHeaderField, value2);
+
+    private final ImmutableByteSequence value1 = copyFrom(0x0800);
+    private final ImmutableByteSequence value2 = copyFrom(0x0806);
+    private final PiMatchFieldId piMatchField = PiMatchFieldId.of(ETH_HEADER_NAME + DOT + ETH_TYPE);
+    private PiExactFieldMatch piExactFieldMatch1 = new PiExactFieldMatch(piMatchField, value1);
+    private PiExactFieldMatch sameAsPiExactFieldMatch1 = new PiExactFieldMatch(piMatchField, value1);
+    private PiExactFieldMatch piExactFieldMatch2 = new PiExactFieldMatch(piMatchField, value2);
 
     /**
      * Checks that the PiExactFieldMatch class is immutable.
@@ -65,8 +68,8 @@
     @Test
     public void testConstruction() {
         final ImmutableByteSequence value = copyFrom(0x0806);
-        final PiHeaderFieldId piHeaderField = PiHeaderFieldId.of(ETH_HEADER_NAME, ETH_TYPE);
-        PiExactFieldMatch piExactFieldMatch = new PiExactFieldMatch(piHeaderField, value);
+        final PiMatchFieldId piMatchField = PiMatchFieldId.of(ETH_HEADER_NAME + DOT + ETH_TYPE);
+        PiExactFieldMatch piExactFieldMatch = new PiExactFieldMatch(piMatchField, value);
         assertThat(piExactFieldMatch, is(notNullValue()));
         assertThat(piExactFieldMatch.value(), is(value));
         assertThat(piExactFieldMatch.type(), is(PiMatchType.EXACT));
diff --git a/core/api/src/test/java/org/onosproject/net/pi/runtime/PiFieldMatchTest.java b/core/api/src/test/java/org/onosproject/net/pi/runtime/PiFieldMatchTest.java
index 89f9442..2e63d45 100644
--- a/core/api/src/test/java/org/onosproject/net/pi/runtime/PiFieldMatchTest.java
+++ b/core/api/src/test/java/org/onosproject/net/pi/runtime/PiFieldMatchTest.java
@@ -17,11 +17,13 @@
 package org.onosproject.net.pi.runtime;
 
 import org.junit.Test;
+import org.onosproject.net.pi.model.PiMatchFieldId;
 import org.onosproject.net.pi.model.PiMatchType;
 
 import static org.junit.Assert.assertEquals;
 import static org.onlab.junit.ImmutableClassChecker.assertThatClassIsImmutableBaseClass;
 import static org.onlab.util.ImmutableByteSequence.copyFrom;
+import static org.onosproject.net.pi.runtime.PiConstantsTest.DOT;
 import static org.onosproject.net.pi.runtime.PiConstantsTest.ETH_HEADER_NAME;
 import static org.onosproject.net.pi.runtime.PiConstantsTest.ETH_TYPE;
 
@@ -41,10 +43,10 @@
 
     @Test
     public void basics() {
-        final PiHeaderFieldId piHeaderField = PiHeaderFieldId.of(ETH_HEADER_NAME, ETH_TYPE);
-        PiFieldMatch piFieldMatch = new PiExactFieldMatch(piHeaderField, copyFrom(0x0806));
+        final PiMatchFieldId piMatchField = PiMatchFieldId.of(ETH_HEADER_NAME + DOT + ETH_TYPE);
+        PiFieldMatch piFieldMatch = new PiExactFieldMatch(piMatchField, copyFrom(0x0806));
 
-        assertEquals(piFieldMatch.fieldId(), piHeaderField);
+        assertEquals(piFieldMatch.fieldId(), piMatchField);
         assertEquals(piFieldMatch.type(), PiMatchType.EXACT);
     }
 }
diff --git a/core/api/src/test/java/org/onosproject/net/pi/runtime/PiHeaderFieldIdTest.java b/core/api/src/test/java/org/onosproject/net/pi/runtime/PiHeaderFieldIdTest.java
deleted file mode 100644
index 8521d5c..0000000
--- a/core/api/src/test/java/org/onosproject/net/pi/runtime/PiHeaderFieldIdTest.java
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * Copyright 2017-present Open Networking Foundation
- *
- * 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.pi.runtime;
-
-import com.google.common.testing.EqualsTester;
-import org.junit.Test;
-
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.hamcrest.Matchers.is;
-import static org.hamcrest.Matchers.notNullValue;
-import static org.onlab.junit.ImmutableClassChecker.assertThatClassIsImmutable;
-import static org.onosproject.net.pi.runtime.PiConstantsTest.DST_ADDR;
-import static org.onosproject.net.pi.runtime.PiConstantsTest.ETH_HEADER_NAME;
-import static org.onosproject.net.pi.runtime.PiConstantsTest.ETH_TYPE;
-import static org.onosproject.net.pi.runtime.PiConstantsTest.IPV4_HEADER_NAME;
-
-/**
- * Unit tests for PiHeaderFieldId class.
- */
-public class PiHeaderFieldIdTest {
-    final String headerName = ETH_HEADER_NAME;
-    final String dstAddr = DST_ADDR;
-    final String etherType = ETH_TYPE;
-
-    final PiHeaderFieldId piHeaderFieldId1 = PiHeaderFieldId.of(headerName, dstAddr);
-    final PiHeaderFieldId sameAsPiHeaderFieldId1 = PiHeaderFieldId.of(headerName, dstAddr);
-    final PiHeaderFieldId piHeaderFieldId2 = PiHeaderFieldId.of(headerName, etherType);
-
-    int index = 10;
-    final PiHeaderFieldId piHeaderFieldId1WithIndex = PiHeaderFieldId.of(headerName, dstAddr, index);
-    final PiHeaderFieldId sameAsPiHeaderFieldId1WithIndex = PiHeaderFieldId.of(headerName, dstAddr, index);
-    final PiHeaderFieldId piHeaderFieldId2WithIndex = PiHeaderFieldId.of(headerName, etherType, index);
-
-    /**
-     * Checks that the PiHeaderFieldId class is immutable.
-     */
-    @Test
-    public void testImmutability() {
-        assertThatClassIsImmutable(PiHeaderFieldId.class);
-    }
-
-    /**
-     * Checks the operation of equals(), hashCode() and toString() methods.
-     */
-    @Test
-    public void testEquals() {
-        new EqualsTester()
-                .addEqualityGroup(piHeaderFieldId1, sameAsPiHeaderFieldId1)
-                .addEqualityGroup(piHeaderFieldId2)
-                .testEquals();
-    }
-
-    /**
-     * Checks the operation of equals(), hashCode() and toString() methods.
-     */
-    @Test
-    public void testEqualsWithIndex() {
-        new EqualsTester()
-                .addEqualityGroup(piHeaderFieldId1WithIndex, sameAsPiHeaderFieldId1WithIndex)
-                .addEqualityGroup(piHeaderFieldId2WithIndex)
-                .testEquals();
-    }
-
-    /**
-     * Checks the construction of a PiHeaderFieldId object.
-     */
-    @Test
-    public void testConstruction() {
-        final String name = IPV4_HEADER_NAME;
-        final String field = DST_ADDR;
-
-        final PiHeaderFieldId piHeaderFieldId = PiHeaderFieldId.of(name, field);
-        assertThat(piHeaderFieldId, is(notNullValue()));
-        assertThat(piHeaderFieldId.headerName(), is(name));
-        assertThat(piHeaderFieldId.fieldName(), is(field));
-    }
-
-    /**
-     * Checks the construction of a PiHeaderFieldId object with index.
-     */
-    @Test
-    public void testConstructionWithIndex() {
-        final String name = IPV4_HEADER_NAME;
-        final String field = DST_ADDR;
-        final int index = 1;
-        final PiHeaderFieldId piHeaderFieldId = PiHeaderFieldId.of(name, field, index);
-        assertThat(piHeaderFieldId, is(notNullValue()));
-        assertThat(piHeaderFieldId.headerName(), is(name));
-        assertThat(piHeaderFieldId.fieldName(), is(field));
-        assertThat(piHeaderFieldId.index(), is(index));
-    }
-}
diff --git a/core/api/src/test/java/org/onosproject/net/pi/runtime/PiLpmFieldMatchTest.java b/core/api/src/test/java/org/onosproject/net/pi/runtime/PiLpmFieldMatchTest.java
index a25c434..8257fcc 100644
--- a/core/api/src/test/java/org/onosproject/net/pi/runtime/PiLpmFieldMatchTest.java
+++ b/core/api/src/test/java/org/onosproject/net/pi/runtime/PiLpmFieldMatchTest.java
@@ -19,6 +19,7 @@
 import com.google.common.testing.EqualsTester;
 import org.junit.Test;
 import org.onlab.util.ImmutableByteSequence;
+import org.onosproject.net.pi.model.PiMatchFieldId;
 import org.onosproject.net.pi.model.PiMatchType;
 
 import static org.hamcrest.MatcherAssert.assertThat;
@@ -26,6 +27,7 @@
 import static org.hamcrest.Matchers.notNullValue;
 import static org.onlab.junit.ImmutableClassChecker.assertThatClassIsImmutable;
 import static org.onlab.util.ImmutableByteSequence.copyFrom;
+import static org.onosproject.net.pi.runtime.PiConstantsTest.DOT;
 import static org.onosproject.net.pi.runtime.PiConstantsTest.DST_ADDR;
 import static org.onosproject.net.pi.runtime.PiConstantsTest.IPV4_HEADER_NAME;
 
@@ -33,13 +35,13 @@
  * Unit tests for PiLpmFieldMatch class.
  */
 public class PiLpmFieldMatchTest {
-    final ImmutableByteSequence value1 = copyFrom(0x0a010101);
-    final ImmutableByteSequence value2 = copyFrom(0x0a010102);
-    int prefixLength = 24;
-    final PiHeaderFieldId piHeaderField = PiHeaderFieldId.of(IPV4_HEADER_NAME, DST_ADDR);
-    PiLpmFieldMatch piLpmFieldMatch1 = new PiLpmFieldMatch(piHeaderField, value1, prefixLength);
-    PiLpmFieldMatch sameAsPiLpmFieldMatch1 = new PiLpmFieldMatch(piHeaderField, value1, prefixLength);
-    PiLpmFieldMatch piLpmFieldMatch2 = new PiLpmFieldMatch(piHeaderField, value2, prefixLength);
+    private final ImmutableByteSequence value1 = copyFrom(0x0a010101);
+    private final ImmutableByteSequence value2 = copyFrom(0x0a010102);
+    private int prefixLength = 24;
+    private final PiMatchFieldId piMatchField = PiMatchFieldId.of(IPV4_HEADER_NAME + DOT + DST_ADDR);
+    private PiLpmFieldMatch piLpmFieldMatch1 = new PiLpmFieldMatch(piMatchField, value1, prefixLength);
+    private PiLpmFieldMatch sameAsPiLpmFieldMatch1 = new PiLpmFieldMatch(piMatchField, value1, prefixLength);
+    private PiLpmFieldMatch piLpmFieldMatch2 = new PiLpmFieldMatch(piMatchField, value2, prefixLength);
 
     /**
      * Checks that the PiLpmFieldMatch class is immutable.
@@ -67,8 +69,8 @@
     public void testConstruction() {
         final ImmutableByteSequence value = copyFrom(0x0a01010a);
         int prefix = 24;
-        final PiHeaderFieldId piHeaderField = PiHeaderFieldId.of(IPV4_HEADER_NAME, DST_ADDR);
-        PiLpmFieldMatch piLpmFieldMatch = new PiLpmFieldMatch(piHeaderField, value, prefix);
+        final PiMatchFieldId piMatchField = PiMatchFieldId.of(IPV4_HEADER_NAME + DOT + DST_ADDR);
+        PiLpmFieldMatch piLpmFieldMatch = new PiLpmFieldMatch(piMatchField, value, prefix);
         assertThat(piLpmFieldMatch, is(notNullValue()));
         assertThat(piLpmFieldMatch.value(), is(value));
         assertThat(piLpmFieldMatch.prefixLength(), is(prefix));
diff --git a/core/api/src/test/java/org/onosproject/net/pi/runtime/PiMatchFieldIdTest.java b/core/api/src/test/java/org/onosproject/net/pi/runtime/PiMatchFieldIdTest.java
new file mode 100644
index 0000000..2724da0
--- /dev/null
+++ b/core/api/src/test/java/org/onosproject/net/pi/runtime/PiMatchFieldIdTest.java
@@ -0,0 +1,104 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * 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.pi.runtime;
+
+import com.google.common.testing.EqualsTester;
+import org.junit.Test;
+import org.onosproject.net.pi.model.PiMatchFieldId;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.notNullValue;
+import static org.onlab.junit.ImmutableClassChecker.assertThatClassIsImmutable;
+import static org.onosproject.net.pi.runtime.PiConstantsTest.DOT;
+import static org.onosproject.net.pi.runtime.PiConstantsTest.DST_ADDR;
+import static org.onosproject.net.pi.runtime.PiConstantsTest.ETH_HEADER_NAME;
+import static org.onosproject.net.pi.runtime.PiConstantsTest.ETH_TYPE;
+import static org.onosproject.net.pi.runtime.PiConstantsTest.IPV4_HEADER_NAME;
+
+/**
+ * Unit tests for PiMatchFieldId class.
+ */
+public class PiMatchFieldIdTest {
+    private final String headerName = ETH_HEADER_NAME;
+    private final String dstAddr = DST_ADDR;
+    private final String etherType = ETH_TYPE;
+
+    private final PiMatchFieldId piMatchFieldId1 = PiMatchFieldId.of(headerName + DOT + dstAddr);
+    private final PiMatchFieldId sameAsPiMatchFieldId1 = PiMatchFieldId.of(headerName + DOT + dstAddr);
+    private final PiMatchFieldId piMatchFieldId2 = PiMatchFieldId.of(headerName + DOT + etherType);
+
+    private int index = 10;
+    private final PiMatchFieldId piMatchFieldId1WithIndex = PiMatchFieldId
+            .of(headerName + DOT + dstAddr + "[" + index + "]");
+    private final PiMatchFieldId sameAsPiMatchFieldId1WithIndex = PiMatchFieldId
+            .of(headerName + DOT + dstAddr + "[" + index + "]");
+    private final PiMatchFieldId piMatchFieldId2WithIndex = PiMatchFieldId
+            .of(headerName + DOT + etherType + "[" + index + "]");
+
+    /**
+     * Checks that the PiMatchFieldId class is immutable.
+     */
+    @Test
+    public void testImmutability() {
+        assertThatClassIsImmutable(PiMatchFieldId.class);
+    }
+
+    /**
+     * Checks the operation of equals(), hashCode() and toString() methods.
+     */
+    @Test
+    public void testEquals() {
+        new EqualsTester()
+                .addEqualityGroup(piMatchFieldId1, sameAsPiMatchFieldId1)
+                .addEqualityGroup(piMatchFieldId2)
+                .testEquals();
+    }
+
+    /**
+     * Checks the operation of equals(), hashCode() and toString() methods.
+     */
+    @Test
+    public void testEqualsWithIndex() {
+        new EqualsTester()
+                .addEqualityGroup(piMatchFieldId1WithIndex, sameAsPiMatchFieldId1WithIndex)
+                .addEqualityGroup(piMatchFieldId2WithIndex)
+                .testEquals();
+    }
+
+    /**
+     * Checks the construction of a PiMatchFieldId object.
+     */
+    @Test
+    public void testConstruction() {
+        final String name = IPV4_HEADER_NAME  + DOT + DST_ADDR;
+        final PiMatchFieldId piMatchFieldId = PiMatchFieldId.of(name);
+        assertThat(piMatchFieldId, is(notNullValue()));
+        assertThat(piMatchFieldId.id(), is(name));
+    }
+
+    /**
+     * Checks the construction of a PiMatchFieldId object with index.
+     */
+    @Test
+    public void testConstructionWithIndex() {
+        final String name = IPV4_HEADER_NAME + DOT + DST_ADDR + "[1]";
+        final PiMatchFieldId piMatchFieldId = PiMatchFieldId.of(name);
+        assertThat(piMatchFieldId, is(notNullValue()));
+        assertThat(piMatchFieldId.id(), is(name));
+    }
+}
diff --git a/core/api/src/test/java/org/onosproject/net/pi/runtime/PiMatchKeyTest.java b/core/api/src/test/java/org/onosproject/net/pi/runtime/PiMatchKeyTest.java
index ea866fa..a6d62af 100644
--- a/core/api/src/test/java/org/onosproject/net/pi/runtime/PiMatchKeyTest.java
+++ b/core/api/src/test/java/org/onosproject/net/pi/runtime/PiMatchKeyTest.java
@@ -21,6 +21,7 @@
 import org.apache.commons.collections.CollectionUtils;
 import org.junit.Test;
 import org.onlab.util.ImmutableByteSequence;
+import org.onosproject.net.pi.model.PiMatchFieldId;
 
 import java.util.Collection;
 
@@ -29,6 +30,7 @@
 import static org.hamcrest.Matchers.notNullValue;
 import static org.onlab.junit.ImmutableClassChecker.assertThatClassIsImmutable;
 import static org.onlab.util.ImmutableByteSequence.copyFrom;
+import static org.onosproject.net.pi.runtime.PiConstantsTest.DOT;
 import static org.onosproject.net.pi.runtime.PiConstantsTest.DST_ADDR;
 import static org.onosproject.net.pi.runtime.PiConstantsTest.IPV4_HEADER_NAME;
 import static org.onosproject.net.pi.runtime.PiConstantsTest.SRC_ADDR;
@@ -38,21 +40,21 @@
  */
 public class PiMatchKeyTest {
 
-    final ImmutableByteSequence value1 = copyFrom(0x0a010101);
-    final ImmutableByteSequence value2 = copyFrom(0x0a010102);
-    int prefixLength = 24;
-    final PiHeaderFieldId piHeaderField1 = PiHeaderFieldId.of(IPV4_HEADER_NAME, SRC_ADDR);
-    final PiHeaderFieldId piHeaderField2 = PiHeaderFieldId.of(IPV4_HEADER_NAME, DST_ADDR);
-    PiLpmFieldMatch piLpmFieldMatch1 = new PiLpmFieldMatch(piHeaderField1, value1, prefixLength);
-    PiLpmFieldMatch piLpmFieldMatch2 = new PiLpmFieldMatch(piHeaderField2, value2, prefixLength);
+    private final ImmutableByteSequence value1 = copyFrom(0x0a010101);
+    private final ImmutableByteSequence value2 = copyFrom(0x0a010102);
+    private int prefixLength = 24;
+    private final PiMatchFieldId piMatchField1 = PiMatchFieldId.of(IPV4_HEADER_NAME + DOT + SRC_ADDR);
+    private final PiMatchFieldId piMatchField2 = PiMatchFieldId.of(IPV4_HEADER_NAME + DOT + DST_ADDR);
+    private PiLpmFieldMatch piLpmFieldMatch1 = new PiLpmFieldMatch(piMatchField1, value1, prefixLength);
+    private PiLpmFieldMatch piLpmFieldMatch2 = new PiLpmFieldMatch(piMatchField2, value2, prefixLength);
 
-    final PiMatchKey piMatchKey1 = PiMatchKey.builder()
+    private final PiMatchKey piMatchKey1 = PiMatchKey.builder()
             .addFieldMatch(piLpmFieldMatch1)
             .build();
-    final PiMatchKey sameAsPiMatchKey1 = PiMatchKey.builder()
+    private final PiMatchKey sameAsPiMatchKey1 = PiMatchKey.builder()
             .addFieldMatch(piLpmFieldMatch1)
             .build();
-    final PiMatchKey piMatchKey2 = PiMatchKey.builder()
+    private final PiMatchKey piMatchKey2 = PiMatchKey.builder()
             .addFieldMatch(piLpmFieldMatch2)
             .build();
 
diff --git a/core/api/src/test/java/org/onosproject/net/pi/runtime/PiPacketMetadataTest.java b/core/api/src/test/java/org/onosproject/net/pi/runtime/PiPacketMetadataTest.java
deleted file mode 100644
index 8ba4d4e..0000000
--- a/core/api/src/test/java/org/onosproject/net/pi/runtime/PiPacketMetadataTest.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright 2017-present Open Networking Foundation
- *
- * 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.pi.runtime;
-
-import com.google.common.testing.EqualsTester;
-import org.junit.Test;
-
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.hamcrest.Matchers.is;
-import static org.hamcrest.Matchers.notNullValue;
-import static org.onlab.junit.ImmutableClassChecker.assertThatClassIsImmutable;
-import static org.onlab.util.ImmutableByteSequence.copyFrom;
-import static org.onosproject.net.pi.runtime.PiConstantsTest.EGRESS_PORT;
-
-/**
- * Unit tests for PiPacketMetadata class.
- */
-public class PiPacketMetadataTest {
-
-    final PiPacketMetadataId piPacketMetadataId = PiPacketMetadataId.of(EGRESS_PORT);
-
-    final PiPacketMetadata piPacketMetadata1 = PiPacketMetadata.builder()
-            .withId(piPacketMetadataId)
-            .withValue(copyFrom(0x10))
-            .build();
-    final PiPacketMetadata sameAsPiPacketMetadata1 = PiPacketMetadata.builder()
-            .withId(piPacketMetadataId)
-            .withValue(copyFrom(0x10))
-            .build();
-    final PiPacketMetadata piPacketMetadata2 = PiPacketMetadata.builder()
-            .withId(piPacketMetadataId)
-            .withValue(copyFrom(0x20))
-            .build();
-
-    /**
-     * Checks that the PiPacketMetadata class is immutable.
-     */
-    @Test
-    public void testImmutability() {
-
-        assertThatClassIsImmutable(PiPacketMetadata.class);
-    }
-
-    /**
-     * Checks the operation of equals(), hashCode() and toString() methods.
-     */
-    @Test
-    public void testEquals() {
-
-        new EqualsTester()
-                .addEqualityGroup(piPacketMetadata1, sameAsPiPacketMetadata1)
-                .addEqualityGroup(piPacketMetadata2)
-                .testEquals();
-    }
-
-    /**
-     * Checks the methods of PiPacketMetadata.
-     */
-    @Test
-    public void testMethods() {
-
-        assertThat(piPacketMetadata1, is(notNullValue()));
-        assertThat(piPacketMetadata1.id(), is(PiPacketMetadataId.of(EGRESS_PORT)));
-        assertThat(piPacketMetadata1.value(), is(copyFrom(0x10)));
-    }
-}
diff --git a/core/api/src/test/java/org/onosproject/net/pi/runtime/PiPacketOperationTest.java b/core/api/src/test/java/org/onosproject/net/pi/runtime/PiPacketOperationTest.java
index 619099f..d675b51 100644
--- a/core/api/src/test/java/org/onosproject/net/pi/runtime/PiPacketOperationTest.java
+++ b/core/api/src/test/java/org/onosproject/net/pi/runtime/PiPacketOperationTest.java
@@ -21,43 +21,50 @@
 import org.apache.commons.collections.CollectionUtils;
 import org.junit.Test;
 import org.onlab.util.ImmutableByteSequence;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.pi.model.PiControlMetadataId;
 
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.Matchers.is;
 import static org.hamcrest.Matchers.notNullValue;
 import static org.onlab.junit.ImmutableClassChecker.assertThatClassIsImmutable;
 import static org.onlab.util.ImmutableByteSequence.copyFrom;
+import static org.onosproject.net.pi.model.PiPacketOperationType.PACKET_OUT;
 import static org.onosproject.net.pi.runtime.PiConstantsTest.EGRESS_PORT;
-import static org.onosproject.net.pi.runtime.PiPacketOperation.Type.PACKET_OUT;
 
 /**
  * Unit tests for PiPacketOperation class.
  */
 public class PiPacketOperationTest {
 
-    final PiPacketOperation piPacketOperation1 = PiPacketOperation.builder()
+    private final DeviceId deviceId = DeviceId.deviceId("dummy");
+
+    private final PiPacketOperation piPacketOperation1 = PiPacketOperation.builder()
+            .forDevice(deviceId)
             .withData(ImmutableByteSequence.ofOnes(512))
             .withType(PACKET_OUT)
-            .withMetadata(PiPacketMetadata.builder()
-                                  .withId(PiPacketMetadataId.of(EGRESS_PORT))
+            .withMetadata(PiControlMetadata.builder()
+                                  .withId(PiControlMetadataId.of(EGRESS_PORT))
                                   .withValue(copyFrom((short) 255))
                                   .build())
             .build();
 
-    final PiPacketOperation sameAsPiPacketOperation1 = PiPacketOperation.builder()
+    private final PiPacketOperation sameAsPiPacketOperation1 = PiPacketOperation.builder()
+            .forDevice(deviceId)
             .withData(ImmutableByteSequence.ofOnes(512))
             .withType(PACKET_OUT)
-            .withMetadata(PiPacketMetadata.builder()
-                                  .withId(PiPacketMetadataId.of(EGRESS_PORT))
+            .withMetadata(PiControlMetadata.builder()
+                                  .withId(PiControlMetadataId.of(EGRESS_PORT))
                                   .withValue(copyFrom((short) 255))
                                   .build())
             .build();
 
-    final PiPacketOperation piPacketOperation2 = PiPacketOperation.builder()
+    private final PiPacketOperation piPacketOperation2 = PiPacketOperation.builder()
+            .forDevice(deviceId)
             .withData(ImmutableByteSequence.ofOnes(512))
             .withType(PACKET_OUT)
-            .withMetadata(PiPacketMetadata.builder()
-                                  .withId(PiPacketMetadataId.of(EGRESS_PORT))
+            .withMetadata(PiControlMetadata.builder()
+                                  .withId(PiControlMetadataId.of(EGRESS_PORT))
                                   .withValue(copyFrom((short) 200))
                                   .build())
             .build();
@@ -90,21 +97,23 @@
     public void testMethods() {
 
         final PiPacketOperation piPacketOperation = PiPacketOperation.builder()
+                .forDevice(deviceId)
                 .withData(ImmutableByteSequence.ofOnes(512))
                 .withType(PACKET_OUT)
-                .withMetadata(PiPacketMetadata.builder()
-                                      .withId(PiPacketMetadataId.of(EGRESS_PORT))
+                .withMetadata(PiControlMetadata.builder()
+                                      .withId(PiControlMetadataId.of(EGRESS_PORT))
                                       .withValue(copyFrom((short) 10))
                                       .build())
                 .build();
 
         assertThat(piPacketOperation, is(notNullValue()));
+        assertThat(piPacketOperation.deviceId(), is(deviceId));
         assertThat(piPacketOperation.type(), is(PACKET_OUT));
         assertThat(piPacketOperation.data(), is(ImmutableByteSequence.ofOnes(512)));
         assertThat("Incorrect metadatas value",
                    CollectionUtils.isEqualCollection(piPacketOperation.metadatas(),
-                                                     ImmutableList.of(PiPacketMetadata.builder()
-                                                                              .withId(PiPacketMetadataId
+                                                     ImmutableList.of(PiControlMetadata.builder()
+                                                                              .withId(PiControlMetadataId
                                                                                               .of(EGRESS_PORT))
                                                                               .withValue(copyFrom((short) 10))
                                                                               .build())));
diff --git a/core/api/src/test/java/org/onosproject/net/pi/runtime/PiRangeFieldMatchTest.java b/core/api/src/test/java/org/onosproject/net/pi/runtime/PiRangeFieldMatchTest.java
index 27c551c..7fb28b9 100644
--- a/core/api/src/test/java/org/onosproject/net/pi/runtime/PiRangeFieldMatchTest.java
+++ b/core/api/src/test/java/org/onosproject/net/pi/runtime/PiRangeFieldMatchTest.java
@@ -19,6 +19,7 @@
 import com.google.common.testing.EqualsTester;
 import org.junit.Test;
 import org.onlab.util.ImmutableByteSequence;
+import org.onosproject.net.pi.model.PiMatchFieldId;
 import org.onosproject.net.pi.model.PiMatchType;
 
 import static org.hamcrest.MatcherAssert.assertThat;
@@ -26,6 +27,7 @@
 import static org.hamcrest.Matchers.notNullValue;
 import static org.onlab.junit.ImmutableClassChecker.assertThatClassIsImmutable;
 import static org.onlab.util.ImmutableByteSequence.copyFrom;
+import static org.onosproject.net.pi.runtime.PiConstantsTest.DOT;
 import static org.onosproject.net.pi.runtime.PiConstantsTest.VID;
 import static org.onosproject.net.pi.runtime.PiConstantsTest.VLAN_HEADER_NAME;
 
@@ -33,15 +35,15 @@
  * Unit tests for PiRangeFieldMatch class.
  */
 public class PiRangeFieldMatchTest {
-    final ImmutableByteSequence high1 = copyFrom(0x10);
-    final ImmutableByteSequence low1 = copyFrom(0x00);
-    final ImmutableByteSequence high2 = copyFrom(0x30);
-    final ImmutableByteSequence low2 = copyFrom(0x40);
+    private final ImmutableByteSequence high1 = copyFrom(0x10);
+    private final ImmutableByteSequence low1 = copyFrom(0x00);
+    private final ImmutableByteSequence high2 = copyFrom(0x30);
+    private final ImmutableByteSequence low2 = copyFrom(0x40);
 
-    final PiHeaderFieldId piHeaderField = PiHeaderFieldId.of(VLAN_HEADER_NAME, VID);
-    PiRangeFieldMatch piRangeFieldMatch1 = new PiRangeFieldMatch(piHeaderField, low1, high1);
-    PiRangeFieldMatch sameAsPiRangeFieldMatch1 = new PiRangeFieldMatch(piHeaderField, low1, high1);
-    PiRangeFieldMatch piRangeFieldMatch2 = new PiRangeFieldMatch(piHeaderField, low2, high2);
+    private final PiMatchFieldId piMatchField = PiMatchFieldId.of(VLAN_HEADER_NAME + DOT + VID);
+    private PiRangeFieldMatch piRangeFieldMatch1 = new PiRangeFieldMatch(piMatchField, low1, high1);
+    private PiRangeFieldMatch sameAsPiRangeFieldMatch1 = new PiRangeFieldMatch(piMatchField, low1, high1);
+    private PiRangeFieldMatch piRangeFieldMatch2 = new PiRangeFieldMatch(piMatchField, low2, high2);
 
     /**
      * Checks that the PiRangeFieldMatch class is immutable.
@@ -69,8 +71,8 @@
     public void testConstruction() {
         final ImmutableByteSequence high = copyFrom(0x50);
         final ImmutableByteSequence low = copyFrom(0x00);
-        final PiHeaderFieldId piHeaderField = PiHeaderFieldId.of(VLAN_HEADER_NAME, VID);
-        PiRangeFieldMatch piRangeFieldMatch = new PiRangeFieldMatch(piHeaderField, low, high);
+        final PiMatchFieldId piMatchField = PiMatchFieldId.of(VLAN_HEADER_NAME + DOT + VID);
+        PiRangeFieldMatch piRangeFieldMatch = new PiRangeFieldMatch(piMatchField, low, high);
         assertThat(piRangeFieldMatch, is(notNullValue()));
         assertThat(piRangeFieldMatch.lowValue(), is(low));
         assertThat(piRangeFieldMatch.highValue(), is(high));
diff --git a/core/api/src/test/java/org/onosproject/net/pi/runtime/PiTableEntryTest.java b/core/api/src/test/java/org/onosproject/net/pi/runtime/PiTableEntryTest.java
index 6caa63c..0b451e8 100644
--- a/core/api/src/test/java/org/onosproject/net/pi/runtime/PiTableEntryTest.java
+++ b/core/api/src/test/java/org/onosproject/net/pi/runtime/PiTableEntryTest.java
@@ -21,13 +21,19 @@
 import org.apache.commons.collections.CollectionUtils;
 import org.junit.Test;
 import org.onlab.util.ImmutableByteSequence;
+import org.onosproject.net.pi.model.PiActionId;
+import org.onosproject.net.pi.model.PiMatchFieldId;
+import org.onosproject.net.pi.model.PiTableId;
 
 import java.util.Map;
 
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.Matchers.is;
 import static org.onlab.junit.ImmutableClassChecker.assertThatClassIsImmutable;
-import static org.onosproject.net.pi.runtime.PiConstantsTest.*;
+import static org.onosproject.net.pi.runtime.PiConstantsTest.DOT;
+import static org.onosproject.net.pi.runtime.PiConstantsTest.DROP;
+import static org.onosproject.net.pi.runtime.PiConstantsTest.DST_ADDR;
+import static org.onosproject.net.pi.runtime.PiConstantsTest.IPV4_HEADER_NAME;
 
 /**
  * Unit tests for PiTableEntry class.
@@ -94,11 +100,11 @@
         long cookie = 0xfff0323;
         int priority = 100;
         double timeout = 1000;
-        PiHeaderFieldId piHeaderFieldId = PiHeaderFieldId.of(IPV4_HEADER_NAME, DST_ADDR);
-        PiFieldMatch piFieldMatch = new PiExactFieldMatch(piHeaderFieldId, ImmutableByteSequence.copyFrom(0x0a010101));
+        PiMatchFieldId piMatchFieldId = PiMatchFieldId.of(IPV4_HEADER_NAME + DOT + DST_ADDR);
+        PiFieldMatch piFieldMatch = new PiExactFieldMatch(piMatchFieldId, ImmutableByteSequence.copyFrom(0x0a010101));
         PiAction piAction = PiAction.builder().withId(PiActionId.of(DROP)).build();
-        final Map<PiHeaderFieldId, PiFieldMatch> fieldMatches = Maps.newHashMap();
-        fieldMatches.put(piHeaderFieldId, piFieldMatch);
+        final Map<PiMatchFieldId, PiFieldMatch> fieldMatches = Maps.newHashMap();
+        fieldMatches.put(piMatchFieldId, piFieldMatch);
         final PiTableEntry piTableEntry = PiTableEntry.builder()
                 .forTable(piTableId)
                 .withMatchKey(PiMatchKey.builder()
@@ -112,6 +118,8 @@
 
         assertThat(piTableEntry.table(), is(piTableId));
         assertThat(piTableEntry.cookie(), is(cookie));
+        assertThat("Priority must be set", piTableEntry.priority().isPresent());
+        assertThat("Timeout must be set", piTableEntry.timeout().isPresent());
         assertThat(piTableEntry.priority().get(), is(priority));
         assertThat(piTableEntry.timeout().get(), is(timeout));
         assertThat("Incorrect match param value",
diff --git a/core/api/src/test/java/org/onosproject/net/pi/runtime/PiTableIdTest.java b/core/api/src/test/java/org/onosproject/net/pi/runtime/PiTableIdTest.java
index d343cd7..eb1de71 100644
--- a/core/api/src/test/java/org/onosproject/net/pi/runtime/PiTableIdTest.java
+++ b/core/api/src/test/java/org/onosproject/net/pi/runtime/PiTableIdTest.java
@@ -18,6 +18,7 @@
 
 import com.google.common.testing.EqualsTester;
 import org.junit.Test;
+import org.onosproject.net.pi.model.PiTableId;
 
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.Matchers.is;
@@ -28,16 +29,12 @@
  * Unit tests for PiTableId class.
  */
 public class PiTableIdTest {
-    final String table10 = "table10";
-    final String table20 = "table20";
-    final PiTableId piTableId1 = PiTableId.of(table10);
-    final PiTableId sameAsPiTableId1 = PiTableId.of(table10);
-    final PiTableId piTableId2 = PiTableId.of(table20);
+    private final String table10 = "table10";
+    private final String table20 = "table20";
+    private final PiTableId piTableId1 = PiTableId.of(table10);
+    private final PiTableId sameAsPiTableId1 = PiTableId.of(table10);
+    private final PiTableId piTableId2 = PiTableId.of(table20);
 
-    final String tableScope = "local";
-    final PiTableId piTableIdWithScope1 = PiTableId.of(tableScope, table10);
-    final PiTableId sameAsPiTableIdWithScope1 = PiTableId.of(tableScope, table10);
-    final PiTableId piTableIdWithScope2 = PiTableId.of(tableScope, table20);
     /**
      * Checks that the PiTableId class is immutable.
      */
@@ -58,37 +55,11 @@
     }
 
     /**
-     * Checks the operation of equals(), hashCode() and toString() methods.
-     */
-    @Test
-    public void testEqualsWithScope() {
-        new EqualsTester()
-                .addEqualityGroup(piTableIdWithScope1, sameAsPiTableIdWithScope1)
-                .addEqualityGroup(piTableIdWithScope2)
-                .testEquals();
-    }
-
-    /**
      * Checks the construction of a PiTableId object.
      */
     @Test
     public void testConstruction() {
-        final String name = "table1";
-        final PiTableId piTableId = PiTableId.of(name);
-        assertThat(piTableId, is(notNullValue()));
-        assertThat(piTableId.name(), is(name));
-    }
-
-    /**
-     * Checks the construction of a PiTableId object.
-     */
-    @Test
-    public void testConstructionWithScope() {
-        final String name = "table1";
-        final String scope = "local";
-        final PiTableId piTableId = PiTableId.of(scope, name);
-        assertThat(piTableId, is(notNullValue()));
-        assertThat(piTableId.name(), is(name));
-        assertThat(piTableId.scope().get(), is(scope));
+        assertThat(piTableId1, is(notNullValue()));
+        assertThat(piTableId1.id(), is(table10));
     }
 }
diff --git a/core/api/src/test/java/org/onosproject/net/pi/runtime/PiTernaryFieldMatchTest.java b/core/api/src/test/java/org/onosproject/net/pi/runtime/PiTernaryFieldMatchTest.java
index 2078496..f36ba6b 100644
--- a/core/api/src/test/java/org/onosproject/net/pi/runtime/PiTernaryFieldMatchTest.java
+++ b/core/api/src/test/java/org/onosproject/net/pi/runtime/PiTernaryFieldMatchTest.java
@@ -19,6 +19,7 @@
 import com.google.common.testing.EqualsTester;
 import org.junit.Test;
 import org.onlab.util.ImmutableByteSequence;
+import org.onosproject.net.pi.model.PiMatchFieldId;
 import org.onosproject.net.pi.model.PiMatchType;
 
 import static org.hamcrest.MatcherAssert.assertThat;
@@ -26,6 +27,7 @@
 import static org.hamcrest.Matchers.notNullValue;
 import static org.onlab.junit.ImmutableClassChecker.assertThatClassIsImmutable;
 import static org.onlab.util.ImmutableByteSequence.copyFrom;
+import static org.onosproject.net.pi.runtime.PiConstantsTest.DOT;
 import static org.onosproject.net.pi.runtime.PiConstantsTest.DST_ADDR;
 import static org.onosproject.net.pi.runtime.PiConstantsTest.IPV4_HEADER_NAME;
 
@@ -33,15 +35,15 @@
  * Unit tests for PiTernaryFieldMatch class.
  */
 public class PiTernaryFieldMatchTest {
-    final ImmutableByteSequence value1 = copyFrom(0x0a010101);
-    final ImmutableByteSequence mask1 = copyFrom(0x00ffffff);
-    final ImmutableByteSequence value2 = copyFrom(0x0a010102);
-    final ImmutableByteSequence mask2 = copyFrom(0x0000ffff);
+    private final ImmutableByteSequence value1 = copyFrom(0x0a010101);
+    private final ImmutableByteSequence mask1 = copyFrom(0x00ffffff);
+    private final ImmutableByteSequence value2 = copyFrom(0x0a010102);
+    private final ImmutableByteSequence mask2 = copyFrom(0x0000ffff);
 
-    final PiHeaderFieldId piHeaderField = PiHeaderFieldId.of(IPV4_HEADER_NAME, DST_ADDR);
-    PiTernaryFieldMatch piTernaryFieldMatch1 = new PiTernaryFieldMatch(piHeaderField, value1, mask1);
-    PiTernaryFieldMatch sameAsPiTernaryFieldMatch1 = new PiTernaryFieldMatch(piHeaderField, value1, mask1);
-    PiTernaryFieldMatch piTernaryFieldMatch2 = new PiTernaryFieldMatch(piHeaderField, value2, mask2);
+    private final PiMatchFieldId piMatchField = PiMatchFieldId.of(IPV4_HEADER_NAME + DOT + DST_ADDR);
+    private PiTernaryFieldMatch piTernaryFieldMatch1 = new PiTernaryFieldMatch(piMatchField, value1, mask1);
+    private PiTernaryFieldMatch sameAsPiTernaryFieldMatch1 = new PiTernaryFieldMatch(piMatchField, value1, mask1);
+    private PiTernaryFieldMatch piTernaryFieldMatch2 = new PiTernaryFieldMatch(piMatchField, value2, mask2);
 
     /**
      * Checks that the PiTernaryFieldMatch class is immutable.
@@ -69,8 +71,8 @@
     public void testConstruction() {
         final ImmutableByteSequence value = copyFrom(0x0a01010a);
         final ImmutableByteSequence mask = copyFrom(0x00ffffff);
-        final PiHeaderFieldId piHeaderField = PiHeaderFieldId.of(IPV4_HEADER_NAME, DST_ADDR);
-        PiTernaryFieldMatch piTernaryFieldMatch = new PiTernaryFieldMatch(piHeaderField, value, mask);
+        final PiMatchFieldId piMatchField = PiMatchFieldId.of(IPV4_HEADER_NAME + DOT + DST_ADDR);
+        PiTernaryFieldMatch piTernaryFieldMatch = new PiTernaryFieldMatch(piMatchField, value, mask);
         assertThat(piTernaryFieldMatch, is(notNullValue()));
         assertThat(piTernaryFieldMatch.value(), is(value));
         assertThat(piTernaryFieldMatch.mask(), is(mask));
diff --git a/core/api/src/test/java/org/onosproject/net/pi/runtime/PiValidFieldMatchTest.java b/core/api/src/test/java/org/onosproject/net/pi/runtime/PiValidFieldMatchTest.java
index 6a32ed1..a62588a 100644
--- a/core/api/src/test/java/org/onosproject/net/pi/runtime/PiValidFieldMatchTest.java
+++ b/core/api/src/test/java/org/onosproject/net/pi/runtime/PiValidFieldMatchTest.java
@@ -18,12 +18,14 @@
 
 import com.google.common.testing.EqualsTester;
 import org.junit.Test;
+import org.onosproject.net.pi.model.PiMatchFieldId;
 import org.onosproject.net.pi.model.PiMatchType;
 
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.Matchers.is;
 import static org.hamcrest.Matchers.notNullValue;
 import static org.onlab.junit.ImmutableClassChecker.assertThatClassIsImmutable;
+import static org.onosproject.net.pi.runtime.PiConstantsTest.DOT;
 import static org.onosproject.net.pi.runtime.PiConstantsTest.VID;
 import static org.onosproject.net.pi.runtime.PiConstantsTest.VLAN_HEADER_NAME;
 
@@ -31,13 +33,12 @@
  * Unit tests for PiValidFieldMatch class.
  */
 public class PiValidFieldMatchTest {
-
-    final boolean isValid1 = true;
-    final boolean isValid2 = false;
-    final PiHeaderFieldId piHeaderField = PiHeaderFieldId.of(VLAN_HEADER_NAME, VID);
-    PiValidFieldMatch piValidFieldMatch1 = new PiValidFieldMatch(piHeaderField, isValid1);
-    PiValidFieldMatch sameAsPiValidFieldMatch1 = new PiValidFieldMatch(piHeaderField, isValid1);
-    PiValidFieldMatch piValidFieldMatch2 = new PiValidFieldMatch(piHeaderField, isValid2);
+    private final boolean isValid1 = true;
+    private final boolean isValid2 = false;
+    private final PiMatchFieldId piMatchField = PiMatchFieldId.of(VLAN_HEADER_NAME + DOT + VID);
+    private PiValidFieldMatch piValidFieldMatch1 = new PiValidFieldMatch(piMatchField, isValid1);
+    private PiValidFieldMatch sameAsPiValidFieldMatch1 = new PiValidFieldMatch(piMatchField, isValid1);
+    private PiValidFieldMatch piValidFieldMatch2 = new PiValidFieldMatch(piMatchField, isValid2);
 
     /**
      * Checks that the PiValidFieldMatch class is immutable.
@@ -63,11 +64,8 @@
      */
     @Test
     public void testConstruction() {
-        final boolean isValid = true;
-        final PiHeaderFieldId piHeaderField = PiHeaderFieldId.of(VLAN_HEADER_NAME, VID);
-        PiValidFieldMatch piTernaryFieldMatch = new PiValidFieldMatch(piHeaderField, isValid);
-        assertThat(piTernaryFieldMatch, is(notNullValue()));
-        assertThat(piTernaryFieldMatch.isValid(), is(isValid));
-        assertThat(piTernaryFieldMatch.type(), is(PiMatchType.VALID));
+        assertThat(piValidFieldMatch1, is(notNullValue()));
+        assertThat(piValidFieldMatch1.isValid(), is(isValid1));
+        assertThat(piValidFieldMatch1.type(), is(PiMatchType.VALID));
     }
 }