Added a set of abstractions for flow rule subsystem.
Added an apps source subtree.
diff --git a/core/api/src/main/java/org/onlab/onos/net/flow/Criteria.java b/core/api/src/main/java/org/onlab/onos/net/flow/Criteria.java
new file mode 100644
index 0000000..9595797
--- /dev/null
+++ b/core/api/src/main/java/org/onlab/onos/net/flow/Criteria.java
@@ -0,0 +1,25 @@
+package org.onlab.onos.net.flow;
+
+/**
+ * Factory class to create various traffic selection criteria.
+ */
+public final class Criteria {
+
+    // Ban construction
+    private Criteria() {
+    }
+
+    /**
+     * Creates a match on ETH_SRC field using the specified value. This value
+     * may be a wildcard mask.
+     *
+     * @param macValue MAC address value or wildcard mask
+     * @return match criterion
+     */
+    public static Criterion matchEthSrc(MACValue macValue) {
+        return null;
+    }
+
+    // Dummy to illustrate the concept for now; delete ASAP
+    private static class MACValue { }
+}
diff --git a/core/api/src/main/java/org/onlab/onos/net/flow/Criterion.java b/core/api/src/main/java/org/onlab/onos/net/flow/Criterion.java
new file mode 100644
index 0000000..0b55a42
--- /dev/null
+++ b/core/api/src/main/java/org/onlab/onos/net/flow/Criterion.java
@@ -0,0 +1,98 @@
+package org.onlab.onos.net.flow;
+
+/**
+ * Representation of a single header field selection.
+ */
+public interface Criterion {
+
+    /**
+     * Types of fields to which the selection criterion may apply.
+     */
+    // From page 42 of OpenFlow 1.3.x spec
+    public enum Type {
+        /** Switch input port. */
+        IN_PORT,
+        /** Switch physical input port. */
+        IN_PHY_PORT,
+        /** Metadata passed between tables. */
+        METADATA,
+        /** Ethernet destination address. */
+        ETH_DST,
+        /** Ethernet source address. */
+        ETH_SRC,
+        /** Ethernet frame type. */
+        ETH_TYPE,
+        /** VLAN id. */
+        VLAN_VID,
+        /** VLAN priority. */
+        VLAN_PCP,
+        /** IP DSCP (6 bits in ToS field). */
+        IP_DSCP,
+        /** IP ECN (2 bits in ToS field). */
+        IP_ECN,
+        /** IP protocol. */
+        IP_PROTO,
+        /** IPv4 source address. */
+        IPV4_SRC,
+        /** IPv4 destination address. */
+        IPV4_DST,
+        /** TCP source port. */
+        TCP_SRC,
+        /** TCP destination port. */
+        TCP_DST,
+        /** UDP source port. */
+        UDP_SRC,
+        /** UDP destination port. */
+        UDP_DST,
+        /** SCTP source port. */
+        SCTP_SRC,
+        /** SCTP destination port. */
+        SCTP_DST,
+        /** ICMP type. */
+        ICMPV4_TYPE,
+        /** ICMP code. */
+        ICMPV4_CODE,
+        /** ARP opcode. */
+        ARP_OP,
+        /** ARP source IPv4 address. */
+        ARP_SPA,
+        /** ARP target IPv4 address. */
+        ARP_TPA,
+        /** ARP source hardware address. */
+        ARP_SHA,
+        /** ARP target hardware address. */
+        ARP_THA,
+        /** IPv6 source address. */
+        IPV6_SRC,
+        /** IPv6 destination address. */
+        IPV6_DST,
+        /** IPv6 Flow Label. */
+        IPV6_FLABEL,
+        /** ICMPv6 type. */
+        ICMPV6_TYPE,
+        /** ICMPv6 code. */
+        ICMPV6_CODE,
+        /** Target address for ND. */
+        IPV6_ND_TARGET,
+        /** Source link-layer for ND. */
+        IPV6_ND_SLL,
+        /** Target link-layer for ND. */
+        IPV6_ND_TLL,
+        /** MPLS label. */
+        MPLS_LABEL,
+        /** MPLS TC. */
+        MPLS_TC,
+        /** MPLS BoS bit. */
+        MPLS_BOS,
+        /** PBB I-SID. */
+        PBB_ISID,
+        /** Logical Port Metadata. */
+        TUNNEL_ID,
+        /** IPv6 Extension Header pseudo-field. */
+        IPV6_EXTHDR
+    }
+
+    // TODO: Create factory class 'Criteria' that will have various factory
+    // to create specific criterions.
+
+}
diff --git a/core/api/src/main/java/org/onlab/onos/net/flow/FlowDescription.java b/core/api/src/main/java/org/onlab/onos/net/flow/FlowDescription.java
deleted file mode 100644
index 2a64815..0000000
--- a/core/api/src/main/java/org/onlab/onos/net/flow/FlowDescription.java
+++ /dev/null
@@ -1,12 +0,0 @@
-package org.onlab.onos.net.flow;
-
-import org.onlab.onos.net.Description;
-
-/**
- * Information about a flow rule.
- */
-public interface FlowDescription extends Description {
-
-    // Match and action, possibly reason for flow rule, unless reason is too OF-specific.
-
-}
diff --git a/core/api/src/main/java/org/onlab/onos/net/flow/FlowEntry.java b/core/api/src/main/java/org/onlab/onos/net/flow/FlowEntry.java
new file mode 100644
index 0000000..12a8cb4
--- /dev/null
+++ b/core/api/src/main/java/org/onlab/onos/net/flow/FlowEntry.java
@@ -0,0 +1,36 @@
+package org.onlab.onos.net.flow;
+
+/**
+ * Represents a flow rule and its associated accumulated metrics.
+ */
+public interface FlowEntry extends FlowRule {
+
+    /**
+     * Returns the number of milliseconds this flow rule has been applied.
+     *
+     * @return number of millis
+     */
+    long lifeMillis();
+
+    /**
+     * Returns the number of milliseconds this flow rule has been idle.
+     *
+     * @return number of millis
+     */
+    long idleMillis();
+
+    /**
+     * Returns the number of packets this flow rule has matched.
+     *
+     * @return number of packets
+     */
+    long packets();
+
+    /**
+     * Returns the number of bytes this flow rule has matched.
+     *
+     * @return number of bytes
+     */
+    long bytes();
+
+}
diff --git a/core/api/src/main/java/org/onlab/onos/net/flow/FlowRule.java b/core/api/src/main/java/org/onlab/onos/net/flow/FlowRule.java
new file mode 100644
index 0000000..7204745
--- /dev/null
+++ b/core/api/src/main/java/org/onlab/onos/net/flow/FlowRule.java
@@ -0,0 +1,43 @@
+package org.onlab.onos.net.flow;
+
+import org.onlab.onos.net.DeviceId;
+
+import java.util.List;
+
+/**
+ * Represents a generalized match & action pair to be applied to
+ * an infrastucture device.
+ */
+public interface FlowRule {
+
+    /**
+     * Returns the flow rule priority given in natural order; higher numbers
+     * mean higher priorities.
+     *
+     * @return flow rule priority
+     */
+    int priority();
+
+    /**
+     * Returns the identity of the device where this rule applies.
+     *
+     * @return device identifier
+     */
+    DeviceId deviceId();
+
+    /**
+     * Returns the traffic selector that identifies what traffic this
+     * rule should apply to.
+     *
+     * @return traffic selector
+     */
+    TrafficSelector selector();
+
+    /**
+     * Returns the traffic treatment that applies to selected traffic.
+     *
+     * @return traffic treatment
+     */
+    List<Treatment> treatments();
+
+}
diff --git a/core/api/src/main/java/org/onlab/onos/net/flow/FlowRuleEvent.java b/core/api/src/main/java/org/onlab/onos/net/flow/FlowRuleEvent.java
new file mode 100644
index 0000000..566c2b4
--- /dev/null
+++ b/core/api/src/main/java/org/onlab/onos/net/flow/FlowRuleEvent.java
@@ -0,0 +1,47 @@
+package org.onlab.onos.net.flow;
+
+import org.onlab.onos.event.AbstractEvent;
+
+/**
+ * Describes flow rule event.
+ */
+public class FlowRuleEvent extends AbstractEvent<FlowRuleEvent.Type, FlowRule> {
+
+    /**
+     * Type of flow rule events.
+     */
+    public enum Type {
+        /**
+         * Signifies that a new flow rule has been detected.
+         */
+        RULE_ADDED,
+
+        /**
+         * Signifies that a flow rule has been removed.
+         */
+        RULE_REMOVED,
+    }
+
+    /**
+     * Creates an event of a given type and for the specified flow rule and the
+     * current time.
+     *
+     * @param type     flow rule event type
+     * @param flowRule event flow rule subject
+     */
+    public FlowRuleEvent(Type type, FlowRule flowRule) {
+        super(type, flowRule);
+    }
+
+    /**
+     * Creates an event of a given type and for the specified flow rule and time.
+     *
+     * @param type     flow rule event type
+     * @param flowRule event flow rule subject
+     * @param time     occurrence time
+     */
+    public FlowRuleEvent(Type type, FlowRule flowRule, long time) {
+        super(type, flowRule, time);
+    }
+
+}
diff --git a/core/api/src/main/java/org/onlab/onos/net/flow/FlowRuleListener.java b/core/api/src/main/java/org/onlab/onos/net/flow/FlowRuleListener.java
new file mode 100644
index 0000000..114732b
--- /dev/null
+++ b/core/api/src/main/java/org/onlab/onos/net/flow/FlowRuleListener.java
@@ -0,0 +1,9 @@
+package org.onlab.onos.net.flow;
+
+import org.onlab.onos.event.EventListener;
+
+/**
+ * Entity capable of receiving flow rule related events.
+ */
+public interface FlowRuleListener extends EventListener<FlowRuleEvent> {
+}
diff --git a/core/api/src/main/java/org/onlab/onos/net/flow/FlowRuleProvider.java b/core/api/src/main/java/org/onlab/onos/net/flow/FlowRuleProvider.java
index 894e245..9d31631 100644
--- a/core/api/src/main/java/org/onlab/onos/net/flow/FlowRuleProvider.java
+++ b/core/api/src/main/java/org/onlab/onos/net/flow/FlowRuleProvider.java
@@ -1,5 +1,6 @@
 package org.onlab.onos.net.flow;
 
