diff --git a/core/store/primitives/src/main/java/org/onosproject/store/primitives/resources/impl/AtomixConsistentMap.java b/core/store/primitives/src/main/java/org/onosproject/store/primitives/resources/impl/AtomixConsistentMap.java
index 8bab853..df567d2 100644
--- a/core/store/primitives/src/main/java/org/onosproject/store/primitives/resources/impl/AtomixConsistentMap.java
+++ b/core/store/primitives/src/main/java/org/onosproject/store/primitives/resources/impl/AtomixConsistentMap.java
@@ -266,7 +266,7 @@
     public synchronized CompletableFuture<Void> addListener(MapEventListener<String, byte[]> listener,
                                                             Executor executor) {
         if (mapEventListeners.isEmpty()) {
-            return client.submit(new Listen()).thenRun(() -> mapEventListeners.putIfAbsent(listener, executor));
+            return client.submit(new Listen()).thenRun(() -> mapEventListeners.put(listener, executor));
         } else {
             mapEventListeners.put(listener, executor);
             return CompletableFuture.completedFuture(null);
diff --git a/core/store/primitives/src/main/java/org/onosproject/store/primitives/resources/impl/AtomixConsistentTreeMap.java b/core/store/primitives/src/main/java/org/onosproject/store/primitives/resources/impl/AtomixConsistentTreeMap.java
new file mode 100644
index 0000000..3baadde
--- /dev/null
+++ b/core/store/primitives/src/main/java/org/onosproject/store/primitives/resources/impl/AtomixConsistentTreeMap.java
@@ -0,0 +1,401 @@
+/*
+ * 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.resources.impl;
+
+import com.google.common.collect.Maps;
+import io.atomix.copycat.client.CopycatClient;
+import io.atomix.resource.AbstractResource;
+import io.atomix.resource.ResourceTypeInfo;
+import org.onlab.util.Match;
+import org.onosproject.store.primitives.TransactionId;
+import org.onosproject.store.primitives.resources.impl.AtomixConsistentTreeMapCommands.FirstKey;
+import org.onosproject.store.primitives.resources.impl.AtomixConsistentTreeMapCommands.FloorEntry;
+import org.onosproject.store.primitives.resources.impl.AtomixConsistentTreeMapCommands.HigherEntry;
+import org.onosproject.store.primitives.resources.impl.AtomixConsistentTreeMapCommands.LastEntry;
+import org.onosproject.store.primitives.resources.impl.AtomixConsistentTreeMapCommands.LowerEntry;
+import org.onosproject.store.service.AsyncConsistentTreeMap;
+import org.onosproject.store.service.MapEvent;
+import org.onosproject.store.service.MapEventListener;
+import org.onosproject.store.service.MapTransaction;
+import org.onosproject.store.service.Versioned;
+
+import java.util.Collection;
+import java.util.ConcurrentModificationException;
+import java.util.List;
+import java.util.Map;
+import java.util.NavigableMap;
+import java.util.NavigableSet;
+import java.util.Properties;
+import java.util.Set;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.Executor;
+import java.util.concurrent.atomic.AtomicReference;
+import java.util.function.BiFunction;
+import java.util.function.Predicate;
+
+import static org.onosproject.store.primitives.resources.impl.AtomixConsistentTreeMapCommands.CeilingEntry;
+import static org.onosproject.store.primitives.resources.impl.AtomixConsistentTreeMapCommands.CeilingKey;
+import static org.onosproject.store.primitives.resources.impl.AtomixConsistentTreeMapCommands.Clear;
+import static org.onosproject.store.primitives.resources.impl.AtomixConsistentTreeMapCommands.ContainsKey;
+import static org.onosproject.store.primitives.resources.impl.AtomixConsistentTreeMapCommands.ContainsValue;
+import static org.onosproject.store.primitives.resources.impl.AtomixConsistentTreeMapCommands.EntrySet;
+import static org.onosproject.store.primitives.resources.impl.AtomixConsistentTreeMapCommands.FirstEntry;
+import static org.onosproject.store.primitives.resources.impl.AtomixConsistentTreeMapCommands.FloorKey;
+import static org.onosproject.store.primitives.resources.impl.AtomixConsistentTreeMapCommands.Get;
+import static org.onosproject.store.primitives.resources.impl.AtomixConsistentTreeMapCommands.HigherKey;
+import static org.onosproject.store.primitives.resources.impl.AtomixConsistentTreeMapCommands.IsEmpty;
+import static org.onosproject.store.primitives.resources.impl.AtomixConsistentTreeMapCommands.KeySet;
+import static org.onosproject.store.primitives.resources.impl.AtomixConsistentTreeMapCommands.LastKey;
+import static org.onosproject.store.primitives.resources.impl.AtomixConsistentTreeMapCommands.Listen;
+import static org.onosproject.store.primitives.resources.impl.AtomixConsistentTreeMapCommands.LowerKey;
+import static org.onosproject.store.primitives.resources.impl.AtomixConsistentTreeMapCommands.PollFirstEntry;
+import static org.onosproject.store.primitives.resources.impl.AtomixConsistentTreeMapCommands.PollLastEntry;
+import static org.onosproject.store.primitives.resources.impl.AtomixConsistentTreeMapCommands.Size;
+import static org.onosproject.store.primitives.resources.impl.AtomixConsistentTreeMapCommands.Unlisten;
+import static org.onosproject.store.primitives.resources.impl.AtomixConsistentTreeMapCommands.UpdateAndGet;
+import static org.onosproject.store.primitives.resources.impl.AtomixConsistentTreeMapCommands.Values;
+
+/**
+ * Implementation of {@link AsyncConsistentTreeMap}.
+ */
+@ResourceTypeInfo(id = -155, factory = AtomixConsistentTreeMapFactory.class)
+public class AtomixConsistentTreeMap extends AbstractResource<AtomixConsistentTreeMap>
+        implements AsyncConsistentTreeMap<String, byte[]> {
+
+    private final Map<MapEventListener<String, byte[]>, Executor>
+            mapEventListeners = Maps.newConcurrentMap();
+
+    public static final String CHANGE_SUBJECT = "changeEvents";
+
+    public AtomixConsistentTreeMap(CopycatClient client, Properties options) {
+        super(client, options);
+    }
+
+    @Override
+    public String name() {
+        return null;
+    }
+
+    @Override
+    public CompletableFuture<AtomixConsistentTreeMap> open() {
+        return super.open().thenApply(result -> {
+            client.onEvent(CHANGE_SUBJECT, this::handleEvent);
+            return result;
+        });
+    }
+
+    private void handleEvent(List<MapEvent<String, byte[]>> events) {
+        events.forEach(event -> mapEventListeners.
+                forEach((listener, executor) ->
+                                executor.execute(() ->
+                                                     listener.event(event))));
+    }
+
+    @Override
+    public CompletableFuture<Boolean> isEmpty() {
+        return client.submit(new IsEmpty());
+    }
+
+    @Override
+    public CompletableFuture<Integer> size() {
+        return client.submit(new Size());
+    }
+
+    @Override
+    public CompletableFuture<Boolean> containsKey(String key) {
+        return client.submit(new ContainsKey(key));
+    }
+
+    @Override
+    public CompletableFuture<Boolean> containsValue(byte[] value) {
+        return client.submit(new ContainsValue(value));
+    }
+
+    @Override
+    public CompletableFuture<Versioned<byte[]>> get(String key) {
+        return client.submit(new Get(key));
+    }
+
+    @Override
+    public CompletableFuture<Set<String>> keySet() {
+        return client.submit(new KeySet());
+    }
+
+    @Override
+    public CompletableFuture<Collection<Versioned<byte[]>>> values() {
+        return client.submit(new Values());
+    }
+
+    @Override
+    public CompletableFuture<Set<Map.Entry<String, Versioned<byte[]>>>> entrySet() {
+        return client.submit(new EntrySet());
+    }
+
+    @Override
+    @SuppressWarnings("unchecked")
+    public CompletableFuture<Versioned<byte[]>> put(String key, byte[] value) {
+        return client.submit(new UpdateAndGet(key, value, Match.ANY, Match.ANY))
+                .whenComplete((r, e) -> throwIfLocked(r.status()))
+                .thenApply(v -> v.oldValue());
+    }
+
+    @Override
+    @SuppressWarnings("unchecked")
+    public CompletableFuture<Versioned<byte[]>> putAndGet(String key, byte[] value) {
+        return client.submit(new UpdateAndGet(key, value, Match.ANY, Match.ANY))
+                .whenComplete((r, e) -> throwIfLocked(r.status()))
+                .thenApply(v -> v.newValue());
+    }
+
+    @Override
+    @SuppressWarnings("unchecked")
+    public CompletableFuture<Versioned<byte[]>> putIfAbsent(String key, byte[] value) {
+        return client.submit(new UpdateAndGet(key, value, Match.NULL, Match.ANY))
+                .whenComplete((r, e) -> throwIfLocked(r.status()))
+                .thenApply(v -> v.oldValue());
+    }
+
+    @Override
+    @SuppressWarnings("unchecked")
+    public CompletableFuture<Versioned<byte[]>> remove(String key) {
+        return client.submit(new UpdateAndGet(key, null, Match.ANY, Match.ANY))
+                .whenComplete((r, e) -> throwIfLocked(r.status()))
+                .thenApply(v -> v.oldValue());
+    }
+
+    @Override
+    @SuppressWarnings("unchecked")
+    public CompletableFuture<Boolean> remove(String key, byte[] value) {
+        return client.submit(new UpdateAndGet(key, null, Match.ifValue(value), Match.ANY))
+                .whenComplete((r, e) -> throwIfLocked(r.status()))
+                .thenApply(v -> v.updated());
+    }
+
+    @Override
+    @SuppressWarnings("unchecked")
+    public CompletableFuture<Boolean> remove(String key, long version) {
+        return client.submit(new UpdateAndGet(key, null, Match.ANY, Match.ifValue(version)))
+                .whenComplete((r, e) -> throwIfLocked(r.status()))
+                .thenApply(v -> v.updated());
+    }
+
+    @Override
+    @SuppressWarnings("unchecked")
+    public CompletableFuture<Versioned<byte[]>> replace(String key, byte[] value) {
+        return client.submit(new UpdateAndGet(key, value, Match.NOT_NULL, Match.ANY))
+                .whenComplete((r, e) -> throwIfLocked(r.status()))
+                .thenApply(v -> v.oldValue());
+    }
+
+    @Override
+    @SuppressWarnings("unchecked")
+    public CompletableFuture<Boolean> replace(String key, byte[] oldValue, byte[] newValue) {
+        return client.submit(new UpdateAndGet(key, newValue, Match.ifValue(oldValue), Match.ANY))
+                .whenComplete((r, e) -> throwIfLocked(r.status()))
+                .thenApply(v -> v.updated());
+    }
+
+    @Override
+    @SuppressWarnings("unchecked")
+    public CompletableFuture<Boolean> replace(String key, long oldVersion, byte[] newValue) {
+        return client.submit(new UpdateAndGet(key, newValue, Match.ANY, Match.ifValue(oldVersion)))
+                .whenComplete((r, e) -> throwIfLocked(r.status()))
+                .thenApply(v -> v.updated());
+    }
+
+    @Override
+    public CompletableFuture<Void> clear() {
+        return client.submit(new Clear())
+                .whenComplete((r, e) -> throwIfLocked(r))
+                .thenApply(v -> null);
+    }
+
+    @Override
+    @SuppressWarnings("unchecked")
+    public CompletableFuture<Versioned<byte[]>> computeIf(String key,
+                                                          Predicate<? super byte[]> condition,
+                                                          BiFunction<? super String,
+                                                                  ? super byte[],
+                                                                  ? extends byte[]> remappingFunction) {
+        return get(key).thenCompose(r1 -> {
+            byte[] existingValue = r1 == null ? null : r1.value();
+
+            if (!condition.test(existingValue)) {
+                return CompletableFuture.completedFuture(r1);
+            }
+
+            AtomicReference<byte[]> computedValue = new AtomicReference<byte[]>();
+            try {
+                computedValue.set(remappingFunction.apply(key, existingValue));
+            } catch (Exception e) {
+                CompletableFuture<Versioned<byte[]>> future = new CompletableFuture<>();
+                future.completeExceptionally(e);
+                return future;
+            }
+            if (computedValue.get() == null && r1 == null) {
+                return CompletableFuture.completedFuture(null);
+            }
+            Match<byte[]> valueMatch = r1 == null ? Match.NULL : Match.ANY;
+            Match<Long> versionMatch = r1 == null ? Match.ANY : Match.ifValue(r1.version());
+            return client.submit(new UpdateAndGet(key, computedValue.get(),
+                                                                      valueMatch, versionMatch))
+                    .whenComplete((r, e) -> throwIfLocked(r.status()))
+                    .thenApply(v -> v.newValue());
+        });
+    }
+
+    @Override
+    public CompletableFuture<Void> addListener(
+            MapEventListener<String, byte[]> listener, Executor executor) {
+        if (mapEventListeners.isEmpty()) {
+            return client.submit(new Listen()).thenRun(() ->
+                                   mapEventListeners.put(listener,
+                                           executor));
+        } else {
+            mapEventListeners.put(listener, executor);
+            return CompletableFuture.completedFuture(null);
+        }
+    }
+
+    @Override
+    public synchronized CompletableFuture<Void> removeListener(MapEventListener<String, byte[]> listener) {
+        if (mapEventListeners.remove(listener) != null &&
+                mapEventListeners.isEmpty()) {
+            return client.submit(new Unlisten())
+                    .thenApply(v -> null);
+        }
+        return CompletableFuture.completedFuture(null);
+    }
+
+
+    private void throwIfLocked(MapEntryUpdateResult.Status status) {
+        if (status == MapEntryUpdateResult.Status.WRITE_LOCK) {
+            throw new ConcurrentModificationException("Cannot update TreeMap: another update is in progress.");
+        }
+    }
+
+    @Override
+    public CompletableFuture<String> firstKey() {
+        return client.submit(new FirstKey<String>());
+    }
+
+    @Override
+    public CompletableFuture<String> lastKey() {
+        return client.submit(new LastKey<String>());
+    }
+
+    @Override
+    public CompletableFuture<Map.Entry<String, Versioned<byte[]>>> ceilingEntry(String key) {
+        return client.submit(new CeilingEntry(key));
+    }
+
+    @Override
+    public CompletableFuture<Map.Entry<String, Versioned<byte[]>>> floorEntry(String key) {
+        return client.submit(new FloorEntry<String, Versioned<byte[]>>(key));
+    }
+
+    @Override
+    public CompletableFuture<Map.Entry<String, Versioned<byte[]>>> higherEntry(
+            String key) {
+        return client.submit(new HigherEntry<String, Versioned<byte[]>>(key));
+    }
+
+    @Override
+    public CompletableFuture<Map.Entry<String, Versioned<byte[]>>> lowerEntry(
+            String key) {
+        return client.submit(new LowerEntry<>(key));
+    }
+
+    @Override
+    public CompletableFuture<Map.Entry<String, Versioned<byte[]>>> firstEntry() {
+        return client.submit(new FirstEntry());
+    }
+
+    @Override
+    public CompletableFuture<Map.Entry<String, Versioned<byte[]>>> lastEntry() {
+        return client.submit(new LastEntry<String, Versioned<byte[]>>());
+    }
+
+    @Override
+    public CompletableFuture<Map.Entry<String, Versioned<byte[]>>> pollFirstEntry() {
+        return client.submit(new PollFirstEntry());
+    }
+
+    @Override
+    public CompletableFuture<Map.Entry<String, Versioned<byte[]>>> pollLastEntry() {
+        return client.submit(new PollLastEntry());
+    }
+
+    @Override
+    public CompletableFuture<String> lowerKey(String key) {
+        return client.submit(new LowerKey(key));
+    }
+
+    @Override
+    public CompletableFuture<String> floorKey(String key) {
+        return client.submit(new FloorKey(key));
+    }
+
+    @Override
+    public CompletableFuture<String> ceilingKey(String key) {
+        return client.submit(new CeilingKey(key));
+    }
+
+    @Override
+    public CompletableFuture<String> higherKey(String key) {
+        return client.submit(new HigherKey(key));
+    }
+
+    @Override
+    public CompletableFuture<NavigableSet<String>> navigableKeySet() {
+        throw new UnsupportedOperationException("This operation is not yet " +
+                                                        "supported.");
+    }
+
+    @Override
+    public CompletableFuture<NavigableMap<String, byte[]>> subMap(
+            String upperKey, String lowerKey, boolean inclusiveUpper,
+            boolean inclusiveLower) {
+        throw new UnsupportedOperationException("This operation is not yet " +
+                                                        "supported.");    }
+
+    @Override
+    public CompletableFuture<Boolean> prepareAndCommit(MapTransaction<String,
+            byte[]> transaction) {
+        throw new UnsupportedOperationException("This operation is not yet " +
+                                                        "supported.");
+    }
+
+    @Override
+    public CompletableFuture<Boolean> prepare(MapTransaction<String, byte[]>
+                                                          transaction) {
+        throw new UnsupportedOperationException("This operation is not yet " +
+                                                        "supported.");
+    }
+
+    @Override
+    public CompletableFuture<Void> commit(TransactionId transactionId) {
+        throw new UnsupportedOperationException("This operation is not yet " +
+                                                        "supported.");
+    }
+
+    @Override
+    public CompletableFuture<Void> rollback(TransactionId transactionId) {
+        throw new UnsupportedOperationException("This operation is not yet " +
+                                                        "supported.");
+    }
+}
diff --git a/core/store/primitives/src/main/java/org/onosproject/store/primitives/resources/impl/AtomixConsistentTreeMapFactory.java b/core/store/primitives/src/main/java/org/onosproject/store/primitives/resources/impl/AtomixConsistentTreeMapFactory.java
new file mode 100644
index 0000000..4d0ec89
--- /dev/null
+++ b/core/store/primitives/src/main/java/org/onosproject/store/primitives/resources/impl/AtomixConsistentTreeMapFactory.java
@@ -0,0 +1,44 @@
+/*
+ * 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.resources.impl;
+
+import io.atomix.catalyst.serializer.SerializableTypeResolver;
+import io.atomix.copycat.client.CopycatClient;
+import io.atomix.resource.ResourceFactory;
+import io.atomix.resource.ResourceStateMachine;
+
+import java.util.Properties;
+
+/**
+ * Factory for {@link AtomixConsistentTreeMap}.
+ */
+public class AtomixConsistentTreeMapFactory implements ResourceFactory<AtomixConsistentTreeMap> {
+    @Override
+    public SerializableTypeResolver createSerializableTypeResolver() {
+        return new AtomixConsistentTreeMapCommands.TypeResolver();
+    }
+
+    @Override
+    public ResourceStateMachine createStateMachine(Properties config) {
+        return new AtomixConsistentTreeMapState(config);
+    }
+
+    @Override
+    public AtomixConsistentTreeMap createInstance(CopycatClient client, Properties options) {
+        return new AtomixConsistentTreeMap(client, options);
+    }
+}
diff --git a/core/store/primitives/src/main/java/org/onosproject/store/primitives/resources/impl/AtomixConsistentTreeMapState.java b/core/store/primitives/src/main/java/org/onosproject/store/primitives/resources/impl/AtomixConsistentTreeMapState.java
new file mode 100644
index 0000000..2f8f5a8
--- /dev/null
+++ b/core/store/primitives/src/main/java/org/onosproject/store/primitives/resources/impl/AtomixConsistentTreeMapState.java
@@ -0,0 +1,579 @@
+/*
+ * 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.resources.impl;
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import com.google.common.collect.Sets;
+import io.atomix.copycat.server.Commit;
+import io.atomix.copycat.server.Snapshottable;
+import io.atomix.copycat.server.StateMachineExecutor;
+import io.atomix.copycat.server.session.ServerSession;
+import io.atomix.copycat.server.session.SessionListener;
+import io.atomix.copycat.server.storage.snapshot.SnapshotReader;
+import io.atomix.copycat.server.storage.snapshot.SnapshotWriter;
+import io.atomix.resource.ResourceStateMachine;
+import org.onlab.util.Match;
+import org.onosproject.store.service.MapEvent;
+import org.onosproject.store.service.Versioned;
+
+import java.util.AbstractMap.SimpleImmutableEntry;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.NavigableMap;
+import java.util.Properties;
+import java.util.Set;
+import java.util.TreeMap;
+import java.util.concurrent.atomic.AtomicLong;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+
+import static org.onosproject.store.primitives.resources.impl.AtomixConsistentTreeMapCommands.CeilingEntry;
+import static org.onosproject.store.primitives.resources.impl.AtomixConsistentTreeMapCommands.CeilingKey;
+import static org.onosproject.store.primitives.resources.impl.AtomixConsistentTreeMapCommands.Clear;
+import static org.onosproject.store.primitives.resources.impl.AtomixConsistentTreeMapCommands.ContainsKey;
+import static org.onosproject.store.primitives.resources.impl.AtomixConsistentTreeMapCommands.ContainsValue;
+import static org.onosproject.store.primitives.resources.impl.AtomixConsistentTreeMapCommands.EntrySet;
+import static org.onosproject.store.primitives.resources.impl.AtomixConsistentTreeMapCommands.FirstEntry;
+import static org.onosproject.store.primitives.resources.impl.AtomixConsistentTreeMapCommands.FirstKey;
+import static org.onosproject.store.primitives.resources.impl.AtomixConsistentTreeMapCommands.FloorEntry;
+import static org.onosproject.store.primitives.resources.impl.AtomixConsistentTreeMapCommands.FloorKey;
+import static org.onosproject.store.primitives.resources.impl.AtomixConsistentTreeMapCommands.Get;
+import static org.onosproject.store.primitives.resources.impl.AtomixConsistentTreeMapCommands.HigherEntry;
+import static org.onosproject.store.primitives.resources.impl.AtomixConsistentTreeMapCommands.HigherKey;
+import static org.onosproject.store.primitives.resources.impl.AtomixConsistentTreeMapCommands.IsEmpty;
+import static org.onosproject.store.primitives.resources.impl.AtomixConsistentTreeMapCommands.KeySet;
+import static org.onosproject.store.primitives.resources.impl.AtomixConsistentTreeMapCommands.LastEntry;
+import static org.onosproject.store.primitives.resources.impl.AtomixConsistentTreeMapCommands.LastKey;
+import static org.onosproject.store.primitives.resources.impl.AtomixConsistentTreeMapCommands.Listen;
+import static org.onosproject.store.primitives.resources.impl.AtomixConsistentTreeMapCommands.LowerEntry;
+import static org.onosproject.store.primitives.resources.impl.AtomixConsistentTreeMapCommands.LowerKey;
+import static org.onosproject.store.primitives.resources.impl.AtomixConsistentTreeMapCommands.PollFirstEntry;
+import static org.onosproject.store.primitives.resources.impl.AtomixConsistentTreeMapCommands.PollLastEntry;
+import static org.onosproject.store.primitives.resources.impl.AtomixConsistentTreeMapCommands.Size;
+import static org.onosproject.store.primitives.resources.impl.AtomixConsistentTreeMapCommands.SubMap;
+import static org.onosproject.store.primitives.resources.impl.AtomixConsistentTreeMapCommands.Unlisten;
+import static org.onosproject.store.primitives.resources.impl.AtomixConsistentTreeMapCommands.UpdateAndGet;
+import static org.onosproject.store.primitives.resources.impl.AtomixConsistentTreeMapCommands.Values;
+import static org.onosproject.store.primitives.resources.impl.MapEntryUpdateResult.*;
+
+/**
+ * State machine corresponding to {@link AtomixConsistentTreeMap} backed by a
+ * {@link TreeMap}.
+ */
+public class AtomixConsistentTreeMapState extends ResourceStateMachine implements SessionListener, Snapshottable {
+
+    private final Map<Long, Commit<? extends Listen>> listeners =
+            Maps.newHashMap();
+    private TreeMap<String, TreeMapEntryValue> tree = Maps.newTreeMap();
+    private final Set<String> preparedKeys = Sets.newHashSet();
+    private AtomicLong versionCounter = new AtomicLong(0);
+
+    private Function<Commit<SubMap>, NavigableMap<String, TreeMapEntryValue>> subMapFunction = this::subMap;
+    private Function<Commit<FirstKey>, String> firstKeyFunction = this::firstKey;
+    private Function<Commit<LastKey>, String> lastKeyFunction = this::lastKey;
+    private Function<Commit<HigherEntry>, Map.Entry<String, Versioned<byte[]>>> higherEntryFunction =
+            this::higherEntry;
+    private Function<Commit<FirstEntry>, Map.Entry<String, Versioned<byte[]>>> firstEntryFunction =
+            this::firstEntry;
+    private Function<Commit<LastEntry>, Map.Entry<String, Versioned<byte[]>>> lastEntryFunction =
+            this::lastEntry;
+    private Function<Commit<PollFirstEntry>, Map.Entry<String, Versioned<byte[]>>> pollFirstEntryFunction =
+            this::pollFirstEntry;
+    private Function<Commit<PollLastEntry>, Map.Entry<String, Versioned<byte[]>>> pollLastEntryFunction =
+            this::pollLastEntry;
+    private Function<Commit<LowerEntry>, Map.Entry<String, Versioned<byte[]>>> lowerEntryFunction =
+            this::lowerEntry;
+    private Function<Commit<LowerKey>, String> lowerKeyFunction = this::lowerKey;
+    private Function<Commit<FloorEntry>, Map.Entry<String, Versioned<byte[]>>> floorEntryFunction =
+            this::floorEntry;
+    private Function<Commit<CeilingEntry>, Map.Entry<String, Versioned<byte[]>>> ceilingEntryFunction =
+            this::ceilingEntry;
+    private Function<Commit<FloorKey>, String> floorKeyFunction = this::floorKey;
+    private Function<Commit<CeilingKey>, String> ceilingKeyFunction = this::ceilingKey;
+    private Function<Commit<HigherKey>, String> higherKeyFunction = this::higherKey;
+
+    public AtomixConsistentTreeMapState(Properties properties) {
+        super(properties);
+    }
+
+    @Override
+    public void snapshot(SnapshotWriter writer) {
+        writer.writeLong(versionCounter.get());
+    }
+
+    @Override
+    public void install(SnapshotReader reader) {
+        versionCounter = new AtomicLong(reader.readLong());
+    }
+
+    @Override
+    public void configure(StateMachineExecutor executor) {
+        // Listeners
+        executor.register(Listen.class, this::listen);
+        executor.register(Unlisten.class, this::unlisten);
+        // Queries
+        executor.register(ContainsKey.class, this::containsKey);
+        executor.register(ContainsValue.class, this::containsValue);
+        executor.register(EntrySet.class, this::entrySet);
+        executor.register(Get.class, this::get);
+        executor.register(IsEmpty.class, this::isEmpty);
+        executor.register(KeySet.class, this::keySet);
+        executor.register(Size.class, this::size);
+        executor.register(Values.class, this::values);
+        executor.register(SubMap.class, subMapFunction);
+        executor.register(FirstKey.class, firstKeyFunction);
+        executor.register(LastKey.class, lastKeyFunction);
+        executor.register(FirstEntry.class, firstEntryFunction);
+        executor.register(LastEntry.class, lastEntryFunction);
+        executor.register(PollFirstEntry.class, pollFirstEntryFunction);
+        executor.register(PollLastEntry.class, pollLastEntryFunction);
+        executor.register(LowerEntry.class, lowerEntryFunction);
+        executor.register(LowerKey.class, lowerKeyFunction);
+        executor.register(FloorEntry.class, floorEntryFunction);
+        executor.register(FloorKey.class, floorKeyFunction);
+        executor.register(CeilingEntry.class, ceilingEntryFunction);
+        executor.register(CeilingKey.class, ceilingKeyFunction);
+        executor.register(HigherEntry.class, higherEntryFunction);
+        executor.register(HigherKey.class, higherKeyFunction);
+
+        // Commands
+        executor.register(UpdateAndGet.class, this::updateAndGet);
+        executor.register(Clear.class, this::clear);
+    }
+
+    @Override
+    public void delete() {
+        listeners.values().forEach(Commit::close);
+        listeners.clear();
+        tree.values().forEach(TreeMapEntryValue::discard);
+        tree.clear();
+    }
+
+    protected boolean containsKey(Commit<? extends ContainsKey> commit) {
+        try {
+            return toVersioned(tree.get((commit.operation().key()))) != null;
+        } finally {
+            commit.close();
+        }
+    }
+
+    protected boolean containsValue(Commit<? extends ContainsValue> commit) {
+        try {
+            Match<byte[]> valueMatch = Match
+                    .ifValue(commit.operation().value());
+            return tree.values().stream().anyMatch(
+                    value -> valueMatch.matches(value.value()));
+        } finally {
+            commit.close();
+        }
+    }
+
+    protected Versioned<byte[]> get(Commit<? extends Get> commit) {
+        try {
+            return toVersioned(tree.get(commit.operation().key()));
+        } finally {
+            commit.close();
+        }
+    }
+
+    protected int size(Commit<? extends Size> commit) {
+        try {
+            return tree.size();
+        } finally {
+            commit.close();
+        }
+    }
+
+    protected boolean isEmpty(Commit<? extends IsEmpty> commit) {
+        try {
+            return tree.isEmpty();
+        } finally {
+            commit.close();
+        }
+    }
+
+    protected Set<String> keySet(Commit<? extends KeySet> commit) {
+        try {
+            return tree.keySet().stream().collect(Collectors.toSet());
+        } finally {
+            commit.close();
+        }
+    }
+
+    protected Collection<Versioned<byte[]>> values(
+            Commit<? extends Values> commit) {
+        try {
+            return tree.values().stream().map(this::toVersioned)
+                    .collect(Collectors.toList());
+        } finally {
+            commit.close();
+        }
+    }
+
+    protected Set<Map.Entry<String, Versioned<byte[]>>> entrySet(
+            Commit<? extends EntrySet> commit) {
+        try {
+            return tree
+                    .entrySet()
+                    .stream()
+                    .map(e -> Maps.immutableEntry(e.getKey(),
+                                                  toVersioned(e.getValue())))
+                    .collect(Collectors.toSet());
+        } finally {
+            commit.close();
+        }
+    }
+
+    protected MapEntryUpdateResult<String, byte[]> updateAndGet(
+            Commit<? extends UpdateAndGet> commit) {
+        Status updateStatus = validate(commit.operation());
+        String key = commit.operation().key();
+        TreeMapEntryValue oldCommitValue = tree.get(commit.operation().key());
+        Versioned<byte[]> oldTreeValue = toVersioned(oldCommitValue);
+
+        if (updateStatus != Status.OK) {
+            commit.close();
+            return new MapEntryUpdateResult<>(updateStatus, "", key,
+                                                  oldTreeValue, oldTreeValue);
+        }
+
+        byte[] newValue = commit.operation().value();
+        long newVersion = versionCounter.incrementAndGet();
+        Versioned<byte[]> newTreeValue = newValue == null ? null
+                : new Versioned<byte[]>(newValue, newVersion);
+
+        MapEvent.Type updateType = newValue == null ? MapEvent.Type.REMOVE
+                : oldCommitValue == null ? MapEvent.Type.INSERT :
+                MapEvent.Type.UPDATE;
+        if (updateType == MapEvent.Type.REMOVE ||
+                updateType == MapEvent.Type.UPDATE) {
+            tree.remove(key);
+            oldCommitValue.discard();
+        }
+        if (updateType == MapEvent.Type.INSERT ||
+                updateType == MapEvent.Type.UPDATE) {
+            tree.put(key, new NonTransactionalCommit(newVersion, commit));
+        } else {
+            commit.close();
+        }
+        publish(Lists.newArrayList(new MapEvent<>("", key, newTreeValue,
+                                                  oldTreeValue)));
+        return new MapEntryUpdateResult<>(updateStatus, "", key, oldTreeValue,
+                                          newTreeValue);
+    }
+
+    protected Status clear(
+            Commit<? extends Clear> commit) {
+        try {
+            Iterator<Map.Entry<String, TreeMapEntryValue>> iterator = tree
+                    .entrySet()
+                    .iterator();
+            while (iterator.hasNext()) {
+                Map.Entry<String, TreeMapEntryValue> entry = iterator.next();
+                String key = entry.getKey();
+                TreeMapEntryValue value = entry.getValue();
+                Versioned<byte[]> removedValue =
+                        new Versioned<byte[]>(value.value(),
+                                              value.version());
+                publish(Lists.newArrayList(new MapEvent<>("", key, null,
+                                                          removedValue)));
+                value.discard();
+                iterator.remove();
+            }
+            return Status.OK;
+        } finally {
+            commit.close();
+        }
+    }
+
+    protected void listen(
+            Commit<? extends Listen> commit) {
+        Long sessionId = commit.session().id();
+        listeners.put(sessionId, commit);
+        commit.session()
+                .onStateChange(
+                        state -> {
+                            if (state == ServerSession.State.CLOSED
+                                    || state == ServerSession.State.EXPIRED) {
+                                Commit<? extends Listen> listener =
+                                        listeners.remove(sessionId);
+                                if (listener != null) {
+                                    listener.close();
+                                }
+                            }
+                        });
+    }
+
+    protected void unlisten(
+            Commit<? extends Unlisten> commit) {
+        try {
+            Commit<? extends AtomixConsistentTreeMapCommands.Listen> listener =
+                    listeners.remove(commit.session());
+            if (listener != null) {
+                listener.close();
+            }
+        } finally {
+            commit.close();
+        }
+    }
+
+    private Status validate(UpdateAndGet update) {
+        TreeMapEntryValue existingValue = tree.get(update.key());
+        if (existingValue == null && update.value() == null) {
+            return Status.NOOP;
+        }
+        if (preparedKeys.contains(update.key())) {
+            return Status.WRITE_LOCK;
+        }
+        byte[] existingRawValue = existingValue == null ? null :
+                existingValue.value();
+        Long existingVersion = existingValue == null ? null :
+                existingValue.version();
+        return update.valueMatch().matches(existingRawValue)
+                && update.versionMatch().matches(existingVersion) ?
+                Status.OK
+                : Status.PRECONDITION_FAILED;
+    }
+
+    protected NavigableMap<String, TreeMapEntryValue> subMap(
+            Commit<? extends SubMap> commit) {
+        //Do not support this until lazy communication is possible.  At present
+        // it transmits up to the entire map.
+        try {
+            SubMap<String, TreeMapEntryValue> subMap = commit.operation();
+            return tree.subMap(subMap.fromKey(), subMap.isInclusiveFrom(),
+                               subMap.toKey(), subMap.isInclusiveTo());
+        } finally {
+            commit.close();
+        }
+    }
+
+    protected String firstKey(Commit<? extends FirstKey> commit) {
+        try {
+            if (tree.isEmpty()) {
+                return null;
+            }
+            return tree.firstKey();
+        } finally {
+            commit.close();
+        }
+    }
+
+    protected String lastKey(Commit<? extends LastKey> commit) {
+        try {
+            return tree.isEmpty() ? null : tree.lastKey();
+        } finally {
+            commit.close();
+        }
+    }
+
+    protected Map.Entry<String, Versioned<byte[]>> higherEntry(
+            Commit<? extends HigherEntry> commit) {
+        try {
+            if (tree.isEmpty()) {
+                return null;
+            }
+            return toVersionedEntry(
+                    tree.higherEntry(commit.operation().key()));
+        } finally {
+            commit.close();
+        }
+    }
+
+    protected Map.Entry<String, Versioned<byte[]>> firstEntry(
+            Commit<? extends FirstEntry> commit) {
+        try {
+            if (tree.isEmpty()) {
+                return null;
+            }
+            return toVersionedEntry(tree.firstEntry());
+        } finally {
+            commit.close();
+        }
+    }
+
+    protected Map.Entry<String, Versioned<byte[]>> lastEntry(
+            Commit<? extends LastEntry> commit) {
+        try {
+            if (tree.isEmpty()) {
+                return null;
+            }
+            return toVersionedEntry(tree.lastEntry());
+        } finally {
+            commit.close();
+        }
+    }
+
+    protected Map.Entry<String, Versioned<byte[]>> pollFirstEntry(
+            Commit<? extends PollFirstEntry> commit) {
+        try {
+            return toVersionedEntry(tree.pollFirstEntry());
+        } finally {
+            commit.close();
+        }
+    }
+
+    protected Map.Entry<String, Versioned<byte[]>> pollLastEntry(
+            Commit<? extends PollLastEntry> commit) {
+        try {
+            return toVersionedEntry(tree.pollLastEntry());
+        } finally {
+            commit.close();
+        }
+    }
+
+    protected Map.Entry<String, Versioned<byte[]>> lowerEntry(
+            Commit<? extends LowerEntry> commit) {
+        try {
+            return toVersionedEntry(tree.lowerEntry(commit.operation().key()));
+        } finally {
+            commit.close();
+        }
+    }
+
+    protected String lowerKey(Commit<? extends LowerKey> commit) {
+        try {
+            return tree.lowerKey(commit.operation().key());
+        } finally {
+            commit.close();
+        }
+    }
+
+    protected Map.Entry<String, Versioned<byte[]>> floorEntry(
+            Commit<? extends FloorEntry> commit) {
+        try {
+            return toVersionedEntry(tree.floorEntry(commit.operation().key()));
+        } finally {
+            commit.close();
+        }
+    }
+
+    protected String floorKey(Commit<? extends FloorKey> commit) {
+        try {
+            return tree.floorKey(commit.operation().key());
+        } finally {
+            commit.close();
+        }
+    }
+
+    protected Map.Entry<String, Versioned<byte[]>> ceilingEntry(
+            Commit<CeilingEntry> commit) {
+        try {
+            return toVersionedEntry(
+                    tree.ceilingEntry(commit.operation().key()));
+        } finally {
+            commit.close();
+        }
+    }
+
+    protected String ceilingKey(Commit<CeilingKey> commit) {
+        try {
+            return tree.ceilingKey(commit.operation().key());
+        } finally {
+            commit.close();
+        }
+    }
+
+    protected String higherKey(Commit<HigherKey> commit) {
+        try {
+            return tree.higherKey(commit.operation().key());
+        } finally {
+            commit.close();
+        }
+    }
+
+    private Versioned<byte[]> toVersioned(TreeMapEntryValue value) {
+        return value == null ? null :
+                new Versioned<byte[]>(value.value(), value.version());
+    }
+
+    private Map.Entry<String, Versioned<byte[]>> toVersionedEntry(
+            Map.Entry<String, TreeMapEntryValue> entry) {
+        //FIXME is this the best type of entry to return?
+        return entry == null ? null : new SimpleImmutableEntry<>(
+                entry.getKey(), toVersioned(entry.getValue()));
+    }
+
+    private void publish(List<MapEvent<String, byte[]>> events) {
+        listeners.values().forEach(commit -> commit.session()
+                .publish(AtomixConsistentTreeMap.CHANGE_SUBJECT, events));
+    }
+
+    @Override
+    public void register(ServerSession session) {
+    }
+
+    @Override
+    public void unregister(ServerSession session) {
+        closeListener(session.id());
+    }
+
+    @Override
+    public void expire(ServerSession session) {
+        closeListener(session.id());
+    }
+
+    @Override
+    public void close(ServerSession session) {
+        closeListener(session.id());
+    }
+
+    private void closeListener(Long sessionId) {
+        Commit<? extends Listen> commit = listeners.remove(sessionId);
+        if (commit != null) {
+            commit.close();
+        }
+    }
+
+    private interface TreeMapEntryValue {
+
+        byte[] value();
+
+        long version();
+
+        void discard();
+    }
+
+    private class NonTransactionalCommit implements TreeMapEntryValue {
+        private final long version;
+        private final Commit<? extends UpdateAndGet> commit;
+
+        public NonTransactionalCommit(long version,
+                                      Commit<? extends UpdateAndGet> commit) {
+            this.version = version;
+            this.commit = commit;
+        }
+
+        @Override
+        public byte[] value() {
+            return commit.operation().value();
+        }
+
+        @Override
+        public long version() {
+            return version;
+        }
+
+        @Override
+        public void discard() {
+            commit.close();
+        }
+    }
+}
