[newOpenTAM] new Upgraded AFM and FlowStatisticService

New Upgraded AFM(Adaptive Flow Monitoring) and FlowStatisticService.
  .Reabsed from master 2016.12.06, and assumed avgPollInterval in FlowStatisticService with flowPollFrequency in case adativeFlowSampling is true or false
  .Fixed Yuta HIGUCHI comments, 2016.12.03
  .Fixed checkstyle warning
  .Rebased and added interrupted flag for exiting while() loop when IterruptException is caught in NewAdaptiveFlowStatsCollector.java

  .Fixed and added javadocs from Thomas Vachuska's comment
  .Removed synchronized block in OpenFlowRuleProvider.java for avoiding performance degradation
  .Rebased from master 2016.10.13 1.8.0.SNAPSHOT
  .Rebased from master 2016.09.09
  .Fixed Yuta HIGUCHI's comments
   (made default getFlowEntriesByLiveType interface,
    added checkArgument() for StoredFlowEntry,
    added @Deprecated annotation @deprecated javadoc,
    added Thread.currentThread.interrupt()
    and fixed Default Adaptive Flow Sampling value with false.)

  .Rebased from master branch
  .Fix typo in FlowRuleService.java comment line
  .Quick Bug fix in NewAdaptiveFlowStatCollector
  .master rebased for fixing build Failure
  .Removed synchronized block in FlowRuleProvider and NewAdaptiveFlowStatCollector for performance upgrade

  .Removed duplicated flow entries in NewAdaptiveFlowStatsCollector
  .Removed additional operation (add/remove/mod) of flow entry in OpenFlowRuleProvider
  .Set default adaptiveFlowSampling value with true
  .Added liveType (IMMEDIATE, SHORT, MID, LONG) member variable in FlowEntry
  .New added PollInterval static class for pollInterval value adjustment
  .Updated FlowEntryBuilder and FlowEntry constructor
  .Added liveType print in FlowListCommand CLI
  .Removed FlowStatisticStore, used existing StatisticStore
  .New added FlowEntryWithLoad for replacing the old TypedFlowEntryWithLoad
  .Added new interfaces in FlowStatisticService
  .Updated GetFlowStatistics CLI for using new interfaces
  .All Typedxxx classes are deprecated

  .new created review 9292 from review 9232
  .fixed Jian Li's review comment from review 9232
  .fixed Build failure in core/net/BUCK file

Change-Id: I7a0e39c5220a2b279b68a195347c183b5bdf1a49
diff --git a/core/api/src/main/java/org/onosproject/net/flow/DefaultFlowEntry.java b/core/api/src/main/java/org/onosproject/net/flow/DefaultFlowEntry.java
index a770e97..943ad84 100644
--- a/core/api/src/main/java/org/onosproject/net/flow/DefaultFlowEntry.java
+++ b/core/api/src/main/java/org/onosproject/net/flow/DefaultFlowEntry.java
@@ -29,31 +29,85 @@
 
     private static final Logger log = getLogger(DefaultFlowEntry.class);
 
+    private static final long DEFAULT_LAST_SEEN = -1;
+    private static final int DEFAULT_ERR_CODE = -1;
+    private static final int DEFAULT_ERR_TYPE = -1;
+
     /* Stored in nanoseconds (allows for 292 years) */
     private long life;
 
     private long packets;
     private long bytes;
     private FlowEntryState state;
+    private FlowLiveType liveType;
 
-    private long lastSeen = -1;
+    private long lastSeen = DEFAULT_LAST_SEEN;
 
     private final int errType;
 
     private final int errCode;
 
+    /**
+     * Creates a flow entry of flow table specified with the flow rule, state
+     * and statistic information.
+     *
+     * @param rule the flow rule
+     * @param state the flow state
+     * @param life the duration second of flow
+     * @param lifeTimeUnit life time unit
+     * @param packets the number of packets of this flow
+     * @param bytes the the number of bytes of this flow
+     */
     public DefaultFlowEntry(FlowRule rule, FlowEntryState state,
                             long life, TimeUnit lifeTimeUnit, long packets, long bytes) {
         super(rule);
         this.state = state;
         this.life = lifeTimeUnit.toNanos(life);
+        this.liveType = FlowLiveType.UNKNOWN;
         this.packets = packets;
         this.bytes = bytes;
-        this.errCode = -1;
-        this.errType = -1;
+        this.errCode = DEFAULT_ERR_CODE;
+        this.errType = DEFAULT_ERR_TYPE;
         this.lastSeen = System.currentTimeMillis();
     }
 
+    /**
+     * Creates a flow entry of flow table specified with the flow rule, state
+     * and statistic information.
+     *
+     * @param rule the flow rule
+     * @param state the flow state
+     * @param life the duration second of flow
+     * @param lifeTimeUnit life time unit
+     * @param liveType the flow live type, i.e., IMMEDIATE, SHORT, MID, LONG
+     * @param packets the number of packets of this flow
+     * @param bytes the the number of bytes of this flow
+     */
+    public DefaultFlowEntry(FlowRule rule, FlowEntryState state,
+                            long life, TimeUnit lifeTimeUnit, FlowLiveType liveType,
+                            long packets, long bytes) {
+        this(rule, state, life, lifeTimeUnit, packets, bytes);
+        this.liveType = liveType;
+    }
+
+    /**
+     * Creates a flow entry of flow table specified with the flow rule, state,
+     * live type and statistic information.
+     *
+     * @param rule the flow rule
+     * @param state the flow state
+     * @param lifeSecs the duration second of flow
+     * @param liveType the flow live type, i.e., IMMEDIATE, SHORT, MID, LONG
+     * @param packets the number of packets of this flow
+     * @param bytes the the number of bytes of this flow
+     */
+    public DefaultFlowEntry(FlowRule rule, FlowEntryState state,
+                            long lifeSecs, FlowLiveType liveType,
+                            long packets, long bytes) {
+        this(rule, state, lifeSecs, SECONDS, packets, bytes);
+        this.liveType = liveType;
+    }
+
     public DefaultFlowEntry(FlowRule rule, FlowEntryState state,
                             long lifeSecs, long packets, long bytes) {
         this(rule, state, lifeSecs, SECONDS, packets, bytes);
@@ -63,6 +117,14 @@
         this(rule, FlowEntryState.PENDING_ADD, 0, 0, 0);
     }
 
+    /**
+     * Creates a flow entry of flow table specified with the flow rule, state,
+     * live type and statistic information.
+     *
+     * @param rule the flow rule
+     * @param errType the error type
+     * @param errCode the error code
+     */
     public DefaultFlowEntry(FlowRule rule, int errType, int errCode) {
         super(rule);
         this.state = FlowEntryState.FAILED;
@@ -82,6 +144,11 @@
     }
 
     @Override
+    public FlowLiveType liveType() {
+        return liveType;
+    }
+
+    @Override
     public long packets() {
         return packets;
     }
@@ -122,6 +189,11 @@
     }
 
     @Override
+    public void setLiveType(FlowLiveType liveType) {
+        this.liveType = liveType;
+    }
+
+    @Override
     public void setPackets(long packets) {
         this.packets = packets;
     }
@@ -146,6 +218,13 @@
         return toStringHelper(this)
                 .add("rule", super.toString())
                 .add("state", state)
+                .add("life", life)
+                .add("liveType", liveType)
+                .add("packets", packets)
+                .add("bytes", bytes)
+                .add("errCode", errCode)
+                .add("errType", errType)
+                .add("lastSeen", lastSeen)
                 .toString();
     }
 }