+import org.onlab.onos.net.DeviceId;
 import org.onlab.onos.net.provider.Provider;
 
 /**
@@ -7,6 +8,23 @@
  */
 public interface FlowRuleProvider extends Provider {
 
-    // TODO: pushFlowRule
+    /**
+     * Instructs the provider to apply the specified flow rules to their
+     * respective devices.
+     * @param flowRules one or more flow rules
+     * throws SomeKindOfException that indicates which ones were applied and
+     *                  which ones failed
+     */
+    void applyFlowRule(FlowRule... flowRules);
+
+
+    /**
+     * Returns the collection of flow entries currently applied on the given
+     * device.
+     *
+     * @param deviceId device identifier
+     * @return collection of flow entries
+     */
+    Iterable<FlowEntry> getFlowMetrics(DeviceId deviceId);
 
 }
diff --git a/core/api/src/main/java/org/onlab/onos/net/flow/FlowRuleProviderService.java b/core/api/src/main/java/org/onlab/onos/net/flow/FlowRuleProviderService.java
index a483d92..76689c2 100644
--- a/core/api/src/main/java/org/onlab/onos/net/flow/FlowRuleProviderService.java
+++ b/core/api/src/main/java/org/onlab/onos/net/flow/FlowRuleProviderService.java
@@ -3,33 +3,23 @@
 import org.onlab.onos.net.provider.ProviderService;
 
 /**
- * Service through which flowrule providers can inject flowrule information into
+ * Service through which flow rule providers can inject information into
  * the core.
  */
 public interface FlowRuleProviderService extends ProviderService<FlowRuleProvider> {
 
     /**
-     * Signals that a flow that was previously installed has been removed.
+     * Signals that a flow rule that was previously installed has been removed.
      *
-     * @param flowDescription information about the removed flow
+     * @param flowRule information about the removed flow
      */
-    void flowRemoved(FlowDescription flowDescription);
+    void flowRemoved(FlowRule flowRule);
 
     /**
-     * Signals that a flowrule is missing for some network traffic.
+     * Signals that a flow rule is missing for some network traffic.
      *
-     * @param flowDescription information about traffic in need of flow rule(s)
+     * @param flowRule information about traffic in need of flow rule(s)
      */
-    void flowMissing(FlowDescription flowDescription);
-
-    /**
-     * Signals that a flowrule has been added.
-     *
-     * TODO  think about if this really makes sense, e.g. if stats collection or
-     * something can leverage it.
-     *
-     * @param flowDescription the rule that was added
-     */
-    void flowAdded(FlowDescription flowDescription);
+    void flowMissing(FlowRule flowRule);
 
 }
