[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/cli/src/main/java/org/onosproject/cli/net/FlowsListCommand.java b/cli/src/main/java/org/onosproject/cli/net/FlowsListCommand.java
index 9de96f9..bd7a246 100644
--- a/cli/src/main/java/org/onosproject/cli/net/FlowsListCommand.java
+++ b/cli/src/main/java/org/onosproject/cli/net/FlowsListCommand.java
@@ -59,7 +59,7 @@
     public static final String ANY = "any";
 
     private static final String LONG_FORMAT = "    id=%s, state=%s, bytes=%s, "
-            + "packets=%s, duration=%s, priority=%s, tableId=%s, appId=%s, "
+            + "packets=%s, duration=%s, liveType=%s, priority=%s, tableId=%s, appId=%s, "
             + "payLoad=%s, selector=%s, treatment=%s";
 
     private static final String SHORT_FORMAT = "    %s, bytes=%s, packets=%s, "
@@ -237,7 +237,7 @@
             } else {
                 ApplicationId appId = coreService.getAppId(f.appId());
                 print(LONG_FORMAT, Long.toHexString(f.id().value()), f.state(),
-                        f.bytes(), f.packets(), f.life(), f.priority(), f.tableId(),
+                        f.bytes(), f.packets(), f.life(), f.liveType(), f.priority(), f.tableId(),
                         appId != null ? appId.name() : "<none>",
                         f.payLoad() == null ? null : f.payLoad().payLoad().toString(),
                         f.selector().criteria(), f.treatment());
diff --git a/cli/src/main/java/org/onosproject/cli/net/GetFlowStatisticsCommand.java b/cli/src/main/java/org/onosproject/cli/net/GetFlowStatisticsCommand.java
index a122204..6d9ff67 100644
--- a/cli/src/main/java/org/onosproject/cli/net/GetFlowStatisticsCommand.java
+++ b/cli/src/main/java/org/onosproject/cli/net/GetFlowStatisticsCommand.java
@@ -26,11 +26,12 @@
 import org.onosproject.net.Port;
 import org.onosproject.net.PortNumber;
 import org.onosproject.net.device.DeviceService;
-import org.onosproject.net.flow.TypedStoredFlowEntry;
+import org.onosproject.net.flow.FlowEntry;
+import org.onosproject.net.flow.StoredFlowEntry;
 import org.onosproject.net.flow.instructions.Instruction;
+import org.onosproject.net.statistic.FlowEntryWithLoad;
 import org.onosproject.net.statistic.FlowStatisticService;
 import org.onosproject.net.statistic.SummaryFlowEntryWithLoad;
-import org.onosproject.net.statistic.TypedFlowEntryWithLoad;
 
 import java.util.List;
 import java.util.Map;
@@ -60,7 +61,7 @@
     boolean showAll = false;
 
     @Option(name = "-t", aliases = "--topn",
-            description = "Show flow stats topn",
+            description = "Show flow stats topn entry",
             required = false, multiValued = false)
     String showTopn = null;
 
@@ -115,7 +116,7 @@
         }
 
         // convert String to FlowLiveType and check validity
-        TypedStoredFlowEntry.FlowLiveType inLiveType;
+        FlowEntry.FlowLiveType inLiveType;
         if (flowLiveType == null) {
             inLiveType = null;
         } else {
@@ -147,20 +148,20 @@
             }
 
             // print show topn head line with type