diff --git a/core/api/src/main/java/org/onosproject/net/flow/DefaultTypedFlowEntry.java b/core/api/src/main/java/org/onosproject/net/flow/DefaultTypedFlowEntry.java
index 31d394a..80b7854 100644
--- a/core/api/src/main/java/org/onosproject/net/flow/DefaultTypedFlowEntry.java
+++ b/core/api/src/main/java/org/onosproject/net/flow/DefaultTypedFlowEntry.java
@@ -26,7 +26,7 @@
  */
 public class DefaultTypedFlowEntry extends DefaultFlowEntry
     implements TypedStoredFlowEntry {
-    private FlowLiveType liveType;
+    private TypedStoredFlowEntry.FlowLiveType liveType;
 
 
     /**
@@ -42,7 +42,7 @@
     public DefaultTypedFlowEntry(FlowRule rule, FlowEntryState state,
                                  long life, TimeUnit lifeTimeUnit, long packets, long bytes) {
         super(rule, state, life, lifeTimeUnit, packets, bytes);
-        this.liveType = FlowLiveType.IMMEDIATE_FLOW;
+        this.liveType = TypedStoredFlowEntry.FlowLiveType.IMMEDIATE_FLOW;
     }
 
     /**
@@ -58,7 +58,7 @@
     public DefaultTypedFlowEntry(FlowRule rule, FlowEntryState state,
                             long life, long packets, long bytes) {
         super(rule, state, life, packets, bytes);
-        this.liveType = FlowLiveType.IMMEDIATE_FLOW;
+        this.liveType = TypedStoredFlowEntry.FlowLiveType.IMMEDIATE_FLOW;
     }
 
     /**
@@ -69,7 +69,7 @@
      */
     public DefaultTypedFlowEntry(FlowRule rule) {
         super(rule);
-        this.liveType = FlowLiveType.IMMEDIATE_FLOW;
+        this.liveType = TypedStoredFlowEntry.FlowLiveType.IMMEDIATE_FLOW;
     }
 
     /**
@@ -80,7 +80,7 @@
      */
     public DefaultTypedFlowEntry(FlowEntry fe) {
         super(fe, fe.state(), fe.life(NANOSECONDS), NANOSECONDS, fe.packets(), fe.bytes());
-        this.liveType = FlowLiveType.IMMEDIATE_FLOW;
+        this.liveType = TypedStoredFlowEntry.FlowLiveType.IMMEDIATE_FLOW;
     }
 
     /**
@@ -90,7 +90,7 @@
      * @param liveType the flow live type
      *
      */
-    public DefaultTypedFlowEntry(FlowRule rule, FlowLiveType liveType) {
+    public DefaultTypedFlowEntry(FlowRule rule, TypedStoredFlowEntry.FlowLiveType liveType) {
         super(rule);
         this.liveType = liveType;
     }
@@ -102,7 +102,7 @@
      * @param liveType the flow live type
      *
      */
-    public DefaultTypedFlowEntry(FlowEntry fe,  FlowLiveType liveType) {
+    public DefaultTypedFlowEntry(FlowEntry fe,  TypedStoredFlowEntry.FlowLiveType liveType) {
         super(fe, fe.state(), fe.life(NANOSECONDS), NANOSECONDS, fe.packets(), fe.bytes());
         this.liveType = liveType;
     }
@@ -116,18 +116,19 @@
      * @param liveType the flow live type
      *
      */
-    public DefaultTypedFlowEntry(FlowRule rule, int errType, int errCode, FlowLiveType liveType) {
+    public DefaultTypedFlowEntry(FlowRule rule, int errType, int errCode,
+                                    TypedStoredFlowEntry.FlowLiveType liveType) {
         super(rule, errType, errCode);
         this.liveType = liveType;
     }
 
     @Override
-    public FlowLiveType flowLiveType() {
+    public TypedStoredFlowEntry.FlowLiveType flowLiveType() {
         return this.liveType;
     }
 
     @Override
-    public void setFlowLiveType(FlowLiveType liveType) {
+    public void setFlowLiveType(TypedStoredFlowEntry.FlowLiveType liveType) {
         this.liveType = liveType;
     }
 
diff --git a/core/api/src/main/java/org/onosproject/net/flow/FlowEntry.java b/core/api/src/main/java/org/onosproject/net/flow/FlowEntry.java
index a235786..f0d8098 100644
--- a/core/api/src/main/java/org/onosproject/net/flow/FlowEntry.java
+++ b/core/api/src/main/java/org/onosproject/net/flow/FlowEntry.java
@@ -68,6 +68,46 @@
      */
     long life();
 
+    enum FlowLiveType {
+
+        /**
+         * Indicates that this rule has been submitted for addition immediately.
+         * Not necessarily collecting flow stats.
+         */
+        IMMEDIATE,
+
+        /**
+         * Indicates that this rule has been submitted for a short time.
+         * Collecting flow stats every SHORT interval, defined by the implementation.
+         */
+        SHORT,
+
+        /**
+         * Indicates that this rule has been submitted for a mid time.
+         * Collecting flow stats every MID interval, defined by the implementation.
+         */
+        MID,
+
+        /**
+         * Indicates that this rule has been submitted for a long time.
+         * Collecting flow stats every LONG interval, defined by the implementation.
+         */
+        LONG,
+
+        /**
+         * Indicates that this rule has been submitted for UNKNOWN or ERROR.
+         * Not necessarily collecting flow stats.
+         */
+        UNKNOWN
+    }
+
+    /**
+     * Gets the flow live type for this entry.
+     *
+     * @return flow live type
+     */
+    FlowLiveType liveType();
+
     /**
      * Returns the time this flow rule has been applied.
      *
diff --git a/core/api/src/main/java/org/onosproject/net/flow/FlowRuleService.java b/core/api/src/main/java/org/onosproject/net/flow/FlowRuleService.java
index 62e725e..37a7c54 100644
--- a/core/api/src/main/java/org/onosproject/net/flow/FlowRuleService.java
+++ b/core/api/src/main/java/org/onosproject/net/flow/FlowRuleService.java
@@ -15,6 +15,7 @@
  */
 package org.onosproject.net.flow;
 
+import com.google.common.collect.Iterables;
 import org.onosproject.core.ApplicationId;
 import org.onosproject.event.ListenerService;
 import org.onosproject.net.DeviceId;
@@ -52,6 +53,20 @@
     Iterable<FlowEntry> getFlowEntries(DeviceId deviceId);
 
     /**
+     * Returns a list of rules filtered by device id and flow live type.
+     *
+     * @param deviceId the device id to lookup
+     * @param liveType the flow live type to lookup
+     * @return collection of flow entries
+     */
+    default Iterable<FlowEntry> getFlowEntriesByLiveType(DeviceId deviceId,
+                                                 FlowEntry.FlowLiveType liveType) {
+        return Iterables.filter(getFlowEntries(deviceId), fe -> fe.liveType() == liveType);
+    }
+
+    // TODO: add createFlowRule factory method and execute operations method
+
+    /**
      * Applies the specified flow rules onto their respective devices. These
      * flow rules will be retained by the system and re-applied anytime the
      * device reconnects to the controller.
diff --git a/core/api/src/main/java/org/onosproject/net/flow/StoredFlowEntry.java b/core/api/src/main/java/org/onosproject/net/flow/StoredFlowEntry.java
index b3a6564..e94e6de 100644
--- a/core/api/src/main/java/org/onosproject/net/flow/StoredFlowEntry.java
+++ b/core/api/src/main/java/org/onosproject/net/flow/StoredFlowEntry.java
@@ -45,6 +45,13 @@
     void setLife(long life, TimeUnit timeUnit);
 
     /**
+     * Sets the flow live type,
+     * i.e., IMMEDIATE, SHORT, MID, LONG.
+     * @param liveType flow live type
+     */
+    void setLiveType(FlowLiveType liveType);
+
+    /**
      * Number of packets seen by this entry.
      * @param packets a long value
      */
diff --git a/core/api/src/main/java/org/onosproject/net/flow/TypedStoredFlowEntry.java b/core/api/src/main/java/org/onosproject/net/flow/TypedStoredFlowEntry.java
index 92fdf7e..8b8554a 100644
--- a/core/api/src/main/java/org/onosproject/net/flow/TypedStoredFlowEntry.java
+++ b/core/api/src/main/java/org/onosproject/net/flow/TypedStoredFlowEntry.java
@@ -57,11 +57,11 @@
      *
      * @return flow live type
      */
-    FlowLiveType flowLiveType();
+    TypedStoredFlowEntry.FlowLiveType flowLiveType();
 
     /**
      * Sets the new flow live type for this entry.
      * @param liveType new flow live type.
      */
-    void setFlowLiveType(FlowLiveType liveType);
+    void setFlowLiveType(TypedStoredFlowEntry.FlowLiveType liveType);
 }
diff --git a/core/api/src/main/java/org/onosproject/net/statistic/DefaultLoad.java b/core/api/src/main/java/org/onosproject/net/statistic/DefaultLoad.java
index 1755136..add3a76 100644
--- a/core/api/src/main/java/org/onosproject/net/statistic/DefaultLoad.java
+++ b/core/api/src/main/java/org/onosproject/net/statistic/DefaultLoad.java
@@ -33,7 +33,7 @@
     /**
      * Indicates the flow statistics poll interval in seconds.
      */
-    private static long pollInterval = 10;
+    private static long pollInterval = 10; // same as IMMEDIATE and SHORT flow live type
 
     /**
      * Creates an invalid load.
diff --git a/core/api/src/main/java/org/onosproject/net/statistic/FlowEntryWithLoad.java b/core/api/src/main/java/org/onosproject/net/statistic/FlowEntryWithLoad.java
new file mode 100644
index 0000000..a5e85b2
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/statistic/FlowEntryWithLoad.java
@@ -0,0 +1,110 @@
+/*
+ * Copyright 2014-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.net.statistic;
+
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.flow.FlowEntry;
+import org.onosproject.net.flow.StoredFlowEntry;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * Load of flow entry with flow live type.
+ */
+public class FlowEntryWithLoad {
+    private final ConnectPoint cp;
+    private final FlowEntry fe;
+    private final Load load;
+
+    /**
+     * Creates a new flow entry with load.
+     *
+     * @param cp connect point
+     * @param fe flow entry with live type
+     * @param load load
+     */
+    public FlowEntryWithLoad(ConnectPoint cp, FlowEntry fe, Load load) {
+        checkArgument(fe instanceof StoredFlowEntry, "FlowEntry must be StoredFlowEntry class type");
+        this.cp = cp;
+        this.fe = fe;
+        this.load = load;
+    }
+
+    /**
+     * Creates a new flow entry with load.
+     *
+     * @param cp connect point
+     * @param fe flow entry with live type
+     */
+    public FlowEntryWithLoad(ConnectPoint cp, FlowEntry fe) {
+        checkArgument(fe instanceof StoredFlowEntry, "FlowEntry must be StoredFlowEntry class type");
+        this.cp = cp;
+        this.fe = fe;
+        this.load = new DefaultLoad(fe.bytes(), 0, typedPollInterval(fe));
+    }
+
+    /**
+     * Returns connect point.
+     *
+     * @return connect point
+     */
+    public ConnectPoint connectPoint() {
+        return cp;
+    }
+
+    /**
+     * Returns stored flow entry.
+     *
+     * @return flow entry
+     */
+    public StoredFlowEntry storedFlowEntry() {
+        return (StoredFlowEntry) fe;
+    }
+
+    /**
+     * Returns current load.
+     *
+     * @return load
+     */
+    public Load load() {
+        return load;
+    }
+
+    /**
+     * Returns current flow entry's polling interval.
+     *
+     * @param fe flow entry
+     * @return poll interval time unit in seconds
+     */
+    private long typedPollInterval(FlowEntry fe) {
+        checkNotNull(fe, "FlowEntry cannot be null");
+
+        PollInterval pollIntervalInstance = PollInterval.getInstance();
+
+        switch (fe.liveType()) {
+            case LONG:
+                return pollIntervalInstance.getLongPollInterval();
+            case MID:
+                return pollIntervalInstance.getMidPollInterval();
+            case SHORT:
+            case IMMEDIATE:
+            case UNKNOWN:
+            default:
+                return pollIntervalInstance.getPollInterval();
+        }
+    }
+}
diff --git a/core/api/src/main/java/org/onosproject/net/statistic/FlowStatisticService.java b/core/api/src/main/java/org/onosproject/net/statistic/FlowStatisticService.java
index e55237e..926b291 100644
--- a/core/api/src/main/java/org/onosproject/net/statistic/FlowStatisticService.java
+++ b/core/api/src/main/java/org/onosproject/net/statistic/FlowStatisticService.java
@@ -19,6 +19,7 @@
 import org.onosproject.net.ConnectPoint;
 import org.onosproject.net.Device;
 import org.onosproject.net.PortNumber;
+import org.onosproject.net.flow.FlowEntry;
 import org.onosproject.net.flow.TypedStoredFlowEntry;
 import org.onosproject.net.flow.instructions.Instruction;
 
@@ -56,6 +57,66 @@
      * @param instType the InstructionType to filter, null means no filtering.
      * @return map of flow entry load
      */
+    Map<ConnectPoint, List<FlowEntryWithLoad>> loadAllByType(Device device,
+                                                             FlowEntry.FlowLiveType liveType,
+                                                             Instruction.Type instType);
+
+    /**
+     * Obtain the flow type and load list for the device with the given link or port.
+     *
+     * @param device the Device to query.
+     * @param pNumber the port number of the Device to query
+     * @param liveType the FlowLiveType  to filter, null means no filtering .
+     * @param instType the InstructionType to filter, null means no filtering.
+     * @return list of flow entry load
+     */
+    List<FlowEntryWithLoad> loadAllByType(Device device,
+                                          PortNumber pNumber,
+                                          FlowEntry.FlowLiveType liveType,
+                                          Instruction.Type instType);
+
+    /**
+     * Obtain the set of the flow type and load topn list for the device with the given link.
+     *
+     * @param device the Device  to query.
+     * @param liveType the FlowLiveType  to filter, null means no filtering .
+     * @param instType the InstructionType to filter, null means no filtering.
+     * @param topn the top number to filter, null means no filtering.
+     * @return map of flow entry load
+     */
+    Map<ConnectPoint, List<FlowEntryWithLoad>> loadTopnByType(Device device,
+                                                              FlowEntry.FlowLiveType liveType,
+                                                              Instruction.Type instType,
+                                                              int topn);
+
+    /**
+     * Obtain the flow type and load topn list for the device with the given link or port.
+     *
+     * @param device the Device  to query.
+     * @param pNumber the port number of the Device to query
+     * @param liveType the FlowLiveType  to filter, null means no filtering .
+     * @param instType the InstructionType to filter, null means no filtering.
+     * @param topn the top n list entry
+     * @return list of flow entry load
+     */
+    List<FlowEntryWithLoad> loadTopnByType(Device device,
+                                           PortNumber pNumber,
+                                           FlowEntry.FlowLiveType liveType,
+                                           Instruction.Type instType,
+                                           int topn);
+
+    // The belows are deprecated interfaces...
+
+    /**
+     * Obtain the set of the flow type and load list for the device with the given link.
+     *
+     * @param device the Device  to query.
+     * @param liveType the FlowLiveType  to filter, null means no filtering .
+     * @param instType the InstructionType to filter, null means no filtering.
+     * @return map of flow entry load
+     * @deprecated in Ibis(1.8.1) release
+     */
+    @Deprecated
     Map<ConnectPoint, List<TypedFlowEntryWithLoad>> loadAllByType(Device device,
                                                                   TypedStoredFlowEntry.FlowLiveType liveType,
                                                                   Instruction.Type instType);
@@ -68,8 +129,11 @@
      * @param liveType the FlowLiveType  to filter, null means no filtering .
      * @param instType the InstructionType to filter, null means no filtering.
      * @return list of flow entry load
+     * @deprecated in Ibis(1.8.1) release
      */
-    List<TypedFlowEntryWithLoad> loadAllByType(Device device, PortNumber pNumber,
+    @Deprecated
+    List<TypedFlowEntryWithLoad> loadAllByType(Device device,
+                                               PortNumber pNumber,
                                                TypedStoredFlowEntry.FlowLiveType liveType,
                                                Instruction.Type instType);
 
@@ -81,7 +145,9 @@
      * @param instType the InstructionType to filter, null means no filtering.
      * @param topn the top number to filter, null means no filtering.
      * @return map of flow entry load
+     * @deprecated in Ibis(1.8.1) release
      */
+    @Deprecated
     Map<ConnectPoint, List<TypedFlowEntryWithLoad>> loadTopnByType(Device device,
                                                                    TypedStoredFlowEntry.FlowLiveType liveType,
                                                                    Instruction.Type instType,
@@ -96,8 +162,11 @@
      * @param instType the InstructionType to filter, null means no filtering.
      * @param topn topn //FIXME what?
      * @return list of flow entry load
+     * @deprecated in Ibis(1.8.1) release
      */
-    List<TypedFlowEntryWithLoad> loadTopnByType(Device device, PortNumber pNumber,
+    @Deprecated
+    List<TypedFlowEntryWithLoad> loadTopnByType(Device device,
+                                                PortNumber pNumber,
                                                 TypedStoredFlowEntry.FlowLiveType liveType,
                                                 Instruction.Type instType,
                                                 int topn);
diff --git a/core/api/src/main/java/org/onosproject/net/statistic/PollInterval.java b/core/api/src/main/java/org/onosproject/net/statistic/PollInterval.java
new file mode 100644
index 0000000..ca19b58
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/statistic/PollInterval.java
@@ -0,0 +1,186 @@
+/*
+ * Copyright 2014-2016 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.net.statistic;
+
+import static com.google.common.base.Preconditions.checkArgument;
+
+/**
+ * Default polling interval values.
+ */
+public final class PollInterval {
+    private static final long DEFAULT_POLL_INTERVAL = 10;
+    private static final long DEFAULT_MID_POLL_INTERVAL = 20;
+    private static final long DEFAULT_LONG_POLL_INTERVAL = 30;
+    private static final long DEFAULT_ENTIRE_POLL_INTERVAL = 60;
+
+    private static PollInterval pollIntervalInstance =
+            new PollInterval(DEFAULT_POLL_INTERVAL,
+                             DEFAULT_MID_POLL_INTERVAL,
+                             DEFAULT_LONG_POLL_INTERVAL,
+                             DEFAULT_ENTIRE_POLL_INTERVAL);
+
+    /**
+     * Indicates the flow statistics poll interval in seconds.
+     */
+    private long pollInterval = DEFAULT_POLL_INTERVAL;
+    // same as IMMEDIATE and SHORT flow live type
+
+    // These may be used in NewFlowStatsCollector
+    private long midPollInterval = DEFAULT_MID_POLL_INTERVAL; // default is 2*pollInterval
+    private long longPollInterval = DEFAULT_LONG_POLL_INTERVAL; // default is 3*pollInterval
+    private long entirePollInterval = DEFAULT_ENTIRE_POLL_INTERVAL; // default is 6*pollInterval
+
+    /**
+     * Returns the singleton PollInterval instance class for FlowStatisticService and other statistic services.
+     * This instance is only used Adaptive Flow Sampling(adaptiveFlowSampling) mode is enabled(true).
+     *
+     * @return the singleton PollInterval instance class
+     */
+    public static PollInterval getInstance() {
+        return pollIntervalInstance;
+    }
+
+    /**
+     * Creates an default poll interval.
+     */
+    protected PollInterval() {
+        this.pollInterval = DEFAULT_POLL_INTERVAL;
+        this.midPollInterval = DEFAULT_MID_POLL_INTERVAL;
+        this.longPollInterval = DEFAULT_LONG_POLL_INTERVAL;
+        this.entirePollInterval = DEFAULT_ENTIRE_POLL_INTERVAL;
+    }
+
+    // Public construction is prohibited
+    /**
+     * Creates a poll interval from the parameters.
+     *
+     * @param pollInterval  the poll interval value
+     * @param midPollInterval the mid poll interval value
+     * @param longPollInterval the long poll interval value
+     * @param entirePollInterval the entire poll interval value
+     */
+    private PollInterval(long pollInterval, long midPollInterval,
+                               long longPollInterval, long entirePollInterval) {
+        checkArgument(pollInterval > 0, "Poll interval must be greater than 0");
+        checkArgument(midPollInterval > 0 && midPollInterval > pollInterval,
+                      "Mid poll interval must be greater than 0 and pollInterval");
+        checkArgument(longPollInterval > 0 && longPollInterval > midPollInterval,
+                      "Long poll interval must be greater than 0 and midPollInterval");
+        checkArgument(entirePollInterval > 0 && entirePollInterval > longPollInterval,
+                      "Entire poll interval must be greater than 0 and longPollInterval");
+
+        this.pollInterval = pollInterval;
+        this.midPollInterval = midPollInterval;
+        this.longPollInterval = longPollInterval;
+        this.entirePollInterval = entirePollInterval;
+    }
+
+    /**
+     * Sets the poll interval in seconds. Used solely for the purpose of
+     * computing the load.
+     *
+     * @param newPollInterval poll interval duration in seconds
+     */
+    public void setPollInterval(long newPollInterval) {
+        checkArgument(newPollInterval > 0, "Poll interval must be greater than 0");
+
+        pollInterval = newPollInterval;
+    }
+
+    /**
+     * Sets the mid poll interval in seconds. Used solely for the purpose of
+     * computing the load.
+     *
+     * @param newPollInterval poll interval duration in seconds
+     */
+    public void setMidPollInterval(long newPollInterval) {
+        checkArgument(newPollInterval > 0 && newPollInterval > pollInterval,
+                      "Mid poll interval must be greater than 0 and pollInterval");
+
+        midPollInterval = newPollInterval;
+    }
+
+    /**
+     * Sets the long poll interval in seconds. Used solely for the purpose of
+     * computing the load.
+     *
+     * @param newPollInterval poll interval duration in seconds
+     */
+    public void setLongPollInterval(long newPollInterval) {
+        checkArgument(newPollInterval > 0 && newPollInterval > midPollInterval,
+                      "Long poll interval must be greater than 0 and midPollInterval");
+
+        longPollInterval = newPollInterval;
+    }
+
+    /**
+     * Sets the entire poll interval in seconds. Used solely for the purpose of
+     * computing the load.
+     *
+     * @param newPollInterval poll interval duration in seconds
+     */
+    public void setEntirePollInterval(long newPollInterval) {
+        checkArgument(newPollInterval > 0 && newPollInterval > longPollInterval,
+                      "Entire poll interval must be greater than 0 and longPollInterval");
+
+        entirePollInterval = newPollInterval;
+    }
+
+    /**
+     * Returns default poll interval value in seconds.
+     *
+     * @return default poll interval
+     */
+    public long getPollInterval() {
+        return pollInterval;
+    }
+
+    /**
+     * Returns mid poll interval value in seconds.
+     *
+     * @return mid poll interval
+     */
+    public long getMidPollInterval() {
+        return midPollInterval;
+    }
+
+    /**
+     * Returns long poll interval value in seconds.
+     *
+     * @return long poll interval
+     */
+    public long getLongPollInterval() {
+        return longPollInterval;
+    }
+
+    /**
+     * Returns entire poll interval value in seconds.
+     *
+     * @return entire poll interval
+     */
+    public long getEntirePollInterval() {
+        return entirePollInterval;
+    }
+
+    /**
+     * Returns average poll interval value in seconds.
+     *
+     * @return average poll interval
+     */
+    public long getAvgPollInterval() {
+        return (pollInterval + midPollInterval + longPollInterval) / 3;
+    }
+}
diff --git a/core/api/src/main/java/org/onosproject/net/statistic/TypedFlowEntryWithLoad.java b/core/api/src/main/java/org/onosproject/net/statistic/TypedFlowEntryWithLoad.java
index 15c4d33..04d78ae 100644
--- a/core/api/src/main/java/org/onosproject/net/statistic/TypedFlowEntryWithLoad.java
+++ b/core/api/src/main/java/org/onosproject/net/statistic/TypedFlowEntryWithLoad.java
@@ -27,14 +27,9 @@
  * Load of flow entry of flow live type.
  */
 public class TypedFlowEntryWithLoad {
-    private ConnectPoint cp;
-    private TypedStoredFlowEntry tfe;
-    private Load load;
-
-    //TODO: make this variables class, and share with NewAdaptivceFlowStatsCollector class
-    private static final int CAL_AND_POLL_INTERVAL = 5; // means SHORT_POLL_INTERVAL
-    private static final int MID_POLL_INTERVAL = 10;
-    private static final int LONG_POLL_INTERVAL = 15;
+    private final ConnectPoint cp;
+    private final TypedStoredFlowEntry tfe;
+    private final Load load;
 
     /**
      * Creates a new typed flow entry with load.
@@ -82,45 +77,6 @@
     public Load load() {
         return load;
     }
-    public void setLoad(Load load) {
-        this.load = load;
-    }
-
-    /**
-     * Returns short polling interval.
-     *
-     * @return short poll interval
-     */
-    public static int shortPollInterval() {
-        return CAL_AND_POLL_INTERVAL;
-    }
-
-    /**
-     * Returns mid polling interval.
-     *
-     * @return mid poll interval
-     */
-    public static int midPollInterval() {
-        return MID_POLL_INTERVAL;
-    }
-
-    /**
-     * Returns long polling interval.
-     *
-     * @return long poll interval
-     */
-    public static int longPollInterval() {
-        return LONG_POLL_INTERVAL;
-    }
-
-    /**
-     * Returns average polling interval.
-     *
-     * @return average poll interval
-     */
-    public static int avgPollInterval() {
-        return (CAL_AND_POLL_INTERVAL + MID_POLL_INTERVAL + LONG_POLL_INTERVAL) / 3;
-    }
 
     /**
      * Returns current typed flow entry's polling interval.
@@ -131,15 +87,17 @@
     public static long typedPollInterval(TypedStoredFlowEntry tfe) {
         checkNotNull(tfe, "TypedStoredFlowEntry cannot be null");
 
+        PollInterval pollIntervalInstance = PollInterval.getInstance();
+
         switch (tfe.flowLiveType()) {
             case LONG_FLOW:
-                return LONG_POLL_INTERVAL;
+                return pollIntervalInstance.getLongPollInterval();
             case MID_FLOW:
-                return MID_POLL_INTERVAL;
+                return pollIntervalInstance.getMidPollInterval();
             case SHORT_FLOW:
             case IMMEDIATE_FLOW:
             default:
-                return CAL_AND_POLL_INTERVAL;
+                return pollIntervalInstance.getPollInterval();
         }
     }
 
@@ -155,17 +113,18 @@
         }
 
         long life = fe.life();
+        PollInterval pollIntervalInstance = PollInterval.getInstance();
 
-        if (life >= LONG_POLL_INTERVAL) {
-            return new DefaultTypedFlowEntry(fe, TypedStoredFlowEntry.FlowLiveType.LONG_FLOW);
-        } else if (life >= MID_POLL_INTERVAL) {
-            return new DefaultTypedFlowEntry(fe, TypedStoredFlowEntry.FlowLiveType.MID_FLOW);
-        } else if (life >= CAL_AND_POLL_INTERVAL) {
-            return new DefaultTypedFlowEntry(fe, TypedStoredFlowEntry.FlowLiveType.SHORT_FLOW);
-        } else if (life >= 0) {
-            return new DefaultTypedFlowEntry(fe, TypedStoredFlowEntry.FlowLiveType.IMMEDIATE_FLOW);
-        } else { // life < 0
+        if (life < 0) {
             return new DefaultTypedFlowEntry(fe, TypedStoredFlowEntry.FlowLiveType.UNKNOWN_FLOW);
+        } else if (life < pollIntervalInstance.getPollInterval()) {
+            return new DefaultTypedFlowEntry(fe, TypedStoredFlowEntry.FlowLiveType.IMMEDIATE_FLOW);
+        } else if (life < pollIntervalInstance.getMidPollInterval()) {
+            return new DefaultTypedFlowEntry(fe, TypedStoredFlowEntry.FlowLiveType.SHORT_FLOW);
+        } else if (life < pollIntervalInstance.getLongPollInterval()) {
+            return new DefaultTypedFlowEntry(fe, TypedStoredFlowEntry.FlowLiveType.MID_FLOW);
+        } else { // >= longPollInterval
+            return new DefaultTypedFlowEntry(fe, TypedStoredFlowEntry.FlowLiveType.LONG_FLOW);
         }
     }
 }
diff --git a/core/common/src/main/java/org/onosproject/utils/Comparators.java b/core/common/src/main/java/org/onosproject/utils/Comparators.java
index 95a9874..27698d9 100644
--- a/core/common/src/main/java/org/onosproject/utils/Comparators.java
+++ b/core/common/src/main/java/org/onosproject/utils/Comparators.java
@@ -31,7 +31,7 @@
 import org.onosproject.net.group.Group;
 import org.onosproject.net.key.DeviceKey;
 import org.onosproject.net.region.Region;
-import org.onosproject.net.statistic.TypedFlowEntryWithLoad;
+import org.onosproject.net.statistic.FlowEntryWithLoad;
 import org.onosproject.net.topology.TopologyCluster;
 import org.onosproject.ui.model.topo.UiTopoLayout;
 
@@ -72,6 +72,12 @@
                         : priorityCompare;
             };
 
+    public static final Comparator<FlowEntryWithLoad> FLOWENTRY_WITHLOAD_COMPARATOR =
+            (fe1, fe2) -> {
+                long delta = fe1.load().rate() - fe2.load().rate();
+                return delta == 0 ? 0 : (delta > 0 ? -1 : +1);
+            };
+
     public static final Comparator<Group> GROUP_COMPARATOR =
             (g1, g2) -> Long.valueOf(g1.id().id()).compareTo((long) g2.id().id());
 
@@ -99,12 +105,6 @@
             (intf1, intf2) ->
                     CONNECT_POINT_COMPARATOR.compare(intf1.connectPoint(), intf2.connectPoint());
 
-    public static final Comparator<TypedFlowEntryWithLoad> TYPEFLOWENTRY_WITHLOAD_COMPARATOR =
-            (fe1, fe2) -> {
-                long delta = fe1.load().rate() - fe2.load().rate();
-                return delta == 0 ? 0 : (delta > 0 ? -1 : +1);
-            };
-
     public static final Comparator<DeviceKey> DEVICE_KEY_COMPARATOR =
             (dk1, dk2) -> dk1.deviceKeyId().id().compareTo(dk2.deviceKeyId().id());
 
diff --git a/core/net/BUCK b/core/net/BUCK
index 773b20a..a9864d5 100644
--- a/core/net/BUCK
+++ b/core/net/BUCK
@@ -1,5 +1,6 @@
 COMPILE_DEPS = [
     '//lib:CORE_DEPS',
+    '//core/common:onos-core-common',
     '//incubator/api:onos-incubator-api',
     '//utils/rest:onlab-rest',
     '//incubator/net:onos-incubator-net',
@@ -9,7 +10,6 @@
 TEST_DEPS = [
     '//lib:TEST_REST',
     '//lib:TEST_ADAPTERS',
-    '//core/common:onos-core-common',
     '//core/store/dist:onos-core-dist',
     '//core/store/dist:onos-core-dist-tests',
     '//utils/osgi:onlab-osgi-tests',
diff --git a/core/net/src/main/java/org/onosproject/net/statistic/impl/FlowStatisticManager.java b/core/net/src/main/java/org/onosproject/net/statistic/impl/FlowStatisticManager.java
index 59afadc..f77a9ea 100644
--- a/core/net/src/main/java/org/onosproject/net/statistic/impl/FlowStatisticManager.java
+++ b/core/net/src/main/java/org/onosproject/net/statistic/impl/FlowStatisticManager.java
@@ -25,32 +25,31 @@
 import org.apache.felix.scr.annotations.Reference;
 import org.apache.felix.scr.annotations.ReferenceCardinality;
 import org.apache.felix.scr.annotations.Service;
-
+import org.onosproject.utils.Comparators;
 import org.onosproject.net.ConnectPoint;
 import org.onosproject.net.Device;
-import org.onosproject.net.ElementId;
 import org.onosproject.net.Port;
 import org.onosproject.net.PortNumber;
 import org.onosproject.net.device.DeviceService;
+import org.onosproject.net.flow.DefaultFlowEntry;
 import org.onosproject.net.flow.DefaultTypedFlowEntry;
 import org.onosproject.net.flow.FlowEntry;
 import org.onosproject.net.flow.FlowRule;
-import org.onosproject.net.flow.FlowRuleEvent;
-import org.onosproject.net.flow.FlowRuleListener;
-import org.onosproject.net.flow.FlowRuleService;
+import org.onosproject.net.flow.StoredFlowEntry;
 import org.onosproject.net.flow.TypedStoredFlowEntry;
 import org.onosproject.net.flow.instructions.Instruction;
 import org.onosproject.net.statistic.DefaultLoad;
+import org.onosproject.net.statistic.FlowEntryWithLoad;
 import org.onosproject.net.statistic.FlowStatisticService;
 import org.onosproject.net.statistic.Load;
-import org.onosproject.net.statistic.FlowStatisticStore;
+import org.onosproject.net.statistic.PollInterval;
+import org.onosproject.net.statistic.StatisticStore;
 import org.onosproject.net.statistic.SummaryFlowEntryWithLoad;
 import org.onosproject.net.statistic.TypedFlowEntryWithLoad;
 
 import org.slf4j.Logger;
 
 import java.util.ArrayList;
-import java.util.Comparator;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -73,52 +72,18 @@
     private final Logger log = getLogger(getClass());
 
     @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
-    protected FlowRuleService flowRuleService;
-
-    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
-    protected FlowStatisticStore flowStatisticStore;
+    protected StatisticStore statisticStore;
 
     @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
     protected DeviceService deviceService;
 
-    private final InternalFlowRuleStatsListener frListener = new InternalFlowRuleStatsListener();
-
-    // FIXME: refactor these comparators to be shared with the CLI implmentations
-    public static final Comparator<ElementId> ELEMENT_ID_COMPARATOR = new Comparator<ElementId>() {
-        @Override
-        public int compare(ElementId id1, ElementId id2) {
-            return id1.toString().compareTo(id2.toString());
-        }
-    };
-
-    public static final Comparator<ConnectPoint> CONNECT_POINT_COMPARATOR = new Comparator<ConnectPoint>() {
-        @Override
-        public int compare(ConnectPoint o1, ConnectPoint o2) {
-            int compareId = ELEMENT_ID_COMPARATOR.compare(o1.elementId(), o2.elementId());
-            return (compareId != 0) ?
-                    compareId :
-                    Long.signum(o1.port().toLong() - o2.port().toLong());
-        }
-    };
-
-    public static final Comparator<TypedFlowEntryWithLoad> TYPEFLOWENTRY_WITHLOAD_COMPARATOR =
-            new Comparator<TypedFlowEntryWithLoad>() {
-                @Override
-                public int compare(TypedFlowEntryWithLoad fe1, TypedFlowEntryWithLoad fe2) {
-                    long delta = fe1.load().rate() - fe2.load().rate();
-                    return delta == 0 ? 0 : (delta > 0 ? -1 : +1);
-                }
-            };
-
     @Activate
     public void activate() {
-        flowRuleService.addListener(frListener);
         log.info("Started");
     }
 
     @Deactivate
     public void deactivate() {
-        flowRuleService.removeListener(frListener);
         log.info("Stopped");
     }
 
@@ -126,7 +91,8 @@
     public Map<ConnectPoint, SummaryFlowEntryWithLoad> loadSummary(Device device) {
         checkPermission(STATISTIC_READ);
 
-        Map<ConnectPoint, SummaryFlowEntryWithLoad> summaryLoad = new TreeMap<>(CONNECT_POINT_COMPARATOR);
+        Map<ConnectPoint, SummaryFlowEntryWithLoad> summaryLoad =
+                                        new TreeMap<>(Comparators.CONNECT_POINT_COMPARATOR);
 
         if (device == null) {
             return summaryLoad;
@@ -152,12 +118,13 @@
     }
 
     @Override
-    public Map<ConnectPoint, List<TypedFlowEntryWithLoad>> loadAllByType(Device device,
-                                                                  TypedStoredFlowEntry.FlowLiveType liveType,
+    public Map<ConnectPoint, List<FlowEntryWithLoad>> loadAllByType(Device device,
+                                                                  FlowEntry.FlowLiveType liveType,
                                                                   Instruction.Type instType) {
         checkPermission(STATISTIC_READ);
 
-        Map<ConnectPoint, List<TypedFlowEntryWithLoad>> allLoad = new TreeMap<>(CONNECT_POINT_COMPARATOR);
+        Map<ConnectPoint, List<FlowEntryWithLoad>> allLoad =
+                                        new TreeMap<>(Comparators.CONNECT_POINT_COMPARATOR);
 
         if (device == null) {
             return allLoad;
@@ -167,16 +134,16 @@
 
         for (Port port : ports) {
             ConnectPoint cp = new ConnectPoint(device.id(), port.number());
-            List<TypedFlowEntryWithLoad> tfel = loadAllPortInternal(cp, liveType, instType);
-            allLoad.put(cp, tfel);
+            List<FlowEntryWithLoad> fel = loadAllPortInternal(cp, liveType, instType);
+            allLoad.put(cp, fel);
         }
 
         return allLoad;
     }
 
     @Override
-    public List<TypedFlowEntryWithLoad> loadAllByType(Device device, PortNumber pNumber,
-                                               TypedStoredFlowEntry.FlowLiveType liveType,
+    public List<FlowEntryWithLoad> loadAllByType(Device device, PortNumber pNumber,
+                                               FlowEntry.FlowLiveType liveType,
                                                Instruction.Type instType) {
         checkPermission(STATISTIC_READ);
 
@@ -185,13 +152,14 @@
     }
 
     @Override
-    public Map<ConnectPoint, List<TypedFlowEntryWithLoad>> loadTopnByType(Device device,
-                                                                   TypedStoredFlowEntry.FlowLiveType liveType,
+    public Map<ConnectPoint, List<FlowEntryWithLoad>> loadTopnByType(Device device,
+                                                                   FlowEntry.FlowLiveType liveType,
                                                                    Instruction.Type instType,
                                                                    int topn) {
         checkPermission(STATISTIC_READ);
 
-        Map<ConnectPoint, List<TypedFlowEntryWithLoad>> allLoad = new TreeMap<>(CONNECT_POINT_COMPARATOR);
+        Map<ConnectPoint, List<FlowEntryWithLoad>> allLoad =
+                                        new TreeMap<>(Comparators.CONNECT_POINT_COMPARATOR);
 
         if (device == null) {
             return allLoad;
@@ -201,16 +169,16 @@
 
         for (Port port : ports) {
             ConnectPoint cp = new ConnectPoint(device.id(), port.number());
-            List<TypedFlowEntryWithLoad> tfel = loadTopnPortInternal(cp, liveType, instType, topn);
-            allLoad.put(cp, tfel);
+            List<FlowEntryWithLoad> fel = loadTopnPortInternal(cp, liveType, instType, topn);
+            allLoad.put(cp, fel);
         }
 
         return allLoad;
     }
 
     @Override
-    public List<TypedFlowEntryWithLoad> loadTopnByType(Device device, PortNumber pNumber,
-                                                TypedStoredFlowEntry.FlowLiveType liveType,
+    public List<FlowEntryWithLoad> loadTopnByType(Device device, PortNumber pNumber,
+                                                FlowEntry.FlowLiveType liveType,
                                                 Instruction.Type instType,
                                                 int topn) {
         checkPermission(STATISTIC_READ);
@@ -226,12 +194,12 @@
         Set<FlowEntry> previousStats;
 
         TypedStatistics typedStatistics;
-        synchronized (flowStatisticStore) {
-             currentStats = flowStatisticStore.getCurrentFlowStatistic(cp);
+        synchronized (statisticStore) {
+             currentStats = statisticStore.getCurrentStatistic(cp);
             if (currentStats == null) {
                 return new SummaryFlowEntryWithLoad(cp, new DefaultLoad());
             }
-            previousStats = flowStatisticStore.getPreviousFlowStatistic(cp);
+            previousStats = statisticStore.getPreviousStatistic(cp);
             if (previousStats == null) {
                 return new SummaryFlowEntryWithLoad(cp, new DefaultLoad());
             }
@@ -245,59 +213,62 @@
         // current and previous set is not empty!
         Set<FlowEntry> currentSet = typedStatistics.current();
         Set<FlowEntry> previousSet = typedStatistics.previous();
-        Load totalLoad = new DefaultLoad(aggregateBytesSet(currentSet), aggregateBytesSet(previousSet),
-                TypedFlowEntryWithLoad.avgPollInterval());
+        PollInterval pollIntervalInstance = PollInterval.getInstance();
 
-        Map<FlowRule, TypedStoredFlowEntry> currentMap;
-        Map<FlowRule, TypedStoredFlowEntry> previousMap;
+        // We assume that default pollInterval is flowPollFrequency in case adaptiveFlowSampling is true or false
+        Load totalLoad = new DefaultLoad(aggregateBytesSet(currentSet), aggregateBytesSet(previousSet),
+                                         pollIntervalInstance.getPollInterval());
+
+        Map<FlowRule, FlowEntry> currentMap;
+        Map<FlowRule, FlowEntry> previousMap;
 
         currentMap = typedStatistics.currentImmediate();
         previousMap = typedStatistics.previousImmediate();
         Load immediateLoad = new DefaultLoad(aggregateBytesMap(currentMap), aggregateBytesMap(previousMap),
-                TypedFlowEntryWithLoad.shortPollInterval());
+                                             pollIntervalInstance.getPollInterval());
 
         currentMap = typedStatistics.currentShort();
         previousMap = typedStatistics.previousShort();
         Load shortLoad = new DefaultLoad(aggregateBytesMap(currentMap), aggregateBytesMap(previousMap),
-                TypedFlowEntryWithLoad.shortPollInterval());
+                                         pollIntervalInstance.getPollInterval());
 
         currentMap = typedStatistics.currentMid();
         previousMap = typedStatistics.previousMid();
         Load midLoad = new DefaultLoad(aggregateBytesMap(currentMap), aggregateBytesMap(previousMap),
-                TypedFlowEntryWithLoad.midPollInterval());
+                                       pollIntervalInstance.getMidPollInterval());
 
         currentMap = typedStatistics.currentLong();
         previousMap = typedStatistics.previousLong();
         Load longLoad = new DefaultLoad(aggregateBytesMap(currentMap), aggregateBytesMap(previousMap),
-                TypedFlowEntryWithLoad.longPollInterval());
+                                        pollIntervalInstance.getLongPollInterval());
 
         currentMap = typedStatistics.currentUnknown();
         previousMap = typedStatistics.previousUnknown();
         Load unknownLoad = new DefaultLoad(aggregateBytesMap(currentMap), aggregateBytesMap(previousMap),
-                TypedFlowEntryWithLoad.avgPollInterval());
+                                           pollIntervalInstance.getPollInterval());
 
         return new SummaryFlowEntryWithLoad(cp, totalLoad, immediateLoad, shortLoad, midLoad, longLoad, unknownLoad);
     }
 
-    private List<TypedFlowEntryWithLoad> loadAllPortInternal(ConnectPoint cp,
-                                                             TypedStoredFlowEntry.FlowLiveType liveType,
+    private List<FlowEntryWithLoad> loadAllPortInternal(ConnectPoint cp,
+                                                             FlowEntry.FlowLiveType liveType,
                                                              Instruction.Type instType) {
         checkPermission(STATISTIC_READ);
 
-        List<TypedFlowEntryWithLoad> retTfel = new ArrayList<>();
+        List<FlowEntryWithLoad> retFel = new ArrayList<>();
 
         Set<FlowEntry> currentStats;
         Set<FlowEntry> previousStats;
 
         TypedStatistics typedStatistics;
-        synchronized (flowStatisticStore) {
-            currentStats = flowStatisticStore.getCurrentFlowStatistic(cp);
+        synchronized (statisticStore) {
+            currentStats = statisticStore.getCurrentStatistic(cp);
             if (currentStats == null) {
-                return retTfel;
+                return retFel;
             }
-            previousStats = flowStatisticStore.getPreviousFlowStatistic(cp);
+            previousStats = statisticStore.getPreviousStatistic(cp);
             if (previousStats == null) {
-                return retTfel;
+                return retFel;
             }
             // copy to local flow entry set
             typedStatistics = new TypedStatistics(currentStats, previousStats);
@@ -307,211 +278,322 @@
         }
 
         // current and previous set is not empty!
-        boolean isAllLiveType = (liveType == null ? true : false); // null is all live type
         boolean isAllInstType = (instType == null ? true : false); // null is all inst type
 
-        Map<FlowRule, TypedStoredFlowEntry> currentMap;
-        Map<FlowRule, TypedStoredFlowEntry> previousMap;
+        Map<FlowRule, FlowEntry> currentMap;
+        Map<FlowRule, FlowEntry> previousMap;
 
-        if (isAllLiveType || liveType == TypedStoredFlowEntry.FlowLiveType.IMMEDIATE_FLOW) {
-            currentMap = typedStatistics.currentImmediate();
-            previousMap = typedStatistics.previousImmediate();
-
-            List<TypedFlowEntryWithLoad> fel = typedFlowEntryLoadByInstInternal(cp, currentMap, previousMap,
-                    isAllInstType, instType, TypedFlowEntryWithLoad.shortPollInterval());
-            if (fel.size() > 0) {
-                retTfel.addAll(fel);
+        if (isAllInstType) {
+            currentMap = typedStatistics.currentAll();
+            previousMap = typedStatistics.previousAll();
+        } else {
+            switch (liveType) {
+                case IMMEDIATE:
+                    currentMap = typedStatistics.currentImmediate();
+                    previousMap = typedStatistics.previousImmediate();
+                    break;
+                case SHORT:
+                    currentMap = typedStatistics.currentShort();
+                    previousMap = typedStatistics.previousShort();
+                    break;
+                case MID:
+                    currentMap = typedStatistics.currentMid();
+                    previousMap = typedStatistics.previousMid();
+                    break;
+                case LONG:
+                    currentMap = typedStatistics.currentLong();
+                    previousMap = typedStatistics.previousLong();
+                    break;
+                case UNKNOWN:
+                    currentMap = typedStatistics.currentUnknown();
+                    previousMap = typedStatistics.previousUnknown();
+                    break;
+                default:
+                    currentMap = new HashMap<>();
+                    previousMap = new HashMap<>();
+                    break;
             }
         }
 
-        if (isAllLiveType || liveType == TypedStoredFlowEntry.FlowLiveType.SHORT_FLOW) {
-            currentMap = typedStatistics.currentShort();
-            previousMap = typedStatistics.previousShort();
-
-            List<TypedFlowEntryWithLoad> fel = typedFlowEntryLoadByInstInternal(cp, currentMap, previousMap,
-                    isAllInstType, instType, TypedFlowEntryWithLoad.shortPollInterval());
-            if (fel.size() > 0) {
-                retTfel.addAll(fel);
-            }
-        }
-
-        if (isAllLiveType || liveType == TypedStoredFlowEntry.FlowLiveType.MID_FLOW) {
-            currentMap = typedStatistics.currentMid();
-            previousMap = typedStatistics.previousMid();
-
-            List<TypedFlowEntryWithLoad> fel = typedFlowEntryLoadByInstInternal(cp, currentMap, previousMap,
-                    isAllInstType, instType, TypedFlowEntryWithLoad.midPollInterval());
-            if (fel.size() > 0) {
-                retTfel.addAll(fel);
-            }
-        }
-
-        if (isAllLiveType || liveType == TypedStoredFlowEntry.FlowLiveType.LONG_FLOW) {
-            currentMap = typedStatistics.currentLong();
-            previousMap = typedStatistics.previousLong();
-
-            List<TypedFlowEntryWithLoad> fel = typedFlowEntryLoadByInstInternal(cp, currentMap, previousMap,
-                    isAllInstType, instType, TypedFlowEntryWithLoad.longPollInterval());
-            if (fel.size() > 0) {
-                retTfel.addAll(fel);
-            }
-        }
-
-        if (isAllLiveType || liveType == TypedStoredFlowEntry.FlowLiveType.UNKNOWN_FLOW) {
-            currentMap = typedStatistics.currentUnknown();
-            previousMap = typedStatistics.previousUnknown();
-
-            List<TypedFlowEntryWithLoad> fel = typedFlowEntryLoadByInstInternal(cp, currentMap, previousMap,
-                    isAllInstType, instType, TypedFlowEntryWithLoad.avgPollInterval());
-            if (fel.size() > 0) {
-                retTfel.addAll(fel);
-            }
-        }
-
-        return retTfel;
+        return typedFlowEntryLoadByInstInternal(cp, currentMap, previousMap, isAllInstType, instType);
     }
 
-    private List<TypedFlowEntryWithLoad> typedFlowEntryLoadByInstInternal(ConnectPoint cp,
-                                                                      Map<FlowRule, TypedStoredFlowEntry> currentMap,
-                                                                      Map<FlowRule, TypedStoredFlowEntry> previousMap,
+    private List<FlowEntryWithLoad> typedFlowEntryLoadByInstInternal(ConnectPoint cp,
+                                                                      Map<FlowRule, FlowEntry> currentMap,
+                                                                      Map<FlowRule, FlowEntry> previousMap,
                                                                       boolean isAllInstType,
-                                                                      Instruction.Type instType,
-                                                                      int liveTypePollInterval) {
-        List<TypedFlowEntryWithLoad> fel = new ArrayList<>();
+                                                                      Instruction.Type instType) {
+        List<FlowEntryWithLoad> fel = new ArrayList<>();
 
-        for (TypedStoredFlowEntry tfe : currentMap.values()) {
+        currentMap.values().forEach(fe -> {
             if (isAllInstType ||
-                    tfe.treatment().allInstructions().stream().
+                    fe.treatment().allInstructions().stream().
                             filter(i -> i.type() == instType).
                             findAny().isPresent()) {
-                long currentBytes = tfe.bytes();
-                long previousBytes = previousMap.getOrDefault(tfe, new DefaultTypedFlowEntry((FlowRule) tfe)).bytes();
+                long currentBytes = fe.bytes();
+                long previousBytes = previousMap.getOrDefault(fe, new DefaultFlowEntry(fe)).bytes();
+                long liveTypePollInterval = getLiveTypePollInterval(fe.liveType());
                 Load fLoad = new DefaultLoad(currentBytes, previousBytes, liveTypePollInterval);
-                fel.add(new TypedFlowEntryWithLoad(cp, tfe, fLoad));
+                fel.add(new FlowEntryWithLoad(cp, fe, fLoad));
             }
-        }
+        });
 
         return fel;
     }
 
-    private List<TypedFlowEntryWithLoad> loadTopnPortInternal(ConnectPoint cp,
-                                                             TypedStoredFlowEntry.FlowLiveType liveType,
+    private List<FlowEntryWithLoad> loadTopnPortInternal(ConnectPoint cp,
+                                                             FlowEntry.FlowLiveType liveType,
                                                              Instruction.Type instType,
                                                              int topn) {
-        List<TypedFlowEntryWithLoad> fel = loadAllPortInternal(cp, liveType, instType);
+        List<FlowEntryWithLoad> fel = loadAllPortInternal(cp, liveType, instType);
 
         // Sort with descending order of load
-        List<TypedFlowEntryWithLoad> tfel =
-                fel.stream().sorted(TYPEFLOWENTRY_WITHLOAD_COMPARATOR).
+        List<FlowEntryWithLoad> retFel =
+                fel.stream().sorted(Comparators.FLOWENTRY_WITHLOAD_COMPARATOR).
                         limit(topn).collect(Collectors.toList());
 
-        return tfel;
+        return retFel;
     }
 
     private long aggregateBytesSet(Set<FlowEntry> setFE) {
         return setFE.stream().mapToLong(FlowEntry::bytes).sum();
     }
 
-    private long aggregateBytesMap(Map<FlowRule, TypedStoredFlowEntry> mapFE) {
+    private long aggregateBytesMap(Map<FlowRule, FlowEntry> mapFE) {
         return mapFE.values().stream().mapToLong(FlowEntry::bytes).sum();
     }
 
+    private long getLiveTypePollInterval(FlowEntry.FlowLiveType liveType) {
+        // returns the flow live type poll interval value
+        PollInterval pollIntervalInstance = PollInterval.getInstance();
+
+        switch (liveType) {
+            case LONG:
+                return pollIntervalInstance.getLongPollInterval();
+            case MID:
+                return pollIntervalInstance.getMidPollInterval();
+            case SHORT:
+            case IMMEDIATE:
+            default: // UNKNOWN
+                return pollIntervalInstance.getPollInterval();
+        }
+    }
+
+    //
+    // Deprecated interfaces...
+    //
+    @Override
+    public Map<ConnectPoint, List<TypedFlowEntryWithLoad>> loadAllByType(Device device,
+                                                                  TypedStoredFlowEntry.FlowLiveType liveType,
+                                                                  Instruction.Type instType) {
+        FlowEntry.FlowLiveType type = toFlowEntryLiveType(liveType);
+
+        Map<ConnectPoint, List<FlowEntryWithLoad>> loadMap = loadAllByType(device, type, instType);
+
+        return toFlowEntryWithLoadMap(loadMap);
+    }
+
+    @Override
+    public List<TypedFlowEntryWithLoad> loadAllByType(Device device, PortNumber pNumber,
+                                               TypedStoredFlowEntry.FlowLiveType liveType,
+                                               Instruction.Type instType) {
+        FlowEntry.FlowLiveType type = toFlowEntryLiveType(liveType);
+
+        List<FlowEntryWithLoad> loadList = loadAllByType(device, pNumber, type, instType);
+
+        return toFlowEntryWithLoad(loadList);
+    }
+
+    @Override
+    public Map<ConnectPoint, List<TypedFlowEntryWithLoad>> loadTopnByType(Device device,
+                                                                   TypedStoredFlowEntry.FlowLiveType liveType,
+                                                                   Instruction.Type instType,
+                                                                   int topn) {
+        FlowEntry.FlowLiveType type = toFlowEntryLiveType(liveType);
+
+        Map<ConnectPoint, List<FlowEntryWithLoad>> loadMap = loadTopnByType(device, type, instType, topn);
+
+        return toFlowEntryWithLoadMap(loadMap);
+    }
+
+    @Override
+    public List<TypedFlowEntryWithLoad> loadTopnByType(Device device, PortNumber pNumber,
+                                                TypedStoredFlowEntry.FlowLiveType liveType,
+                                                Instruction.Type instType,
+                                                int topn) {
+        FlowEntry.FlowLiveType type = toFlowEntryLiveType(liveType);
+
+        List<FlowEntryWithLoad> loadList = loadTopnByType(device, pNumber, type, instType, topn);
+
+        return toFlowEntryWithLoad(loadList);
+    }
+
+    private FlowEntry.FlowLiveType toFlowEntryLiveType(TypedStoredFlowEntry.FlowLiveType liveType) {
+        if (liveType == null) {
+            return null;
+        }
+
+        // convert TypedStoredFlowEntry flow live type to FlowEntry one
+        switch (liveType) {
+            case IMMEDIATE_FLOW:
+                return FlowEntry.FlowLiveType.IMMEDIATE;
+            case SHORT_FLOW:
+                return FlowEntry.FlowLiveType.SHORT;
+            case MID_FLOW:
+                return FlowEntry.FlowLiveType.MID;
+            case LONG_FLOW:
+                return FlowEntry.FlowLiveType.LONG;
+            default:
+                return FlowEntry.FlowLiveType.UNKNOWN;
+        }
+    }
+
+    private TypedStoredFlowEntry.FlowLiveType toTypedStoredFlowEntryLiveType(FlowEntry.FlowLiveType liveType) {
+        if (liveType == null) {
+            return null;
+        }
+
+        // convert TypedStoredFlowEntry flow live type to FlowEntry one
+        switch (liveType) {
+            case IMMEDIATE:
+                return TypedStoredFlowEntry.FlowLiveType.IMMEDIATE_FLOW;
+            case SHORT:
+                return TypedStoredFlowEntry.FlowLiveType.SHORT_FLOW;
+            case MID:
+                return TypedStoredFlowEntry.FlowLiveType.MID_FLOW;
+            case LONG:
+                return TypedStoredFlowEntry.FlowLiveType.LONG_FLOW;
+            default:
+                return TypedStoredFlowEntry.FlowLiveType.UNKNOWN_FLOW;
+        }
+    }
+
+    private Map<ConnectPoint, List<TypedFlowEntryWithLoad>> toFlowEntryWithLoadMap(
+            Map<ConnectPoint, List<FlowEntryWithLoad>> loadMap) {
+        // convert FlowEntryWithLoad list to TypedFlowEntryWithLoad list
+        Map<ConnectPoint, List<TypedFlowEntryWithLoad>> allLoad =
+                                        new TreeMap<>(Comparators.CONNECT_POINT_COMPARATOR);
+
+        loadMap.forEach((k, v) -> {
+            List<TypedFlowEntryWithLoad> tfelList =
+                    toFlowEntryWithLoad(v);
+            allLoad.put(k, tfelList);
+        });
+
+        return allLoad;
+    }
+
+    private List<TypedFlowEntryWithLoad> toFlowEntryWithLoad(List<FlowEntryWithLoad> loadList) {
+        // convert FlowEntryWithLoad list to TypedFlowEntryWithLoad list
+        List<TypedFlowEntryWithLoad> tfelList = new ArrayList<>();
+        loadList.forEach(fel -> {
+            StoredFlowEntry sfe = fel.storedFlowEntry();
+            TypedStoredFlowEntry.FlowLiveType liveType = toTypedStoredFlowEntryLiveType(sfe.liveType());
+            TypedStoredFlowEntry tfe = new DefaultTypedFlowEntry(sfe, liveType);
+            TypedFlowEntryWithLoad tfel = new TypedFlowEntryWithLoad(fel.connectPoint(), tfe, fel.load());
+            tfelList.add(tfel);
+        });
+
+        return tfelList;
+    }
+
     /**
-     * Internal data class holding two set of typed flow entries.
+     * Internal data class holding two set of flow entries included flow liveType.
      */
     private static class TypedStatistics {
-        private final ImmutableSet<FlowEntry> currentAll;
-        private final ImmutableSet<FlowEntry> previousAll;
+        private final ImmutableSet<FlowEntry> current;
+        private final ImmutableSet<FlowEntry> previous;
 
-        private final Map<FlowRule, TypedStoredFlowEntry> currentImmediate = new HashMap<>();
-        private final Map<FlowRule, TypedStoredFlowEntry> previousImmediate = new HashMap<>();
+        private final Map<FlowRule, FlowEntry> currentAll = new HashMap<>();
+        private final Map<FlowRule, FlowEntry> previousAll = new HashMap<>();
 
-        private final Map<FlowRule, TypedStoredFlowEntry> currentShort = new HashMap<>();
-        private final Map<FlowRule, TypedStoredFlowEntry> previousShort = new HashMap<>();
+        private final Map<FlowRule, FlowEntry> currentImmediate = new HashMap<>();
+        private final Map<FlowRule, FlowEntry> previousImmediate = new HashMap<>();
 
-        private final Map<FlowRule, TypedStoredFlowEntry> currentMid = new HashMap<>();
-        private final Map<FlowRule, TypedStoredFlowEntry> previousMid = new HashMap<>();
+        private final Map<FlowRule, FlowEntry> currentShort = new HashMap<>();
+        private final Map<FlowRule, FlowEntry> previousShort = new HashMap<>();
 
-        private final Map<FlowRule, TypedStoredFlowEntry> currentLong = new HashMap<>();
-        private final Map<FlowRule, TypedStoredFlowEntry> previousLong = new HashMap<>();
+        private final Map<FlowRule, FlowEntry> currentMid = new HashMap<>();
+        private final Map<FlowRule, FlowEntry> previousMid = new HashMap<>();
 
-        private final Map<FlowRule, TypedStoredFlowEntry> currentUnknown = new HashMap<>();
-        private final Map<FlowRule, TypedStoredFlowEntry> previousUnknown = new HashMap<>();
+        private final Map<FlowRule, FlowEntry> currentLong = new HashMap<>();
+        private final Map<FlowRule, FlowEntry> previousLong = new HashMap<>();
+
+        private final Map<FlowRule, FlowEntry> currentUnknown = new HashMap<>();
+        private final Map<FlowRule, FlowEntry> previousUnknown = new HashMap<>();
 
         public TypedStatistics(Set<FlowEntry> current, Set<FlowEntry> previous) {
-            this.currentAll = ImmutableSet.copyOf(checkNotNull(current));
-            this.previousAll = ImmutableSet.copyOf(checkNotNull(previous));
+            this.current = ImmutableSet.copyOf(checkNotNull(current));
+            this.previous = ImmutableSet.copyOf(checkNotNull(previous));
 
-            currentAll.forEach(fe -> {
-                TypedStoredFlowEntry tfe = TypedFlowEntryWithLoad.newTypedStoredFlowEntry(fe);
-
-                switch (tfe.flowLiveType()) {
-                    case IMMEDIATE_FLOW:
-                        currentImmediate.put(fe, tfe);
+            current.forEach(fe -> {
+                switch (fe.liveType()) {
+                    case IMMEDIATE:
+                        currentImmediate.put(fe, fe);
                         break;
-                    case SHORT_FLOW:
-                        currentShort.put(fe, tfe);
+                    case SHORT:
+                        currentShort.put(fe, fe);
                         break;
-                    case MID_FLOW:
-                        currentMid.put(fe, tfe);
+                    case MID:
+                        currentMid.put(fe, fe);
                         break;
-                    case LONG_FLOW:
-                        currentLong.put(fe, tfe);
+                    case LONG:
+                        currentLong.put(fe, fe);
                         break;
-                    default:
-                        currentUnknown.put(fe, tfe);
+                    default: // unknown
+                        currentUnknown.put(fe, fe);
                         break;
                 }
+                currentAll.put(fe, fe);
             });
 
-            previousAll.forEach(fe -> {
-                TypedStoredFlowEntry tfe = TypedFlowEntryWithLoad.newTypedStoredFlowEntry(fe);
-
-                switch (tfe.flowLiveType()) {
-                    case IMMEDIATE_FLOW:
+            previous.forEach(fe -> {
+                switch (fe.liveType()) {
+                    case IMMEDIATE:
                         if (currentImmediate.containsKey(fe)) {
-                            previousImmediate.put(fe, tfe);
+                            previousImmediate.put(fe, fe);
                         } else if (currentShort.containsKey(fe)) {
-                            previousShort.put(fe, tfe);
+                            previousShort.put(fe, fe);
                         } else if (currentMid.containsKey(fe)) {
-                            previousMid.put(fe, tfe);
+                            previousMid.put(fe, fe);
                         } else if (currentLong.containsKey(fe)) {
-                            previousLong.put(fe, tfe);
+                            previousLong.put(fe, fe);
                         } else {
-                            previousUnknown.put(fe, tfe);
+                            previousUnknown.put(fe, fe);
                         }
                         break;
-                    case SHORT_FLOW:
+                    case SHORT:
                         if (currentShort.containsKey(fe)) {
-                            previousShort.put(fe, tfe);
+                            previousShort.put(fe, fe);
                         } else if (currentMid.containsKey(fe)) {
-                            previousMid.put(fe, tfe);
+                            previousMid.put(fe, fe);
                         } else if (currentLong.containsKey(fe)) {
-                            previousLong.put(fe, tfe);
+                            previousLong.put(fe, fe);
                         } else {
-                            previousUnknown.put(fe, tfe);
+                            previousUnknown.put(fe, fe);
                         }
                         break;
-                    case MID_FLOW:
+                    case MID:
                         if (currentMid.containsKey(fe)) {
-                            previousMid.put(fe, tfe);
+                            previousMid.put(fe, fe);
                         } else if (currentLong.containsKey(fe)) {
-                            previousLong.put(fe, tfe);
+                            previousLong.put(fe, fe);
                         } else {
-                            previousUnknown.put(fe, tfe);
+                            previousUnknown.put(fe, fe);
                         }
                         break;
-                    case LONG_FLOW:
+                    case LONG:
                         if (currentLong.containsKey(fe)) {
-                            previousLong.put(fe, tfe);
+                            previousLong.put(fe, fe);
                         } else {
-                            previousUnknown.put(fe, tfe);
+                            previousUnknown.put(fe, fe);
                         }
                         break;
-                    default:
-                        previousUnknown.put(fe, tfe);
+                    default: // unknown
+                        previousUnknown.put(fe, fe);
                         break;
                 }
+                previousAll.put(fe, fe);
             });
         }
 
@@ -521,7 +603,7 @@
          * @return flow entries as the current value
          */
         public ImmutableSet<FlowEntry> current() {
-            return currentAll;
+            return current;
         }
 
         /**
@@ -530,37 +612,45 @@
          * @return flow entries as the previous value
          */
         public ImmutableSet<FlowEntry> previous() {
+            return previous;
+        }
+
+        public Map<FlowRule, FlowEntry> currentAll() {
+            return currentAll;
+        }
+
+        public Map<FlowRule, FlowEntry> previousAll() {
             return previousAll;
         }
 
-        public Map<FlowRule, TypedStoredFlowEntry> currentImmediate() {
+        public Map<FlowRule, FlowEntry> currentImmediate() {
             return currentImmediate;
         }
-        public Map<FlowRule, TypedStoredFlowEntry> previousImmediate() {
+        public Map<FlowRule, FlowEntry> previousImmediate() {
             return previousImmediate;
         }
-        public Map<FlowRule, TypedStoredFlowEntry> currentShort() {
+        public Map<FlowRule, FlowEntry> currentShort() {
             return currentShort;
         }
-        public Map<FlowRule, TypedStoredFlowEntry> previousShort() {
+        public Map<FlowRule, FlowEntry> previousShort() {
             return previousShort;
         }
-        public Map<FlowRule, TypedStoredFlowEntry> currentMid() {
+        public Map<FlowRule, FlowEntry> currentMid() {
             return currentMid;
         }
-        public Map<FlowRule, TypedStoredFlowEntry> previousMid() {
+        public Map<FlowRule, FlowEntry> previousMid() {
             return previousMid;
         }
-        public Map<FlowRule, TypedStoredFlowEntry> currentLong() {
+        public Map<FlowRule, FlowEntry> currentLong() {
             return currentLong;
         }
-        public Map<FlowRule, TypedStoredFlowEntry> previousLong() {
+        public Map<FlowRule, FlowEntry> previousLong() {
             return previousLong;
         }
-        public Map<FlowRule, TypedStoredFlowEntry> currentUnknown() {
+        public Map<FlowRule, FlowEntry> currentUnknown() {
             return currentUnknown;
         }
-        public Map<FlowRule, TypedStoredFlowEntry> previousUnknown() {
+        public Map<FlowRule, FlowEntry> previousUnknown() {
             return previousUnknown;
         }
 
@@ -632,32 +722,13 @@
     }
 
     /**
-     * Internal flow rule event listener for FlowStatisticManager.
+     * Creates a predicate that checks the flow type of a flow entry is the same as
+     * the specified live type.
+     *
+     * @param liveType flow live type to be checked
+     * @return predicate
      */
-    private class InternalFlowRuleStatsListener implements FlowRuleListener {
-
-        @Override
-        public void event(FlowRuleEvent event) {
-            FlowRule rule = event.subject();
-            switch (event.type()) {
-                case RULE_ADDED:
-                    if (rule instanceof FlowEntry) {
-                        flowStatisticStore.addFlowStatistic((FlowEntry) rule);
-                    }
-                    break;
-                case RULE_UPDATED:
-                    flowStatisticStore.updateFlowStatistic((FlowEntry) rule);
-                    break;
-                case RULE_ADD_REQUESTED:
-                    break;
-                case RULE_REMOVE_REQUESTED:
-                    break;
-                case RULE_REMOVED:
-                    flowStatisticStore.removeFlowStatistic(rule);
-                    break;
-                default:
-                    log.warn("Unknown flow rule event {}", event);
-            }
-        }
+    private static Predicate<FlowEntry> hasLiveType(FlowEntry.FlowLiveType liveType) {
+        return flowEntry -> flowEntry.liveType() == liveType;
     }
 }
diff --git a/core/store/dist/src/main/java/org/onosproject/store/flow/impl/DistributedFlowRuleStore.java b/core/store/dist/src/main/java/org/onosproject/store/flow/impl/DistributedFlowRuleStore.java
index 9e2c53d..699a4d3 100644
--- a/core/store/dist/src/main/java/org/onosproject/store/flow/impl/DistributedFlowRuleStore.java
+++ b/core/store/dist/src/main/java/org/onosproject/store/flow/impl/DistributedFlowRuleStore.java
@@ -568,6 +568,7 @@
             //FIXME modification of "stored" flow entry outside of flow table
             stored.setBytes(rule.bytes());
             stored.setLife(rule.life(TimeUnit.NANOSECONDS), TimeUnit.NANOSECONDS);
+            stored.setLiveType(rule.liveType());
             stored.setPackets(rule.packets());
             stored.setLastSeen();
             if (stored.state() == FlowEntryState.PENDING_ADD) {