diff --git a/core/api/src/main/java/org/onlab/onos/net/flow/FlowRuleService.java b/core/api/src/main/java/org/onlab/onos/net/flow/FlowRuleService.java
new file mode 100644
index 0000000..ccb6a51
--- /dev/null
+++ b/core/api/src/main/java/org/onlab/onos/net/flow/FlowRuleService.java
@@ -0,0 +1,42 @@
+package org.onlab.onos.net.flow;
+
+import org.onlab.onos.net.DeviceId;
+
+/**
+ * Service for injecting flow rules into the environment and for obtaining
+ * information about flow rules already in the environment.
+ */
+public interface FlowRuleService {
+
+    /**
+     * Returns the collection of flow entries applied on the specified device.
+     *
+     * @param deviceId device identifier
+     * @return collection of flow rules
+     */
+    Iterable<FlowEntry> getFlowEntries(DeviceId deviceId);
+
+    /**
+     * Applies the specified flow rules onto their respective devices.
+     *
+     * @param flowRules one or more flow rules
+     * throws SomeKindOfException that indicates which ones were applied and
+     *                  which ones failed
+     */
+    void applyFlowRules(FlowRule... flowRules);
+
+    /**
+     * Adds the specified flow rule listener.
+     *
+     * @param listener flow rule listener
+     */
+    void addListener(FlowRuleListener listener);
+
+    /**
+     * Removes the specified flow rule listener.
+     *
+     * @param listener flow rule listener
+     */
+    void removeListener(FlowRuleListener listener);
+
+}
diff --git a/core/api/src/main/java/org/onlab/onos/net/flow/Instruction.java b/core/api/src/main/java/org/onlab/onos/net/flow/Instruction.java
new file mode 100644
index 0000000..9fc1489
--- /dev/null
+++ b/core/api/src/main/java/org/onlab/onos/net/flow/Instruction.java
@@ -0,0 +1,36 @@
+package org.onlab.onos.net.flow;
+
+/**
+ * Abstraction of a single traffic treatment step.
+ */
+public interface Instruction {
+
+    /**
+     * Represents the type of traffic treatment.
+     */
+    public enum Type {
+        /**
+         * Signifies that the traffic should be dropped.
+         */
+        DROP,
+
+        /**
+         * Signifies that the traffic should be output to a port.
+         */
+        OUTPUT,
+
+        /**
+         * Signifies that.... (do we need this?)
+         */
+        GROUP,
+
+        /**
+         * Signifies that the traffic should be modified in some way.
+         */
+        MODIFICATION
+    }
+
+    // TODO: Create factory class 'Instructions' that will have various factory
+    // to create specific instructions.
+
+}
diff --git a/core/api/src/main/java/org/onlab/onos/net/flow/Instructions.java b/core/api/src/main/java/org/onlab/onos/net/flow/Instructions.java
new file mode 100644
index 0000000..13114c3
--- /dev/null
+++ b/core/api/src/main/java/org/onlab/onos/net/flow/Instructions.java
@@ -0,0 +1,27 @@
+package org.onlab.onos.net.flow;
+
+import org.onlab.onos.net.PortNumber;
+
+/**
+ * Factory class for creating various traffic treatment instructions.
+ */
+public final class Instructions {
+
+    // Ban construction
+    private Instructions() {
+    }
+
+    /**
+     * Creates an output instruction using the specified port number. This can
+     * include logical ports such as CONTROLLER, FLOOD, etc.
+     *
+     * @param number port number
+     * @return output instruction
+     */
+    public static Instruction createOutput(PortNumber number) {
+        return null;
+    }
+
+    // TODO: add create methods
+
+}
diff --git a/core/api/src/main/java/org/onlab/onos/net/flow/TrafficSelector.java b/core/api/src/main/java/org/onlab/onos/net/flow/TrafficSelector.java
new file mode 100644
index 0000000..c024e9c
--- /dev/null
+++ b/core/api/src/main/java/org/onlab/onos/net/flow/TrafficSelector.java
@@ -0,0 +1,38 @@
+package org.onlab.onos.net.flow;
+
+import java.util.List;
+
+/**
+ * Abstraction of a slice of network traffic.
+ */
+public interface TrafficSelector {
+
+    /**
+     * Returns selection criteria as an ordered list.
+     *
+     * @return list of criteria
+     */
+    List<Criterion> criteria();
+
+    /**
+     * Builder of traffic selector entities.
+     */
+    public interface Builder {
+
+        /**
+         * Adds a traffic selection criterion. If a same type criterion has
+         * already been added, it will be replaced by this one.
+         *
+         * @param criterion new criterion
+         */
+        void add(Criterion criterion);
+
+        /**
+         * Builds an immutable traffic selector.
+         *
+         * @return traffic selector
+         */
+        TrafficSelector build();
+    }
+
+}
diff --git a/core/api/src/main/java/org/onlab/onos/net/flow/TrafficTreatment.java b/core/api/src/main/java/org/onlab/onos/net/flow/TrafficTreatment.java
new file mode 100644
index 0000000..0eb5299
--- /dev/null
+++ b/core/api/src/main/java/org/onlab/onos/net/flow/TrafficTreatment.java
@@ -0,0 +1,38 @@
+package org.onlab.onos.net.flow;
+
+import java.util.List;
+
+/**
+ * Abstraction of network traffic treatment.
+ */
+public interface TrafficTreatment {
+
+    /**
+     * Returns list of instructions on how to treat traffic.
+     *
+     * @return list of treatment instructions
+     */
+    List<Instruction> instructions();
+
+    /**
+     * Builder of traffic treatment entities.
+     */
+    public interface Builder {
+
+        /**
+         * Adds a traffic treatment instruction. If a same type instruction has
+         * already been added, it will be replaced by this one.
+         *
+         * @param instruction new instruction
+         */
+        void add(Instruction instruction);
+
+        /**
+         * Builds an immutable traffic treatment descriptor.
+         *
+         * @return traffic treatment
+         */
+        TrafficTreatment build();
+    }
+
+}
diff --git a/core/api/src/main/java/org/onlab/onos/net/packet/Treatment.java b/core/api/src/main/java/org/onlab/onos/net/flow/Treatment.java
similarity index 92%
rename from core/api/src/main/java/org/onlab/onos/net/packet/Treatment.java
rename to core/api/src/main/java/org/onlab/onos/net/flow/Treatment.java
index 411ec38..8318b66 100644
--- a/core/api/src/main/java/org/onlab/onos/net/packet/Treatment.java
+++ b/core/api/src/main/java/org/onlab/onos/net/flow/Treatment.java
@@ -1,4 +1,4 @@
-package org.onlab.onos.net.packet;
+package org.onlab.onos.net.flow;
 
 import org.onlab.onos.net.PortNumber;
 
