Refactored primitive builders to consolidate methods into the base DistributedPrimitiveBuilder

Change-Id: I9a24117b41d1feeb5cf460c6adfa484aabcbb8c1
diff --git a/core/api/src/main/java/org/onosproject/store/primitives/DefaultDistributedSet.java b/core/api/src/main/java/org/onosproject/store/primitives/DefaultDistributedSet.java
new file mode 100644
index 0000000..e719fe9
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/store/primitives/DefaultDistributedSet.java
@@ -0,0 +1,153 @@
+/*
+ * Copyright 2015 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;
+
+import java.lang.reflect.Array;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+
+import org.onosproject.store.service.AsyncDistributedSet;
+import org.onosproject.store.service.DistributedSet;
+import org.onosproject.store.service.SetEventListener;
+import org.onosproject.store.service.StorageException;
+import org.onosproject.store.service.Synchronous;
+
+/**
+ * Implementation of {@link DistributedSet} that merely delegates to a {@link AsyncDistributedSet}
+ * and waits for the operation to complete.
+
+ * @param <E> set element type
+ */
+public class DefaultDistributedSet<E> extends Synchronous<AsyncDistributedSet<E>> implements DistributedSet<E> {
+
+    private final long operationTimeoutMillis;
+
+    private final AsyncDistributedSet<E> asyncSet;
+
+    public DefaultDistributedSet(AsyncDistributedSet<E> asyncSet, long operationTimeoutMillis) {
+        super(asyncSet);
+        this.asyncSet = asyncSet;
+        this.operationTimeoutMillis = operationTimeoutMillis;
+    }
+
+    @Override
+    public int size() {
+        return complete(asyncSet.size());
+    }
+
+    @Override
+    public boolean isEmpty() {
+        return complete(asyncSet.isEmpty());
+    }
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public boolean contains(Object o) {
+        return complete(asyncSet.contains((E) o));
+    }
+
+    @Override
+    public Iterator<E> iterator() {
+        return complete(asyncSet.getAsImmutableSet()).iterator();
+    }
+
+    @Override
+    public Object[] toArray() {
+        return complete(asyncSet.getAsImmutableSet()).stream().toArray();
+    }
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public <T> T[] toArray(T[] a) {
+        // TODO: Optimize this to only allocate a new array if the set size
+        // is larger than the array.length. If the set size is smaller than
+        // the array.length then copy the data into the array and set the
+        // last element in the array to be null.
+        final T[] resizedArray =
+                (T[]) Array.newInstance(a.getClass().getComponentType(), complete(asyncSet.getAsImmutableSet()).size());
+        return complete(asyncSet.getAsImmutableSet()).toArray(resizedArray);
+    }
+
+    @Override
+    public boolean add(E e) {
+        return complete(asyncSet.add(e));
+    }
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public boolean remove(Object o) {
+        return complete(asyncSet.remove((E) o));
+    }
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public boolean containsAll(Collection<?> c) {
+        return complete(asyncSet.containsAll((Collection<? extends E>) c));
+    }
+
+    @Override
+    public boolean addAll(Collection<? extends E> c) {
+        return complete(asyncSet.addAll(c));
+    }
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public boolean retainAll(Collection<?> c) {
+        return complete(asyncSet.retainAll((Collection<? extends E>) c));
+    }
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public boolean removeAll(Collection<?> c) {
+        return complete(asyncSet.removeAll((Collection<? extends E>) c));
+    }
+
+    @Override
+    public void clear() {
+        complete(asyncSet.clear());
+    }
+
+    @Override
+    public void addListener(SetEventListener<E> listener) {
+        complete(asyncSet.addListener(listener));
+    }
+
+    @Override
+    public void removeListener(SetEventListener<E> listener) {
+        complete(asyncSet.removeListener(listener));
+    }
+
+    private <T> T complete(CompletableFuture<T> future) {
+        try {
+            return future.get(operationTimeoutMillis, TimeUnit.MILLISECONDS);
+        } catch (InterruptedException e) {
+            Thread.currentThread().interrupt();
+            throw new StorageException.Interrupted();
+        } catch (TimeoutException e) {
+            throw new StorageException.Timeout();
+        } catch (ExecutionException e) {
+            if (e.getCause() instanceof StorageException) {
+                throw (StorageException) e.getCause();
+            } else {
+                throw new StorageException(e.getCause());
+            }
+        }
+    }
+}
diff --git a/core/api/src/main/java/org/onosproject/store/primitives/DistributedPrimitiveBuilder.java b/core/api/src/main/java/org/onosproject/store/primitives/DistributedPrimitiveBuilder.java
index 2792ac5..7ed8e81 100644
--- a/core/api/src/main/java/org/onosproject/store/primitives/DistributedPrimitiveBuilder.java
+++ b/core/api/src/main/java/org/onosproject/store/primitives/DistributedPrimitiveBuilder.java
@@ -24,7 +24,8 @@
  *
  * @param <T> distributed primitive type
  */
