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/main/java/org/onosproject/net/pi/model/PiHeaderFieldTypeModel.java b/core/api/src/main/java/org/onosproject/net/pi/model/PiActionGroupType.java
similarity index 67%
copy from core/api/src/main/java/org/onosproject/net/pi/model/PiHeaderFieldTypeModel.java
copy to core/api/src/main/java/org/onosproject/net/pi/model/PiActionGroupType.java
index 2f4c67b..dd92888 100644
--- a/core/api/src/main/java/org/onosproject/net/pi/model/PiHeaderFieldTypeModel.java
+++ b/core/api/src/main/java/org/onosproject/net/pi/model/PiActionGroupType.java
@@ -19,21 +19,13 @@
 import com.google.common.annotations.Beta;
 
 /**
- * Model of a header's field type in a protocol-independent pipeline.
+ * Type of action group in a protocol-independent pipeline.
  */
 @Beta
-public interface PiHeaderFieldTypeModel {
-    /**
-     * Returns the name of this header type field.
-     *
-     * @return a string value
-     */
-    String name();
+public enum PiActionGroupType {
 
     /**
-     * Returns the bit width of this header type field.
-     *
-     * @return an integer value
+     * Performs load-balancing among different members of the group.
      */
-    int bitWidth();
+    SELECT
 }
diff --git a/core/api/src/main/java/org/onosproject/net/pi/model/PiActionId.java b/core/api/src/main/java/org/onosproject/net/pi/model/PiActionId.java
new file mode 100644
index 0000000..1718726
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/pi/model/PiActionId.java
@@ -0,0 +1,52 @@
+/*
+ * 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.model;
+
+import com.google.common.annotations.Beta;
+import org.onlab.util.Identifier;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * Identifier of an action of a match+action table in a protocol-independent pipeline, unique within the scope of a
+ * pipeline model.
+ */
+@Beta
+public final class PiActionId extends Identifier<String> {
+
+    /**
+     * Creates an action identifier.
+     *
+     * @param name action name
+     */
+    private PiActionId(String name) {
+        super(name);
+    }
+
+    /**
+     * Returns an action identifier for the given action name.
+     *
+     * @param name action name
+     * @return action identifier
+     */
+    public static PiActionId of(String name) {
+        checkNotNull(name);
+        checkArgument(!name.isEmpty(), "Name can't be empty");
+        return new PiActionId(name);
+    }
+}
diff --git a/core/api/src/main/java/org/onosproject/net/pi/model/PiActionModel.java b/core/api/src/main/java/org/onosproject/net/pi/model/PiActionModel.java
index 8fd8dc4..4dad230 100644
--- a/core/api/src/main/java/org/onosproject/net/pi/model/PiActionModel.java
+++ b/core/api/src/main/java/org/onosproject/net/pi/model/PiActionModel.java
@@ -18,7 +18,7 @@
 
 import com.google.common.annotations.Beta;
 
-import java.util.List;
+import java.util.Collection;
 import java.util.Optional;
 
 /**
@@ -26,26 +26,27 @@
  */
 @Beta
 public interface PiActionModel {
-    /**
-     * Returns the name of this action.
-     *
-     * @return a string value
-     */
-    String name();
 
     /**
-     * Returns the model of this action's parameter defined by the given name, if present.
+     * Returns the ID of the action.
      *
-     * @param name action name
+     * @return action ID
+     */
+    PiActionId id();
+
+    /**
+     * Returns the model of the action's parameter defined by the given ID, if present.
+     *
+     * @param paramId parameter ID
      * @return action parameter model
      */
-    Optional<PiActionParamModel> param(String name);
+    Optional<PiActionParamModel> param(PiActionParamId paramId);
 
     /**
-     * Returns the list of action parameter models, ordered according to the same action parameters
-     * defined in the pipeline model.
+     * Returns the collection of all parameter models for the action, or an empty collection if this action has no
+     * parameters.
      *
-     * @return list of action parameter models
+     * @return collection of action parameter models
      */
-    List<PiActionParamModel> params();
+    Collection<PiActionParamModel> params();
 }
diff --git a/core/api/src/main/java/org/onosproject/net/pi/model/PiActionParamId.java b/core/api/src/main/java/org/onosproject/net/pi/model/PiActionParamId.java
new file mode 100644
index 0000000..143c7bd
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/pi/model/PiActionParamId.java
@@ -0,0 +1,47 @@
+/*
+ * 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.model;
+
+import com.google.common.annotations.Beta;
+import org.onlab.util.Identifier;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * Identifier of an action runtime parameter in a match+action table of a protocol-independent pipeline, unique within
+ * the scope an action model.
+ */
+@Beta
+public final class PiActionParamId extends Identifier<String> {
+
+    private PiActionParamId(String name) {
+        super(name);
+    }
+
+    /**
+     * Returns a parameter identifier for the given parameter name.
+     *
+     * @param name parameter name
+     * @return parameter identifier
+     */
+    public static PiActionParamId of(String name) {
+        checkNotNull(name);
+        checkArgument(!name.isEmpty(), "Name can't be empty");
+        return new PiActionParamId(name);
+    }
+}
diff --git a/core/api/src/main/java/org/onosproject/net/pi/model/PiActionParamModel.java b/core/api/src/main/java/org/onosproject/net/pi/model/PiActionParamModel.java
index 22ceef6..284d2b2 100644
--- a/core/api/src/main/java/org/onosproject/net/pi/model/PiActionParamModel.java
+++ b/core/api/src/main/java/org/onosproject/net/pi/model/PiActionParamModel.java
@@ -19,21 +19,22 @@
 import com.google.common.annotations.Beta;
 
 /**
- * Model of an action parameter in a protocol-independent pipeline.
+ * Model of an action runtime parameter in a protocol-independent pipeline.
  */
 @Beta
 public interface PiActionParamModel {
-    /**
-     * Returns the name of this action parameter.
-     *
-     * @return a string value
-     */
-    String name();
 
     /**
-     * Return the bit width of this action parameter.
+     * Returns the ID of this action parameter.
      *
-     * @return an integer value
+     * @return action parameter ID
+     */
+    PiActionParamId id();
+
+    /**
+     * Return the size in bits of this action parameter.
+     *
+     * @return size in bits
      */
     int bitWidth();
 }
diff --git a/core/api/src/main/java/org/onosproject/net/pi/model/PiActionProfileId.java b/core/api/src/main/java/org/onosproject/net/pi/model/PiActionProfileId.java
new file mode 100644
index 0000000..5ff6cae
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/pi/model/PiActionProfileId.java
@@ -0,0 +1,41 @@
+/*
+ * 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.model;
+
+import com.google.common.annotations.Beta;
+import org.onlab.util.Identifier;
+
+/**
+ * Identifier of an action profile in a protocol-independent pipeline, unique withing the scope of a pipeline model.
+ */
+@Beta
+public final class PiActionProfileId extends Identifier<String> {
+
+    private PiActionProfileId(String actionProfileName) {
+        super(actionProfileName);
+    }
+
+    /**
+     * Returns an identifier for the given action profile name.
+     *
+     * @param name action profile name
+     * @return action profile ID
+     */
+    public static PiActionProfileId of(String name) {
+        return new PiActionProfileId(name);
+    }
+}
diff --git a/core/api/src/main/java/org/onosproject/net/pi/model/PiActionProfileModel.java b/core/api/src/main/java/org/onosproject/net/pi/model/PiActionProfileModel.java
new file mode 100644
index 0000000..66b8c53
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/pi/model/PiActionProfileModel.java
@@ -0,0 +1,56 @@
+/*
+ * 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.model;
+
+import com.google.common.annotations.Beta;
+
+import java.util.Collection;
+
+/**
+ * Model of an action profile in a protocol-independent pipeline.
+ */
+@Beta
+public interface PiActionProfileModel {
+
+    /**
+     * Returns the ID of this action profile.
+     *
+     * @return action profile ID
+     */
+    PiActionProfileId id();
+
+    /**
+     * Returns the collection of table IDs that use this action profile.
+     *
+     * @return collection of table models
+     */
+    Collection<PiTableId> tables();
+
+    /**
+     * Returns true if this action profile implements dynamic selection, false otherwise.
+     *
+     * @return true if action profile implements dynamic selection, false otherwise
+     */
+    boolean hasSelector();
+
+    /**
+     * Returns the maximum number of member entries of this action profile.
+     *
+     * @return maximum number of member entries
+     */
+    long maxSize();
+}
diff --git a/core/api/src/main/java/org/onosproject/net/pi/model/PiControlMetadataId.java b/core/api/src/main/java/org/onosproject/net/pi/model/PiControlMetadataId.java
new file mode 100644
index 0000000..b17c766
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/pi/model/PiControlMetadataId.java
@@ -0,0 +1,46 @@
+/*
+ * 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.model;
+
+import com.google.common.annotations.Beta;
+import org.onlab.util.Identifier;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * Identifier of a control metadata in a protocol-independent pipeline, unique within the scope of a pipeline model.
+ */
+@Beta
+public final class PiControlMetadataId extends Identifier<String> {
+
+    private PiControlMetadataId(String name) {
+        super(name);
+    }
+
+    /**
+     * Returns an identifier for the given control metadata name.
+     *
+     * @param name control metadata name
+     * @return control metadata ID
+     */
+    public static PiControlMetadataId of(String name) {
+        checkNotNull(name);
+        checkArgument(!name.isEmpty(), "Name can't be empty");
+        return new PiControlMetadataId(name);
+    }
+}
diff --git a/core/api/src/main/java/org/onosproject/net/pi/model/PiHeaderFieldTypeModel.java b/core/api/src/main/java/org/onosproject/net/pi/model/PiControlMetadataModel.java
similarity index 71%
rename from core/api/src/main/java/org/onosproject/net/pi/model/PiHeaderFieldTypeModel.java
rename to core/api/src/main/java/org/onosproject/net/pi/model/PiControlMetadataModel.java
index 2f4c67b..3748eac 100644
--- a/core/api/src/main/java/org/onosproject/net/pi/model/PiHeaderFieldTypeModel.java
+++ b/core/api/src/main/java/org/onosproject/net/pi/model/PiControlMetadataModel.java
@@ -19,21 +19,22 @@
 import com.google.common.annotations.Beta;
 
 /**
- * Model of a header's field type in a protocol-independent pipeline.
+ * Model of a control metadata for a protocol-independent pipeline.
  */
 @Beta
-public interface PiHeaderFieldTypeModel {
-    /**
-     * Returns the name of this header type field.
-     *
-     * @return a string value
-     */
-    String name();
+public interface PiControlMetadataModel {
 
     /**
-     * Returns the bit width of this header type field.
+     * Returns the ID of this control metadata.
      *
-     * @return an integer value
+     * @return packet operation metadata ID
+     */
+    PiControlMetadataId id();
+
+    /**
+     * Returns the size in bits of this metadata.
+     *
+     * @return size in bit
      */
     int bitWidth();
 }
diff --git a/core/api/src/main/java/org/onosproject/net/pi/model/PiCounterId.java b/core/api/src/main/java/org/onosproject/net/pi/model/PiCounterId.java
new file mode 100644
index 0000000..e9fdc5b
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/pi/model/PiCounterId.java
@@ -0,0 +1,46 @@
+/*
+ * 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.model;
+
+import com.google.common.annotations.Beta;
+import org.onlab.util.Identifier;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * Identifier of a counter in a protocol-independent pipeline, unique within the scope of a pipeline model.
+ */
+@Beta
+public final class PiCounterId extends Identifier<String> {
+
+    private PiCounterId(String name) {
+        super(name);
+    }
+
+    /**
+     * Returns an identifier for the given counter name.
+     *
+     * @param name counter name
+     * @return counter ID
+     */
+    public static PiCounterId of(String name) {
+        checkNotNull(name);
+        checkArgument(!name.isEmpty(), "Name can't be empty");
+        return new PiCounterId(name);
+    }
+}
diff --git a/core/api/src/main/java/org/onosproject/net/pi/model/PiCounterModel.java b/core/api/src/main/java/org/onosproject/net/pi/model/PiCounterModel.java
new file mode 100644
index 0000000..4cfbc92
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/pi/model/PiCounterModel.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.model;
+
+import com.google.common.annotations.Beta;
+
+/**
+ * Model of a counter in protocol-independent pipeline.
+ */
+@Beta
+public interface PiCounterModel {
+
+    /**
+     * Counter unit.
+     */
+    enum Unit {
+        /**
+         * Counts only bytes.
+         */
+        BYTES,
+        /**
+         * Counts only packets.
+         */
+        PACKETS,
+        /**
+         * Counts both packets and bytes.
+         */
+        PACKETS_AND_BYTES
+    }
+
+    /**
+     * Returns the ID of this counter.
+     *
+     * @return counter ID
+     */
+    PiCounterId id();
+
+    /**
+     * Returns the type of counter.
+     *
+     * @return counter type
+     */
+    PiCounterType counterType();
+
+    /**
+     * Returns the unit of this counter.
+     *
+     * @return counter unit
+     */
+    Unit unit();
+
+    /**
+     * Returns the table ID associated with this counter. Meaningful only if the counter type is {@link
+     * PiCounterType#DIRECT}.
+     *
+     * @return table model
+     */
+    PiTableId table();
+
+    /**
+     * Returns the number of cells of this counter. Meaningful only if the counter type is {@link
+     * PiCounterType#INDIRECT}.
+     *
+     * @return size
+     */
+    long size();
+}
diff --git a/core/api/src/main/java/org/onosproject/net/pi/model/PiHeaderFieldTypeModel.java b/core/api/src/main/java/org/onosproject/net/pi/model/PiCounterType.java
similarity index 69%
copy from core/api/src/main/java/org/onosproject/net/pi/model/PiHeaderFieldTypeModel.java
copy to core/api/src/main/java/org/onosproject/net/pi/model/PiCounterType.java
index 2f4c67b..4e73483 100644
--- a/core/api/src/main/java/org/onosproject/net/pi/model/PiHeaderFieldTypeModel.java
+++ b/core/api/src/main/java/org/onosproject/net/pi/model/PiCounterType.java
@@ -19,21 +19,18 @@
 import com.google.common.annotations.Beta;
 
 /**
- * Model of a header's field type in a protocol-independent pipeline.
+ * Type of counter in a protocol-independent pipeline.
  */
 @Beta
-public interface PiHeaderFieldTypeModel {
-    /**
-     * Returns the name of this header type field.
-     *
-     * @return a string value
-     */
-    String name();
+public enum PiCounterType {
 
     /**
-     * Returns the bit width of this header type field.
-     *
-     * @return an integer value
+     * Identifies a counter associated to a match-action table, where cells are directly associated to table entries.
      */
-    int bitWidth();
+    DIRECT,
+
+    /**
+     * Identifies a counter not associated with any other resource.
+     */
+    INDIRECT
 }
diff --git a/core/api/src/main/java/org/onosproject/net/pi/model/PiHeaderFieldModel.java b/core/api/src/main/java/org/onosproject/net/pi/model/PiHeaderFieldModel.java
deleted file mode 100644
index 25e9aa1..0000000
--- a/core/api/src/main/java/org/onosproject/net/pi/model/PiHeaderFieldModel.java
+++ /dev/null
@@ -1,39 +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.model;
-
-import com.google.common.annotations.Beta;
-
-/**
- * Model of a header's field instance in a protocol-independent pipeline.
- */
-@Beta
-public interface PiHeaderFieldModel {
-    /**
-     * Returns the header instance of this field instance.
-     *
-     * @return a header instance
-     */
-    PiHeaderModel header();
-
-    /**
-     * Returns the type of this header's field instance.
-     *
-     * @return a field type value
-     */
-    PiHeaderFieldTypeModel type();
-}
diff --git a/core/api/src/main/java/org/onosproject/net/pi/model/PiHeaderModel.java b/core/api/src/main/java/org/onosproject/net/pi/model/PiHeaderModel.java
deleted file mode 100644
index 22d1a24..0000000
--- a/core/api/src/main/java/org/onosproject/net/pi/model/PiHeaderModel.java
+++ /dev/null
@@ -1,58 +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.model;
-
-import com.google.common.annotations.Beta;
-
-/**
- * Model of a header instance in a protocol-independent pipeline.
- */
-@Beta
-public interface PiHeaderModel {
-
-    /**
-     * Returns the name of this header instance.
-     *
-     * @return a string value
-     */
-    String name();
-
-    /**
-     * Returns the type of this header instance.
-     *
-     * @return a header type value
-     */
-    PiHeaderTypeModel type();
-
-    /**
-     * Returns true if this header instance is a metadata, false elsewhere.
-     *
-     * @return a boolean value
-     */
-    boolean isMetadata();
-
-    /**
-     * Returns the index of this header w.r.t. to other headers of the same type.
-     * Index 0 points to the first instance of the header, 1 the second one, etc.
-     * Helpful when dealing with stacked headers. e.g. to match on the second MPLS label.
-     *
-     * @return a non-negative integer value
-     */
-    default int index() {
-        return 0;
-    }
-}
diff --git a/core/api/src/main/java/org/onosproject/net/pi/model/PiHeaderTypeModel.java b/core/api/src/main/java/org/onosproject/net/pi/model/PiHeaderTypeModel.java
deleted file mode 100644
index cfb5ad5..0000000
--- a/core/api/src/main/java/org/onosproject/net/pi/model/PiHeaderTypeModel.java
+++ /dev/null
@@ -1,52 +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.model;
-
-import com.google.common.annotations.Beta;
-
-import java.util.List;
-import java.util.Optional;
-
-/**
- * Model of a header type in a protocol-independent pipeline.
- */
-@Beta
-public interface PiHeaderTypeModel {
-
-    /**
-     * Returns the name of this header type.
-     *
-     * @return name
-     */
-    String name();
-
-    /**
-     * Returns the field type model defined by the given name, if present.
-     *
-     * @param fieldName field name
-     * @return optional field type model
-     */
-    Optional<PiHeaderFieldTypeModel> field(String fieldName);
-
-    /**
-     * Returns a list of field type models for this header type, ordered according to the same
-     * order of header fields as defined in the pipeline model.
-     *
-     * @return list of field type models
-     */
-    List<PiHeaderFieldTypeModel> fields();
-}
diff --git a/core/api/src/main/java/org/onosproject/net/pi/model/PiMatchFieldId.java b/core/api/src/main/java/org/onosproject/net/pi/model/PiMatchFieldId.java
new file mode 100644
index 0000000..ae6f7ca
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/pi/model/PiMatchFieldId.java
@@ -0,0 +1,46 @@
+/*
+ * 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.model;
+
+import com.google.common.annotations.Beta;
+import org.onlab.util.Identifier;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * Identifier of a match field in a protocol-independent pipeline, unique within the scope of a table model.
+ */
+@Beta
+public final class PiMatchFieldId extends Identifier<String> {
+
+    private PiMatchFieldId(String name) {
+        super(name);
+    }
+
+    /**
+     * Returns an identifier for the given match field name.
+     *
+     * @param name match field name
+     * @return match field ID
+     */
+    public static PiMatchFieldId of(String name) {
+        checkNotNull(name);
+        checkArgument(!name.isEmpty(), "Name cannot be empty");
+        return new PiMatchFieldId(name);
+    }
+}
diff --git a/core/api/src/main/java/org/onosproject/net/pi/model/PiTableMatchFieldModel.java b/core/api/src/main/java/org/onosproject/net/pi/model/PiMatchFieldModel.java
similarity index 73%
rename from core/api/src/main/java/org/onosproject/net/pi/model/PiTableMatchFieldModel.java
rename to core/api/src/main/java/org/onosproject/net/pi/model/PiMatchFieldModel.java
index 4daf96f..57d817a 100644
--- a/core/api/src/main/java/org/onosproject/net/pi/model/PiTableMatchFieldModel.java
+++ b/core/api/src/main/java/org/onosproject/net/pi/model/PiMatchFieldModel.java
@@ -22,18 +22,26 @@
  * Model of a table match field in a protocol-independent pipeline.
  */
 @Beta
-public interface PiTableMatchFieldModel {
+public interface PiMatchFieldModel {
+
     /**
-     * Returns the match type of this key.
+     * Returns the ID of this match field.
+     *
+     * @return match field ID
+     */
+    PiMatchFieldId id();
+
+    /**
+     * Returns the number of bits matched by this field.
+     *
+     * @return number of bits
+     */
+    int bitWidth();
+
+    /**
+     * Returns the type of match applied to this field.
      *
      * @return a match type
      */
     PiMatchType matchType();
-
-    /**
-     * Returns the header field instance matched by this key.
-     *
-     * @return a header field value
-     */
-    PiHeaderFieldModel field();
 }
diff --git a/core/api/src/main/java/org/onosproject/net/pi/model/PiMatchType.java b/core/api/src/main/java/org/onosproject/net/pi/model/PiMatchType.java
index 4f6ab07..1e24fce 100644
--- a/core/api/src/main/java/org/onosproject/net/pi/model/PiMatchType.java
+++ b/core/api/src/main/java/org/onosproject/net/pi/model/PiMatchType.java
@@ -23,22 +23,27 @@
  */
 @Beta
 public enum PiMatchType {
+
     /**
      * Exact match type.
      */
     EXACT,
+
     /**
      * Ternary match type.
      */
     TERNARY,
+
     /**
      * Longest-prefix match type.
      */
     LPM,
+
     /**
      * Valid match type.
      */
     VALID,
+
     /**
      * Range match type.
      */
diff --git a/core/api/src/main/java/org/onosproject/net/pi/model/PiMeterId.java b/core/api/src/main/java/org/onosproject/net/pi/model/PiMeterId.java
new file mode 100644
index 0000000..cc88133
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/pi/model/PiMeterId.java
@@ -0,0 +1,46 @@
+/*
+ * 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.model;
+
+import com.google.common.annotations.Beta;
+import org.onlab.util.Identifier;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * Identifier of a meter in a protocol-independent pipeline, unique within the scope of a pipeline model.
+ */
+@Beta
+public final class PiMeterId extends Identifier<String> {
+
+    private PiMeterId(String name) {
+        super(name);
+    }
+
+    /**
+     * Returns an identifier for the given meter name.
+     *
+     * @param name meter name
+     * @return meter ID
+     */
+    public static PiMeterId of(String name) {
+        checkNotNull(name);
+        checkArgument(!name.isEmpty(), "Name can't be empty");
+        return new PiMeterId(name);
+    }
+}
diff --git a/core/api/src/main/java/org/onosproject/net/pi/model/PiMeterModel.java b/core/api/src/main/java/org/onosproject/net/pi/model/PiMeterModel.java
new file mode 100644
index 0000000..237da05
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/pi/model/PiMeterModel.java
@@ -0,0 +1,76 @@
+/*
+ * 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.model;
+
+import com.google.common.annotations.Beta;
+
+/**
+ * Model of a meter in a protocol-independent pipeline.
+ */
+@Beta
+public interface PiMeterModel {
+
+    /**
+     * Meter rate unit.
+     */
+    enum Unit {
+        /**
+         * Measures rate of bytes.
+         */
+        BYTES,
+        /**
+         * Measures rate of packets.
+         */
+        PACKETS
+    }
+
+    /**
+     * Returns the ID of this meter.
+     *
+     * @return meter ID
+     */
+    PiMeterId id();
+
+    /**
+     * Returns the type of this meter.
+     *
+     * @return meter type
+     */
+    PiMeterType meterType();
+
+    /**
+     * Returns the unit of this meter.
+     *
+     * @return unit
+     */
+    Unit unit();
+
+    /**
+     * Returns the table model associated with this meter. Meaningful only if the meter type is {@link
+     * PiMeterType#DIRECT}.
+     *
+     * @return table model
+     */
+    PiTableId table();
+
+    /**
+     * Returns the number of cells of this meter. Meaningful only if the meter type is {@link PiMeterType#INDIRECT}.
+     *
+     * @return size
+     */
+    long size();
+}
diff --git a/core/api/src/main/java/org/onosproject/net/pi/model/PiHeaderFieldTypeModel.java b/core/api/src/main/java/org/onosproject/net/pi/model/PiMeterType.java
similarity index 69%
copy from core/api/src/main/java/org/onosproject/net/pi/model/PiHeaderFieldTypeModel.java
copy to core/api/src/main/java/org/onosproject/net/pi/model/PiMeterType.java
index 2f4c67b..cb2b57f 100644
--- a/core/api/src/main/java/org/onosproject/net/pi/model/PiHeaderFieldTypeModel.java
+++ b/core/api/src/main/java/org/onosproject/net/pi/model/PiMeterType.java
@@ -19,21 +19,19 @@
 import com.google.common.annotations.Beta;
 
 /**
- * Model of a header's field type in a protocol-independent pipeline.
+ * Types of meter in protocol-independent pipeline.
  */
 @Beta
-public interface PiHeaderFieldTypeModel {
-    /**
-     * Returns the name of this header type field.
-     *
-     * @return a string value
-     */
-    String name();
+public enum PiMeterType {
 
     /**
-     * Returns the bit width of this header type field.
-     *
-     * @return an integer value
+     * Identifies a meter associated to a match-action table, where meter cells are directly associated to table
+     * entries.
      */
-    int bitWidth();
+    DIRECT,
+
+    /**
+     * Identifies a meter not associated with any other resource.
+     */
+    INDIRECT
 }
diff --git a/core/api/src/main/java/org/onosproject/net/pi/model/PiPacketOperationModel.java b/core/api/src/main/java/org/onosproject/net/pi/model/PiPacketOperationModel.java
new file mode 100644
index 0000000..70659a6
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/pi/model/PiPacketOperationModel.java
@@ -0,0 +1,44 @@
+/*
+ * 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.model;
+
+import com.google.common.annotations.Beta;
+
+import java.util.List;
+
+/**
+ * Model of a packet operation in a protocol-independent pipeline.
+ */
+@Beta
+public interface PiPacketOperationModel {
+
+    /**
+     * Returns the type of this packet operation.
+     *
+     * @return packet operation type
+     */
+    PiPacketOperationType type();
+
+    /**
+     * Returns a list of control metadata models for this packet operation. The metadata models are returned in the same
+     * order as they would appear on the control header that is prepended to the packet.
+     *
+     * @return list of packet operation metadata models
+     */
+    List<PiControlMetadataModel> metadatas();
+
+}
diff --git a/core/api/src/main/java/org/onosproject/net/pi/model/PiHeaderFieldTypeModel.java b/core/api/src/main/java/org/onosproject/net/pi/model/PiPacketOperationType.java
similarity index 60%
copy from core/api/src/main/java/org/onosproject/net/pi/model/PiHeaderFieldTypeModel.java
copy to core/api/src/main/java/org/onosproject/net/pi/model/PiPacketOperationType.java
index 2f4c67b..360c621 100644
--- a/core/api/src/main/java/org/onosproject/net/pi/model/PiHeaderFieldTypeModel.java
+++ b/core/api/src/main/java/org/onosproject/net/pi/model/PiPacketOperationType.java
@@ -19,21 +19,20 @@
 import com.google.common.annotations.Beta;
 
 /**
- * Model of a header's field type in a protocol-independent pipeline.
+ * Type of packet operation in a protocol-independent pipeline.
  */
 @Beta
-public interface PiHeaderFieldTypeModel {
-    /**
-     * Returns the name of this header type field.
-     *
-     * @return a string value
-     */
-    String name();
+public enum PiPacketOperationType {
 
     /**
-     * Returns the bit width of this header type field.
-     *
-     * @return an integer value
+     * Represents a packet-out, i.e. a packet generated by the control plane, optionally encapsulated with control
+     * information and sent through a network device port.
      */
-    int bitWidth();
+    PACKET_OUT,
+
+    /**
+     * Represents a packet-in, i.e. a packet originated at the data plane, optionally encapsulated with control
+     * information and sent to the controller for further inspection.
+     */
+    PACKET_IN,
 }
diff --git a/core/api/src/main/java/org/onosproject/net/pi/model/PiPipeconf.java b/core/api/src/main/java/org/onosproject/net/pi/model/PiPipeconf.java
index 0185e9b..9b353c8 100644
--- a/core/api/src/main/java/org/onosproject/net/pi/model/PiPipeconf.java
+++ b/core/api/src/main/java/org/onosproject/net/pi/model/PiPipeconf.java
@@ -24,8 +24,8 @@
 import java.util.Optional;
 
 /**
- * Configuration of a protocol-independent pipeline that includes a pipeline model, a collection of
- * pipeline-specific behaviours implementation, and extensions.
+ * Configuration of a protocol-independent pipeline that includes a pipeline model, a collection of pipeline-specific
+ * behaviour implementations, and extensions.
  */
 @Beta
 public interface PiPipeconf {
@@ -75,13 +75,13 @@
      * @param type extension type
      * @return extension input stream
      */
-    // FIXME: this is a sloppy way of handling extensions.
     Optional<InputStream> extension(ExtensionType type);
 
     /**
      * Type of extension of a protocol-independent pipeline configuration.
      */
     enum ExtensionType {
+
         /**
          * The P4Info as returned by the p4c compiler in text format.
          */
diff --git a/core/api/src/main/java/org/onosproject/net/pi/model/PiPipeconfId.java b/core/api/src/main/java/org/onosproject/net/pi/model/PiPipeconfId.java
index fd1b1bd..4f334e2 100644
--- a/core/api/src/main/java/org/onosproject/net/pi/model/PiPipeconfId.java
+++ b/core/api/src/main/java/org/onosproject/net/pi/model/PiPipeconfId.java
@@ -20,7 +20,7 @@
 import org.onlab.util.Identifier;
 
 /**
- * An identifier of a protocol-independent pipeline configuration.
+ * An identifier of a protocol-independent pipeline configuration, unique within the scope of ONOS.
  */
 @Beta
 public final class PiPipeconfId extends Identifier<String> {
diff --git a/core/api/src/main/java/org/onosproject/net/pi/model/PiPipelineInterpreter.java b/core/api/src/main/java/org/onosproject/net/pi/model/PiPipelineInterpreter.java
index 738996f..1068026 100644
--- a/core/api/src/main/java/org/onosproject/net/pi/model/PiPipelineInterpreter.java
+++ b/core/api/src/main/java/org/onosproject/net/pi/model/PiPipelineInterpreter.java
@@ -17,105 +17,99 @@
 package org.onosproject.net.pi.model;
 
 import com.google.common.annotations.Beta;
-import org.onosproject.net.DeviceId;
 import org.onosproject.net.driver.HandlerBehaviour;
 import org.onosproject.net.flow.TrafficTreatment;
 import org.onosproject.net.flow.criteria.Criterion;
 import org.onosproject.net.packet.InboundPacket;
 import org.onosproject.net.packet.OutboundPacket;
 import org.onosproject.net.pi.runtime.PiAction;
-import org.onosproject.net.pi.runtime.PiCounterId;
-import org.onosproject.net.pi.runtime.PiHeaderFieldId;
 import org.onosproject.net.pi.runtime.PiPacketOperation;
-import org.onosproject.net.pi.runtime.PiTableId;
 
 import java.util.Collection;
 import java.util.Optional;
 
 /**
- * An interpreter of a protocol-independent pipeline model.
+ * An interpreter of a PI pipeline model.
  */
 @Beta
 public interface PiPipelineInterpreter extends HandlerBehaviour {
 
     /**
-     * Returns the protocol-independent header field identifier that is equivalent to the given criterion type, if
-     * present. If not present, it means that the given criterion type is not supported by this interpreter.
+     * Returns a PI match field ID that is equivalent to the given criterion type, if present. If not present, it means
+     * that the given criterion type is not supported by this interpreter.
      *
      * @param type criterion type
-     * @return optional header field identifier
+     * @return optional match field ID
      */
-    Optional<PiHeaderFieldId> mapCriterionType(Criterion.Type type);
+    Optional<PiMatchFieldId> mapCriterionType(Criterion.Type type);
 
     /**
-     * Returns the criterion type that is equivalent to the given protocol-independent header field identifier, if
-     * present. If not present, it means that the given field identifier is not supported by this interpreter.
+     * Returns the criterion type that is equivalent to the given PI match field ID, if present. If not present, it
+     * means that the given match field is not supported by this interpreter.
      *
-     * @param headerFieldId header field identifier
+     * @param fieldId match field ID
      * @return optional criterion type
      */
-    Optional<Criterion.Type> mapPiHeaderFieldId(PiHeaderFieldId headerFieldId);
+    Optional<Criterion.Type> mapPiMatchFieldId(PiMatchFieldId fieldId);
 
     /**
-     * Returns a protocol-independent table id equivalent to the given numeric table id (as in {@link
-     * org.onosproject.net.flow.FlowRule#tableId()}). If not present, it means that the given numeric table id cannot be
+     * Returns a PI table ID equivalent to the given numeric table ID (as in {@link
+     * org.onosproject.net.flow.FlowRule#tableId()}). If not present, it means that the given integer table ID cannot be
      * mapped to any table of the pipeline model.
      *
-     * @param flowRuleTableId a numeric table id
-     * @return a protocol-independent table id
+     * @param flowRuleTableId a numeric table ID
+     * @return PI table ID
      */
     Optional<PiTableId> mapFlowRuleTableId(int flowRuleTableId);
 
     /**
-     * Returns a numeric table id (as in {@link org.onosproject.net.flow.FlowRule#tableId()}) equivalent to the given
-     * protocol-independent table id. If not present, it means that the given protocol-independent table id refers to a
-     * table that does not exist, or that cannot be used for flow rule operations.
+     * Returns an integer table ID equivalent to the given PI table ID. If not present, it means that the given PI table
+     * ID refers to a table that does not exist, or that cannot be used for flow rule operations.
      *
-     * @param piTableId protocol-independent table id
-     * @return numeric table id
+     * @param piTableId PI table ID
+     * @return numeric table ID
      */
     Optional<Integer> mapPiTableId(PiTableId piTableId);
 
     /**
-     * Returns an action of a protocol-independent pipeline that is functionally equivalent to the given ONOS traffic
-     * treatment for the given table.
+     * Returns an action of a PI pipeline that is functionally equivalent to the given traffic treatment for the given
+     * table.
      *
-     * @param treatment a ONOS traffic treatment
-     * @param piTableId PI table identifier
-     * @return an action object
-     * @throws PiInterpreterException if the treatment cannot be mapped to any table action
+     * @param treatment traffic treatment
+     * @param piTableId PI table ID
+     * @return action object
+     * @throws PiInterpreterException if the treatment cannot be mapped to any PI action
      */
     PiAction mapTreatment(TrafficTreatment treatment, PiTableId piTableId)
             throws PiInterpreterException;
 
     /**
-     * Returns a protocol-independent direct counter identifier for the given table, if present. If not present, it
-     * means that the given table does not support direct counters.
+     * Returns a PI direct counter ID for the given table, if present. If not present, it means that the given table
+     * does not support direct counters.
      *
-     * @param piTableId table identifier
-     * @return optional direct counter identifier
+     * @param piTableId table ID
+     * @return optional direct counter ID
      */
     Optional<PiCounterId> mapTableCounter(PiTableId piTableId);
 
     /**
-     * Returns a collection of packet operations equivalent to the given OutboundPacket.
+     * Returns a collection of PI packet operations equivalent to the given outbound packet instance.
      *
-     * @param packet a ONOS outbound packet
-     * @return a collection of packet operations
-     * @throws PiInterpreterException if the packet treatments cannot be mapped to any metadata
+     * @param packet outbound packet
+     * @return collection of PI packet operations
+     * @throws PiInterpreterException if the packet treatments cannot be executed by this pipeline
      */
     Collection<PiPacketOperation> mapOutboundPacket(OutboundPacket packet)
             throws PiInterpreterException;
 
     /**
-     * Returns a InboundPacket equivalent to the given packet operation.
+     * Returns an inbound packet equivalent to the given PI packet operation.
      *
-     * @param deviceId          the device that originated the packet-in
-     * @param packetInOperation the packet operation
-     * @return an ONOS inbound packet
-     * @throws PiInterpreterException if the port can't be extracted from the packet metadata
+     * @param packetOperation packet operation
+     * @return inbound packet
+     * @throws PiInterpreterException if the packet operation cannot be mapped to an inbound packet
      */
-    InboundPacket mapInboundPacket(DeviceId deviceId, PiPacketOperation packetInOperation)
+    InboundPacket mapInboundPacket(PiPacketOperation packetOperation)
             throws PiInterpreterException;
 
     /**
@@ -127,4 +121,4 @@
             super(message);
         }
     }
-}
\ No newline at end of file
+}
diff --git a/core/api/src/main/java/org/onosproject/net/pi/model/PiPipelineModel.java b/core/api/src/main/java/org/onosproject/net/pi/model/PiPipelineModel.java
index 123388a..c1840d9 100644
--- a/core/api/src/main/java/org/onosproject/net/pi/model/PiPipelineModel.java
+++ b/core/api/src/main/java/org/onosproject/net/pi/model/PiPipelineModel.java
@@ -28,57 +28,12 @@
 public interface PiPipelineModel {
 
     /**
-     * Returns the header type associated with the given name, if present.
+     * Returns the table model associated with the given ID, if present.
      *
-     * @param name string value
-     * @return optional header type model
-     */
-    Optional<PiHeaderTypeModel> headerType(String name);
-
-    /**
-     * Returns the collection of all header types defined by this pipeline model.
-     *
-     * @return collection of header types
-     */
-    Collection<PiHeaderTypeModel> headerTypes();
-
-    /**
-     * Returns the header instance associated with the given name, if present.
-     *
-     * @param name string value
-     * @return optional header instance model
-     */
-    Optional<PiHeaderModel> header(String name);
-
-    /**
-     * Returns the collection of all header instance models defined by this pipeline model.
-     *
-     * @return collection of header types
-     */
-    Collection<PiHeaderModel> headers();
-
-    /**
-     * Returns the action model associated with the given name, if present.
-     *
-     * @param name string value
-     * @return optional action model
-     */
-    Optional<PiActionModel> action(String name);
-
-    /**
-     * Returns the collection of all action models defined by this pipeline model.
-     *
-     * @return collection of actions
-     */
-    Collection<PiActionModel> actions();
-
-    /**
-     * Returns the table model associated with the given name, if present.
-     *
-     * @param name string value
+     * @param tableId table ID
      * @return optional table model
      */
-    Optional<PiTableModel> table(String name);
+    Optional<PiTableModel> table(PiTableId tableId);
 
     /**
      * Returns the collection of all table models defined by this pipeline model.
@@ -86,4 +41,57 @@
      * @return collection of actions
      */
     Collection<PiTableModel> tables();
+
+    /**
+     * Returns the counter model associated with the given ID, id present.
+     *
+     * @param counterId counter ID
+     * @return optional counter model
+     */
+    Optional<PiCounterModel> counter(PiCounterId counterId);
+
+    /**
+     * Returns all counter models defined by this pipeline model.
+     *
+     * @return collection of counter models
+     */
+    Collection<PiCounterModel> counters();
+
+    /**
+     * Returns the meter model associated with the given ID, id present.
+     *
+     * @param meterId meter ID
+     * @return optional meter model
+     */
+    Optional<PiMeterModel> meter(PiMeterId meterId);
+
+    /**
+     * Returns all meter models defined by this pipeline model.
+     *
+     * @return collection of meter models
+     */
+    Collection<PiMeterModel> meters();
+
+    /**
+     * Returns the action profile model associated with the given ID, id present.
+     *
+     * @param actionProfileId action profile ID
+     * @return optional action profile model
+     */
+    Optional<PiActionProfileModel> actionProfiles(PiActionProfileId actionProfileId);
+
+    /**
+     * Returns all action profile models defined by this pipeline model.
+     *
+     * @return collection of action profile models
+     */
+    Collection<PiActionProfileModel> actionProfiles();
+
+    /**
+     * Returns the packet operation model of the given type, if present.
+     *
+     * @param type packet operation type
+     * @return packet operation model
+     */
+    Optional<PiPacketOperationModel> packetOperationModel(PiPacketOperationType type);
 }
diff --git a/core/api/src/main/java/org/onosproject/net/pi/model/PiPipelineProgrammable.java b/core/api/src/main/java/org/onosproject/net/pi/model/PiPipelineProgrammable.java
deleted file mode 100644
index c222fe6..0000000
--- a/core/api/src/main/java/org/onosproject/net/pi/model/PiPipelineProgrammable.java
+++ /dev/null
@@ -1,43 +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.model;
-
-import org.onosproject.net.driver.HandlerBehaviour;
-
-import java.util.Optional;
-import java.util.concurrent.CompletableFuture;
-
-/**
- * Behavior to program the pipeline of a device.
- */
-public interface PiPipelineProgrammable extends HandlerBehaviour {
-    /**
-     * Deploys the given pipeconf to the device.
-     *
-     * @param pipeconf pipeconf
-     * @return true if the operation was successful, false otherwise
-     */
-    // TODO: return an explanation of why things went wrong, and the status of the device.
-    CompletableFuture<Boolean> deployPipeconf(PiPipeconf pipeconf);
-
-    /**
-     * Returns the default pipeconf for ths device, to be used when any other pipeconf is not available.
-     *
-     * @return optional pipeconf
-     */
-    Optional<PiPipeconf> getDefaultPipeconf();
-}
diff --git a/core/api/src/main/java/org/onosproject/net/pi/model/PiTableId.java b/core/api/src/main/java/org/onosproject/net/pi/model/PiTableId.java
new file mode 100644
index 0000000..2e799a9
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/pi/model/PiTableId.java
@@ -0,0 +1,52 @@
+/*
+ * 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.model;
+
+import com.google.common.annotations.Beta;
+import org.onlab.util.Identifier;
+import org.onosproject.net.flow.TableId;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * Identifier of a table in a protocol-independent pipeline, unique within the scope of a pipeline model.
+ */
+@Beta
+public final class PiTableId extends Identifier<String> implements TableId {
+
+    private PiTableId(String name) {
+        super(name);
+    }
+
+    /**
+     * Returns an identifier for the given table name.
+     *
+     * @param name table name
+     * @return table ID
+     */
+    public static PiTableId of(String name) {
+        checkNotNull(name);
+        checkArgument(!name.isEmpty(), "Name can't be empty");
+        return new PiTableId(name);
+    }
+
+    @Override
+    public Type type() {
+        return Type.PIPELINE_INDEPENDENT;
+    }
+}
diff --git a/core/api/src/main/java/org/onosproject/net/pi/model/PiTableModel.java b/core/api/src/main/java/org/onosproject/net/pi/model/PiTableModel.java
index 038dadd..e2461a8 100644
--- a/core/api/src/main/java/org/onosproject/net/pi/model/PiTableModel.java
+++ b/core/api/src/main/java/org/onosproject/net/pi/model/PiTableModel.java
@@ -28,25 +28,47 @@
 public interface PiTableModel {
 
     /**
-     * Returns the name of this table.
+     * Returns the ID of this table.
      *
      * @return a string value
      */
-    String name();
+    PiTableId id();
+
+    /**
+     * Returns the type of this table.
+     *
+     * @return table type
+     */
+    PiTableType tableType();
+
+    /**
+     * Returns the model of the action profile that implements this table. Meaningful if this table is of type {@link
+     * PiTableType#INDIRECT}, otherwise returns null.
+     *
+     * @return action profile ID
+     */
+    PiActionProfileModel actionProfile();
 
     /**
      * Returns the maximum number of entries supported by this table.
      *
      * @return an integer value
      */
-    int maxSize();
+    long maxSize();
 
     /**
-     * Returns true if this table has counters, false otherwise.
+     * Returns a collection of direct counters associated to this table.
      *
-     * @return a boolean value
+     * @return collection of direct counters
      */
-    boolean hasCounters();
+    Collection<PiCounterModel> counters();
+
+    /**
+     * Returns a collection of direct meters associated to this table.
+     *
+     * @return collection of direct meters
+     */
+    Collection<PiMeterModel> meters();
 
     /**
      * Returns true if this table supports aging, false otherwise.
@@ -60,7 +82,7 @@
      *
      * @return a collection of match field models
      */
-    Collection<PiTableMatchFieldModel> matchFields();
+    Collection<PiMatchFieldModel> matchFields();
 
     /**
      * Returns the actions supported by this table.
@@ -70,12 +92,35 @@
     Collection<PiActionModel> actions();
 
     /**
-     * Returns the action model associated with the given name, if present.
-     * If not present, it means that this table does not support such an action.
+     * Returns the model of the default action associated with this table, if any.
      *
-     * @param name string value
+     * @return optional default action model
+     */
+    Optional<PiActionModel> defaultAction();
+
+    /**
+     * Returns true if the default action has mutable parameters that can be changed at runtime, false otherwise.
+     *
+     * @return true if the default action has mutable parameters, false otherwise
+     */
+    boolean hasDefaultMutableParams();
+
+    /**
+     * Returns the action model associated with the given ID, if present. If not present, it means that this table does
+     * not support such an action.
+     *
+     * @param actionId action ID
      * @return optional action model
      */
-    Optional<PiActionModel> action(String name);
+    Optional<PiActionModel> action(PiActionId actionId);
+
+    /**
+     * Returns the match field model associated with the given ID, if present. If not present, it means that this table
+     * does not support such a match field.
+     *
+     * @param matchFieldId match field ID
+     * @return optional match field model
+     */
+    Optional<PiMatchFieldModel> matchField(PiMatchFieldId matchFieldId);
 
 }
diff --git a/core/api/src/main/java/org/onosproject/net/pi/model/PiHeaderFieldTypeModel.java b/core/api/src/main/java/org/onosproject/net/pi/model/PiTableType.java
similarity index 64%
copy from core/api/src/main/java/org/onosproject/net/pi/model/PiHeaderFieldTypeModel.java
copy to core/api/src/main/java/org/onosproject/net/pi/model/PiTableType.java
index 2f4c67b..9fa31ed 100644
--- a/core/api/src/main/java/org/onosproject/net/pi/model/PiHeaderFieldTypeModel.java
+++ b/core/api/src/main/java/org/onosproject/net/pi/model/PiTableType.java
@@ -16,24 +16,18 @@
 
 package org.onosproject.net.pi.model;
 
-import com.google.common.annotations.Beta;
-
 /**
- * Model of a header's field type in a protocol-independent pipeline.
+ * Types of match+action table in a protocol-independent pipeline.
  */
-@Beta
-public interface PiHeaderFieldTypeModel {
-    /**
-     * Returns the name of this header type field.
-     *
-     * @return a string value
-     */
-    String name();
+public enum PiTableType {
 
     /**
-     * Returns the bit width of this header type field.
-     *
-     * @return an integer value
+     * Regular match+action table.
      */
-    int bitWidth();
+    DIRECT,
+
+    /**
+     * Implementation-based table, e.g. ECMP table where the action executed depends on a selection function.
+     */
+    INDIRECT
 }
diff --git a/core/api/src/main/java/org/onosproject/net/pi/model/package-info.java b/core/api/src/main/java/org/onosproject/net/pi/model/package-info.java
index 5d9a05b..a218d7c 100644
--- a/core/api/src/main/java/org/onosproject/net/pi/model/package-info.java
+++ b/core/api/src/main/java/org/onosproject/net/pi/model/package-info.java
@@ -15,6 +15,6 @@
  */
 
 /**
- * Base abstractions of a protocol-independent packet forwarding pipeline.
+ * Base abstractions of a protocol-independent packet processing pipeline.
  */
-package org.onosproject.net.pi.model;
\ No newline at end of file
+package org.onosproject.net.pi.model;