diff --git a/core/api/src/main/java/org/onlab/onos/net/packet/DefaultOutboundPacket.java b/core/api/src/main/java/org/onlab/onos/net/packet/DefaultOutboundPacket.java
index 7a55f32..8c2495c 100644
--- a/core/api/src/main/java/org/onlab/onos/net/packet/DefaultOutboundPacket.java
+++ b/core/api/src/main/java/org/onlab/onos/net/packet/DefaultOutboundPacket.java
@@ -1,31 +1,30 @@
 package org.onlab.onos.net.packet;
 
 import com.google.common.base.MoreObjects;
-import com.google.common.collect.ImmutableList;
 import org.onlab.onos.net.DeviceId;
+import org.onlab.onos.net.flow.TrafficTreatment;
 
 import java.nio.ByteBuffer;
-import java.util.List;
 
 /**
  * Default implementation of an immutable outbound packet.
  */
 public class DefaultOutboundPacket implements OutboundPacket {
     private final DeviceId sendThrough;
-    private final List<Treatment> treatments;
+    private final TrafficTreatment treatment;
     private final ByteBuffer data;
 
     /**
      * Creates an immutable outbound packet.
      *
      * @param sendThrough identifier through which to send the packet
-     * @param treatments  list of packet treatments
+     * @param treatment   list of packet treatments
      * @param data        raw packet data
      */
     public DefaultOutboundPacket(DeviceId sendThrough,
-                                 List<Treatment> treatments, ByteBuffer data) {
+                                 TrafficTreatment treatment, ByteBuffer data) {
         this.sendThrough = sendThrough;
-        this.treatments = ImmutableList.copyOf(treatments);
+        this.treatment = treatment;
         this.data = data;
     }
 
@@ -35,8 +34,8 @@
     }
 
     @Override
