diff --git a/cli/src/main/java/org/onosproject/cli/net/PartitionsListCommand.java b/cli/src/main/java/org/onosproject/cli/net/PartitionsListCommand.java
index f38c78e..c540ea8 100644
--- a/cli/src/main/java/org/onosproject/cli/net/PartitionsListCommand.java
+++ b/cli/src/main/java/org/onosproject/cli/net/PartitionsListCommand.java
@@ -27,7 +27,6 @@
 import org.onosproject.store.primitives.PartitionAdminService;
 import org.onosproject.store.service.PartitionClientInfo;
 import org.onosproject.store.service.PartitionInfo;
-import org.onosproject.store.service.StorageAdminService;
 
 import com.fasterxml.jackson.databind.JsonNode;
 import com.fasterxml.jackson.databind.ObjectMapper;
@@ -175,9 +174,8 @@
 
     @Override
     protected void doExecute() {
-        StorageAdminService storageAdminService = get(StorageAdminService.class);
+        PartitionAdminService partitionAdminService = get(PartitionAdminService.class);
         if (reportClientInfo) {
-            PartitionAdminService partitionAdminService = get(PartitionAdminService.class);
             List<PartitionClientInfo> partitionClientInfo = partitionAdminService.partitionClientInfo();
             if (outputJson()) {
                 print("%s", jsonForClientInfo(partitionClientInfo));
@@ -185,7 +183,7 @@
                 displayPartitionClients(partitionClientInfo);
             }
         } else {
-            List<PartitionInfo> partitionInfo = storageAdminService.getPartitionInfo();
+            List<PartitionInfo> partitionInfo = partitionAdminService.partitionInfo();
             if (outputJson()) {
                 print("%s", json(partitionInfo));
             } else {
diff --git a/core/api/src/main/java/org/onosproject/codec/ExtensionSelectorCodec.java b/core/api/src/main/java/org/onosproject/codec/ExtensionSelectorCodec.java
deleted file mode 100644
index 48feb4c..0000000
--- a/core/api/src/main/java/org/onosproject/codec/ExtensionSelectorCodec.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright 2016-present Open Networking Foundation
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onosproject.codec;
-
-import com.fasterxml.jackson.databind.node.ObjectNode;
-import org.onosproject.net.driver.HandlerBehaviour;
-import org.onosproject.net.flow.criteria.ExtensionSelector;
-
-/**
- * Interface for encode and decode extension selector.
- * @deprecated 1.11.0 Loon use interface under core/api/net/flow.
- */
-@Deprecated
-public interface ExtensionSelectorCodec extends HandlerBehaviour {
-
-    /**
-     * Encodes an extension selector to an JSON object.
-     *
-     * @param extensionSelector extension selector
-     * @param  context encoding context
-     * @return JSON object
-     */
-    default ObjectNode encode(ExtensionSelector extensionSelector, CodecContext context) {
-        return null;
-    }
-
-    /**
-     * Decodes an JSON object to an extension selector.
-     *
-     * @param objectNode JSON object
-     * @param  context decoding context
-     * @return extension selector
-     */
-    default ExtensionSelector decode(ObjectNode objectNode, CodecContext context) {
-        return null;
-    }
-}
diff --git a/core/api/src/main/java/org/onosproject/codec/ExtensionTreatmentCodec.java b/core/api/src/main/java/org/onosproject/codec/ExtensionTreatmentCodec.java
deleted file mode 100644
index 416f02c..0000000
--- a/core/api/src/main/java/org/onosproject/codec/ExtensionTreatmentCodec.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright 2016-present Open Networking Foundation
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onosproject.codec;
-
-import com.fasterxml.jackson.databind.node.ObjectNode;
-import org.onosproject.net.driver.HandlerBehaviour;
-import org.onosproject.net.flow.instructions.ExtensionTreatment;
-
-/**
- * Interface for encode and decode extension treatment.
- * @deprecated 1.11.0 Loon use interface under core/api/net/flow.
- */
-@Deprecated
-public interface ExtensionTreatmentCodec extends HandlerBehaviour {
-
-    /**
-     * Encodes an extension treatment to an JSON object.
-     *
-     * @param extensionTreatment extension treatment
-     * @param  context encoding context
-     * @return JSON object
-     */
-    default ObjectNode encode(ExtensionTreatment extensionTreatment, CodecContext context) {
-        return null;
-    }
-
-    /**
-     * Decodes an JSON object to an extension treatment.
-     *
-     * @param objectNode JSON object
-     * @param  context decoding context
-     * @return extension treatment
-     */
-    default ExtensionTreatment decode(ObjectNode objectNode, CodecContext context) {
-        return null;
-    }
-}
diff --git a/core/api/src/main/java/org/onosproject/net/device/DefaultPortDescription.java b/core/api/src/main/java/org/onosproject/net/device/DefaultPortDescription.java
index 12396c2..d687a8b 100644
--- a/core/api/src/main/java/org/onosproject/net/device/DefaultPortDescription.java
+++ b/core/api/src/main/java/org/onosproject/net/device/DefaultPortDescription.java
@@ -170,20 +170,6 @@
          *
          * @param number to set
          * @return self
-         *
-         * @deprecated in 1.13.0 use withPortNumber() instead.
-         */
-
-        @Deprecated
-        public Builder withPortNumer(PortNumber number) {
-            return withPortNumber(number);
-        }
-
-        /**
-         * Sets mandatory field PortNumber.
-         *
-         * @param number to set
-         * @return self
          */
         public Builder withPortNumber(PortNumber number) {
             this.number = checkNotNull(number);
diff --git a/core/api/src/main/java/org/onosproject/net/flow/DefaultTableStatisticsEntry.java b/core/api/src/main/java/org/onosproject/net/flow/DefaultTableStatisticsEntry.java
index bf34437..e84b343 100644
--- a/core/api/src/main/java/org/onosproject/net/flow/DefaultTableStatisticsEntry.java
+++ b/core/api/src/main/java/org/onosproject/net/flow/DefaultTableStatisticsEntry.java
@@ -35,30 +35,6 @@
      * Default table statistics constructor.
      *
      * @param deviceId device identifier
-     * @param tableId index table identifier
-     * @param activeFlowEntries number of active flow entries in the table
-     * @param packetsLookedupCount number of packets looked up in table
-     * @param packetsMatchedCount number of packets that hit table
-     * @deprecated since 1.15, suggest using the Builder class.
-     */
-    @Deprecated
-    public DefaultTableStatisticsEntry(DeviceId deviceId,
-                                       int  tableId,
-                                       long activeFlowEntries,
-                                       long packetsLookedupCount,
-                                       long packetsMatchedCount) {
-        this.deviceId = checkNotNull(deviceId);
-        this.tableId = IndexTableId.of(tableId);
-        this.activeFlowEntries = activeFlowEntries;
-        this.packetsLookedupCount = packetsLookedupCount;
-        this.packetsMatchedCount = packetsMatchedCount;
-        this.maxSize = NOT_PRESENT;
-    }
-
-    /**
-     * Default table statistics constructor.
-     *
-     * @param deviceId device identifier
      * @param tableId table identifier
      * @param activeFlowEntries number of active flow entries in the table
      * @param packetsLookedupCount number of packets looked up in table
diff --git a/core/api/src/main/java/org/onosproject/net/intent/IntentData.java b/core/api/src/main/java/org/onosproject/net/intent/IntentData.java
index 2c996c2..3375570 100644
--- a/core/api/src/main/java/org/onosproject/net/intent/IntentData.java
+++ b/core/api/src/main/java/org/onosproject/net/intent/IntentData.java
@@ -223,69 +223,13 @@
     }
 
     /**
-     * Creates a new intent data object.
-     *
-     * @param intent intent this metadata references
-     * @param state intent state
-     * @param version version of the intent for this key
-     * @param origin ID of the node where the data was originally created
-     *
-     * @deprecated in 1.11.0
-     */
-    // No longer used in the code base anywhere
-    @Deprecated
-    public IntentData(Intent intent, IntentState state, Timestamp version, NodeId origin) {
-        checkNotNull(intent);
-        checkNotNull(state);
-        checkNotNull(version);
-        checkNotNull(origin);
-
-        this.intent = intent;
-        this.state = state;
-        this.request = state;
-        this.version = version;
-        this.origin = origin;
-    }
-
-    /**
-     * Creates a new intent data object.
-     *
-     * @param intent intent this metadata references
-     * @param state intent state
-     * @param request intent request
-     * @param version version of the intent for this key
-     * @param origin ID of the node where the data was originally created
-     *
-     * @deprecated in 1.11.0
-     */
-    // No longer used in the code base anywhere
-    // was used when IntentData is picked up by some of the node and was assigned with a version
-    @Deprecated
-    public IntentData(Intent intent, IntentState state, IntentState request, Timestamp version, NodeId origin) {
-        checkNotNull(intent);
-        checkNotNull(state);
-        checkNotNull(request);
-        checkNotNull(version);
-        checkNotNull(origin);
-
-        this.intent = intent;
-        this.state = state;
-        this.request = request;
-        this.version = version;
-        this.origin = origin;
-    }
-
-    /**
      * Copy constructor.
      *
      * @param intentData intent data to copy
      *
-     * @deprecated in 1.11.0 use {@link #copy(IntentData)} instead
      */
     // used to create a defensive copy
-    // to be made private
-    @Deprecated
-    public IntentData(IntentData intentData) {
+    private IntentData(IntentData intentData) {
         checkNotNull(intentData);
 
         intent = intentData.intent;
diff --git a/core/api/src/main/java/org/onosproject/store/primitives/DistributedPrimitiveOptions.java b/core/api/src/main/java/org/onosproject/store/primitives/DistributedPrimitiveOptions.java
index 1691086..224358e 100644
--- a/core/api/src/main/java/org/onosproject/store/primitives/DistributedPrimitiveOptions.java
+++ b/core/api/src/main/java/org/onosproject/store/primitives/DistributedPrimitiveOptions.java
@@ -101,17 +101,6 @@
     }
 
     /**
-     * Disables recording usage stats for this primitive.
-     * @deprecated usage of this method is discouraged for most common scenarios.
-     * @return this builder
-     */
-    @Deprecated
-    public O withMeteringDisabled() {
-        this.meteringDisabled = true;
-        return (O) this;
-    }
-
-    /**
      * Disables state changing operations on the returned distributed primitive.
      * @return this builder
      */
diff --git a/core/api/src/main/java/org/onosproject/store/primitives/PartitionService.java b/core/api/src/main/java/org/onosproject/store/primitives/PartitionService.java
index a392e20..1478159 100644
--- a/core/api/src/main/java/org/onosproject/store/primitives/PartitionService.java
+++ b/core/api/src/main/java/org/onosproject/store/primitives/PartitionService.java
@@ -42,29 +42,9 @@
     Set<NodeId> getConfiguredMembers(PartitionId partitionId);
 
     /**
-     * Returns the set of controller nodes that are the current active members of a partition.
-     *
-     * @param partitionId partition identifier
-     * @return set of node identifiers
-     * @deprecated since 1.14
-     */
-    @Deprecated
-    Set<NodeId> getActiveMembersMembers(PartitionId partitionId);
-
-    /**
      * Returns the identifiers of all partitions.
      *
      * @return set of partition identifiers
      */
     Set<PartitionId> getAllPartitionIds();
-
-    /**
-     * Returns a DistributedPrimitiveCreator that can create primitives hosted on a partition.
-     *
-     * @param partitionId partition identifier
-     * @return distributed primitive creator
-     * @deprecated since 1.14
-     */
-    @Deprecated
-    DistributedPrimitiveCreator getDistributedPrimitiveCreator(PartitionId partitionId);
 }
diff --git a/core/api/src/main/java/org/onosproject/store/service/DistributedPrimitive.java b/core/api/src/main/java/org/onosproject/store/service/DistributedPrimitive.java
index 620e16d..f7c056c 100644
--- a/core/api/src/main/java/org/onosproject/store/service/DistributedPrimitive.java
+++ b/core/api/src/main/java/org/onosproject/store/service/DistributedPrimitive.java
@@ -136,12 +136,6 @@
     long DEFAULT_OPERATION_TIMEOUT_MILLIS = 15000L;
 
     /**
-     * Use {@link #DEFAULT_OPERATION_TIMEOUT_MILLIS} instead.
-     */
-    @Deprecated
-    long DEFAULT_OPERTATION_TIMEOUT_MILLIS = DEFAULT_OPERATION_TIMEOUT_MILLIS;
-
-    /**
      * Returns the name of this primitive.
      * @return name
      */
diff --git a/core/api/src/main/java/org/onosproject/store/service/MapEvent.java b/core/api/src/main/java/org/onosproject/store/service/MapEvent.java
index ecea954..e2258af 100644
--- a/core/api/src/main/java/org/onosproject/store/service/MapEvent.java
+++ b/core/api/src/main/java/org/onosproject/store/service/MapEvent.java
@@ -111,19 +111,6 @@
     }
 
     /**
-     * Returns the value associated with this event. If type is REMOVE,
-     * this is the value that was removed. If type is INSERT/UPDATE, this is
-     * the new value.
-     *
-     * @return the value
-     * @deprecated 1.5.0 Falcon release. Use {@link #newValue()} or {@link #oldValue()} instead.
-     */
-    @Deprecated
-    public Versioned<V> value() {
-        return type == Type.REMOVE ? oldValue() : newValue();
-    }
-
-    /**
      * Returns the new value in the map associated with the key. If {@link #type()} returns {@code REMOVE},
      * this method will return {@code null}.
      *
diff --git a/core/api/src/main/java/org/onosproject/store/service/PartitionClientInfo.java b/core/api/src/main/java/org/onosproject/store/service/PartitionClientInfo.java
index ac5c48c..e33c0b4 100644
--- a/core/api/src/main/java/org/onosproject/store/service/PartitionClientInfo.java
+++ b/core/api/src/main/java/org/onosproject/store/service/PartitionClientInfo.java
@@ -19,7 +19,6 @@
 
 import org.onosproject.cluster.NodeId;
 import org.onosproject.cluster.PartitionId;
-import org.onosproject.store.service.DistributedPrimitive.Status;
 
 import com.google.common.collect.ImmutableList;
 
@@ -54,24 +53,4 @@
     public Collection<NodeId> servers() {
         return servers;
     }
-
-    /**
-     * Return the sessionId for the partition client.
-     * @return session id
-     * @deprecated in Loon release (1.11.0)
-     */
-    @Deprecated
-    public long sessionId() {
-        return 0;
-    }
-
-    /**
-     * Returns the current status for the client session.
-     * @return status
-     * @deprecated in Loon release (1.11.0)
-     */
-    @Deprecated
-    public Status status() {
-        return null;
-    }
 }
diff --git a/core/api/src/main/java/org/onosproject/store/service/StorageAdminService.java b/core/api/src/main/java/org/onosproject/store/service/StorageAdminService.java
index f44d398..405bc7c 100644
--- a/core/api/src/main/java/org/onosproject/store/service/StorageAdminService.java
+++ b/core/api/src/main/java/org/onosproject/store/service/StorageAdminService.java
@@ -27,15 +27,6 @@
 public interface StorageAdminService {
 
     /**
-     * Returns information about all partitions in the system.
-     *
-     * @return list of partition information
-     * @deprecated 1.5.0 Falcon Release
-     */
-    @Deprecated
-    List<PartitionInfo> getPartitionInfo();
-
-    /**
      * Returns information about all the consistent maps in the system.
      *
      * @return list of map information
diff --git a/core/api/src/test/java/org/onosproject/store/service/MapEventTest.java b/core/api/src/test/java/org/onosproject/store/service/MapEventTest.java
index 1510df7b..646d055 100644
--- a/core/api/src/test/java/org/onosproject/store/service/MapEventTest.java
+++ b/core/api/src/test/java/org/onosproject/store/service/MapEventTest.java
@@ -47,21 +47,18 @@
         assertThat(stats1.name(), is("a"));
         assertThat(stats1.type(), is(MapEvent.Type.INSERT));
         assertThat(stats1.key(), is("1"));
-        assertThat(stats1.value(), is(vStatsNew));
         assertThat(stats1.newValue(), is(vStatsNew));
         assertThat(stats1.oldValue(), is((Versioned<Integer>) null));
 
         assertThat(stats2.name(), is("a"));
         assertThat(stats2.type(), is(MapEvent.Type.REMOVE));
         assertThat(stats2.key(), is("1"));
-        assertThat(stats2.value(), is(vStatsOld));
         assertThat(stats2.newValue(), is((Versioned<Integer>) null));
         assertThat(stats2.oldValue(), is(vStatsOld));
 
         assertThat(stats3.name(), is("a"));
         assertThat(stats3.type(), is(MapEvent.Type.UPDATE));
         assertThat(stats3.key(), is("1"));
-        assertThat(stats3.value(), is(vStatsNew));
         assertThat(stats3.newValue(), is(vStatsNew));
         assertThat(stats3.oldValue(), is(vStatsOld));
     }
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
deleted file mode 100644
index e0fe04d..0000000
--- a/core/store/dist/src/main/java/org/onosproject/store/flow/impl/DistributedFlowRuleStore.java
+++ /dev/null
@@ -1,755 +0,0 @@
-/*
- * Copyright 2014-present Open Networking Foundation
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onosproject.store.flow.impl;
-
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Iterables;
-import com.google.common.collect.Maps;
-import com.google.common.collect.Sets;
-import com.google.common.collect.Streams;
-import org.onlab.util.KryoNamespace;
-import org.onlab.util.Tools;
-import org.onosproject.cluster.ClusterService;
-import org.onosproject.cluster.NodeId;
-import org.onosproject.core.CoreService;
-import org.onosproject.core.IdGenerator;
-import org.onosproject.mastership.MastershipService;
-import org.onosproject.net.DeviceId;
-import org.onosproject.net.device.DeviceService;
-import org.onosproject.net.flow.CompletedBatchOperation;
-import org.onosproject.net.flow.DefaultFlowEntry;
-import org.onosproject.net.flow.FlowEntry;
-import org.onosproject.net.flow.FlowEntry.FlowEntryState;
-import org.onosproject.net.flow.FlowId;
-import org.onosproject.net.flow.FlowRule;
-import org.onosproject.net.flow.FlowRuleEvent;
-import org.onosproject.net.flow.FlowRuleEvent.Type;
-import org.onosproject.net.flow.FlowRuleService;
-import org.onosproject.net.flow.FlowRuleStore;
-import org.onosproject.net.flow.FlowRuleStoreDelegate;
-import org.onosproject.net.flow.StoredFlowEntry;
-import org.onosproject.net.flow.TableStatisticsEntry;
-import org.onosproject.net.flow.oldbatch.FlowRuleBatchEntry;
-import org.onosproject.net.flow.oldbatch.FlowRuleBatchEntry.FlowRuleOperation;
-import org.onosproject.net.flow.oldbatch.FlowRuleBatchEvent;
-import org.onosproject.net.flow.oldbatch.FlowRuleBatchOperation;
-import org.onosproject.net.flow.oldbatch.FlowRuleBatchRequest;
-import org.onosproject.store.AbstractStore;
-import org.onosproject.store.cluster.messaging.ClusterCommunicationService;
-import org.onosproject.store.cluster.messaging.MessageSubject;
-import org.onosproject.store.impl.MastershipBasedTimestamp;
-import org.onosproject.store.serializers.KryoNamespaces;
-import org.onosproject.store.service.AsyncDocumentTree;
-import org.onosproject.store.service.DocumentPath;
-import org.onosproject.store.service.DocumentTree;
-import org.onosproject.store.service.EventuallyConsistentMap;
-import org.onosproject.store.service.EventuallyConsistentMapEvent;
-import org.onosproject.store.service.EventuallyConsistentMapListener;
-import org.onosproject.store.service.IllegalDocumentModificationException;
-import org.onosproject.store.service.NoSuchDocumentPathException;
-import org.onosproject.store.service.Serializer;
-import org.onosproject.store.service.StorageException;
-import org.onosproject.store.service.StorageService;
-import org.onosproject.store.service.Versioned;
-import org.onosproject.store.service.WallClockTimestamp;
-import org.osgi.service.component.annotations.Activate;
-import org.osgi.service.component.annotations.Component;
-import org.osgi.service.component.annotations.Deactivate;
-import org.osgi.service.component.annotations.Reference;
-import org.osgi.service.component.annotations.ReferenceCardinality;
-import org.slf4j.Logger;
-
-import java.security.SecureRandom;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
-import java.util.Random;
-import java.util.Set;
-import java.util.concurrent.CompletableFuture;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.TimeUnit;
-import java.util.function.Supplier;
-import java.util.stream.Collectors;
-
-import static org.onlab.util.Tools.groupedThreads;
-import static org.onosproject.net.flow.FlowRuleEvent.Type.RULE_REMOVED;
-import static org.onosproject.net.flow.FlowRuleEvent.Type.RULE_UPDATED;
-import static org.slf4j.LoggerFactory.getLogger;
-
-/**
- * Manages inventory of flow rules using a distributed state management protocol.
- *
- * @deprecated in Nightingale Release (1.13)
- */
-@Deprecated
-@Component(enabled = false, service = FlowRuleStore.class)
-public class DistributedFlowRuleStore
-        extends AbstractStore<FlowRuleBatchEvent, FlowRuleStoreDelegate>
-        implements FlowRuleStore {
-
-    private final Logger log = getLogger(getClass());
-
-    // Constant exception used to indicate an atomic read-modify-write operation needs to be retried.
-    // We don't want to populate a stack trace every time an optimistic lock is retried.
-    private static final StorageException.ConcurrentModification RETRY;
-
-    // Initialize retry exception with an empty stack trace.
-    static {
-        RETRY = new StorageException.ConcurrentModification();
-        RETRY.setStackTrace(new StackTraceElement[0]);
-    }
-
-    private static final int SCHEDULED_THREAD_POOL_SIZE = 8;
-    private static final int MESSAGE_HANDLER_THREAD_POOL_SIZE = 8;
-    private static final int MAX_RETRY_DELAY_MILLIS = 50;
-
-    private static final String FLOW_TABLE = "onos-flow-table";
-
-    private static final MessageSubject APPLY_BATCH_FLOWS = new MessageSubject("onos-flow-apply");
-    private static final MessageSubject COMPLETE_BATCH = new MessageSubject("onos-flow-batch-complete");
-
-    @Reference(cardinality = ReferenceCardinality.MANDATORY)
-    protected DeviceService deviceService;
-
-    @Reference(cardinality = ReferenceCardinality.MANDATORY)
-    protected CoreService coreService;
-
-    @Reference(cardinality = ReferenceCardinality.MANDATORY)
-    protected MastershipService mastershipService;
-
-    @Reference(cardinality = ReferenceCardinality.MANDATORY)
-    protected ClusterCommunicationService clusterCommunicator;
-
-    @Reference(cardinality = ReferenceCardinality.MANDATORY)
-    protected ClusterService clusterService;
-
-    @Reference(cardinality = ReferenceCardinality.MANDATORY)
-    protected StorageService storageService;
-
-    protected final Serializer serializer = Serializer.using(KryoNamespaces.API);
-
-    protected final KryoNamespace.Builder serializerBuilder = KryoNamespace.newBuilder()
-            .register(KryoNamespaces.API)
-            .register(MastershipBasedTimestamp.class);
-
-    private EventuallyConsistentMap<DeviceId, List<TableStatisticsEntry>> deviceTableStats;
-    private final EventuallyConsistentMapListener<DeviceId, List<TableStatisticsEntry>> tableStatsListener =
-            new InternalTableStatsListener();
-
-    private Set<Long> pendingBatches = Sets.newConcurrentHashSet();
-    private ScheduledExecutorService scheduledExecutor;
-    private ExecutorService messageHandlingExecutor;
-    private final Random random = new SecureRandom();
-
-    private AsyncDocumentTree<Map<StoredFlowEntry, StoredFlowEntry>> asyncFlows;
-    private DocumentTree<Map<StoredFlowEntry, StoredFlowEntry>> flows;
-    private IdGenerator idGenerator;
-    private NodeId local;
-
-    @Activate
-    public void activate() {
-        idGenerator = coreService.getIdGenerator(FlowRuleService.FLOW_OP_TOPIC);
-
-        local = clusterService.getLocalNode().id();
-
-        scheduledExecutor = Executors.newScheduledThreadPool(
-                SCHEDULED_THREAD_POOL_SIZE,
-                groupedThreads("onos/store/flow", "schedulers", log));
-
-        messageHandlingExecutor = Executors.newFixedThreadPool(
-                MESSAGE_HANDLER_THREAD_POOL_SIZE,
-                groupedThreads("onos/store/flow", "message-handlers", log));
-
-        deviceTableStats = storageService.<DeviceId, List<TableStatisticsEntry>>eventuallyConsistentMapBuilder()
-                .withName("onos-flow-table-stats")
-                .withSerializer(serializerBuilder)
-                .withAntiEntropyPeriod(5, TimeUnit.SECONDS)
-                .withTimestampProvider((k, v) -> new WallClockTimestamp())
-                .withTombstonesDisabled()
-                .build();
-        deviceTableStats.addListener(tableStatsListener);
-
-        asyncFlows = storageService.<Map<StoredFlowEntry, StoredFlowEntry>>documentTreeBuilder()
-                .withName(FLOW_TABLE)
-                .withSerializer(serializer)
-                .buildDocumentTree();
-        flows = asyncFlows.asDocumentTree();
-
-        clusterCommunicator.addSubscriber(
-                APPLY_BATCH_FLOWS,
-                serializer::decode,
-                this::applyBatchFlows,
-                messageHandlingExecutor);
-        clusterCommunicator.addSubscriber(
-                COMPLETE_BATCH,
-                serializer::decode,
-                this::completeBatch,
-                messageHandlingExecutor);
-
-        log.info("Started");
-    }
-
-    @Deactivate
-    public void deactivate() {
-        deviceTableStats.removeListener(tableStatsListener);
-        deviceTableStats.destroy();
-        clusterCommunicator.removeSubscriber(APPLY_BATCH_FLOWS);
-        clusterCommunicator.removeSubscriber(COMPLETE_BATCH);
-        messageHandlingExecutor.shutdownNow();
-        scheduledExecutor.shutdownNow();
-        log.info("Stopped");
-    }
-
-    /**
-     * Retries the given supplier until successful.
-     * <p>
-     * This method retries the given supplier until no {@code ConcurrentModification} exceptions are thrown. In
-     * between retries, it waits a semi-random interval to attempt to avoid transaction conflicts with other processes.
-     *
-     * @param supplier the supplier to retry
-     * @param <T> the return type
-     * @return the return value of the given supplier once it runs successfully
-     */
-    private <T> T retryUntilSuccess(Supplier<T> supplier) {
-        return Tools.retryable(
-                supplier,
-                StorageException.ConcurrentModification.class,
-                Integer.MAX_VALUE,
-                MAX_RETRY_DELAY_MILLIS)
-                .get();
-    }
-
-    /**
-     * Retries the given asynchronous supplier until successful.
-     * <p>
-     * This method retries the given supplier until no {@code ConcurrentModification} exceptions are thrown. In
-     * between retries, it waits a semi-random interval to attempt to avoid transaction conflicts with other processes.
-     *
-     * @param supplier the supplier to retry
-     * @param <T> the return type
-     * @return the return value of the given supplier once it runs successfully
-     */
-    private <T> CompletableFuture<T> retryAsyncUntilSuccess(Supplier<CompletableFuture<T>> supplier) {
-        return retryAsyncUntilSuccess(supplier, new CompletableFuture<>());
-    }
-
-    /**
-     * Retries the given asynchronous supplier until successful.
-     * <p>
-     * This method retries the given supplier until no {@code ConcurrentModification} exceptions are thrown. In
-     * between retries, it waits a semi-random interval to attempt to avoid transaction conflicts with other processes.
-     *
-     * @param supplier the supplier to retry
-     * @param future future to be completed once the operation has been successful
-     * @param <T> the return type
-     * @return the return value of the given supplier once it runs successfully
-     */
-    private <T> CompletableFuture<T> retryAsyncUntilSuccess(
-            Supplier<CompletableFuture<T>> supplier,
-            CompletableFuture<T> future) {
-        supplier.get().whenComplete((result, error) -> {
-            if (error == null) {
-                future.complete(result);
-            } else {
-                Throwable cause = error.getCause() != null ? error.getCause() : error;
-                if (cause instanceof StorageException.ConcurrentModification) {
-                    scheduledExecutor.schedule(
-                            () -> retryAsyncUntilSuccess(supplier, future),
-                            random.nextInt(50),
-                            TimeUnit.MILLISECONDS);
-                } else {
-                    future.completeExceptionally(error);
-                }
-            }
-        });
-        return future;
-    }
-
-    /**
-     * Return method for {@link #retryUntilSuccess(Supplier)} callbacks to indicate that the callback needs to be
-     * retried after a randomized delay.
-     *
-     * @param <T> the return type
-     * @return nothing
-     * @throws StorageException.ConcurrentModification to force a retry of the callback
-     */
-    private <T> T retry() {
-        throw RETRY;
-    }
-
-    /**
-     * Handles a completed batch event received from the master node.
-     * <p>
-     * If this node is the source of the batch, notifies event listeners to complete the operations.
-     *
-     * @param event the event to handle
-     */
-    private void completeBatch(FlowRuleBatchEvent event) {
-        if (pendingBatches.remove(event.subject().batchId())) {
-            notifyDelegate(event);
-        }
-    }
-
-    // This is not a efficient operation on a distributed sharded
-    // flow store. We need to revisit the need for this operation or at least
-    // make it device specific.
-    @Override
-    public int getFlowRuleCount() {
-        return Streams.stream(deviceService.getDevices()).parallel()
-                .mapToInt(device -> Iterables.size(getFlowEntries(device.id())))
-                .sum();
-    }
-
-    /**
-     * Returns the {@link DocumentPath} for the given {@link DeviceId}.
-     *
-     * @param deviceId the device identifier for which to return a path
-     * @return the path for the given device
-     */
-    private DocumentPath getPathFor(DeviceId deviceId) {
-        return DocumentPath.from("root", deviceId.toString());
-    }
-
-    /**
-     * Returns the {@link DocumentPath} for the given {@link DeviceId} and {@link FlowId}.
-     *
-     * @param deviceId the device identifier for which to return the path
-     * @param flowId the flow identifier for which to return the path
-     * @return the path for the given device/flow
-     */
-    private DocumentPath getPathFor(DeviceId deviceId, FlowId flowId) {
-        return DocumentPath.from("root", deviceId.toString(), flowId.toString());
-    }
-
-    @Override
-    @SuppressWarnings("unchecked")
-    public FlowEntry getFlowEntry(FlowRule rule) {
-        DeviceId deviceId = rule.deviceId();
-        if (mastershipService.getMasterFor(deviceId) != null) {
-            DocumentPath path = getPathFor(deviceId, rule.id());
-            Versioned<Map<StoredFlowEntry, StoredFlowEntry>> flowEntries = flows.get(path);
-            return flowEntries != null ? flowEntries.value().get(rule) : null;
-        } else {
-            log.debug("Failed to getFlowEntries: No master for {}", deviceId);
-            return null;
-        }
-
-
-    }
-
-    @Override
-    public Iterable<FlowEntry> getFlowEntries(DeviceId deviceId) {
-        if (mastershipService.getMasterFor(deviceId) != null) {
-            DocumentPath path = getPathFor(deviceId);
-            try {
-                return getFlowEntries(path);
-            } catch (NoSuchDocumentPathException e) {
-                return Collections.emptyList();
-            }
-        } else {
-            log.debug("Failed to getFlowEntries: No master for {}", deviceId);
-            return Collections.emptyList();
-        }
-
-    }
-
-    @SuppressWarnings("unchecked")
-    private Iterable<FlowEntry> getFlowEntries(DocumentPath path) {
-        return flows.getChildren(path)
-                .values()
-                .stream()
-                .flatMap(v -> v.value().values().stream())
-                .collect(Collectors.toList());
-    }
-
-    @Override
-    @SuppressWarnings("unchecked")
-    public void storeFlowRule(FlowRule rule) {
-        storeBatch(new FlowRuleBatchOperation(
-                Collections.singletonList(new FlowRuleBatchEntry(FlowRuleOperation.ADD, rule)),
-                rule.deviceId(), idGenerator.getNewId()));
-    }
-
-    @Override
-    public void storeBatch(FlowRuleBatchOperation operation) {
-        if (operation.getOperations().isEmpty()) {
-            notifyDelegate(FlowRuleBatchEvent.completed(
-                    new FlowRuleBatchRequest(operation.id(), Collections.emptySet()),
-                    new CompletedBatchOperation(true, Collections.emptySet(), operation.deviceId())));
-            return;
-        }
-
-        DeviceId deviceId = operation.deviceId();
-        NodeId master = mastershipService.getMasterFor(deviceId);
-
-        if (master == null) {
-            log.warn("No master for {} ", deviceId);
-
-            updateStoreInternal(operation).whenComplete((result, error) -> {
-                notifyDelegate(FlowRuleBatchEvent.completed(
-                        new FlowRuleBatchRequest(operation.id(), Collections.emptySet()),
-                        new CompletedBatchOperation(true, Collections.emptySet(), operation.deviceId())));
-            });
-            return;
-        }
-
-        pendingBatches.add(operation.id());
-
-        // If the local node is the master, apply the flows. Otherwise, send them to the master.
-        if (Objects.equals(local, master)) {
-            applyBatchFlows(operation);
-        } else {
-            log.trace("Forwarding storeBatch to {}, which is the primary (master) for device {}", master, deviceId);
-            clusterCommunicator.unicast(
-                    operation,
-                    APPLY_BATCH_FLOWS,
-                    serializer::encode,
-                    master);
-        }
-    }
-
-    /**
-     * Asynchronously applies a batch of flows to the store.
-     * <p>
-     * This operation is performed on the master node to ensure that events occur <em>after</em> flows have been stored
-     * and are visible to the master node. If a non-master node stores flows and then triggers events on the master,
-     * the flows may not yet be visible to the master node due to the nature of sequentially consistent reads on the
-     * underlying {@code DocumentTree} primitive.
-     */
-    private void applyBatchFlows(FlowRuleBatchOperation operation) {
-        updateStoreInternal(operation).whenComplete((operations, error) -> {
-            if (error == null) {
-                if (operations.isEmpty()) {
-                    batchOperationComplete(FlowRuleBatchEvent.completed(
-                            new FlowRuleBatchRequest(operation.id(), Collections.emptySet()),
-                            new CompletedBatchOperation(true, Collections.emptySet(), operation.deviceId())));
-                } else {
-                    notifyDelegate(FlowRuleBatchEvent.requested(
-                            new FlowRuleBatchRequest(operation.id(), operations),
-                            operation.deviceId()));
-                }
-            }
-        });
-    }
-
-    private CompletableFuture<Set<FlowRuleBatchEntry>> updateStoreInternal(FlowRuleBatchOperation operation) {
-        return Tools.allOf(operation.getOperations().stream().map(op -> {
-            switch (op.operator()) {
-                case ADD:
-                case MODIFY:
-                    return addBatchEntry(op).thenApply(succeeded -> succeeded ? op : null);
-                case REMOVE:
-                    return removeBatchEntry(op).thenApply(succeeded -> succeeded ? op : null);
-                default:
-                    log.warn("Unknown flow operation operator: {}", op.operator());
-                    return CompletableFuture.<FlowRuleBatchEntry>completedFuture(null);
-            }
-        }).collect(Collectors.toList()))
-                .thenApply(results -> results.stream()
-                        .filter(Objects::nonNull)
-                        .collect(Collectors.toSet()));
-    }
-
-    @SuppressWarnings("unchecked")
-    private CompletableFuture<Boolean> addBatchEntry(FlowRuleBatchEntry batchEntry) {
-        StoredFlowEntry entry = new DefaultFlowEntry(batchEntry.target());
-        DocumentPath path = getPathFor(entry.deviceId(), entry.id());
-        return retryAsyncUntilSuccess(() -> {
-            CompletableFuture<Boolean> future = new CompletableFuture<>();
-            asyncFlows.get(path).whenComplete((value, getError) -> {
-                if (getError == null) {
-                    if (value != null) {
-                        Map<StoredFlowEntry, StoredFlowEntry> entries = Maps.newHashMap(value.value());
-                        entries.put(entry, entry);
-                        asyncFlows.replace(path, entries, value.version()).whenComplete((succeeded, replaceError) -> {
-                            if (replaceError == null) {
-                                if (succeeded) {
-                                    log.trace("Stored new flow rule: {}", entry);
-                                    future.complete(true);
-                                } else {
-                                    log.trace("Failed to store new flow rule: {}", entry);
-                                    future.completeExceptionally(RETRY);
-                                }
-                            } else {
-                                future.completeExceptionally(replaceError);
-                            }
-                        });
-                    } else {
-                        // If there are no entries stored for the device, initialize the device's flows.
-                        Map<StoredFlowEntry, StoredFlowEntry> map = Maps.newHashMap();
-                        map.put(entry, entry);
-                        asyncFlows.createRecursive(path, map).whenComplete((succeeded, createError) -> {
-                            if (createError == null) {
-                                if (succeeded) {
-                                    log.trace("Stored new flow rule: {}", entry);
-                                    future.complete(true);
-                                } else {
-                                    log.trace("Failed to store new flow rule: {}", entry);
-                                    future.completeExceptionally(RETRY);
-                                }
-                            } else {
-                                future.completeExceptionally(createError);
-                            }
-                        });
-                    }
-                } else {
-                    future.completeExceptionally(getError);
-                }
-            });
-            return future;
-        });
-    }
-
-    @SuppressWarnings("unchecked")
-    private CompletableFuture<Boolean> removeBatchEntry(FlowRuleBatchEntry batchEntry) {
-        FlowRule rule = batchEntry.target();
-        DocumentPath path = getPathFor(rule.deviceId(), rule.id());
-        return retryAsyncUntilSuccess(() -> {
-            CompletableFuture<Boolean> future = new CompletableFuture<>();
-            asyncFlows.get(path).whenComplete((value, getError) -> {
-                if (getError == null) {
-                    if (value != null) {
-                        Map<StoredFlowEntry, StoredFlowEntry> entries = Maps.newHashMap(value.value());
-                        StoredFlowEntry entry = entries.get(rule);
-                        if (entry != null) {
-                            entry.setState(FlowEntryState.PENDING_REMOVE);
-                            asyncFlows.replace(path, entries, value.version()).whenComplete((succeeded, error) -> {
-                                if (error == null) {
-                                    if (succeeded) {
-                                        log.trace("Updated flow rule state to PENDING_REMOVE: {}", entry);
-                                        future.complete(true);
-                                    } else {
-                                        log.trace("Failed to update flow rule state to PENDING_REMOVE: {}", entry);
-                                        future.completeExceptionally(RETRY);
-                                    }
-                                } else {
-                                    future.completeExceptionally(error);
-                                }
-                            });
-                        } else {
-                            future.complete(false);
-                        }
-                    } else {
-                        future.complete(false);
-                    }
-                } else {
-                    future.completeExceptionally(getError);
-                }
-            });
-            return future;
-        });
-    }
-
-    @Override
-    public void batchOperationComplete(FlowRuleBatchEvent event) {
-        if (pendingBatches.remove(event.subject().batchId())) {
-            notifyDelegate(event);
-        } else {
-            clusterCommunicator.broadcast(event, COMPLETE_BATCH, serializer::encode);
-        }
-    }
-
-    @Override
-    public void deleteFlowRule(FlowRule rule) {
-        storeBatch(
-                new FlowRuleBatchOperation(
-                        Collections.singletonList(
-                                new FlowRuleBatchEntry(
-                                        FlowRuleOperation.REMOVE,
-                                        rule)), rule.deviceId(), idGenerator.getNewId()));
-    }
-
-    @Override
-    public FlowRuleEvent pendingFlowRule(FlowEntry rule) {
-        DocumentPath path = getPathFor(rule.deviceId(), rule.id());
-        return retryUntilSuccess(() -> {
-            Versioned<Map<StoredFlowEntry, StoredFlowEntry>> value = flows.get(path);
-            if (value != null) {
-                Map<StoredFlowEntry, StoredFlowEntry> entries = Maps.newHashMap(value.value());
-                StoredFlowEntry entry = entries.get(rule);
-                if (entry != null && entry.state() != FlowEntryState.PENDING_ADD) {
-                    entry.setState(FlowEntryState.PENDING_ADD);
-                    if (flows.replace(path, entries, value.version())) {
-                        log.trace("Updated flow rule state to PENDING_ADD: {}", entry);
-                        return new FlowRuleEvent(RULE_UPDATED, rule);
-                    } else {
-                        log.trace("Failed to update flow rule state to PENDING_ADD: {}", entry);
-                        return retry();
-                    }
-                } else {
-                    return null;
-                }
-            } else {
-                return null;
-            }
-        });
-    }
-
-    @Override
-    @SuppressWarnings("unchecked")
-    public FlowRuleEvent addOrUpdateFlowRule(FlowEntry rule) {
-        DocumentPath path = getPathFor(rule.deviceId(), rule.id());
-        return retryUntilSuccess(() -> {
-            Versioned<Map<StoredFlowEntry, StoredFlowEntry>> value = flows.get(path);
-            if (value != null) {
-                Map<StoredFlowEntry, StoredFlowEntry> entries = Maps.newHashMap(value.value());
-                StoredFlowEntry entry = entries.get(rule);
-                if (entry != null) {
-                    FlowRuleEvent event;
-                    String message;
-
-                    entry.setBytes(rule.bytes());
-                    entry.setLife(rule.life(TimeUnit.NANOSECONDS), TimeUnit.NANOSECONDS);
-                    entry.setLiveType(rule.liveType());
-                    entry.setPackets(rule.packets());
-                    entry.setLastSeen();
-
-                    // If the entry state is PENDING_ADD, set it to ADDED. Otherwise, just update the rule.
-                    if (entry.state() == FlowEntryState.PENDING_ADD) {
-                        entry.setState(FlowEntryState.ADDED);
-                        event = new FlowRuleEvent(Type.RULE_ADDED, rule);
-                        message = "Updated flow rule state to ADDED: {}";
-                    } else {
-                        event = new FlowRuleEvent(Type.RULE_UPDATED, rule);
-                        message = "Updated flow rule: {}";
-                    }
-
-                    if (flows.replace(path, entries, value.version())) {
-                        log.trace(message, entry);
-                        return event;
-                    } else {
-                        log.trace("Failed to update flow rule: {}", entry);
-                        return retry();
-                    }
-                } else {
-                    // If the rule does not exist, return null. Inserting the rule risks race conditions
-                    // that can result in removed rules being retained.
-                    return null;
-                }
-            } else {
-                return null;
-            }
-        });
-    }
-
-    @Override
-    @SuppressWarnings("unchecked")
-    public FlowRuleEvent removeFlowRule(FlowEntry rule) {
-        DocumentPath path = getPathFor(rule.deviceId(), rule.id());
-        return retryUntilSuccess(() -> {
-            Versioned<Map<StoredFlowEntry, StoredFlowEntry>> value = flows.get(path);
-            if (value != null) {
-                Map<StoredFlowEntry, StoredFlowEntry> entries = Maps.newHashMap(value.value());
-                StoredFlowEntry entry = entries.remove(rule);
-                if (entry != null) {
-                    if (flows.replace(path, entries, value.version())) {
-                        log.trace("Removed flow rule: {}", entry);
-                        return new FlowRuleEvent(RULE_REMOVED, entry);
-                    } else {
-                        log.trace("Failed to remove flow rule: {}", entry);
-                        return retry();
-                    }
-                } else {
-                    return null;
-                }
-            } else {
-                return null;
-            }
-        });
-    }
-
-    @Override
-    public void purgeFlowRule(DeviceId deviceId) {
-        DocumentPath path = getPathFor(deviceId);
-        retryUntilSuccess(() -> {
-            try {
-                for (String flowId : flows.getChildren(path).keySet()) {
-                    flows.removeNode(DocumentPath.from("root", deviceId.toString(), flowId));
-                }
-            } catch (NoSuchDocumentPathException e) {
-                // Do nothing. There are no flows for the device.
-            }
-
-            // New children may have been created since they were removed above. Catch
-            // IllegalDocumentModificationException and retry if necessary.
-            try {
-                flows.removeNode(path);
-            } catch (NoSuchDocumentPathException e) {
-                return null;
-            } catch (IllegalDocumentModificationException e) {
-                return retry();
-            }
-            return null;
-        });
-    }
-
-    @Override
-    public void purgeFlowRules() {
-        try {
-            for (String deviceId : flows.getChildren(flows.root()).keySet()) {
-                purgeFlowRule(DeviceId.deviceId(deviceId));
-            }
-        } catch (NoSuchDocumentPathException e) {
-            // Do nothing if no children exist.
-        }
-    }
-
-    @Override
-    public FlowRuleEvent updateTableStatistics(DeviceId deviceId,
-            List<TableStatisticsEntry> tableStats) {
-        deviceTableStats.put(deviceId, tableStats);
-        return null;
-    }
-
-    @Override
-    public Iterable<TableStatisticsEntry> getTableStatistics(DeviceId deviceId) {
-        if (mastershipService.getMasterFor(deviceId) != null) {
-            List<TableStatisticsEntry> tableStats = deviceTableStats.get(deviceId);
-            if (tableStats == null) {
-                return Collections.emptyList();
-            }
-            return ImmutableList.copyOf(tableStats);
-        } else {
-            log.debug("Failed to getTableStatistics: No master for {}", deviceId);
-            return Collections.emptyList();
-        }
-
-    }
-
-    @Override
-    public long getActiveFlowRuleCount(DeviceId deviceId) {
-        if (mastershipService.getMasterFor(deviceId) != null) {
-            return Streams.stream(getTableStatistics(deviceId))
-                    .mapToLong(TableStatisticsEntry::activeFlowEntries)
-                    .sum();
-        } else {
-            log.debug("Failed to getActiveFlowRuleCount: No master for {}", deviceId);
-            return 0;
-        }
-    }
-
-    private class InternalTableStatsListener
-            implements EventuallyConsistentMapListener<DeviceId, List<TableStatisticsEntry>> {
-        @Override
-        public void event(EventuallyConsistentMapEvent<DeviceId,
-                List<TableStatisticsEntry>> event) {
-            //TODO: Generate an event to listeners (do we need?)
-        }
-    }
-}
\ No newline at end of file
diff --git a/core/store/dist/src/test/java/org/onosproject/store/flow/impl/DistributedFlowRuleStoreTest.java b/core/store/dist/src/test/java/org/onosproject/store/flow/impl/DistributedFlowRuleStoreTest.java
deleted file mode 100644
index 9b9c4db..0000000
--- a/core/store/dist/src/test/java/org/onosproject/store/flow/impl/DistributedFlowRuleStoreTest.java
+++ /dev/null
@@ -1,308 +0,0 @@
-/*
- * Copyright 2016-present Open Networking Foundation
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onosproject.store.flow.impl;
-
-import java.util.Collections;
-import java.util.Iterator;
-
-import com.google.common.collect.ArrayListMultimap;
-import com.google.common.collect.Multimap;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Ignore;
-import org.junit.Test;
-import org.onlab.packet.Ip4Address;
-import org.onlab.packet.IpAddress;
-import org.onosproject.cluster.ClusterService;
-import org.onosproject.cluster.ControllerNode;
-import org.onosproject.cluster.NodeId;
-import org.onosproject.core.CoreServiceAdapter;
-import org.onosproject.mastership.MastershipServiceAdapter;
-import org.onosproject.net.DeviceId;
-import org.onosproject.net.MastershipRole;
-import org.onosproject.net.device.DeviceServiceAdapter;
-import org.onosproject.net.flow.DefaultFlowEntry;
-import org.onosproject.net.flow.DefaultFlowRule;
-import org.onosproject.net.flow.FlowEntry;
-import org.onosproject.net.flow.FlowRule;
-import org.onosproject.net.flow.oldbatch.FlowRuleBatchEntry;
-import org.onosproject.net.flow.oldbatch.FlowRuleBatchOperation;
-import org.onosproject.net.flow.FlowRuleOperation;
-import org.onosproject.net.intent.IntentTestsMocks;
-import org.onosproject.store.cluster.messaging.ClusterCommunicationServiceAdapter;
-import org.onosproject.store.service.AsyncDocumentTree;
-import org.onosproject.store.service.DocumentTreeBuilder;
-import org.onosproject.store.service.Serializer;
-import org.onosproject.store.service.TestAsyncDocumentTree;
-import org.onosproject.store.service.TestStorageService;
-import org.onosproject.store.service.TestTopic;
-import org.onosproject.store.service.Topic;
-
-import static org.easymock.EasyMock.createMock;
-import static org.easymock.EasyMock.expect;
-import static org.easymock.EasyMock.replay;
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.hamcrest.Matchers.emptyIterable;
-import static org.hamcrest.Matchers.is;
-import static org.hamcrest.Matchers.notNullValue;
-import static org.junit.Assert.assertEquals;
-import static org.onosproject.net.NetTestTools.APP_ID;
-import static org.onosproject.net.NetTestTools.did;
-
-/**
- * Test class for DistributedFlowRuleStore.
- *
- * @deprecated in Nightingale Release (1.13)
- */
-@Deprecated
-@Ignore("The distributed flow rule store has been deprecated")
-public class DistributedFlowRuleStoreTest {
-
-    DistributedFlowRuleStore flowStoreImpl;
-    private ClusterService mockClusterService;
-    private ControllerNode mockControllerNode;
-
-    private NodeId nodeId;
-
-    private static final IntentTestsMocks.MockSelector SELECTOR =
-            new IntentTestsMocks.MockSelector();
-    private static final IntentTestsMocks.MockTreatment TREATMENT =
-            new IntentTestsMocks.MockTreatment();
-    DeviceId deviceId = did("device1");
-    FlowRule flowRule =
-            DefaultFlowRule.builder()
-                    .forDevice(deviceId)
-                    .withSelector(SELECTOR)
-                    .withTreatment(TREATMENT)
-                    .withPriority(22)
-                    .makeTemporary(44)
-                    .fromApp(APP_ID)
-                    .build();
-    FlowRule flowRule1 =
-            DefaultFlowRule.builder()
-                    .forDevice(deviceId)
-                    .withSelector(SELECTOR)
-                    .withTreatment(TREATMENT)
-                    .withPriority(33)
-                    .makeTemporary(44)
-                    .fromApp(APP_ID)
-                    .build();
-
-    static class MasterOfAll extends MastershipServiceAdapter {
-        @Override
-        public MastershipRole getLocalRole(DeviceId deviceId) {
-            return MastershipRole.MASTER;
-        }
-
-        @Override
-        public NodeId getMasterFor(DeviceId deviceId) {
-            return new NodeId("1");
-        }
-    }
-
-
-    private static class MockControllerNode implements ControllerNode {
-        final NodeId id;
-
-        public MockControllerNode(NodeId id) {
-            this.id = id;
-        }
-
-        @Override
-        public NodeId id() {
-            return this.id;
-        }
-
-        @Override
-        public String host() {
-            return "127.0.0.1";
-        }
-
-        @Override
-        public Ip4Address ip() {
-            return Ip4Address.valueOf("127.0.0.1");
-        }
-
-        @Override
-        public IpAddress ip(boolean resolve) {
-            return ip();
-        }
-
-        @Override
-        public int tcpPort() {
-            return 0;
-        }
-    }
-
-    private static class MockStorageService extends TestStorageService {
-        @Override
-        public <V> DocumentTreeBuilder<V> documentTreeBuilder() {
-            return new DocumentTreeBuilder<V>() {
-                @Override
-                public AsyncDocumentTree<V> buildDocumentTree() {
-                    return build();
-                }
-
-                @Override
-                @SuppressWarnings("unchecked")
-                public AsyncDocumentTree<V> build() {
-                    return new TestAsyncDocumentTree<>(name());
-                }
-            };
-        }
-
-        @Override
-        public <T> Topic<T> getTopic(String name, Serializer serializer) {
-            return new TestTopic<>(name);
-        }
-    }
-
-    @Before
-    public void setUp() throws Exception {
-        flowStoreImpl = new DistributedFlowRuleStore();
-        flowStoreImpl.storageService = new MockStorageService();
-        mockClusterService = createMock(ClusterService.class);
-        flowStoreImpl.clusterService = mockClusterService;
-        nodeId = new NodeId("1");
-        mockControllerNode = new MockControllerNode(nodeId);
-
-        expect(mockClusterService.getLocalNode())
-                .andReturn(mockControllerNode).anyTimes();
-        replay(mockClusterService);
-
-        flowStoreImpl.clusterCommunicator = new ClusterCommunicationServiceAdapter();
-        flowStoreImpl.mastershipService = new MasterOfAll();
-        flowStoreImpl.deviceService = new DeviceServiceAdapter();
-        flowStoreImpl.coreService = new CoreServiceAdapter();
-        flowStoreImpl.activate();
-    }
-
-    @After
-    public void tearDown() throws Exception {
-        flowStoreImpl.deactivate();
-    }
-
-    /**
-     * Tests the initial state of the store.
-     */
-    @Test
-    public void testEmptyStore() {
-        assertThat(flowStoreImpl.getFlowRuleCount(), is(0));
-        assertThat(flowStoreImpl.getFlowEntries(deviceId), is(emptyIterable()));
-    }
-
-    /**
-     * Tests initial state of flowrule.
-     */
-    @Test
-    public void testStoreBatch() {
-        FlowRuleOperation op = new FlowRuleOperation(flowRule, FlowRuleOperation.Type.ADD);
-        Multimap<DeviceId, FlowRuleBatchEntry> perDeviceBatches = ArrayListMultimap.create();
-        perDeviceBatches.put(op.rule().deviceId(),
-                new FlowRuleBatchEntry(FlowRuleBatchEntry.FlowRuleOperation.ADD, op.rule()));
-        FlowRuleBatchOperation b = new FlowRuleBatchOperation(perDeviceBatches.get(deviceId),
-                deviceId, 1);
-        flowStoreImpl.storeBatch(b);
-        FlowEntry flowEntry1 = flowStoreImpl.getFlowEntry(flowRule);
-        assertEquals("PENDING_ADD", flowEntry1.state().toString());
-    }
-
-    /**
-     * Tests adding a flowrule.
-     */
-    @Test
-    public void testAddFlow() {
-        FlowEntry flowEntry = new DefaultFlowEntry(flowRule);
-        FlowRuleOperation op = new FlowRuleOperation(flowRule, FlowRuleOperation.Type.ADD);
-        Multimap<DeviceId, FlowRuleBatchEntry> perDeviceBatches = ArrayListMultimap.create();
-        perDeviceBatches.put(op.rule().deviceId(),
-                new FlowRuleBatchEntry(FlowRuleBatchEntry.FlowRuleOperation.ADD, op.rule()));
-        FlowRuleBatchOperation b = new FlowRuleBatchOperation(perDeviceBatches.get(deviceId),
-                deviceId, 1);
-        flowStoreImpl.storeBatch(b);
-        FlowEntry flowEntry1 = flowStoreImpl.getFlowEntry(flowRule);
-        assertEquals("PENDING_ADD", flowEntry1.state().toString());
-
-        flowStoreImpl.addOrUpdateFlowRule(flowEntry);
-        Iterable<FlowEntry> flows = flowStoreImpl.getFlowEntries(deviceId);
-        int sum = 0;
-        Iterator it = flows.iterator();
-        while (it.hasNext()) {
-            it.next();
-            sum++;
-        }
-        assertThat(sum, is(1));
-
-        FlowEntry flowEntry2 = flowStoreImpl.getFlowEntry(flowRule);
-        assertEquals("ADDED", flowEntry2.state().toString());
-        assertThat(flowStoreImpl.getTableStatistics(deviceId), notNullValue());
-    }
-
-    /**
-     * Tests flow removal.
-     */
-    @Test
-    public void testRemoveFlow() {
-        Iterable<FlowEntry> flows1 = flowStoreImpl.getFlowEntries(deviceId);
-        for (FlowEntry flow : flows1) {
-            flowStoreImpl.removeFlowRule(flow);
-        }
-
-        Iterable<FlowEntry> flows2 = flowStoreImpl.getFlowEntries(deviceId);
-        int sum = 0;
-        Iterator it = flows2.iterator();
-        while (it.hasNext()) {
-            it.next();
-            sum++;
-        }
-        assertThat(sum, is(0));
-    }
-
-    /**
-     * Tests purge flow for a device.
-     */
-    @Test
-    public void testPurgeFlow() {
-        FlowEntry flowEntry = new DefaultFlowEntry(flowRule);
-        flowStoreImpl.storeBatch(new FlowRuleBatchOperation(
-                Collections.singletonList(new FlowRuleBatchEntry(FlowRuleBatchEntry.FlowRuleOperation.ADD, flowEntry)),
-                flowEntry.deviceId(), 1));
-
-        FlowEntry flowEntry1 = new DefaultFlowEntry(flowRule1);
-        flowStoreImpl.storeBatch(new FlowRuleBatchOperation(
-                Collections.singletonList(new FlowRuleBatchEntry(FlowRuleBatchEntry.FlowRuleOperation.ADD, flowEntry1)),
-                flowEntry1.deviceId(), 2));
-
-        Iterable<FlowEntry> flows1 = flowStoreImpl.getFlowEntries(deviceId);
-        int sum2 = 0;
-        Iterator it1 = flows1.iterator();
-        while (it1.hasNext()) {
-            it1.next();
-            sum2++;
-        }
-        assertThat(sum2, is(2));
-        flowStoreImpl.purgeFlowRule(deviceId);
-
-        Iterable<FlowEntry> flows3 = flowStoreImpl.getFlowEntries(deviceId);
-        int sum3 = 0;
-        Iterator it3 = flows3.iterator();
-        while (it3.hasNext()) {
-            it3.next();
-            sum3++;
-        }
-        assertThat(sum3, is(0));
-    }
-}
diff --git a/core/store/primitives/src/main/java/org/onosproject/store/atomix/primitives/impl/PartitionManager.java b/core/store/primitives/src/main/java/org/onosproject/store/atomix/primitives/impl/PartitionManager.java
index e10a03c..0e6c11c 100644
--- a/core/store/primitives/src/main/java/org/onosproject/store/atomix/primitives/impl/PartitionManager.java
+++ b/core/store/primitives/src/main/java/org/onosproject/store/atomix/primitives/impl/PartitionManager.java
@@ -23,7 +23,6 @@
 import org.onosproject.cluster.PartitionId;
 import org.onosproject.event.AbstractListenerManager;
 import org.onosproject.store.atomix.impl.AtomixManager;
-import org.onosproject.store.primitives.DistributedPrimitiveCreator;
 import org.onosproject.store.primitives.PartitionAdminService;
 import org.onosproject.store.primitives.PartitionEvent;
 import org.onosproject.store.primitives.PartitionEventListener;
@@ -87,12 +86,6 @@
     }
 
     @Override
-    public DistributedPrimitiveCreator getDistributedPrimitiveCreator(PartitionId partitionId) {
-        checkPermission(PARTITION_READ);
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
     public Set<NodeId> getConfiguredMembers(PartitionId partitionId) {
         checkPermission(PARTITION_READ);
         io.atomix.primitive.partition.PartitionId atomixPartitionId =
@@ -104,14 +97,6 @@
     }
 
     @Override
-    public Set<NodeId> getActiveMembersMembers(PartitionId partitionId) {
-        checkPermission(PARTITION_READ);
-        // TODO: This needs to query metadata to determine currently active
-        // members of partition
-        return getConfiguredMembers(partitionId);
-    }
-
-    @Override
     public List<PartitionInfo> partitionInfo() {
         checkPermission(PARTITION_READ);
         return partitionGroup.getPartitions()
diff --git a/core/store/primitives/src/main/java/org/onosproject/store/atomix/primitives/impl/StorageManager.java b/core/store/primitives/src/main/java/org/onosproject/store/atomix/primitives/impl/StorageManager.java
index cd15895..0800179 100644
--- a/core/store/primitives/src/main/java/org/onosproject/store/atomix/primitives/impl/StorageManager.java
+++ b/core/store/primitives/src/main/java/org/onosproject/store/atomix/primitives/impl/StorageManager.java
@@ -50,7 +50,6 @@
 import org.onosproject.store.service.EventuallyConsistentMapBuilder;
 import org.onosproject.store.service.LeaderElectorBuilder;
 import org.onosproject.store.service.MapInfo;
-import org.onosproject.store.service.PartitionInfo;
 import org.onosproject.store.service.Serializer;
 import org.onosproject.store.service.StorageAdminService;
 import org.onosproject.store.service.StorageService;
@@ -340,11 +339,6 @@
     }
 
     @Override
-    public List<PartitionInfo> getPartitionInfo() {
-        return partitionAdminService.partitionInfo();
-    }
-
-    @Override
     public Collection<TransactionId> getPendingTransactions() {
         return atomix.getTransactionService().getActiveTransactions()
             .stream()
