diff --git a/core/store/primitives/src/main/java/org/onosproject/store/primitives/impl/StorageManager.java b/core/store/primitives/src/main/java/org/onosproject/store/primitives/impl/StorageManager.java
new file mode 100644
index 0000000..f1eb4ce
--- /dev/null
+++ b/core/store/primitives/src/main/java/org/onosproject/store/primitives/impl/StorageManager.java
@@ -0,0 +1,220 @@
+/*
+ * Copyright 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.store.primitives.impl;
+
+import static org.slf4j.LoggerFactory.getLogger;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+import java.util.function.Supplier;
+import java.util.stream.Collectors;
+
+import org.apache.commons.collections.ListUtils;
+import org.apache.felix.scr.annotations.Activate;
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Deactivate;
+import org.apache.felix.scr.annotations.Reference;
+import org.apache.felix.scr.annotations.ReferenceCardinality;
+import org.apache.felix.scr.annotations.Service;
+import org.onosproject.cluster.ClusterService;
+import org.onosproject.cluster.PartitionId;
+import org.onosproject.persistence.PersistenceService;
+import org.onosproject.store.cluster.messaging.ClusterCommunicationService;
+import org.onosproject.store.primitives.DistributedPrimitiveCreator;
+import org.onosproject.store.primitives.MapUpdate;
+import org.onosproject.store.primitives.PartitionService;
+import org.onosproject.store.primitives.TransactionId;
+import org.onosproject.store.serializers.KryoNamespaces;
+import org.onosproject.store.service.AsyncConsistentMap;
+import org.onosproject.store.service.AtomicCounterBuilder;
+import org.onosproject.store.service.AtomicValueBuilder;
+import org.onosproject.store.service.ConsistentMap;
+import org.onosproject.store.service.ConsistentMapBuilder;
+import org.onosproject.store.service.DistributedQueueBuilder;
+import org.onosproject.store.service.DistributedSetBuilder;
+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;
+import org.onosproject.store.service.TransactionContextBuilder;
+import org.slf4j.Logger;
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import com.google.common.util.concurrent.Futures;
+
+/**
+ * Implementation for {@code StorageService} and {@code StorageAdminService}.
+ */
+@Service
+@Component(immediate = true, enabled = false)
+public class StorageManager implements StorageService, StorageAdminService {
+
+    private final Logger log = getLogger(getClass());
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected ClusterService clusterService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected ClusterCommunicationService clusterCommunicator;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected PersistenceService persistenceService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected PartitionService partitionService;
+
+    private final Supplier<TransactionId> transactionIdGenerator =
+            () -> TransactionId.from(UUID.randomUUID().toString());
+    private DistributedPrimitiveCreator basePrimitiveCreator;
+    private DistributedPrimitiveCreator federatedPrimitiveCreator;
+    private AsyncConsistentMap<TransactionId, Transaction.State> transactions;
+    private TransactionCoordinator transactionCoordinator;
+
+    @Activate
+    public void actiavte() {
+        basePrimitiveCreator = partitionService.getDistributedPrimitiveCreator(PartitionId.from(0));
+        Map<PartitionId, DistributedPrimitiveCreator> partitionMap = Maps.newHashMap();
+        partitionService.getAllPartitionIds().stream()
+            .filter(id -> !id.equals(PartitionId.from(0)))
+            .forEach(id -> partitionMap.put(id, partitionService.getDistributedPrimitiveCreator(id)));
+        federatedPrimitiveCreator = new FederatedDistributedPrimitiveCreator(partitionMap);
+        transactions = this.<TransactionId, Transaction.State>consistentMapBuilder()
+                    .withName("onos-transactions")
+                    .withSerializer(Serializer.using(KryoNamespaces.API,
+                            MapUpdate.class,
+                            MapUpdate.Type.class,
+                            Transaction.class,
+                            Transaction.State.class))
+                    .buildAsyncMap();
+        transactionCoordinator = new TransactionCoordinator(transactions);
+        log.info("Started");
+    }
+
+    @Deactivate
+    public void deactivate() {
+        log.info("Stopped");
+    }
+
+    @Override
+    public <K, V> EventuallyConsistentMapBuilder<K, V> eventuallyConsistentMapBuilder() {
+        return new EventuallyConsistentMapBuilderImpl<>(clusterService,
+                clusterCommunicator,
+                persistenceService);
+    }
+
+    @Override
+    public <K, V> ConsistentMapBuilder<K, V> consistentMapBuilder() {
+        return new NewDefaultConsistentMapBuilder<>(basePrimitiveCreator, federatedPrimitiveCreator);
+    }
+
+    @Override
+    public <E> DistributedSetBuilder<E> setBuilder() {
+        return new DefaultDistributedSetBuilder<>(() -> this.<E, Boolean>consistentMapBuilder());
+    }
+
+    @Override
+    public <E> DistributedQueueBuilder<E> queueBuilder() {
+        // TODO: implement
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public AtomicCounterBuilder atomicCounterBuilder() {
+        return new NewDefaultAtomicCounterBuilder(basePrimitiveCreator, federatedPrimitiveCreator);
+    }
+
+    @Override
+    public <V> AtomicValueBuilder<V> atomicValueBuilder() {
+        Supplier<ConsistentMapBuilder<String, byte[]>> mapBuilderSupplier =
+                () -> this.<String, byte[]>consistentMapBuilder()
+                          .withName("onos-atomic-values")
+                          .withMeteringDisabled()
+                          .withSerializer(Serializer.using(KryoNamespaces.BASIC));
+        return new DefaultAtomicValueBuilder<>(mapBuilderSupplier);
+    }
+
+    @Override
+    public TransactionContextBuilder transactionContextBuilder() {
+        return new NewDefaultTransactionContextBuilder(transactionIdGenerator.get(),
+                basePrimitiveCreator,
+                federatedPrimitiveCreator,
+                transactionCoordinator);
+    }
+
+    @Override
+    public LeaderElectorBuilder leaderElectorBuilder() {
+        return new DefaultLeaderElectorBuilder(basePrimitiveCreator,
+                federatedPrimitiveCreator);
+    }
+
+    @Override
+    public List<MapInfo> getMapInfo() {
+        return ListUtils.union(listMapInfo(basePrimitiveCreator), listMapInfo(federatedPrimitiveCreator));
+    }
+
+    @Override
+    public Map<String, Long> getCounters() {
+        Map<String, Long> result = Maps.newHashMap();
+        result.putAll(getInMemoryDatabaseCounters());
+        result.putAll(getPartitionedDatabaseCounters());
+        return result;
+    }
+
+    @Override
+    public Map<String, Long> getInMemoryDatabaseCounters() {
+        return getCounters(basePrimitiveCreator);
+    }
+
+    @Override
+    public Map<String, Long> getPartitionedDatabaseCounters() {
+        return getCounters(federatedPrimitiveCreator);
+    }
+
+    public Map<String, Long> getCounters(DistributedPrimitiveCreator creator) {
+        Map<String, Long> counters = Maps.newConcurrentMap();
+        creator.getAsyncAtomicCounterNames()
+               .forEach(name -> counters.put(name, creator.newAsyncCounter(name).asAtomicCounter().get()));
+        return counters;
+    }
+
+    @Override
+    public List<PartitionInfo> getPartitionInfo() {
+        return Lists.newArrayList();
+    }
+
+    @Override
+    public Collection<TransactionId> getPendingTransactions() {
+        return Futures.getUnchecked(transactions.keySet());
+    }
+
+    private List<MapInfo> listMapInfo(DistributedPrimitiveCreator creator) {
+        Serializer serializer = Serializer.using(KryoNamespaces.BASIC);
+        return creator.getAsyncConsistentMapNames()
+        .stream()
+        .map(name -> {
+            ConsistentMap<String, byte[]> map =
+                    creator.<String, byte[]>newAsyncConsistentMap(name, serializer)
+                                             .asConsistentMap();
+                    return new MapInfo(name, map.size());
+        }).collect(Collectors.toList());
+    }
+}
\ No newline at end of file