-    public List<Treatment> treatments() {
-        return treatments;
+    public TrafficTreatment treatment() {
+        return treatment;
     }
 
     @Override
@@ -49,7 +48,7 @@
     public String toString() {
         return MoreObjects.toStringHelper(this)
                 .add("sendThrough", sendThrough)
-                .add("treatments", treatments)
+                .add("treatment", treatment)
                 .toString();
     }
 }
diff --git a/core/api/src/main/java/org/onlab/onos/net/packet/OutboundPacket.java b/core/api/src/main/java/org/onlab/onos/net/packet/OutboundPacket.java
index 5307f00..05a5074 100644
--- a/core/api/src/main/java/org/onlab/onos/net/packet/OutboundPacket.java
+++ b/core/api/src/main/java/org/onlab/onos/net/packet/OutboundPacket.java
@@ -1,9 +1,9 @@
 package org.onlab.onos.net.packet;
 
 import org.onlab.onos.net.DeviceId;
+import org.onlab.onos.net.flow.TrafficTreatment;
 
 import java.nio.ByteBuffer;
-import java.util.List;
 
 /**
  * Represents an outbound data packet that is to be emitted to network via
@@ -20,14 +20,14 @@
     DeviceId sendThrough();
 
     /**
-     * Returns list of treatments for the outbound packet.
+     * Returns how the outbound packet should be treated.
      *
      * @return output treatment
      */