-            print("deviceId=%s, show TOPN=%s flows, live type=%s, instruction type=%s",
+            print("deviceId=%s, show TOPN=%s flows, liveType=%s, instruction type=%s",
                     deviceUri,
                     Integer.toString(topn),
                     flowLiveType == null ? "ALL" : flowLiveType,
                     instructionType == null ? "ALL" : instructionType);
             if (ingressPortNumber == null) {
-                Map<ConnectPoint, List<TypedFlowEntryWithLoad>> typedFlowLoadMap =
+                Map<ConnectPoint, List<FlowEntryWithLoad>> typedFlowLoadMap =
                           flowStatsService.loadTopnByType(device, inLiveType, inInstructionType, topn);
                 // print all ports topn flows load for a given device
                 for (ConnectPoint cp : typedFlowLoadMap.keySet()) {
                     printPortFlowsLoad(cp, typedFlowLoadMap.get(cp));
                 }
             } else {
-                List<TypedFlowEntryWithLoad> typedFlowLoad =
+                List<FlowEntryWithLoad> typedFlowLoad =
                         flowStatsService.loadTopnByType(device, ingressPortNumber, inLiveType, inInstructionType, topn);
                 // print device/port topn flows load
                 ConnectPoint cp = new ConnectPoint(ingressDeviceId, ingressPortNumber);
@@ -168,19 +169,19 @@
             }
         } else if (showAll) { // is true?
             // print show all head line with type
-            print("deviceId=%s, show ALL flows, live type=%s, instruction type=%s",
+            print("deviceId=%s, show ALL flows, liveType=%s, instruction type=%s",
                     deviceUri,
                     flowLiveType == null ? "ALL" : flowLiveType,
                     instructionType == null ? "ALL" : instructionType);
             if (ingressPortNumber == null) {
-                Map<ConnectPoint, List<TypedFlowEntryWithLoad>> typedFlowLoadMap =
+                Map<ConnectPoint, List<FlowEntryWithLoad>> typedFlowLoadMap =
                         flowStatsService.loadAllByType(device, inLiveType, inInstructionType);
                 // print all ports all flows load for a given device
                 for (ConnectPoint cp : typedFlowLoadMap.keySet()) {
                     printPortFlowsLoad(cp, typedFlowLoadMap.get(cp));
                 }
             } else {
-                List<TypedFlowEntryWithLoad> typedFlowLoad =
+                List<FlowEntryWithLoad> typedFlowLoad =
                         flowStatsService.loadAllByType(device, ingressPortNumber, inLiveType, inInstructionType);
                 // print device/port all flows load
                 ConnectPoint cp = new ConnectPoint(ingressDeviceId, ingressPortNumber);
@@ -243,24 +244,24 @@
     }
 
     /**
-     * converts string of flow live type to FloeLiveType enum.
+     * converts string of flow live type to FlowLiveType enum.
      *
      * @param liveType string representing the flow live type
-     * @return TypedStoredFlowEntry.FlowLiveType
+     * @return FlowEntry.FlowLiveType
      */
-    private TypedStoredFlowEntry.FlowLiveType getFlowLiveType(String liveType) {
+    private FlowEntry.FlowLiveType getFlowLiveType(String liveType) {
         String liveTypeUC = liveType.toUpperCase();
 
         if (liveTypeUC.equals("IMMEDIATE")) {
-            return TypedStoredFlowEntry.FlowLiveType.IMMEDIATE_FLOW;
+            return FlowEntry.FlowLiveType.IMMEDIATE;
         } else if (liveTypeUC.equals("SHORT")) {
-            return TypedStoredFlowEntry.FlowLiveType.SHORT_FLOW;
+            return FlowEntry.FlowLiveType.SHORT;
         } else if (liveTypeUC.equals("MID")) {
-            return TypedStoredFlowEntry.FlowLiveType.MID_FLOW;
+            return FlowEntry.FlowLiveType.MID;
         } else if (liveTypeUC.equals("LONG")) {
-            return TypedStoredFlowEntry.FlowLiveType.LONG_FLOW;
+            return FlowEntry.FlowLiveType.LONG;
         } else if (liveTypeUC.equals("UNKNOWN")) {
-            return TypedStoredFlowEntry.FlowLiveType.UNKNOWN_FLOW;
+            return FlowEntry.FlowLiveType.UNKNOWN;
         } else {
             return null; // flow live type error
         }
@@ -294,16 +295,16 @@
         }
     }
 
-    private void printPortFlowsLoad(ConnectPoint cp, List<TypedFlowEntryWithLoad> typedFlowLoad) {
+    private void printPortFlowsLoad(ConnectPoint cp, List<FlowEntryWithLoad> typedFlowLoad) {
        print("  deviceId/Port=%s/%s, %s flows", cp.elementId(), cp.port(), typedFlowLoad.size());
-        for (TypedFlowEntryWithLoad tfel: typedFlowLoad) {
-            TypedStoredFlowEntry tfe =  tfel.typedStoredFlowEntry();
+        for (FlowEntryWithLoad fel: typedFlowLoad) {
+            StoredFlowEntry sfe =  fel.storedFlowEntry();
             print("    flowId=%s, state=%s, liveType=%s, life=%s -> %s",
-                    Long.toHexString(tfe.id().value()),
-                    tfe.state(),
-                    tfe.flowLiveType(),
-                    tfe.life(),
-                    tfel.load().isValid() ? tfel.load() : "Load{rate=0, NOT VALID}");
+                  Long.toHexString(sfe.id().value()),
+                  sfe.state(),
+                  sfe.liveType(),
+                  sfe.life(),
+                  fel.load().isValid() ? fel.load() : "Load{rate=0, NOT VALID}");
         }
     }
 
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) {
diff --git a/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/NewAdaptiveFlowStatsCollector.java b/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/NewAdaptiveFlowStatsCollector.java
index 52d6099..8d885a1 100644
--- a/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/NewAdaptiveFlowStatsCollector.java
+++ b/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/NewAdaptiveFlowStatsCollector.java
@@ -16,19 +16,18 @@
 
 package org.onosproject.provider.of.flow.impl;
 
-import com.google.common.base.Objects;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Maps;
-import com.google.common.collect.Sets;
+import com.google.common.collect.Iterables;
+import org.onlab.osgi.DefaultServiceDirectory;
+import org.onosproject.net.DeviceId;
 import org.onosproject.net.driver.DriverService;
-import org.onosproject.net.flow.DefaultTypedFlowEntry;
 import org.onosproject.net.flow.FlowEntry;
-import org.onosproject.net.flow.FlowId;
-import org.onosproject.net.flow.FlowRule;
+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.flow.instructions.Instructions;
+import org.onosproject.net.statistic.DefaultLoad;
+import org.onosproject.net.statistic.PollInterval;
+import org.onosproject.openflow.controller.Dpid;
 import org.onosproject.openflow.controller.OpenFlowSwitch;
 import org.onosproject.openflow.controller.RoleState;
 import org.projectfloodlight.openflow.protocol.OFFlowStatsRequest;
@@ -37,19 +36,15 @@
 import org.projectfloodlight.openflow.types.TableId;
 import org.slf4j.Logger;
 
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
 import java.util.Optional;
-import java.util.Set;
 import java.util.concurrent.Executors;
 import java.util.concurrent.ScheduledExecutorService;
 import java.util.concurrent.ScheduledFuture;
 import java.util.concurrent.TimeUnit;
 
 import static com.google.common.base.Preconditions.checkNotNull;
+import static java.lang.Thread.sleep;
 import static org.onlab.util.Tools.groupedThreads;
-import static org.onosproject.net.flow.TypedStoredFlowEntry.FlowLiveType;
 import static org.slf4j.LoggerFactory.getLogger;
 
 /**
@@ -64,18 +59,16 @@
                     + ", priority={}, selector={}, treatment={} dpid={}";
 
     private static final String CHECK_AND_MOVE_COUNT_LOG =
-            "checkAndMoveLiveFlowAll: Total Flow_Count={}, add-remove_Count={}"
+            "checkAndMoveLiveFlowAll: Total Flow_Count={}, "
                     + ", IMMEDIATE_FLOW_Count={}, SHORT_FLOW_Count={}"
-                    + ", MID_FLOW_Count={}, LONG_FLOW_Count={}, add_Count={}"
-                    + ", addWithSetFlowLiveType_Count={}, remove_Count={}, dpid={}";
+                    + ", MID_FLOW_Count={}, LONG_FLOW_Count={}, UNKNOWN_FLOW_Count={}";
 
-    private static final String ADD_INVALID_LOG =
-            "addOrUpdateFlows: invalid flow update! The new life is SMALLER than the previous one"
-                    + ", new flowId={}, old flowId={}, new bytes={}, old bytes={}"
-                    + ", new life={}, old life={}, new lastSeen={}, old lastSeen={}";
+    private static final int SLEEP_LOOP_COUNT = 10;
+    private static final int SLEEP_MS = 100;
 
     private final DriverService driverService;
     private final OpenFlowSwitch sw;
+    private final DeviceId did;
 
     private ScheduledExecutorService adaptiveFlowStatsScheduler =
             Executors.newScheduledThreadPool(4, groupedThreads("onos/flow", "device-stats-collector-%d", log));
@@ -113,13 +106,13 @@
     private int callCountMidFlowsTask = 0;   // increased MID_POLL_TIMES whenever Task is called
     private int callCountLongFlowsTask = 0;  // increased LONG_POLL_TIMES whenever Task is called
 
-    private InternalDeviceFlowTable deviceFlowTable = new InternalDeviceFlowTable();
-
     private boolean isFirstTimeStart = true;
 
     public static final long NO_FLOW_MISSING_XID = (-1);
     private long flowMissingXid = NO_FLOW_MISSING_XID;
 
+    private FlowRuleService flowRuleService;
+
     /**
      * Creates a new adaptive collector for the given switch and default cal_and_poll frequency.
      *
@@ -130,9 +123,25 @@
     NewAdaptiveFlowStatsCollector(DriverService driverService, OpenFlowSwitch sw, int pollInterval) {
         this.driverService = driverService;
         this.sw = sw;
+        this.did = DeviceId.deviceId(Dpid.uri(sw.getId()));
+
+        flowRuleService = get(FlowRuleService.class);
+
         initMemberVars(pollInterval);
     }
 
+    /**
+     * Returns the reference to the implementation of the specified service.
+     *
+     * @param serviceClass service class
+     * @param <T>          type of service
+     * @return service implementation
+     * @throws org.onlab.osgi.ServiceNotFoundException if service is unavailable
+     */
+    private static <T> T get(Class<T> serviceClass) {
+        return DefaultServiceDirectory.getService(serviceClass);
+    }
+
     // check calAndPollInterval validity and set all pollInterval values and finally initialize each task call count
     private void initMemberVars(int pollInterval) {
         if (pollInterval < MIN_CAL_AND_POLL_FREQUENCY) {
@@ -148,6 +157,16 @@
         longPollInterval = LONG_POLL_TIMES * calAndPollInterval;
         entirePollInterval = ENTIRE_POLL_TIMES * calAndPollInterval;
 
+        // Set the PollInterval values for statistic manager and others usage
+        DefaultLoad.setPollInterval(calAndPollInterval);
+
+        PollInterval pollInterval1Instance = PollInterval.getInstance();
+
+        pollInterval1Instance.setPollInterval(calAndPollInterval);
+        pollInterval1Instance.setMidPollInterval(midPollInterval);
+        pollInterval1Instance.setLongPollInterval(longPollInterval);
+        pollInterval1Instance.setEntirePollInterval(entirePollInterval);
+
         callCountCalAndShortFlowsTask = 0;
         callCountMidFlowsTask = 0;
         callCountLongFlowsTask = 0;
@@ -228,23 +247,21 @@
     }
 
     // send openflow flow stats request message with getting all flow entries to a given switch sw
-    private void ofFlowStatsRequestAllSend() {
+    private synchronized void ofFlowStatsRequestAllSend() {
         OFFlowStatsRequest request = sw.factory().buildFlowStatsRequest()
                 .setMatch(sw.factory().matchWildcardAll())
                 .setTableId(TableId.ALL)
                 .setOutPort(OFPort.NO_MASK)
                 .build();
 
-        synchronized (this) {
-            // set the request xid to check the reply in OpenFlowRuleProvider
-            // After processing the reply of this request message,
-            // this must be set to NO_FLOW_MISSING_XID(-1) by provider
-            setFlowMissingXid(request.getXid());
-            log.debug("ofFlowStatsRequestAllSend: request={}, dpid={}",
+        // set the request xid to check the reply in OpenFlowRuleProvider
+        // After processing the reply of this request message,
+        // this must be set to NO_FLOW_MISSING_XID(-1) by provider
+        setFlowMissingXid(request.getXid());
+        log.debug("ofFlowStatsRequestAllSend: request={}, dpid={}",
                     request.toString(), sw.getStringId());
 
-            sw.sendMsg(request);
-        }
+        sw.sendMsg(request);
     }
 
     // send openflow flow stats request message with getting the specific flow entry(fe) to a given switch sw
@@ -271,22 +288,54 @@
                 .setOutPort(ofPort)
                 .build();
 
-        synchronized (this) {
-            if (getFlowMissingXid() != NO_FLOW_MISSING_XID) {
-                log.debug("ofFlowStatsRequestFlowSend: previous FlowStatsRequestAll does not be processed yet,"
-                                + " set no flow missing xid anyway, for {}",
-                        sw.getStringId());
-                setFlowMissingXid(NO_FLOW_MISSING_XID);
-            }
+        // Wait for 1 second until the FlowRuleProvider finishes to process FlowStatReply message
+        int loop = 0;
+        boolean interrupted = false;
+        while (!interrupted && getFlowMissingXid() != NO_FLOW_MISSING_XID) {
+            if (loop++ < SLEEP_LOOP_COUNT) {
+                log.debug("ofFlowStatsRequestFlowSend: previous FlowStatsRequestAll (xid={})" +
+                                  " does not be processed yet, do sleep for {} ms, for {}",
+                          getFlowMissingXid(),
+                          SLEEP_MS,
+                          sw.getStringId());
+                try {
+                    sleep(SLEEP_MS);
+                } catch (InterruptedException ie) {
+                    log.debug("ofFlowStatsRequestFlowSend: Interrupted Exception = {}, for {}",
+                              ie.toString(),
+                              sw.getStringId());
+                    // for exiting while loop gracefully
+                    interrupted = true;
+                }
+            } else {
+                log.debug("ofFlowStatsRequestFlowSend: previous FlowStatsRequestAll (xid={})" +
+                                  " does not be processed yet, for {} ms," +
+                                  " just set xid with NO_FLOW_MISSING_XID, for {}",
+                          getFlowMissingXid(),
+                          loop * SLEEP_MS,
+                          sw.getStringId());
 
-            sw.sendMsg(request);
+                setFlowMissingXid(NO_FLOW_MISSING_XID);
+                break;
+            }
         }
+
+        sw.sendMsg(request);
+
     }
 
     private void calAndShortFlowsTaskInternal() {
-        deviceFlowTable.checkAndMoveLiveFlowAll();
+        checkAndMoveLiveFlowAll();
 
-        deviceFlowTable.getShortFlows().forEach(fe -> {
+        ofFlowStatsRequestInternal(FlowEntry.FlowLiveType.SHORT);
+    }
+
+    private void ofFlowStatsRequestInternal(FlowEntry.FlowLiveType liveType) {
+
+        Iterable<FlowEntry> flowEntries =
+                flowRuleService.getFlowEntriesByLiveType(did, liveType);
+
+        flowEntries.forEach(fe -> {
             ofFlowStatsRequestFlowSend(fe);
         });
     }
@@ -309,9 +358,7 @@
     }
 
     private void midFlowsTaskInternal() {
-        deviceFlowTable.getMidFlows().forEach(fe -> {
-            ofFlowStatsRequestFlowSend(fe);
-        });
+        ofFlowStatsRequestInternal(FlowEntry.FlowLiveType.MID);
     }
 
     private class LongFlowsTask implements Runnable {
@@ -332,9 +379,7 @@
     }
 
     private void longFlowsTaskInternal() {
-        deviceFlowTable.getLongFlows().forEach(fe -> {
-            ofFlowStatsRequestFlowSend(fe);
-        });
+        ofFlowStatsRequestInternal(FlowEntry.FlowLiveType.LONG);
     }
 
     /**
@@ -396,111 +441,6 @@
     }
 
     /**
-     * Adds typed flow entry from flow rule into the internal flow table.
-     *
-     * @param flowRules the flow rules
-     */
-    public synchronized void addWithFlowRule(FlowRule... flowRules) {
-        for (FlowRule fr : flowRules) {
-            // First remove old entry unconditionally, if exist
-            deviceFlowTable.remove(fr);
-
-            // add new flow entry, we suppose IMMEDIATE_FLOW
-            TypedStoredFlowEntry newFlowEntry = new DefaultTypedFlowEntry(fr,
-                    FlowLiveType.IMMEDIATE_FLOW);
-            deviceFlowTable.addWithCalAndSetFlowLiveType(newFlowEntry);
-        }
-    }
-
-    /**
-     * Adds or updates typed flow entry from flow entry into the internal flow table.
-     *
-     * @param flowEntries the flow entries
-     */
-    public synchronized void addOrUpdateFlows(FlowEntry... flowEntries) {
-        for (FlowEntry fe : flowEntries) {
-            // check if this new rule is an update to an existing entry
-            TypedStoredFlowEntry stored = deviceFlowTable.getFlowEntry(fe);
-
-            if (stored != null) {
-                // duplicated flow entry is collected!, just skip
-                if (fe.bytes() == stored.bytes() && fe.packets() == stored.packets()
-                        && fe.life() == stored.life()) {
-                    if (log.isTraceEnabled()) {
-                        log.trace("addOrUpdateFlows({}): flowId={},is DUPLICATED stats collection, just skip.",
-                                sw.getStringId(), fe.id());
-                    }
-
-                    //FIXME modification of "stored" flow entry outside of store
-                    stored.setLastSeen();
-                    continue;
-                } else if (fe.life() < stored.life()) {
-                    // Invalid updates the stats values, i.e., bytes, packets, durations ...
-                    if (log.isDebugEnabled()) {
-                        log.debug(ADD_INVALID_LOG, fe.id(), stored.id(), fe.bytes(),
-                                stored.bytes(), fe.life(), stored.life(),
-                                fe.lastSeen(), stored.lastSeen());
-                    }
-                    // go next
-                    //FIXME modification of "stored" flow entry outside of store
-                    stored.setLastSeen();
-                    continue;
-                }
-
-                // update now
-                //FIXME modification of "stored" flow entry outside of store
-                stored.setLife(fe.life(TimeUnit.NANOSECONDS), TimeUnit.NANOSECONDS);
-                stored.setPackets(fe.packets());
-                stored.setBytes(fe.bytes());
-                stored.setLastSeen();
-                if (stored.state() == FlowEntry.FlowEntryState.PENDING_ADD) {
-                    // flow is really RULE_ADDED
-                    stored.setState(FlowEntry.FlowEntryState.ADDED);
-                }
-                // flow is RULE_UPDATED, skip adding and just updating flow live table
-                //deviceFlowTable.calAndSetFlowLiveType(stored);
-                continue;
-            }
-
-            // add new flow entry, we suppose IMMEDIATE_FLOW
-            TypedStoredFlowEntry newFlowEntry = new DefaultTypedFlowEntry(fe,
-                    FlowLiveType.IMMEDIATE_FLOW);
-            deviceFlowTable.addWithCalAndSetFlowLiveType(newFlowEntry);
-        }
-    }
-
-    /**
-     * Removes typed flow entry from the internal flow table.
-     *
-     * @param flowRules the flow entries
-     */
-    public synchronized void removeFlows(FlowRule...  flowRules) {
-        for (FlowRule rule : flowRules) {
-            deviceFlowTable.remove(rule);
-        }
-    }
-
-    // same as removeFlows() function
-    /**
-     * Removes typed flow entry from the internal flow table.
-     *
-     * @param flowRules the flow entries
-     */
-    public void flowRemoved(FlowRule... flowRules) {
-        removeFlows(flowRules);
-    }
-
-    // same as addOrUpdateFlows() function
-    /**
-     * Adds or updates typed flow entry from flow entry into the internal flow table.
-     *
-     * @param flowEntries the flow entry list
-     */
-    public void pushFlowMetrics(List<FlowEntry> flowEntries) {
-        flowEntries.forEach(this::addOrUpdateFlows);
-    }
-
-    /**
      * Returns flowMissingXid that indicates the execution of flowMissing process or not(NO_FLOW_MISSING_XID(-1)).
      *
      * @return xid of missing flow
@@ -518,339 +458,146 @@
         this.flowMissingXid = flowMissingXid;
     }
 
-    private class InternalDeviceFlowTable {
+    /**
+     * Calculates the flow live type.
+     *
+     * @param life the flow life time in seconds
+     * @return computed flow live type
+     */
+    public FlowEntry.FlowLiveType calFlowLiveType(long life) {
+        if (life < 0) {
+            return FlowEntry.FlowLiveType.UNKNOWN;
+        } else if (life < calAndPollInterval) {
+            return FlowEntry.FlowLiveType.IMMEDIATE;
+        } else if (life < midPollInterval) {
+            return FlowEntry.FlowLiveType.SHORT;
+        } else if (life < longPollInterval) {
+            return FlowEntry.FlowLiveType.MID;
+        } else { // >= longPollInterval
+            return FlowEntry.FlowLiveType.LONG;
+        }
+    }
 
-        private final Map<FlowId, Set<TypedStoredFlowEntry>>
-                flowEntries = Maps.newConcurrentMap();
+    /**
+     * Calculates and set the flow live type.
+     * It maybe called pushFlowMetrics of FlowRuleService for the ReplyFlowStat message
+     * at the first time and every entire polling time.
+     *
+     * @param fe the flow entry rule
+     * @return computed flow live type
+     */
+    public FlowEntry.FlowLiveType calAndSetFlowLiveType(StoredFlowEntry fe) {
+        checkNotNull(fe);
 
-        private final Set<StoredFlowEntry> shortFlows = new HashSet<>();
-        private final Set<StoredFlowEntry> midFlows = new HashSet<>();
-        private final Set<StoredFlowEntry> longFlows = new HashSet<>();
+        long life = fe.life();
 
-        // Assumed latency adjustment(default=500 millisecond) between FlowStatsRequest and Reply
-        private final long latencyFlowStatsRequestAndReplyMillis = 500;
-
-
-        // Statistics for table operation
-        private long addCount = 0, addWithSetFlowLiveTypeCount = 0;
-        private long removeCount = 0;
-
-        /**
-         * Resets all count values to zero.
-         */
-        public void resetAllCount() {
-            addCount = 0;
-            addWithSetFlowLiveTypeCount = 0;
-            removeCount = 0;
+        if (life < 0) {
+            fe.setLiveType(FlowEntry.FlowLiveType.UNKNOWN);
+        } else if (life < calAndPollInterval) {
+            fe.setLiveType(FlowEntry.FlowLiveType.IMMEDIATE);
+        } else if (life < midPollInterval) {
+            fe.setLiveType(FlowEntry.FlowLiveType.SHORT);
+        } else if (life < longPollInterval) {
+            fe.setLiveType(FlowEntry.FlowLiveType.MID);
+        } else { // >= longPollInterval
+            fe.setLiveType(FlowEntry.FlowLiveType.LONG);
         }
 
-        // get set of flow entries for the given flowId
-        private Set<TypedStoredFlowEntry> getFlowEntriesInternal(FlowId flowId) {
-            return flowEntries.computeIfAbsent(flowId, id -> Sets.newCopyOnWriteArraySet());
-        }
+        return fe.liveType();
+    }
 
-        // get flow entry for the given flow rule
-        private TypedStoredFlowEntry getFlowEntryInternal(FlowRule rule) {
-            Set<TypedStoredFlowEntry> flowEntries = getFlowEntriesInternal(rule.id());
-            return flowEntries.stream()
-                    .filter(entry -> Objects.equal(entry, rule))
-                    .findAny()
-                    .orElse(null);
-        }
+    /**
+     * Check and move live type for all type flow entries in table at every calAndPollInterval time.
+     *
+     */
+    private void checkAndMoveLiveFlowAll() {
 
-        // get the flow entries for all flows in flow table
-        private Set<TypedStoredFlowEntry> getFlowEntriesInternal() {
-            Set<TypedStoredFlowEntry> result = Sets.newHashSet();
+        Iterable<FlowEntry> flowEntries = flowRuleService.getFlowEntries(did);
 
-            flowEntries.values().forEach(result::addAll);
-            return result;
-        }
+        flowEntries.forEach(fe -> {
+            checkAndMoveLiveFlowInternal((StoredFlowEntry) fe);
+        });
 
-        /**
-         * Gets the number of flow entry in flow table.
-         *
-         * @return the number of flow entry
-         */
-        public long getFlowCount() {
-            return flowEntries.values().stream().mapToLong(Set::size).sum();
-        }
+        // print table counts for debug
+        if (log.isDebugEnabled()) {
+            Iterable<FlowEntry> fes;
+            synchronized (this) {
+                long totalFlowCount = flowRuleService.getFlowRuleCount();
+                fes = flowRuleService.getFlowEntriesByLiveType(
+                        did, FlowEntry.FlowLiveType.IMMEDIATE);
+                long immediateFlowCount = Iterables.size(fes);
+                fes = flowRuleService.getFlowEntriesByLiveType(
+                        did, FlowEntry.FlowLiveType.SHORT);
+                long shortFlowCount = Iterables.size(fes);
+                fes = flowRuleService.getFlowEntriesByLiveType(
+                        did, FlowEntry.FlowLiveType.MID);
+                long midFlowCount = Iterables.size(fes);
+                fes = flowRuleService.getFlowEntriesByLiveType(
+                        did, FlowEntry.FlowLiveType.LONG);
+                long longFlowCount = Iterables.size(fes);
+                fes = flowRuleService.getFlowEntriesByLiveType(
+                        did, FlowEntry.FlowLiveType.UNKNOWN);
+                long unknownFlowCount = Iterables.size(fes);
 
-        /**
-         * Gets the number of flow entry in flow table.
-         *
-         * @param rule the flow rule
-         * @return the typed flow entry
-         */
-        public TypedStoredFlowEntry getFlowEntry(FlowRule rule) {
-            checkNotNull(rule);
+                log.trace(CHECK_AND_MOVE_COUNT_LOG, totalFlowCount,
+                            immediateFlowCount, shortFlowCount, midFlowCount, longFlowCount, unknownFlowCount);
 
-            return getFlowEntryInternal(rule);
-        }
-
-        /**
-         * Gets the all typed flow entries in flow table.
-         *
-         * @return the set of typed flow entry
-         */
-        public Set<TypedStoredFlowEntry> getFlowEntries() {
-            return getFlowEntriesInternal();
-        }
-
-        /**
-         * Gets the short typed flow entries in flow table.
-         *
-         * @return the set of typed flow entry
-         */
-        public Set<StoredFlowEntry> getShortFlows() {
-            return ImmutableSet.copyOf(shortFlows);
-        }
-
-        /**
-         * Gets the mid typed flow entries in flow table.
-         *
-         * @return the set of typed flow entry
-         */
-        public Set<StoredFlowEntry> getMidFlows() {
-            return ImmutableSet.copyOf(midFlows);
-        }
-
-        /**
-         * Gets the long typed flow entries in flow table.
-         *
-         * @return the set of typed flow entry
-         */
-        public Set<StoredFlowEntry> getLongFlows() {
-            return ImmutableSet.copyOf(longFlows);
-        }
-
-        /**
-         * Add typed flow entry into table only.
-         *
-         * @param rule the flow rule
-         */
-        public synchronized void add(TypedStoredFlowEntry rule) {
-            checkNotNull(rule);
-
-            //rule have to be new DefaultTypedFlowEntry
-            boolean result = getFlowEntriesInternal(rule.id()).add(rule);
-
-            if (result) {
-                addCount++;
-            }
-        }
-
-        /**
-         * Calculates and sets the flow live type at the first time,
-         * and then add it into a corresponding typed flow table.
-         *
-         * @param rule the flow rule
-         */
-        public void calAndSetFlowLiveType(TypedStoredFlowEntry rule) {
-            checkNotNull(rule);
-
-            calAndSetFlowLiveTypeInternal(rule);
-        }
-
-        /**
-         * Adds the typed flow entry into table, and calculates and set the flow live type,
-         * and then add it into a corresponding typed flow table.
-         *
-         * @param rule the flow rule
-         */
-        public synchronized void addWithCalAndSetFlowLiveType(TypedStoredFlowEntry rule) {
-            checkNotNull(rule);
-
-            //rule have to be new DefaultTypedFlowEntry
-            boolean result = getFlowEntriesInternal(rule.id()).add(rule);
-            if (result) {
-                calAndSetFlowLiveTypeInternal(rule);
-                addWithSetFlowLiveTypeCount++;
-            } else {
-                if (log.isDebugEnabled()) {
-                    log.debug("FlowId {} ADD failed, it may already exist in table - {}",
-                            rule.id(), sw.getStringId());
+                if (immediateFlowCount < 0) {
+                    log.error("Immediate flow count is negative");
                 }
             }
         }
+        log.trace("checkAndMoveLiveFlowAll, AdaptiveStats for {}", sw.getStringId());
+    }
 
-        // In real, calculates and set the flow live type at the first time,
-        // and then add it into a corresponding typed flow table
-        private void calAndSetFlowLiveTypeInternal(TypedStoredFlowEntry rule) {
-            long life = rule.life();
-            FlowLiveType prevFlowLiveType = rule.flowLiveType();
+    // check and set the flow live type based on current time
+    private boolean checkAndMoveLiveFlowInternal(StoredFlowEntry fe) {
+        long fromLastSeen = ((System.currentTimeMillis() - fe.lastSeen()) / 1000);
+        // fe.life() unit is SECOND!
+        long liveTime = fe.life() + fromLastSeen;
 
-            if (life >= longPollInterval) {
-                rule.setFlowLiveType(FlowLiveType.LONG_FLOW);
-                longFlows.add(rule);
-            } else if (life >= midPollInterval) {
-                rule.setFlowLiveType(FlowLiveType.MID_FLOW);
-                midFlows.add(rule);
-            } else if (life >= calAndPollInterval) {
-                rule.setFlowLiveType(FlowLiveType.SHORT_FLOW);
-                shortFlows.add(rule);
-            } else if (life >= 0) {
-                rule.setFlowLiveType(FlowLiveType.IMMEDIATE_FLOW);
-            } else { // life < 0
-                rule.setFlowLiveType(FlowLiveType.UNKNOWN_FLOW);
-            }
+        FlowEntry.FlowLiveType oldLiveType = fe.liveType();
 
-            if (rule.flowLiveType() != prevFlowLiveType) {
-                switch (prevFlowLiveType) {
-                // delete it from previous flow table
-                case SHORT_FLOW:
-                    shortFlows.remove(rule);
-                    break;
-                case MID_FLOW:
-                    midFlows.remove(rule);
-                    break;
-                case LONG_FLOW:
-                    longFlows.remove(rule);
-                    break;
-                default:
-                    break;
-                }
-            }
-        }
-
-
-        // check the flow live type based on current time, then set and add it into corresponding table
-        private boolean checkAndMoveLiveFlowInternal(TypedStoredFlowEntry fe, long cTime) {
-            long curTime = (cTime > 0 ? cTime : System.currentTimeMillis());
-            // For latency adjustment(default=500 millisecond) between FlowStatsRequest and Reply
-            long fromLastSeen = ((curTime - fe.lastSeen() + latencyFlowStatsRequestAndReplyMillis) / 1000);
-            // fe.life() unit is SECOND!
-            long liveTime = fe.life() + fromLastSeen;
-
-
-            switch (fe.flowLiveType()) {
-            case IMMEDIATE_FLOW:
-                if (liveTime >= longPollInterval) {
-                    fe.setFlowLiveType(FlowLiveType.LONG_FLOW);
-                    longFlows.add(fe);
-                } else if (liveTime >= midPollInterval) {
-                    fe.setFlowLiveType(FlowLiveType.MID_FLOW);
-                    midFlows.add(fe);
-                } else if (liveTime >= calAndPollInterval) {
-                    fe.setFlowLiveType(FlowLiveType.SHORT_FLOW);
-                    shortFlows.add(fe);
+        switch (fe.liveType()) {
+            case IMMEDIATE:
+                if (liveTime >= calAndPollInterval) {
+                    fe.setLiveType(FlowEntry.FlowLiveType.SHORT);
                 }
                 break;
-            case SHORT_FLOW:
-                if (liveTime >= longPollInterval) {
-                    fe.setFlowLiveType(FlowLiveType.LONG_FLOW);
-                    shortFlows.remove(fe);
-                    longFlows.add(fe);
-                } else if (liveTime >= midPollInterval) {
-                    fe.setFlowLiveType(FlowLiveType.MID_FLOW);
-                    shortFlows.remove(fe);
-                    midFlows.add(fe);
+            case SHORT:
+                if (liveTime >= midPollInterval) {
+                    fe.setLiveType(FlowEntry.FlowLiveType.MID);
                 }
                 break;
-            case MID_FLOW:
+            case MID:
                 if (liveTime >= longPollInterval) {
-                    fe.setFlowLiveType(FlowLiveType.LONG_FLOW);
-                    midFlows.remove(fe);
-                    longFlows.add(fe);
+                    fe.setLiveType(FlowEntry.FlowLiveType.LONG);
                 }
                 break;
-            case LONG_FLOW:
+            case LONG:
                 if (fromLastSeen > entirePollInterval) {
-                    log.trace("checkAndMoveLiveFlowInternal: flow is already removed at switch.");
+                    log.trace("checkAndMoveLiveFlowInternal, flow may be already removed at switch.");
                     return false;
                 }
                 break;
-            case UNKNOWN_FLOW: // Unknown flow is an internal error flow type, just fall through
+            case UNKNOWN: // Unknown live type is calculated and set with correct flow live type here.
+                calAndSetFlowLiveType(fe);
+                break;
             default:
-                log.error("Unknown live type error for {}", sw.getStringId());
+                // Error Live Type
+                log.error("checkAndMoveLiveFlowInternal, Unknown Live Type error!"
+                            + " AdaptiveStats collection thread for {}",
+                            sw.getStringId());
                 return false;
-            }
+        }
 
-            if (log.isTraceEnabled()) {
-                log.trace(CHECK_AND_MOVE_LOG, fe.id(), fe.state(), fe.flowLiveType(),
+        if (log.isTraceEnabled()) {
+            log.trace(CHECK_AND_MOVE_LOG, fe.id(), fe.state(), fe.liveType(),
                         liveTime, fe.life(), fe.bytes(), fe.packets(), fromLastSeen,
                         fe.priority(), fe.selector().criteria(), fe.treatment(),
                         sw.getStringId());
-            }
-
-            return true;
         }
 
-        /**
-         * Checks and moves live type for all type flow entries in table at every calAndPollInterval time.
-         */
-        public void checkAndMoveLiveFlowAll() {
-            Set<TypedStoredFlowEntry> typedFlowEntries = getFlowEntriesInternal();
-
-            long calCurTime = System.currentTimeMillis();
-            typedFlowEntries.forEach(fe -> {
-                if (!checkAndMoveLiveFlowInternal(fe, calCurTime)) {
-                    remove(fe);
-                }
-            });
-
-            // print table counts for debug
-            if (log.isTraceEnabled()) {
-                synchronized (this) {
-                    long totalFlowCount = getFlowCount();
-                    long shortFlowCount = shortFlows.size();
-                    long midFlowCount = midFlows.size();
-                    long longFlowCount = longFlows.size();
-                    long immediateFlowCount = totalFlowCount - shortFlowCount - midFlowCount - longFlowCount;
-                    long calTotalCount = addCount + addWithSetFlowLiveTypeCount - removeCount;
-
-                    log.trace(CHECK_AND_MOVE_COUNT_LOG, totalFlowCount, calTotalCount,
-                            immediateFlowCount, shortFlowCount, midFlowCount, longFlowCount,
-                            addCount, addWithSetFlowLiveTypeCount, removeCount, sw.getStringId());
-
-                    if (totalFlowCount != calTotalCount) {
-                        log.error("Real total flow count and calculated total flow count do NOT match");
-                    }
-                    if (immediateFlowCount < 0) {
-                        log.error("Immediate flow count is negative");
-                    }
-                }
-            }
-            log.trace("checkAndMoveLiveFlowAll: adaptiveStats for {}", sw.getStringId());
-        }
-
-        /**
-         * Removes the typed flow entry from table.
-         *
-         * @param rule the flow rule
-         */
-        public synchronized void remove(FlowRule rule) {
-            checkNotNull(rule);
-
-            TypedStoredFlowEntry removeStore = getFlowEntryInternal(rule);
-            if (removeStore != null) {
-                removeLiveFlowsInternal(removeStore);
-                boolean result = getFlowEntriesInternal(rule.id()).remove(removeStore);
-
-                if (result) {
-                    removeCount++;
-                }
-            }
-        }
-
-        // Remove the typed flow entry from corresponding table
-        private void removeLiveFlowsInternal(TypedStoredFlowEntry fe) {
-            switch (fe.flowLiveType()) {
-            case IMMEDIATE_FLOW:
-                // do nothing
-                break;
-            case SHORT_FLOW:
-                shortFlows.remove(fe);
-                break;
-            case MID_FLOW:
-                midFlows.remove(fe);
-                break;
-            case LONG_FLOW:
-                longFlows.remove(fe);
-                break;
-            default: // error in Flow Live Type
-                log.error("removeLiveFlowsInternal: unknown live type error");
-                break;
-            }
-        }
+        return true;
     }
 }
diff --git a/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/OpenFlowRuleProvider.java b/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/OpenFlowRuleProvider.java
index 9c9f154..886fb97 100644
--- a/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/OpenFlowRuleProvider.java
+++ b/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/OpenFlowRuleProvider.java
@@ -140,7 +140,9 @@
 
     private Cache<Long, InternalCacheEntry> pendingBatches;
 
-    private final Timer timer = new Timer("onos-openflow-flowstats-collector");
+    private final Timer timer = new Timer("onos-openflow-collector");
+
+    // Old simple collector set
     private final Map<Dpid, FlowStatsCollector> simpleCollectors = Maps.newConcurrentMap();
 
     // NewAdaptiveFlowStatsCollector Set
@@ -303,14 +305,6 @@
         }
         sw.sendMsg(FlowModBuilder.builder(flowRule, sw.factory(),
                 Optional.empty(), Optional.of(driverService)).buildFlowAdd());
-
-        if (adaptiveFlowSampling) {
-            // Add TypedFlowEntry to deviceFlowEntries in NewAdaptiveFlowStatsCollector
-            NewAdaptiveFlowStatsCollector collector = afsCollectors.get(dpid);
-            if (collector != null) {
-                collector.addWithFlowRule(flowRule);
-            }
-        }
     }
 
     @Override
@@ -336,14 +330,6 @@
         }
         sw.sendMsg(FlowModBuilder.builder(flowRule, sw.factory(),
                                           Optional.empty(), Optional.of(driverService)).buildFlowDel());
-
-        if (adaptiveFlowSampling) {
-            // Remove TypedFlowEntry to deviceFlowEntries in NewAdaptiveFlowStatsCollector
-            NewAdaptiveFlowStatsCollector collector = afsCollectors.get(dpid);
-            if (collector != null) {
-                collector.removeFlows(flowRule);
-            }
-        }
     }
 
     @Override
@@ -384,25 +370,12 @@
             switch (fbe.operator()) {
                 case ADD:
                     mod = builder.buildFlowAdd();
-                    if (adaptiveFlowSampling && collector != null) {
-                        // Add TypedFlowEntry to deviceFlowEntries in NewAdaptiveFlowStatsCollector
-                        collector.addWithFlowRule(fbe.target());
-                    }
                     break;
                 case REMOVE:
                     mod = builder.buildFlowDel();
-                    if (adaptiveFlowSampling && collector != null) {
-                        // Remove TypedFlowEntry to deviceFlowEntries in NewAdaptiveFlowStatsCollector
-                        collector.removeFlows(fbe.target());
-                    }
                     break;
                 case MODIFY:
                     mod = builder.buildFlowMod();
-                    if (adaptiveFlowSampling && collector != null) {
-                        // Add or Update TypedFlowEntry to deviceFlowEntries in NewAdaptiveFlowStatsCollector
-                        // afsCollectors.get(dpid).addWithFlowRule(fbe.target()); //check if add is good or not
-                        collector.addOrUpdateFlows((FlowEntry) fbe.target());
-                    }
                     break;
                 default:
                     log.error("Unsupported batch operation {}; skipping flowmod {}",
@@ -462,14 +435,6 @@
 
                     FlowEntry fr = new FlowEntryBuilder(deviceId, removed, driverService).build();
                     providerService.flowRemoved(fr);
-
-                    if (adaptiveFlowSampling) {
-                        // Removed TypedFlowEntry to deviceFlowEntries in NewAdaptiveFlowStatsCollector
-                        NewAdaptiveFlowStatsCollector collector = afsCollectors.get(dpid);
-                        if (collector != null) {
-                            collector.flowRemoved(fr);
-                        }
-                    }
                     break;
                 case STATS_REPLY:
                     if (((OFStatsReply) msg).getStatsType() == OFStatsType.FLOW) {
@@ -646,40 +611,34 @@
         private void pushFlowMetrics(Dpid dpid, OFFlowStatsReply replies) {
 
             DeviceId did = DeviceId.deviceId(Dpid.uri(dpid));
+            NewAdaptiveFlowStatsCollector afsc = afsCollectors.get(dpid);
 
-            List<FlowEntry> flowEntries = replies.getEntries().stream()
-                    .map(entry -> new FlowEntryBuilder(did, entry, driverService).build())
-                    .collect(Collectors.toList());
+            if (adaptiveFlowSampling && afsc != null)  {
+                List<FlowEntry> flowEntries = replies.getEntries().stream()
+                        .map(entry -> new FlowEntryBuilder(did, entry, driverService).withSetAfsc(afsc).build())
+                        .collect(Collectors.toList());
 
-            if (adaptiveFlowSampling)  {
-                NewAdaptiveFlowStatsCollector afsc = afsCollectors.get(dpid);
-
-                synchronized (afsc) {
-                    if (afsc.getFlowMissingXid() != NewAdaptiveFlowStatsCollector.NO_FLOW_MISSING_XID) {
-                        log.debug("OpenFlowRuleProvider:pushFlowMetrics, flowMissingXid={}, " +
-                                        "OFFlowStatsReply Xid={}, for {}",
-                                afsc.getFlowMissingXid(), replies.getXid(), dpid);
+                // Check that OFFlowStatsReply Xid is same with the one of OFFlowStatsRequest?
+                if (afsc.getFlowMissingXid() != NewAdaptiveFlowStatsCollector.NO_FLOW_MISSING_XID) {
+                        log.debug("OpenFlowRuleProvider:pushFlowMetrics, flowMissingXid={}, "
+                                          + "OFFlowStatsReply Xid={}, for {}",
+                                  afsc.getFlowMissingXid(), replies.getXid(), dpid);
+                    if (afsc.getFlowMissingXid() == replies.getXid()) {
+                        // call entire flow stats update with flowMissing synchronization.
+                        // used existing pushFlowMetrics
+                        providerService.pushFlowMetrics(did, flowEntries);
                     }
-
-                    // Check that OFFlowStatsReply Xid is same with the one of OFFlowStatsRequest?
-                    if (afsc.getFlowMissingXid() != NewAdaptiveFlowStatsCollector.NO_FLOW_MISSING_XID) {
-                        if (afsc.getFlowMissingXid() == replies.getXid()) {
-                            // call entire flow stats update with flowMissing synchronization.
-                            // used existing pushFlowMetrics
-                            providerService.pushFlowMetrics(did, flowEntries);
-                        }
-                        // reset flowMissingXid to NO_FLOW_MISSING_XID
-                        afsc.setFlowMissingXid(NewAdaptiveFlowStatsCollector.NO_FLOW_MISSING_XID);
-
-                    } else {
-                        // call individual flow stats update
-                        providerService.pushFlowMetricsWithoutFlowMissing(did, flowEntries);
-                    }
-
-                    // Update TypedFlowEntry to deviceFlowEntries in NewAdaptiveFlowStatsCollector
-                    afsc.pushFlowMetrics(flowEntries);
+                    // reset flowMissingXid to NO_FLOW_MISSING_XID
+                    afsc.setFlowMissingXid(NewAdaptiveFlowStatsCollector.NO_FLOW_MISSING_XID);
+                } else {
+                    // call individual flow stats update
+                    providerService.pushFlowMetricsWithoutFlowMissing(did, flowEntries);
                 }
             } else {
+                List<FlowEntry> flowEntries = replies.getEntries().stream()
+                        .map(entry -> new FlowEntryBuilder(did, entry, driverService).build())
+                        .collect(Collectors.toList());
+
                 // call existing entire flow stats update with flowMissing synchronization
                 providerService.pushFlowMetrics(did, flowEntries);
             }
diff --git a/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/util/FlowEntryBuilder.java b/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/util/FlowEntryBuilder.java
index 2b042e6..c9f5dd3 100644
--- a/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/util/FlowEntryBuilder.java
+++ b/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/util/FlowEntryBuilder.java
@@ -48,6 +48,7 @@
 import org.onosproject.net.flow.instructions.Instructions;
 import org.onosproject.openflow.controller.ExtensionSelectorInterpreter;
 import org.onosproject.openflow.controller.ExtensionTreatmentInterpreter;
+import org.onosproject.provider.of.flow.impl.NewAdaptiveFlowStatsCollector;
 import org.projectfloodlight.openflow.protocol.OFFlowMod;
 import org.projectfloodlight.openflow.protocol.OFFlowRemoved;
 import org.projectfloodlight.openflow.protocol.OFFlowStatsEntry;
@@ -124,6 +125,10 @@
 
     private final DriverService driverService;
 
+    // NewAdaptiveFlowStatsCollector for AdaptiveFlowSampling mode,
+    // null is not AFM mode, namely SimpleStatsCollector mode
+    private NewAdaptiveFlowStatsCollector afsc;
+
     public FlowEntryBuilder(DeviceId deviceId, OFFlowStatsEntry entry, DriverService driverService) {
         this.stat = entry;
         this.match = entry.getMatch();
@@ -133,6 +138,7 @@
         this.flowMod = null;
         this.type = FlowType.STAT;
         this.driverService = driverService;
+        this.afsc = null;
     }
 
     public FlowEntryBuilder(DeviceId deviceId, OFFlowRemoved removed, DriverService driverService) {
@@ -144,6 +150,7 @@
         this.flowMod = null;
         this.type = FlowType.REMOVED;
         this.driverService = driverService;
+        this.afsc = null;
     }
 
     public FlowEntryBuilder(DeviceId deviceId, OFFlowMod fm, DriverService driverService) {
@@ -155,6 +162,12 @@
         this.stat = null;
         this.removed = null;
         this.driverService = driverService;
+        this.afsc = null;
+    }
+
+    public FlowEntryBuilder withSetAfsc(NewAdaptiveFlowStatsCollector afsc) {
+        this.afsc = afsc;
+        return this;
     }
 
     public FlowEntry build(FlowEntryState... state) {
@@ -173,11 +186,21 @@
                         builder.forTable(stat.getTableId().getValue());
                     }
 
-                    return new DefaultFlowEntry(builder.build(), FlowEntryState.ADDED,
-                                                SECONDS.toNanos(stat.getDurationSec())
-                                                        + stat.getDurationNsec(), NANOSECONDS,
-                                                stat.getPacketCount().getValue(),
-                                                stat.getByteCount().getValue());
+                    if (afsc != null) {
+                        FlowEntry.FlowLiveType liveType = afsc.calFlowLiveType(stat.getDurationSec());
+                        return new DefaultFlowEntry(builder.build(), FlowEntryState.ADDED,
+                                                    SECONDS.toNanos(stat.getDurationSec())
+                                                            + stat.getDurationNsec(), NANOSECONDS,
+                                                    liveType,
+                                                    stat.getPacketCount().getValue(),
+                                                    stat.getByteCount().getValue());
+                    } else {
+                        return new DefaultFlowEntry(builder.build(), FlowEntryState.ADDED,
+                                                    stat.getDurationSec(),
+                                                    stat.getPacketCount().getValue(),
+                                                    stat.getByteCount().getValue());
+                    }
+
                 case REMOVED:
                     builder = DefaultFlowRule.builder()
                             .forDevice(deviceId)
@@ -191,11 +214,21 @@
                         builder.forTable(removed.getTableId().getValue());
                     }
 
-                    return new DefaultFlowEntry(builder.build(), FlowEntryState.REMOVED,
-                                                SECONDS.toNanos(removed.getDurationSec())
-                                                        + removed.getDurationNsec(), NANOSECONDS,
-                                                removed.getPacketCount().getValue(),
-                                                removed.getByteCount().getValue());
+                    if (afsc != null) {
+                        FlowEntry.FlowLiveType liveType = afsc.calFlowLiveType(removed.getDurationSec());
+                        return new DefaultFlowEntry(builder.build(), FlowEntryState.REMOVED,
+                                                    SECONDS.toNanos(removed.getDurationSec())
+                                                            + removed.getDurationNsec(), NANOSECONDS,
+                                                    liveType,
+                                                    removed.getPacketCount().getValue(),
+                                                    removed.getByteCount().getValue());
+                    } else {
+                        return new DefaultFlowEntry(builder.build(), FlowEntryState.REMOVED,
+                                                    removed.getDurationSec(),
+                                                    removed.getPacketCount().getValue(),
+                                                    removed.getByteCount().getValue());
+                    }
+
                 case MOD:
                     FlowEntryState flowState = state.length > 0 ? state[0] : FlowEntryState.FAILED;
                     builder = DefaultFlowRule.builder()
@@ -209,7 +242,12 @@
                         builder.forTable(flowMod.getTableId().getValue());
                     }
 
-                    return new DefaultFlowEntry(builder.build(), flowState, 0, 0, 0);
+                    if (afsc != null) {
+                        FlowEntry.FlowLiveType liveType = FlowEntry.FlowLiveType.IMMEDIATE;
+                        return new DefaultFlowEntry(builder.build(), flowState, 0, liveType, 0, 0);
+                    } else {
+                        return new DefaultFlowEntry(builder.build(), flowState, 0, 0, 0);
+                    }
                 default:
                     log.error("Unknown flow type : {}", this.type);
                     return null;
diff --git a/web/api/src/test/java/org/onosproject/rest/resources/FlowsResourceTest.java b/web/api/src/test/java/org/onosproject/rest/resources/FlowsResourceTest.java
index 2ba847e..9c7318c 100644
--- a/web/api/src/test/java/org/onosproject/rest/resources/FlowsResourceTest.java
+++ b/web/api/src/test/java/org/onosproject/rest/resources/FlowsResourceTest.java
@@ -147,6 +147,11 @@
         }
 
         @Override
+        public FlowLiveType liveType() {
+            return  FlowLiveType.IMMEDIATE;
+        }
+
+        @Override
         public long packets() {
             return baseValue + 22;
         }
diff --git a/web/api/src/test/java/org/onosproject/rest/resources/IntentsResourceTest.java b/web/api/src/test/java/org/onosproject/rest/resources/IntentsResourceTest.java
index a42855b..a49cafc 100644
--- a/web/api/src/test/java/org/onosproject/rest/resources/IntentsResourceTest.java
+++ b/web/api/src/test/java/org/onosproject/rest/resources/IntentsResourceTest.java
@@ -169,6 +169,11 @@
         }
 
         @Override
+        public FlowLiveType liveType() {
+            return null;
+        }
+
+        @Override
         public long life(TimeUnit timeUnit) {
             return SECONDS.convert(baseValue + 11, timeUnit);
         }