-public abstract class DistributedPrimitiveBuilder<T extends DistributedPrimitive> {
+public abstract class DistributedPrimitiveBuilder<B extends DistributedPrimitiveBuilder<B, T>,
+                                                  T extends DistributedPrimitive> {
 
     private DistributedPrimitive.Type type;
     private String name;
@@ -32,6 +33,8 @@
     private Serializer serializer;
     private boolean partitionsDisabled = false;
     private boolean meteringDisabled = false;
+    private boolean readOnly = false;
+    private boolean relaxedReadConsistency = false;
 
     public DistributedPrimitiveBuilder(DistributedPrimitive.Type type) {
         this.type = type;
@@ -43,9 +46,9 @@
      * @param name primitive name
      * @return this builder
      */
-    public DistributedPrimitiveBuilder<T> withName(String name) {
+    public B withName(String name) {
         this.name = name;
-        return this;
+        return (B) this;
     }
 
     /**
@@ -54,9 +57,9 @@
      * @param serializer serializer
      * @return this builder
      */
-    public DistributedPrimitiveBuilder<T> withSerializer(Serializer serializer) {
+    public B withSerializer(Serializer serializer) {
         this.serializer = serializer;
-        return this;
+        return (B) this;
     }
 
     /**
@@ -65,9 +68,9 @@
      * @param applicationId application identifier
      * @return this builder
      */
-    public DistributedPrimitiveBuilder<T> withApplicationId(ApplicationId applicationId) {
+    public B withApplicationId(ApplicationId applicationId) {
         this.applicationId = applicationId;
-        return this;
+        return (B) this;
     }
 
     /**
@@ -77,9 +80,9 @@
      * @return this builder
      */
     @Deprecated
-    public DistributedPrimitiveBuilder<T> withPartitionsDisabled() {
+    public B withPartitionsDisabled() {
         this.partitionsDisabled = true;
-        return this;
+        return (B) this;
     }
 
     /**
@@ -88,9 +91,27 @@
      * @return this builder
      */
     @Deprecated
-    public DistributedPrimitiveBuilder<T> withMeteringDisabled() {
+    public B withMeteringDisabled() {
         this.meteringDisabled = true;
-        return this;
+        return (B) this;
+    }
+
+    /**
+     * Disables state changing operations on the returned distributed primitive.
+     * @return this builder
+     */
+    public B withUpdatesDisabled() {
+        this.readOnly = true;
+        return (B) this;
+    }
+
+    /**
+     * Turns on relaxed consistency for read operations.
+     * @return this builder
+     */
+    public B withRelaxedReadConsistency() {
+        this.relaxedReadConsistency = true;
+        return (B) this;
     }
 
     /**
@@ -112,6 +133,24 @@
     }
 
     /**
+     * Returns if updates are disabled.
+     *
+     * @return {@code true} if yes; {@code false} otherwise
+     */
+    public final boolean readOnly() {
+        return readOnly;
+    }
+
+    /**
+     * Returns if consistency is relaxed for read operations.
+     *
+     * @return {@code true} if yes; {@code false} otherwise
+     */
+    public final boolean relaxedReadConsistency() {
+        return relaxedReadConsistency;
+    }
+
+    /**
      * Returns the serializer.
      *
      * @return serializer
diff --git a/core/api/src/main/java/org/onosproject/store/service/AsyncDistributedSet.java b/core/api/src/main/java/org/onosproject/store/service/AsyncDistributedSet.java
index 251ee14..3f1a215 100644
--- a/core/api/src/main/java/org/onosproject/store/service/AsyncDistributedSet.java
+++ b/core/api/src/main/java/org/onosproject/store/service/AsyncDistributedSet.java
@@ -19,6 +19,8 @@
 import java.util.Set;
 import java.util.concurrent.CompletableFuture;
 
+import org.onosproject.store.primitives.DefaultDistributedSet;
+
 /**
  * A distributed collection designed for holding unique elements.
  * <p>
@@ -122,6 +124,26 @@
      */
     CompletableFuture<Boolean> removeAll(Collection<? extends E> c);
 
+
+    /**
+     * Returns a new {@link DistributedSet} that is backed by this instance.
+     *
+     * @return new {@code DistributedSet} instance
+     */
+    default DistributedSet<E> asDistributedSet() {
+        return asDistributedSet(DistributedPrimitive.DEFAULT_OPERTATION_TIMEOUT_MILLIS);
+    }
+
+    /**
+     * Returns a new {@link DistributedSet} that is backed by this instance.
+     *
+     * @param timeoutMillis timeout duration for the returned DistributedSet operations
+     * @return new {@code DistributedSet} instance
+     */
+    default DistributedSet<E> asDistributedSet(long timeoutMillis) {
+        return new DefaultDistributedSet<>(this, timeoutMillis);
+    }
+
     /**
      * Returns the entries as a immutable set. The returned set is a snapshot and will not reflect new changes made to
      * this AsyncDistributedSet
diff --git a/core/api/src/main/java/org/onosproject/store/service/AtomicCounterBuilder.java b/core/api/src/main/java/org/onosproject/store/service/AtomicCounterBuilder.java
index 0728b20..29f7d73 100644
--- a/core/api/src/main/java/org/onosproject/store/service/AtomicCounterBuilder.java
+++ b/core/api/src/main/java/org/onosproject/store/service/AtomicCounterBuilder.java
@@ -20,7 +20,8 @@
 /**
  * Builder for AtomicCounter.
  */
-public abstract class AtomicCounterBuilder extends DistributedPrimitiveBuilder<AsyncAtomicCounter> {
+public abstract class AtomicCounterBuilder
+    extends DistributedPrimitiveBuilder<AtomicCounterBuilder, AsyncAtomicCounter> {
     public AtomicCounterBuilder() {
         super(DistributedPrimitive.Type.COUNTER);
     }
diff --git a/core/api/src/main/java/org/onosproject/store/service/AtomicValueBuilder.java b/core/api/src/main/java/org/onosproject/store/service/AtomicValueBuilder.java
index 81c484f..ba85511 100644
--- a/core/api/src/main/java/org/onosproject/store/service/AtomicValueBuilder.java
+++ b/core/api/src/main/java/org/onosproject/store/service/AtomicValueBuilder.java
@@ -22,7 +22,8 @@
  *
  * @param <V> atomic value type
  */
-public abstract class AtomicValueBuilder<V> extends DistributedPrimitiveBuilder<AsyncAtomicValue<V>> {
+public abstract class AtomicValueBuilder<V>
+    extends DistributedPrimitiveBuilder<AtomicValueBuilder<V>, AsyncAtomicValue<V>> {
 
     public AtomicValueBuilder() {
         super(DistributedPrimitive.Type.VALUE);
diff --git a/core/api/src/main/java/org/onosproject/store/service/ConsistentMapBuilder.java b/core/api/src/main/java/org/onosproject/store/service/ConsistentMapBuilder.java
index 466c8f1..060aa8f 100644
--- a/core/api/src/main/java/org/onosproject/store/service/ConsistentMapBuilder.java
+++ b/core/api/src/main/java/org/onosproject/store/service/ConsistentMapBuilder.java
@@ -15,7 +15,7 @@
  */
 package org.onosproject.store.service;
 
-import org.onosproject.core.ApplicationId;
+import org.onosproject.store.primitives.DistributedPrimitiveBuilder;
 
 /**
  * Builder for {@link ConsistentMap} instances.
@@ -23,115 +23,32 @@
  * @param <K> type for map key
  * @param <V> type for map value
  */
-public interface ConsistentMapBuilder<K, V> {
+public abstract class ConsistentMapBuilder<K, V>
+    extends DistributedPrimitiveBuilder<ConsistentMapBuilder<K, V>, ConsistentMap<K, V>> {
+
+    private boolean purgeOnUninstall = false;
+
+    public ConsistentMapBuilder() {
+        super(DistributedPrimitive.Type.CONSISTENT_MAP);
+    }
 
     /**
-     * Sets the name of the map.
-     * <p>
-     * Each map is identified by a unique map name. Different instances with the same name are all backed by the
-     * same backend state.
-     * </p>
-     * <p>
-     * <b>Note:</b> This is a mandatory parameter.
-     * </p>
+     * Clears map contents when the owning application is uninstalled.
      *
-     * @param name name of the map
-     * @return this ConsistentMapBuilder
+     * return this builder
      */
-    ConsistentMapBuilder<K, V> withName(String name);
+    public ConsistentMapBuilder<K, V> withPurgeOnUninstall() {
+        purgeOnUninstall = true;
+        return this;
+    }
 
     /**
-     * Sets the identifier of the application that owns this map instance.
-     * <p>
-     * Note: If {@code purgeOnUninstall} option is enabled, applicationId
-     * must be specified.
-     * </p>
-     *
-     * @param id applicationId owning the consistent map
-     * @return this ConsistentMapBuilder
+     * Returns if map entries need to be cleared when owning application is uninstalled.
+     * @return {@code true} if yes; {@code false} otherwise.
      */
-    ConsistentMapBuilder<K, V> withApplicationId(ApplicationId id);
-
-    /**
-     * Sets a serializer that can be used to serialize
-     * both the keys and values inserted into the map. The serializer
-     * builder should be pre-populated with any classes that will be
-     * put into the map.
-     * <p>
-     * Note: This is a mandatory parameter.
-     * </p>
-     *
-     * @param serializer serializer
-     * @return this ConsistentMapBuilder
-     */
-    ConsistentMapBuilder<K, V> withSerializer(Serializer serializer);
-
-    /**
-     * Disables distribution of map entries across multiple database partitions.
-     * <p>
-     * When partitioning is disabled, the returned map will have a single partition
-     * that spans the entire cluster. Furthermore, the changes made to the map are
-     * ephemeral and do not survive a full cluster restart.
-     * </p>
-     * <p>
-     * Disabling partitions is more appropriate when the returned map is used for
-     * coordination activities such as leader election and not for long term data persistence.
-     * </p>
-     * <p>
-     * Note: By default partitions are enabled and entries in the map are durable.
-     * </p>
-     * @return this ConsistentMapBuilder
-     */
-    ConsistentMapBuilder<K, V> withPartitionsDisabled();
-
-    /**
-     * Disables map updates.
-     * <p>
-     * Attempt to update the built map will throw {@code UnsupportedOperationException}.
-     *
-     * @return this ConsistentMapBuilder
-     */
-    ConsistentMapBuilder<K, V> withUpdatesDisabled();
-
-    /**
-     * Purges map contents when the application owning the map is uninstalled.
-     * <p>
-     * When this option is enabled, the caller must provide a applicationId via
-     * the {@code withAppliationId} builder method.
-     * <p>
-     * By default map entries will NOT be purged when owning application is uninstalled.
-     *
-     * @return this ConsistentMapBuilder
-     */
-    ConsistentMapBuilder<K, V> withPurgeOnUninstall();
-
-    /**
-     * Instantiates Metering service to gather usage and performance metrics.
-     * By default, usage data will be stored.
-     *
-     * @return this ConsistentMapBuilder
-     */
-    ConsistentMapBuilder<K, V> withMeteringDisabled();
-
-    /**
-     * Provides weak consistency for map gets.
-     * <p>
-     * While this can lead to improved read performance, it can also make the behavior
-     * heard to reason. Only turn this on if you know what you are doing. By default
-     * reads are strongly consistent.
-     *
-     * @return this ConsistentMapBuilder
-     */
-    ConsistentMapBuilder<K, V> withRelaxedReadConsistency();
-
-    /**
-     * Builds an consistent map based on the configuration options
-     * supplied to this builder.
-     *
-     * @return new consistent map
-     * @throws java.lang.RuntimeException if a mandatory parameter is missing
-     */
-    ConsistentMap<K, V> build();
+    public boolean purgeOnUninstall() {
+        return purgeOnUninstall;
+    }
 
     /**
      * Builds an async consistent map based on the configuration options
@@ -140,5 +57,5 @@
      * @return new async consistent map
      * @throws java.lang.RuntimeException if a mandatory parameter is missing
      */
-    AsyncConsistentMap<K, V> buildAsyncMap();
+    public abstract AsyncConsistentMap<K, V> buildAsyncMap();
 }
diff --git a/core/api/src/main/java/org/onosproject/store/service/DistributedSetBuilder.java b/core/api/src/main/java/org/onosproject/store/service/DistributedSetBuilder.java
index 09ba794..d05182a 100644
--- a/core/api/src/main/java/org/onosproject/store/service/DistributedSetBuilder.java
+++ b/core/api/src/main/java/org/onosproject/store/service/DistributedSetBuilder.java
@@ -15,127 +15,37 @@
  */
 package org.onosproject.store.service;
 
-import org.onosproject.core.ApplicationId;
+import org.onosproject.store.primitives.DistributedPrimitiveBuilder;
 
 /**
  * Builder for distributed set.
  *
  * @param <E> type set elements.
  */
-public interface DistributedSetBuilder<E> {
+public abstract class DistributedSetBuilder<E> extends DistributedPrimitiveBuilder<DistributedSetBuilder<E>,
+                                                                                   AsyncDistributedSet<E>> {
+
+    private boolean purgeOnUninstall = false;
+
+    public DistributedSetBuilder() {
+        super(DistributedPrimitive.Type.SET);
+    }
 
     /**
-     * Sets the name of the set.
-     * <p>
-     * Each set is identified by a unique name.
-     * </p>
-     * <p>
-     * Note: This is a mandatory parameter.
-     * </p>
+     * Enables clearing set contents when the owning application is uninstalled.
      *
-     * @param name name of the set
-     * @return this DistributedSetBuilder
+     * return this builder
      */
-    DistributedSetBuilder<E> withName(String name);
+    public DistributedSetBuilder<E> withPurgeOnUninstall() {
+        purgeOnUninstall = true;
+        return this;
+    }
 
     /**
-     * Sets the owner applicationId for the set.
-     * <p>
-     * Note: If {@code purgeOnUninstall} option is enabled, applicationId
-     * must be specified.
-     * </p>
-     *
-     * @param id applicationId owning the set
-     * @return this DistributedSetBuilder
+     * Returns if set contents need to be cleared when owning application is uninstalled.
+     * @return {@code true} if yes; {@code false} otherwise.
      */
-    DistributedSetBuilder<E> withApplicationId(ApplicationId id);
-
-    /**
-     * Sets a serializer that can be used to serialize
-     * the elements add to the set. The serializer
-     * builder should be pre-populated with any classes that will be
-     * put into the set.
-     * <p>
-     * Note: This is a mandatory parameter.
-     * </p>
-     *
-     * @param serializer serializer
-     * @return this DistributedSetBuilder
-     */
-    DistributedSetBuilder<E> withSerializer(Serializer serializer);
-
-    /**
-     * Disables set updates.
-     * <p>
-     * Attempt to update the built set will throw {@code UnsupportedOperationException}.
-     *
-     * @return this DistributedSetBuilder
-     */
-    DistributedSetBuilder<E> withUpdatesDisabled();
-
-    /**
-     * Provides weak consistency for set reads.
-     * <p>
-     * While this can lead to improved read performance, it can also make the behavior
-     * heard to reason. Only turn this on if you know what you are doing. By default
-     * reads are strongly consistent.
-     *
-     * @return this DistributedSetBuilder
-     */
-    DistributedSetBuilder<E> withRelaxedReadConsistency();
-
-    /**
-     * Disables distribution of set entries across multiple database partitions.
-     * <p>
-     * When partitioning is disabled, the returned set will have a single partition
-     * that spans the entire cluster. Furthermore, the changes made to the set are
-     * ephemeral and do not survive a full cluster restart.
-     * </p>
-     * <p>
-     * Disabling partitions is more appropriate when the returned set is used for
-     * simple coordination activities and not for long term data persistence.
-     * </p>
-     * <p>
-     * Note: By default partitions are enabled and entries in the set are durable.
-     * </p>
-     * @return this DistributedSetBuilder
-     */
-    DistributedSetBuilder<E> withPartitionsDisabled();
-
-    /**
-     * Instantiate Metrics service to gather usage and performance metrics.
-     * By default usage information is enabled
-     * @return this DistributedSetBuilder
-     */
-    DistributedSetBuilder<E> withMeteringDisabled();
-
-    /**
-     * Purges set contents when the application owning the set is uninstalled.
-     * <p>
-     * When this option is enabled, the caller must provide a applicationId via
-     * the {@code withAppliationId} builder method.
-     * <p>
-     * By default set contents will NOT be purged when owning application is uninstalled.
-     *
-     * @return this DistributedSetBuilder
-     */
-    DistributedSetBuilder<E> withPurgeOnUninstall();
-
-    /**
-     * Builds an set based on the configuration options
-     * supplied to this builder.
-     *
-     * @return new set
-     * @throws java.lang.RuntimeException if a mandatory parameter is missing
-     */
-    DistributedSet<E> build();
-
-    /**
-     * Builds an {@link AsyncDistributedSet async set} based on the configuration options
-     * supplied to this builder.
-     *
-     * @return new AsyncDistributedSet
-     * @throws java.lang.RuntimeException if a mandatory parameter is missing
-     */
-    AsyncDistributedSet<E> buildAsyncSet();
+    public boolean purgeOnUninstall() {
+        return purgeOnUninstall;
+    }
 }
diff --git a/core/api/src/main/java/org/onosproject/store/service/TransactionContextBuilder.java b/core/api/src/main/java/org/onosproject/store/service/TransactionContextBuilder.java
index 8a43995..2242bad 100644
--- a/core/api/src/main/java/org/onosproject/store/service/TransactionContextBuilder.java
+++ b/core/api/src/main/java/org/onosproject/store/service/TransactionContextBuilder.java
@@ -20,7 +20,8 @@
 /**
  * Abstract base class for a transaction context builder.
  */
-public abstract class TransactionContextBuilder extends DistributedPrimitiveBuilder<TransactionContext> {
+public abstract class TransactionContextBuilder
+    extends DistributedPrimitiveBuilder<TransactionContextBuilder, TransactionContext> {
 
     public TransactionContextBuilder() {
         super(DistributedPrimitive.Type.TRANSACTION_CONTEXT);
diff --git a/core/api/src/test/java/org/onosproject/store/service/TestConsistentMap.java b/core/api/src/test/java/org/onosproject/store/service/TestConsistentMap.java
index f7857ad..0efdd4a 100644
--- a/core/api/src/test/java/org/onosproject/store/service/TestConsistentMap.java
+++ b/core/api/src/test/java/org/onosproject/store/service/TestConsistentMap.java
@@ -29,7 +29,6 @@
 import java.util.function.Predicate;
 import java.util.stream.Collectors;
 
-import org.onosproject.core.ApplicationId;
 import org.onosproject.store.primitives.ConsistentMapBackedJavaMap;
 
 import com.google.common.base.Objects;
@@ -293,53 +292,11 @@
         return new Builder();
     }
 
-    public static class Builder<K, V> implements ConsistentMapBuilder<K, V> {
-        String mapName = "map";
-
-        @Override
-        public ConsistentMapBuilder<K, V> withName(String mapName) {
-            this.mapName = mapName;
-            return this;
-        }
-
-        @Override
-        public ConsistentMapBuilder<K, V> withApplicationId(ApplicationId id) {
-            return this;
-        }
-
-        @Override
-        public ConsistentMapBuilder<K, V> withSerializer(Serializer serializer) {
-            return this;
-        }
-
-        @Override
-        public ConsistentMapBuilder<K, V> withPartitionsDisabled() {
-            return this;
-        }
-
-        @Override
-        public ConsistentMapBuilder<K, V> withUpdatesDisabled() {
-            return this;
-        }
-
-        @Override
-        public ConsistentMapBuilder<K, V> withPurgeOnUninstall() {
-            return this;
-        }
-
-        @Override
-        public ConsistentMapBuilder<K, V> withRelaxedReadConsistency() {
-            return this;
-        }
-
-        @Override
-        public ConsistentMapBuilder<K, V> withMeteringDisabled() {
-            return this;
-        }
+    public static class Builder<K, V> extends ConsistentMapBuilder<K, V> {
 
         @Override
         public ConsistentMap<K, V> build() {
-            return new TestConsistentMap<>(mapName);
+            return new TestConsistentMap<>(name());
         }
 
         @Override