-    List<Treatment> treatments();
+    TrafficTreatment treatment();
 
     /**
-     * Returns the raw data to be sent.
+     * Returns immutable view of the raw data to be sent.
      *
      * @return data to emit
      */
diff --git a/core/api/src/main/java/org/onlab/onos/net/packet/PacketContext.java b/core/api/src/main/java/org/onlab/onos/net/packet/PacketContext.java
index a9af312..b77635b 100644
--- a/core/api/src/main/java/org/onlab/onos/net/packet/PacketContext.java
+++ b/core/api/src/main/java/org/onlab/onos/net/packet/PacketContext.java
@@ -1,5 +1,7 @@
 package org.onlab.onos.net.packet;
 
+import org.onlab.onos.net.flow.TrafficTreatment;
+
 /**
  * Represents context for processing an inbound packet, and (optionally)
  * emitting a corresponding outbound packet.
@@ -28,11 +30,11 @@
     OutboundPacket outPacket();
 
     /**
-     * Appends a new treatment to be applied to the outbound packet.
+     * Returns a builder for constructing traffic treatment.
      *
-     * @param treatment output treatment
+     * @return traffic treatment builder
      */
-    void appendTreatment(Treatment treatment);
+    TrafficTreatment.Builder treatmentBuilder();
 
     /**
      * Triggers the outbound packet to be sent.