You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@datasketches.apache.org by le...@apache.org on 2021/08/15 23:30:55 UTC

[datasketches-memory] branch MajorRefactorAndFix created (now b4b17f1)

This is an automated email from the ASF dual-hosted git repository.

leerho pushed a change to branch MajorRefactorAndFix
in repository https://gitbox.apache.org/repos/asf/datasketches-memory.git.


      at b4b17f1  Interim commit

This branch includes the following new commits:

     new b4b17f1  Interim commit

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@datasketches.apache.org
For additional commands, e-mail: commits-help@datasketches.apache.org


[datasketches-memory] 01/01: Interim commit

Posted by le...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

leerho pushed a commit to branch MajorRefactorAndFix
in repository https://gitbox.apache.org/repos/asf/datasketches-memory.git

commit b4b17f1fda3ba78515bc8dcbdfd4aea8c00d2772
Author: Lee Rhodes <le...@users.noreply.github.com>
AuthorDate: Sun Aug 15 16:30:01 2021 -0700

    Interim commit
---
 .../memory/test/AllocateDirectMemoryTest.java      |  22 +-
 .../test/AllocateDirectWritableMapMemoryTest.java  |  12 +-
 .../datasketches/memory/test/BaseBufferTest.java   |   8 +-
 .../datasketches/memory/test/Buffer2Test.java      |   2 +-
 .../memory/test/BufferReadWriteSafetyTest.java     |   2 +-
 .../memory/test/DruidIssue11544Test.java           |   4 +-
 .../test/ExampleMemoryRequestServerTest.java       |  48 +--
 .../datasketches/memory/test/LeafImplTest.java     |  55 ++--
 .../memory/test/MemoryReadWriteSafetyTest.java     |   2 +-
 .../datasketches/memory/test/MemoryTest.java       |  93 +++---
 .../memory/test/NativeWritableBufferImplTest.java  |  26 +-
 .../memory/test/NativeWritableMemoryImplTest.java  |   4 +-
 .../datasketches/memory/test/SpecificLeafTest.java |  57 ++--
 .../memory/test/WritableMemoryTest.java            |   8 +-
 .../org/apache/datasketches/memory/BaseState.java  |   2 +-
 .../org/apache/datasketches/memory/Buffer.java     |  63 ++--
 .../memory/DefaultMemoryRequestServer.java         |  10 +-
 .../org/apache/datasketches/memory/Handle.java     |   2 +-
 .../org/apache/datasketches/memory/Memory.java     | 296 +++++++----------
 .../datasketches/memory/MemoryRequestServer.java   |  15 +-
 .../memory/{internal => }/ReadOnlyException.java   |   4 +-
 .../apache/datasketches/memory/WritableBuffer.java |  81 +++--
 .../apache/datasketches/memory/WritableMemory.java | 355 +++++++++++----------
 .../memory/internal/AllocateDirectWritableMap.java |   1 +
 .../internal/BBNonNativeWritableBufferImpl.java    |  40 ++-
 .../internal/BBNonNativeWritableMemoryImpl.java    |  25 +-
 .../memory/internal/BBWritableBufferImpl.java      |  40 ++-
 .../memory/internal/BBWritableMemoryImpl.java      |  25 +-
 .../memory/internal/BaseBufferImpl.java            |   1 +
 .../memory/internal/BaseStateImpl.java             |  37 ++-
 .../memory/internal/BaseWritableBufferImpl.java    | 107 ++++---
 .../memory/internal/BaseWritableMemoryImpl.java    | 116 ++-----
 .../datasketches/memory/internal/BufferImpl.java   | 162 ----------
 .../DirectNonNativeWritableBufferImpl.java         |  41 +--
 .../DirectNonNativeWritableMemoryImpl.java         |  25 +-
 .../memory/internal/DirectWritableBufferImpl.java  |  41 +--
 .../memory/internal/DirectWritableMemoryImpl.java  |  25 +-
 .../internal/HeapNonNativeWritableBufferImpl.java  |  37 ++-
 .../internal/HeapNonNativeWritableMemoryImpl.java  |  26 +-
 .../memory/internal/HeapWritableBufferImpl.java    |  37 ++-
 .../memory/internal/HeapWritableMemoryImpl.java    |  28 +-
 .../internal/MapNonNativeWritableBufferImpl.java   |  34 +-
 .../internal/MapNonNativeWritableMemoryImpl.java   |  19 +-
 .../memory/internal/MapWritableBufferImpl.java     |  34 +-
 .../memory/internal/MapWritableMemoryImpl.java     |  19 +-
 .../datasketches/memory/internal/MemoryImpl.java   | 225 -------------
 .../memory/internal/NativeWritableBufferImpl.java  |   8 +-
 .../memory/internal/NativeWritableMemoryImpl.java  |   4 +-
 .../internal/NonNativeWritableBufferImpl.java      |   8 +-
 .../internal/NonNativeWritableMemoryImpl.java      |   4 +-
 .../apache/datasketches/memory/internal/Utf8.java  |   6 +-
 .../apache/datasketches/memory/internal/Util.java  |  19 +-
 .../memory/internal/WritableBufferImpl.java        | 170 ----------
 .../memory/internal/WritableMapHandleImpl.java     |   3 +-
 .../memory/internal/WritableMemoryImpl.java        | 254 ---------------
 55 files changed, 1000 insertions(+), 1792 deletions(-)

diff --git a/datasketches-memory-java8-tests/src/test/java/org/apache/datasketches/memory/test/AllocateDirectMemoryTest.java b/datasketches-memory-java8-tests/src/test/java/org/apache/datasketches/memory/test/AllocateDirectMemoryTest.java
index 99d03e7..fddab0b 100644
--- a/datasketches-memory-java8-tests/src/test/java/org/apache/datasketches/memory/test/AllocateDirectMemoryTest.java
+++ b/datasketches-memory-java8-tests/src/test/java/org/apache/datasketches/memory/test/AllocateDirectMemoryTest.java
@@ -21,10 +21,10 @@ package org.apache.datasketches.memory.test;
 
 import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.assertFalse;
-import static org.testng.Assert.assertNotNull;
 import static org.testng.Assert.fail;
 
 import org.apache.datasketches.memory.BaseState;
+import org.apache.datasketches.memory.DefaultMemoryRequestServer;
 import org.apache.datasketches.memory.MemoryRequestServer;
 import org.apache.datasketches.memory.WritableHandle;
 import org.apache.datasketches.memory.WritableMemory;
@@ -72,8 +72,13 @@ public class AllocateDirectMemoryTest {
 
       int longs2 = 64;
       int bytes2 = longs2 << 3;
-      MemoryRequestServer memReqSvr = origWmem.getMemoryRequestServer();
-      WritableMemory newWmem = memReqSvr.request(bytes2);
+      MemoryRequestServer memReqSvr;
+      if (BaseState.defaultMemReqSvr == null) {
+        memReqSvr = new DefaultMemoryRequestServer();
+      } else {
+        memReqSvr = origWmem.getMemoryRequestServer();
+      }
+      WritableMemory newWmem = memReqSvr.request(origWmem, bytes2);
       assertFalse(newWmem.isDirect()); //on heap by default
       for (int i = 0; i < longs2; i++) {
           newWmem.putLong(i << 3, i);
@@ -86,17 +91,8 @@ public class AllocateDirectMemoryTest {
   }
 
   @Test
-  public void checkNullMemoryRequestServer() throws Exception {
-    try (WritableHandle wh = WritableMemory.allocateDirect(128, Util.nativeByteOrder, null)) {
-      WritableMemory wmem = wh.getWritable();
-      assertNotNull(wmem.getMemoryRequestServer());
-    }
-  }
-
-
-  @Test
   public void checkNonNativeDirect() throws Exception {
-    try (WritableHandle h = WritableMemory.allocateDirect(128, Util.nonNativeByteOrder, null)) {
+    try (WritableHandle h = WritableMemory.allocateDirect(128, Util.NON_NATIVE_BYTE_ORDER, null)) {
       WritableMemory wmem = h.getWritable();
       wmem.putChar(0, (char) 1);
       assertEquals(wmem.getByte(1), (byte) 1);
diff --git a/datasketches-memory-java8-tests/src/test/java/org/apache/datasketches/memory/test/AllocateDirectWritableMapMemoryTest.java b/datasketches-memory-java8-tests/src/test/java/org/apache/datasketches/memory/test/AllocateDirectWritableMapMemoryTest.java
index 8bd42ed..f7400c9 100644
--- a/datasketches-memory-java8-tests/src/test/java/org/apache/datasketches/memory/test/AllocateDirectWritableMapMemoryTest.java
+++ b/datasketches-memory-java8-tests/src/test/java/org/apache/datasketches/memory/test/AllocateDirectWritableMapMemoryTest.java
@@ -41,10 +41,10 @@ import java.nio.ByteOrder;
 import org.apache.datasketches.memory.BaseState;
 import org.apache.datasketches.memory.MapHandle;
 import org.apache.datasketches.memory.Memory;
+import org.apache.datasketches.memory.ReadOnlyException;
 import org.apache.datasketches.memory.WritableHandle;
 import org.apache.datasketches.memory.WritableMapHandle;
 import org.apache.datasketches.memory.WritableMemory;
-import org.apache.datasketches.memory.internal.ReadOnlyException;
 import org.apache.datasketches.memory.internal.Util;
 import org.testng.annotations.AfterClass;
 import org.testng.annotations.BeforeClass;
@@ -147,7 +147,7 @@ public class AllocateDirectWritableMapMemoryTest {
     file.deleteOnExit();  //comment out if you want to examine the file.
 
     final long bytes = 8;
-    try (WritableMapHandle h = WritableMemory.writableMap(file, 0L, bytes, Util.nonNativeByteOrder)) {
+    try (WritableMapHandle h = WritableMemory.writableMap(file, 0L, bytes, Util.NON_NATIVE_BYTE_ORDER)) {
       WritableMemory wmem = h.getWritable();
       wmem.putChar(0, (char) 1);
       assertEquals(wmem.getByte(1), (byte) 1);
@@ -166,15 +166,17 @@ public class AllocateDirectWritableMapMemoryTest {
   public void simpleMap2() throws Exception {
     File file = getResourceFile("GettysburgAddress.txt");
     assertTrue(isFileReadOnly(file));
-    try (WritableMapHandle rh = WritableMemory.writableMap(file)) { //throws
+    try (WritableMapHandle rh =
+        WritableMemory.writableMap(file)) { //throws
       //
     }
   }
 
-  @Test(expectedExceptions = IllegalArgumentException.class)
+  @Test(expectedExceptions = ReadOnlyException.class)
   public void checkOverLength() throws Exception  {
     File file = getResourceFile("GettysburgAddress.txt");
-    try (WritableMapHandle rh = WritableMemory.writableMap(file, 0, 1 << 20, ByteOrder.nativeOrder())) {
+    try (WritableMapHandle rh =
+        WritableMemory.writableMap(file, 0, 1 << 20, ByteOrder.nativeOrder())) {
       //
     } catch (IOException e) {
       throw new RuntimeException(e);
diff --git a/datasketches-memory-java8-tests/src/test/java/org/apache/datasketches/memory/test/BaseBufferTest.java b/datasketches-memory-java8-tests/src/test/java/org/apache/datasketches/memory/test/BaseBufferTest.java
index 659bdf4..b20831d 100644
--- a/datasketches-memory-java8-tests/src/test/java/org/apache/datasketches/memory/test/BaseBufferTest.java
+++ b/datasketches-memory-java8-tests/src/test/java/org/apache/datasketches/memory/test/BaseBufferTest.java
@@ -21,9 +21,9 @@ package org.apache.datasketches.memory.test;
 
 import static org.testng.Assert.fail;
 
-import org.apache.datasketches.memory.WritableHandle;
 import org.apache.datasketches.memory.Buffer;
 import org.apache.datasketches.memory.Memory;
+import org.apache.datasketches.memory.WritableHandle;
 import org.apache.datasketches.memory.WritableMemory;
 import org.testng.annotations.Test;
 
@@ -82,7 +82,9 @@ public class BaseBufferTest {
       wmem = hand.getWritable();
       buf = wmem.asBuffer();
     }
-    @SuppressWarnings("unused")
-    Memory mem = buf.asMemory();
+    try {
+      @SuppressWarnings("unused")
+      Memory mem = buf.asMemory();
+    } catch (AssertionError ae) { }
   }
 }
diff --git a/datasketches-memory-java8-tests/src/test/java/org/apache/datasketches/memory/test/Buffer2Test.java b/datasketches-memory-java8-tests/src/test/java/org/apache/datasketches/memory/test/Buffer2Test.java
index ad2b876..11ca0f2 100644
--- a/datasketches-memory-java8-tests/src/test/java/org/apache/datasketches/memory/test/Buffer2Test.java
+++ b/datasketches-memory-java8-tests/src/test/java/org/apache/datasketches/memory/test/Buffer2Test.java
@@ -30,9 +30,9 @@ import java.nio.ByteOrder;
 import org.apache.datasketches.memory.Buffer;
 import org.apache.datasketches.memory.DefaultMemoryRequestServer;
 import org.apache.datasketches.memory.Memory;
+import org.apache.datasketches.memory.ReadOnlyException;
 import org.apache.datasketches.memory.WritableBuffer;
 import org.apache.datasketches.memory.WritableMemory;
-import org.apache.datasketches.memory.internal.ReadOnlyException;
 import org.testng.annotations.Test;
 
 @SuppressWarnings("javadoc")
diff --git a/datasketches-memory-java8-tests/src/test/java/org/apache/datasketches/memory/test/BufferReadWriteSafetyTest.java b/datasketches-memory-java8-tests/src/test/java/org/apache/datasketches/memory/test/BufferReadWriteSafetyTest.java
index de56ca3..91e0465 100644
--- a/datasketches-memory-java8-tests/src/test/java/org/apache/datasketches/memory/test/BufferReadWriteSafetyTest.java
+++ b/datasketches-memory-java8-tests/src/test/java/org/apache/datasketches/memory/test/BufferReadWriteSafetyTest.java
@@ -22,7 +22,7 @@ package org.apache.datasketches.memory.test;
 import java.nio.ByteBuffer;
 
 import org.apache.datasketches.memory.Buffer;
-import org.apache.datasketches.memory.internal.ReadOnlyException;
+import org.apache.datasketches.memory.ReadOnlyException;
 import org.apache.datasketches.memory.WritableBuffer;
 import org.apache.datasketches.memory.WritableMemory;
 import org.testng.annotations.Test;
diff --git a/datasketches-memory-java8-tests/src/test/java/org/apache/datasketches/memory/test/DruidIssue11544Test.java b/datasketches-memory-java8-tests/src/test/java/org/apache/datasketches/memory/test/DruidIssue11544Test.java
index b5e7e63..f4ffbee 100644
--- a/datasketches-memory-java8-tests/src/test/java/org/apache/datasketches/memory/test/DruidIssue11544Test.java
+++ b/datasketches-memory-java8-tests/src/test/java/org/apache/datasketches/memory/test/DruidIssue11544Test.java
@@ -27,6 +27,7 @@ import static org.testng.Assert.assertTrue;
 import java.nio.ByteBuffer;
 import java.nio.ByteOrder;
 
+import org.apache.datasketches.memory.DefaultMemoryRequestServer;
 import org.apache.datasketches.memory.MemoryRequestServer;
 import org.apache.datasketches.memory.WritableMemory;
 import org.testng.annotations.Test;
@@ -65,9 +66,10 @@ public class DruidIssue11544Test {
 
     //Request Bigger Memory
     MemoryRequestServer svr = mem.getMemoryRequestServer();
+    if (svr == null) { svr = new DefaultMemoryRequestServer(); }
     assertNotNull(svr); //before the fix, this was null.
 
-    WritableMemory newMem = svr.request(initialMemSize * 2);
+    WritableMemory newMem = svr.request(mem, initialMemSize * 2);
 
     //Confirm that newMem is on the heap (the default) and 2X size
     assertFalse(newMem.isDirect());
diff --git a/datasketches-memory-java8-tests/src/test/java/org/apache/datasketches/memory/test/ExampleMemoryRequestServerTest.java b/datasketches-memory-java8-tests/src/test/java/org/apache/datasketches/memory/test/ExampleMemoryRequestServerTest.java
index a89a37e..604222d 100644
--- a/datasketches-memory-java8-tests/src/test/java/org/apache/datasketches/memory/test/ExampleMemoryRequestServerTest.java
+++ b/datasketches-memory-java8-tests/src/test/java/org/apache/datasketches/memory/test/ExampleMemoryRequestServerTest.java
@@ -37,21 +37,23 @@ import org.testng.annotations.Test;
 public class ExampleMemoryRequestServerTest {
 
   /**
-   * In this version all of the memory allocations are done through the MemoryRequestServer
+   * This version is without a TWR block.all of the memory allocations are done through the MemoryRequestServer
    * and each is closed by the MemoryClient when it is done with each.
    */
+  @SuppressWarnings("resource")
   @Test
   public void checkExampleMemoryRequestServer1() {
     int bytes = 8;
     ExampleMemoryRequestServer svr = new ExampleMemoryRequestServer();
-    WritableMemory wMem = svr.request(bytes);
+    WritableMemory memStart = WritableMemory.allocateDirect(8).getWritable();
+    WritableMemory wMem = svr.request(memStart, bytes);
     MemoryClient client = new MemoryClient(wMem);
     client.process();
     svr.cleanup();
   }
 
   /**
-   * In this version the first memory allocation is done separately.
+   * In this version the first memory allocation is done up front in a TWR block.
    * And then the MemoryClient allocates new memories as needed, which are then closed
    * by the MemoryClient when it is done with the new memory allocations.
    * The initial allocation stays open until the end where it is closed at the end of the
@@ -63,10 +65,10 @@ public class ExampleMemoryRequestServerTest {
     int bytes = 8;
     ExampleMemoryRequestServer svr = new ExampleMemoryRequestServer();
     try (WritableHandle handle = WritableMemory.allocateDirect(bytes, ByteOrder.nativeOrder(), svr)) {
-      WritableMemory wMem = handle.getWritable();
-      MemoryClient client = new MemoryClient(wMem);
+      WritableMemory memStart = handle.getWritable();
+      MemoryClient client = new MemoryClient(memStart);
       client.process();
-      svr.cleanup();
+      svr.cleanup(); //just to be sure all are closed.
     }
   }
 
@@ -88,9 +90,9 @@ public class ExampleMemoryRequestServerTest {
     WritableMemory smallMem;
     MemoryRequestServer svr;
 
-    MemoryClient(WritableMemory wmem) {
-      smallMem = wmem;
-      svr = wmem.getMemoryRequestServer();
+    MemoryClient(WritableMemory memStart) {
+      smallMem = memStart;
+      svr = memStart.getMemoryRequestServer();
     }
 
     void process() {
@@ -98,7 +100,7 @@ public class ExampleMemoryRequestServerTest {
       smallMem.fill((byte) 1);                //fill it, but not big enough
       println(smallMem.toHexString("Small", 0, (int)cap1));
 
-      WritableMemory bigMem = svr.request(2 * cap1); //get bigger mem
+      WritableMemory bigMem = svr.request(smallMem, 2 * cap1); //get bigger mem
       long cap2 = bigMem.getCapacity();
       smallMem.copyTo(0, bigMem, 0, cap1);    //copy data from small to big
       svr.requestClose(smallMem, bigMem);     //done with smallMem, release it
@@ -106,7 +108,7 @@ public class ExampleMemoryRequestServerTest {
       bigMem.fill(cap1, cap1, (byte) 2);      //fill the rest of bigMem, still not big enough
       println(bigMem.toHexString("Big", 0, (int)cap2));
 
-      WritableMemory giantMem = svr.request(2 * cap2); //get giant mem
+      WritableMemory giantMem = svr.request(bigMem, 2 * cap2); //get giant mem
       long cap3 = giantMem.getCapacity();
       bigMem.copyTo(0, giantMem, 0, cap2);    //copy data from small to big
       svr.requestClose(bigMem, giantMem);     //done with bigMem, release it
@@ -119,15 +121,17 @@ public class ExampleMemoryRequestServerTest {
 
   /**
    * This example MemoryRequestServer is simplistic but demonstrates one of many ways to
-   * possibly manage the continuous requests for larger memory.
+   * possibly manage the continuous requests for larger memory and to track the associations between
+   * handles and their associated memory.
    */
   public static class ExampleMemoryRequestServer implements MemoryRequestServer {
     IdentityHashMap<WritableMemory, WritableHandle> map = new IdentityHashMap<>();
 
     @SuppressWarnings("resource")
     @Override
-    public WritableMemory request(long capacityBytes) {
-     WritableHandle handle = WritableMemory.allocateDirect(capacityBytes, ByteOrder.nativeOrder(), this);
+    public WritableMemory request(WritableMemory currentWMem, long capacityBytes) {
+     ByteOrder order = currentWMem.getTypeByteOrder();
+     WritableHandle handle = WritableMemory.allocateDirect(capacityBytes, order, this);
      WritableMemory wmem = handle.getWritable();
      map.put(wmem, handle); //We track the newly allocated memory and its handle.
      return wmem;
@@ -137,14 +141,12 @@ public class ExampleMemoryRequestServerTest {
     @Override
     //here we actually release it, in reality it might be a lot more complex.
     public void requestClose(WritableMemory memToRelease, WritableMemory newMemory) {
-      if (memToRelease != null) {
-        WritableHandle handle = map.get(memToRelease);
-        if (handle != null && handle.getWritable() == memToRelease) {
-          try {
-            handle.close();
-          } catch (Exception e) {
-            throw new RuntimeException(e);
-          }
+      WritableHandle handle = map.get(memToRelease);
+      if (handle != null && handle.getWritable() == memToRelease) {
+        try {
+          handle.close();
+        } catch (Exception e) {
+          throw new RuntimeException(e);
         }
       }
     }
@@ -156,7 +158,7 @@ public class ExampleMemoryRequestServerTest {
           v.close();
         } catch (Exception e) {
           throw new RuntimeException(e);
-        } //harmless
+        }
       });
     }
   }
diff --git a/datasketches-memory-java8-tests/src/test/java/org/apache/datasketches/memory/test/LeafImplTest.java b/datasketches-memory-java8-tests/src/test/java/org/apache/datasketches/memory/test/LeafImplTest.java
index c3974f2..f9e6d6d 100644
--- a/datasketches-memory-java8-tests/src/test/java/org/apache/datasketches/memory/test/LeafImplTest.java
+++ b/datasketches-memory-java8-tests/src/test/java/org/apache/datasketches/memory/test/LeafImplTest.java
@@ -19,8 +19,9 @@
 
 package org.apache.datasketches.memory.test;
 
-import static org.apache.datasketches.memory.internal.Util.nativeByteOrder;
-import static org.apache.datasketches.memory.internal.Util.nonNativeByteOrder;
+import static org.apache.datasketches.memory.internal.Util.NATIVE_BYTE_ORDER;
+import static org.apache.datasketches.memory.internal.Util.NON_NATIVE_BYTE_ORDER;
+import static org.apache.datasketches.memory.internal.Util.otherByteOrder;
 import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.assertFalse;
 import static org.testng.Assert.assertNotNull;
@@ -44,15 +45,13 @@ import org.testng.annotations.Test;
  */
 @SuppressWarnings("javadoc")
 public class LeafImplTest {
-  private static final ByteOrder NO = nativeByteOrder;
-  private static final ByteOrder NNO = nonNativeByteOrder;
+  private static final ByteOrder NBO = NATIVE_BYTE_ORDER;
+  private static final ByteOrder NNBO = NON_NATIVE_BYTE_ORDER;
   private static final MemoryRequestServer dummyMemReqSvr = new DummyMemoryRequestServer();
 
-  private static ByteOrder otherOrder(ByteOrder order) { return (order == NO) ? NNO : NO; }
-
   static class DummyMemoryRequestServer implements MemoryRequestServer {
     @Override
-    public WritableMemory request(long capacityBytes) { return null; }
+    public WritableMemory request(WritableMemory currentWMem, long capacityBytes) { return null; }
     @Override
     public void requestClose(WritableMemory memToClose, WritableMemory newMemory) { }
   }
@@ -62,20 +61,20 @@ public class LeafImplTest {
     long off = 0;
     long cap = 128;
     // Off Heap, Native order, No ByteBuffer, has MemReqSvr
-    try (WritableHandle wdh = WritableMemory.allocateDirect(cap, NO, dummyMemReqSvr)) {
+    try (WritableHandle wdh = WritableMemory.allocateDirect(cap, NBO, dummyMemReqSvr)) {
       WritableMemory memNO = wdh.getWritable();
       memNO.putShort(0, (short) 1);
       assertNull(ReflectUtil.getUnsafeObject(memNO));
       assertTrue(memNO.isDirect());
-      checkCombinations(memNO, off, cap, memNO.isDirect(), NO, false, true);
+      checkCombinations(memNO, off, cap, memNO.isDirect(), NBO, false, true);
     }
     // Off Heap, Non Native order, No ByteBuffer, has MemReqSvr
-    try (WritableHandle wdh = WritableMemory.allocateDirect(cap, NNO, dummyMemReqSvr)) {
+    try (WritableHandle wdh = WritableMemory.allocateDirect(cap, NNBO, dummyMemReqSvr)) {
       WritableMemory memNNO = wdh.getWritable();
       memNNO.putShort(0, (short) 1);
       assertNull(ReflectUtil.getUnsafeObject(memNNO));
       assertTrue(memNNO.isDirect());
-      checkCombinations(memNNO, off, cap, memNNO.isDirect(), NNO, false, true);
+      checkCombinations(memNNO, off, cap, memNNO.isDirect(), NNBO, false, true);
     }
   }
 
@@ -85,36 +84,36 @@ public class LeafImplTest {
     long cap = 128;
     //BB on heap, native order, has ByteBuffer, has MemReqSvr
     ByteBuffer bb = ByteBuffer.allocate((int)cap);
-    bb.order(NO);
+    bb.order(NBO);
     bb.putShort(0, (short) 1);
-    WritableMemory mem = WritableMemory.writableWrap(bb, NO, dummyMemReqSvr);
+    WritableMemory mem = WritableMemory.writableWrap(bb, NBO, dummyMemReqSvr);
     assertEquals(bb.isDirect(), mem.isDirect());
     assertNotNull(ReflectUtil.getUnsafeObject(mem));
     checkCombinations(mem, off, cap, mem.isDirect(), mem.getTypeByteOrder(), true, true);
 
     //BB off heap, native order, has ByteBuffer, has MemReqSvr
     ByteBuffer dbb = ByteBuffer.allocateDirect((int)cap);
-    dbb.order(NO);
+    dbb.order(NBO);
     dbb.putShort(0, (short) 1);
-    mem = WritableMemory.writableWrap(dbb, NO, dummyMemReqSvr);
+    mem = WritableMemory.writableWrap(dbb, NBO, dummyMemReqSvr);
     assertEquals(dbb.isDirect(), mem.isDirect());
     assertNull(ReflectUtil.getUnsafeObject(mem));
     checkCombinations(mem, off, cap,  mem.isDirect(), mem.getTypeByteOrder(), true, true);
 
     //BB on heap, non native order, has ByteBuffer, has MemReqSvr
     bb = ByteBuffer.allocate((int)cap);
-    bb.order(NNO);
+    bb.order(NNBO);
     bb.putShort(0, (short) 1);
-    mem = WritableMemory.writableWrap(bb, NNO, dummyMemReqSvr);
+    mem = WritableMemory.writableWrap(bb, NNBO, dummyMemReqSvr);
     assertEquals(bb.isDirect(), mem.isDirect());
     assertNotNull(ReflectUtil.getUnsafeObject(mem));
     checkCombinations(mem, off, cap, mem.isDirect(), mem.getTypeByteOrder(), true, true);
 
     //BB off heap, non native order, has ByteBuffer, has MemReqSvr
     dbb = ByteBuffer.allocateDirect((int)cap);
-    dbb.order(NNO);
+    dbb.order(NNBO);
     dbb.putShort(0, (short) 1);
-    mem = WritableMemory.writableWrap(dbb, NNO, dummyMemReqSvr);
+    mem = WritableMemory.writableWrap(dbb, NNBO, dummyMemReqSvr);
     assertEquals(dbb.isDirect(), mem.isDirect());
     assertNull(ReflectUtil.getUnsafeObject(mem));
     checkCombinations(mem, off, cap,  mem.isDirect(), mem.getTypeByteOrder(), true, true);
@@ -137,20 +136,20 @@ public class LeafImplTest {
     assertTrue(file.isFile());
     file.deleteOnExit();  //comment out if you want to examine the file.
     // Off Heap, Native order, No ByteBuffer, No MemReqSvr
-    try (WritableMapHandle wmh = WritableMemory.writableMap(file, off, cap, NO)) {
+    try (WritableMapHandle wmh = WritableMemory.writableMap(file, off, cap, NBO)) {
       WritableMemory memNO = wmh.getWritable();
       memNO.putShort(0, (short) 1);
       assertNull(ReflectUtil.getUnsafeObject(memNO));
       assertTrue(memNO.isDirect());
-      checkCombinations(memNO, off, cap, memNO.isDirect(), NO, false, false);
+      checkCombinations(memNO, off, cap, memNO.isDirect(), NBO, false, false);
     }
     // Off heap, Non Native order, No ByteBuffer, no MemReqSvr
-    try (WritableMapHandle wmh = WritableMemory.writableMap(file, off, cap, NNO)) {
+    try (WritableMapHandle wmh = WritableMemory.writableMap(file, off, cap, NNBO)) {
       WritableMemory memNNO = wmh.getWritable();
       memNNO.putShort(0, (short) 1);
       assertNull(ReflectUtil.getUnsafeObject(memNNO));
       assertTrue(memNNO.isDirect());
-      checkCombinations(memNNO, off, cap, memNNO.isDirect(), NNO, false, false);
+      checkCombinations(memNNO, off, cap, memNNO.isDirect(), NNBO, false, false);
     }
   }
 
@@ -159,22 +158,22 @@ public class LeafImplTest {
     long off = 0;
     long cap = 128;
     // On Heap, Native order, No ByteBuffer, No MemReqSvr
-    WritableMemory memNO = WritableMemory.allocate((int)cap); //assumes NO
+    WritableMemory memNO = WritableMemory.allocate((int)cap); //assumes NBO
     memNO.putShort(0, (short) 1);
     assertNotNull(ReflectUtil.getUnsafeObject(memNO));
     assertFalse(memNO.isDirect());
-    checkCombinations(memNO, off, cap, memNO.isDirect(), NO, false, false);
+    checkCombinations(memNO, off, cap, memNO.isDirect(), NBO, false, false);
     // On Heap, Non-native order, No ByteBuffer, No MemReqSvr
-    WritableMemory memNNO = WritableMemory.allocate((int)cap, NNO);
+    WritableMemory memNNO = WritableMemory.allocate((int)cap, NNBO);
     memNNO.putShort(0, (short) 1);
     assertNotNull(ReflectUtil.getUnsafeObject(memNNO));
     assertFalse(memNNO.isDirect());
-    checkCombinations(memNNO, off, cap, memNNO.isDirect(), NNO, false, false);
+    checkCombinations(memNNO, off, cap, memNNO.isDirect(), NNBO, false, false);
   }
 
   private static void checkCombinations(WritableMemory mem, long off, long cap,
       boolean direct, ByteOrder bo, boolean hasByteBuffer, boolean hasMemReqSvr) {
-    ByteOrder oo = otherOrder(bo);
+    ByteOrder oo = otherByteOrder(bo);
 
     assertEquals(mem.writableRegion(off, cap, bo).getShort(0), 1);
     assertEquals(mem.writableRegion(off, cap, oo).getShort(0), 256);
diff --git a/datasketches-memory-java8-tests/src/test/java/org/apache/datasketches/memory/test/MemoryReadWriteSafetyTest.java b/datasketches-memory-java8-tests/src/test/java/org/apache/datasketches/memory/test/MemoryReadWriteSafetyTest.java
index 9181f94..f73a28e 100644
--- a/datasketches-memory-java8-tests/src/test/java/org/apache/datasketches/memory/test/MemoryReadWriteSafetyTest.java
+++ b/datasketches-memory-java8-tests/src/test/java/org/apache/datasketches/memory/test/MemoryReadWriteSafetyTest.java
@@ -26,7 +26,7 @@ import java.nio.ByteOrder;
 
 import org.apache.datasketches.memory.MapHandle;
 import org.apache.datasketches.memory.Memory;
-import org.apache.datasketches.memory.internal.ReadOnlyException;
+import org.apache.datasketches.memory.ReadOnlyException;
 import org.apache.datasketches.memory.WritableMemory;
 import org.testng.annotations.Test;
 
diff --git a/datasketches-memory-java8-tests/src/test/java/org/apache/datasketches/memory/test/MemoryTest.java b/datasketches-memory-java8-tests/src/test/java/org/apache/datasketches/memory/test/MemoryTest.java
index 6cd91a0..6a06c20 100644
--- a/datasketches-memory-java8-tests/src/test/java/org/apache/datasketches/memory/test/MemoryTest.java
+++ b/datasketches-memory-java8-tests/src/test/java/org/apache/datasketches/memory/test/MemoryTest.java
@@ -38,10 +38,10 @@ import java.util.List;
 import org.apache.datasketches.memory.BaseState;
 import org.apache.datasketches.memory.MapHandle;
 import org.apache.datasketches.memory.Memory;
+import org.apache.datasketches.memory.WritableBuffer;
 import org.apache.datasketches.memory.WritableHandle;
 import org.apache.datasketches.memory.WritableMemory;
 import org.apache.datasketches.memory.internal.Util;
-import org.testng.Assert;
 import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
 import org.testng.collections.Lists;
@@ -212,7 +212,7 @@ public class MemoryTest {
     ByteBuffer bb = ByteBuffer.allocate(n * 8);
     bb.order(ByteOrder.BIG_ENDIAN);
     Memory mem = Memory.wrap(bb);
-    assertFalse(mem.getTypeByteOrder() == Util.nativeByteOrder);
+    assertFalse(mem.getTypeByteOrder() == Util.NATIVE_BYTE_ORDER);
     assertEquals(mem.getTypeByteOrder(), ByteOrder.BIG_ENDIAN);
   }
 
@@ -268,7 +268,7 @@ public class MemoryTest {
     long[] arr = new long[n];
     for (int i = 0; i < n; i++) { arr[i] = i; }
     Memory mem = Memory.wrap(arr);
-    Memory reg = mem.region(n2 * 8, n2 * 8, Util.nonNativeByteOrder); //top half
+    Memory reg = mem.region(n2 * 8, n2 * 8, Util.NON_NATIVE_BYTE_ORDER); //top half
     for (int i = 0; i < n2; i++) {
       long v = Long.reverseBytes(reg.getLong(i * 8));
       long e = i + n2;
@@ -308,7 +308,7 @@ public class MemoryTest {
       //println("" + wmem.getLong(i * 8));
     }
     //println("");
-    WritableMemory reg = wmem.writableRegion(n2 * 8, n2 * 8, Util.nonNativeByteOrder);
+    WritableMemory reg = wmem.writableRegion(n2 * 8, n2 * 8, Util.NON_NATIVE_BYTE_ORDER);
     for (int i = 0; i < n2; i++) { reg.putLong(i * 8, i); }
     for (int i = 0; i < n; i++) {
       long v = wmem.getLong(i * 8);
@@ -346,43 +346,6 @@ public class MemoryTest {
     region.getByte(0);
   }
 
-  @Test
-  public void checkUnsafeByteBufferView() throws Exception {
-    try ( WritableHandle wh = WritableMemory.allocateDirect(2)) {
-      WritableMemory wmem = wh.getWritable();
-      wmem.putByte(0, (byte) 1);
-      wmem.putByte(1, (byte) 2);
-      checkUnsafeByteBufferView(wmem);
-    }
-
-    checkUnsafeByteBufferView(Memory.wrap(new byte[] {1, 2}));
-
-    try {
-      @SuppressWarnings("unused")
-      ByteBuffer unused = Memory.wrap(new int[]{1}).unsafeByteBufferView(0, 1);
-      Assert.fail();
-    } catch (UnsupportedOperationException ingore) {
-      // expected
-    }
-  }
-
-  private static void checkUnsafeByteBufferView(final Memory mem) {
-    ByteBuffer emptyByteBuffer = mem.unsafeByteBufferView(0, 0);
-    Assert.assertEquals(emptyByteBuffer.capacity(), 0);
-    ByteBuffer bb = mem.unsafeByteBufferView(1, 1);
-    Assert.assertTrue(bb.isReadOnly());
-    Assert.assertEquals(bb.capacity(), 1);
-    Assert.assertEquals(bb.get(), 2);
-
-    try {
-      @SuppressWarnings("unused")
-      ByteBuffer unused = mem.unsafeByteBufferView(1, 2);
-      Assert.fail();
-    } catch (IllegalArgumentException ignore) {
-      // expected
-    }
-  }
-
   @SuppressWarnings({ "resource"})
   @Test
   public void checkMonitorDirectStats() throws Exception {
@@ -427,14 +390,48 @@ public class MemoryTest {
   }
 
   @Test
-  public void checkNullMemReqSvr() throws Exception {
-    WritableMemory wmem = WritableMemory.writableWrap(new byte[16]);
-    assertNull(wmem.getMemoryRequestServer());
-    try (WritableHandle wdh = WritableMemory.allocateDirect(16)) {
-      WritableMemory wmem2 = wdh.getWritable();
-      assertNotNull(wmem2.getMemoryRequestServer());
+  public void checkMemReqSvr() throws Exception {
+    WritableMemory wmem;
+    WritableBuffer wbuf;
+    if (BaseState.defaultMemReqSvr == null) { //This is a policy choice
+      //ON HEAP
+      wmem = WritableMemory.writableWrap(new byte[16]);
+      assertNull(wmem.getMemoryRequestServer());
+      wbuf = wmem.asWritableBuffer();
+      assertNull(wbuf.getMemoryRequestServer());
+      //OFF HEAP
+      try (WritableHandle wdh = WritableMemory.allocateDirect(16)) { //OFF HEAP
+        wmem = wdh.getWritable();
+        assertNull(wmem.getMemoryRequestServer());
+        wbuf = wmem.asWritableBuffer();
+        assertNull(wbuf.getMemoryRequestServer());
+      }
+      //ByteBuffer
+      ByteBuffer bb = ByteBuffer.allocate(16);
+      wmem = WritableMemory.writableWrap(bb);
+      assertNull(wmem.getMemoryRequestServer());
+      wbuf = wmem.asWritableBuffer();
+      assertNull(wbuf.getMemoryRequestServer());
+    } else {
+      //ON HEAP
+      wmem = WritableMemory.writableWrap(new byte[16]);
+      assertNotNull(wmem.getMemoryRequestServer());
+      wbuf = wmem.asWritableBuffer();
+      assertNotNull(wbuf.getMemoryRequestServer());
+      //OFF HEAP
+      try (WritableHandle wdh = WritableMemory.allocateDirect(16)) {
+        WritableMemory wmem2 = wdh.getWritable();
+        assertNotNull(wmem2.getMemoryRequestServer());
+        wbuf = wmem.asWritableBuffer();
+        assertNotNull(wbuf.getMemoryRequestServer());
+      }
+      //ByteBuffer
+      ByteBuffer bb = ByteBuffer.allocate(16);
+      wmem = WritableMemory.writableWrap(bb);
+      assertNotNull(wmem.getMemoryRequestServer());
+      wbuf = wmem.asWritableBuffer();
+      assertNotNull(wbuf.getMemoryRequestServer());
     }
-    println(wmem.toHexString("Test", 0, 16));
   }
 
   @Test
diff --git a/datasketches-memory-java8-tests/src/test/java/org/apache/datasketches/memory/test/NativeWritableBufferImplTest.java b/datasketches-memory-java8-tests/src/test/java/org/apache/datasketches/memory/test/NativeWritableBufferImplTest.java
index 06f6697..be503a7 100644
--- a/datasketches-memory-java8-tests/src/test/java/org/apache/datasketches/memory/test/NativeWritableBufferImplTest.java
+++ b/datasketches-memory-java8-tests/src/test/java/org/apache/datasketches/memory/test/NativeWritableBufferImplTest.java
@@ -21,19 +21,20 @@ package org.apache.datasketches.memory.test;
 
 import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertNotNull;
 import static org.testng.Assert.assertTrue;
 
 import java.nio.ByteBuffer;
 import java.nio.ByteOrder;
 
-import org.apache.datasketches.memory.WritableHandle;
 import org.apache.datasketches.memory.Buffer;
 import org.apache.datasketches.memory.Memory;
-import org.apache.datasketches.memory.internal.ReadOnlyException;
-import org.apache.datasketches.memory.internal.UnsafeUtil;
-import org.apache.datasketches.memory.internal.Util;
+import org.apache.datasketches.memory.ReadOnlyException;
 import org.apache.datasketches.memory.WritableBuffer;
+import org.apache.datasketches.memory.WritableHandle;
 import org.apache.datasketches.memory.WritableMemory;
+import org.apache.datasketches.memory.internal.UnsafeUtil;
+import org.apache.datasketches.memory.internal.Util;
 import org.testng.Assert;
 import org.testng.annotations.Test;
 
@@ -287,8 +288,10 @@ public class NativeWritableBufferImplTest {
     ByteBuffer byteBuf = ByteBuffer.allocate(memCapacity);
     byteBuf.order(ByteOrder.nativeOrder());
     ByteBuffer byteBufRO = byteBuf.asReadOnlyBuffer();
-
-    WritableBuffer.writableWrap(byteBufRO);
+    byteBufRO.order(ByteOrder.nativeOrder());
+    assertTrue(true);
+    WritableBuffer wbuf = WritableBuffer.writableWrap(byteBufRO);
+    assertTrue(wbuf.isReadOnly());
   }
 
   @Test
@@ -503,14 +506,13 @@ public class NativeWritableBufferImplTest {
   public void checkAsWritableMemoryRO() {
     ByteBuffer bb = ByteBuffer.allocate(64);
     WritableBuffer wbuf = WritableBuffer.writableWrap(bb);
-    @SuppressWarnings("unused")
-    WritableMemory wmem = wbuf.asWritableMemory();
+    WritableMemory wmem = wbuf.asWritableMemory(); //OK
+    assertNotNull(wmem);
 
     try {
-      Buffer buf = Buffer.wrap(bb);
+      Buffer buf = Buffer.wrap(bb.asReadOnlyBuffer());
       wbuf = (WritableBuffer) buf;
-      @SuppressWarnings("unused")
-      WritableMemory wmem2 = wbuf.asWritableMemory();
+      wmem = wbuf.asWritableMemory();
       Assert.fail();
     } catch (ReadOnlyException expected) {
       // expected
@@ -583,7 +585,7 @@ public class NativeWritableBufferImplTest {
   public void checkDuplicateNonNative() {
     WritableMemory wmem = WritableMemory.allocate(64);
     wmem.putShort(0, (short) 1);
-    Buffer buf = wmem.asWritableBuffer().duplicate(Util.nonNativeByteOrder);
+    Buffer buf = wmem.asWritableBuffer().duplicate(Util.NON_NATIVE_BYTE_ORDER);
     assertEquals(buf.getShort(0), 256);
   }
 
diff --git a/datasketches-memory-java8-tests/src/test/java/org/apache/datasketches/memory/test/NativeWritableMemoryImplTest.java b/datasketches-memory-java8-tests/src/test/java/org/apache/datasketches/memory/test/NativeWritableMemoryImplTest.java
index 017d4e2..d4628eb 100644
--- a/datasketches-memory-java8-tests/src/test/java/org/apache/datasketches/memory/test/NativeWritableMemoryImplTest.java
+++ b/datasketches-memory-java8-tests/src/test/java/org/apache/datasketches/memory/test/NativeWritableMemoryImplTest.java
@@ -30,7 +30,7 @@ import java.nio.ByteOrder;
 import org.apache.datasketches.memory.WritableHandle;
 import org.apache.datasketches.memory.Buffer;
 import org.apache.datasketches.memory.Memory;
-import org.apache.datasketches.memory.internal.ReadOnlyException;
+import org.apache.datasketches.memory.ReadOnlyException;
 import org.apache.datasketches.memory.internal.UnsafeUtil;
 import org.apache.datasketches.memory.internal.Util;
 import org.apache.datasketches.memory.WritableBuffer;
@@ -708,7 +708,7 @@ public class NativeWritableMemoryImplTest {
   public void checkAsBufferNonNative() {
     WritableMemory wmem = WritableMemory.allocate(64);
     wmem.putShort(0, (short) 1);
-    Buffer buf = wmem.asBuffer(Util.nonNativeByteOrder);
+    Buffer buf = wmem.asBuffer(Util.NON_NATIVE_BYTE_ORDER);
     assertEquals(buf.getShort(0), 256);
   }
 
diff --git a/datasketches-memory-java8-tests/src/test/java/org/apache/datasketches/memory/test/SpecificLeafTest.java b/datasketches-memory-java8-tests/src/test/java/org/apache/datasketches/memory/test/SpecificLeafTest.java
index 3f2a500..4c3a053 100644
--- a/datasketches-memory-java8-tests/src/test/java/org/apache/datasketches/memory/test/SpecificLeafTest.java
+++ b/datasketches-memory-java8-tests/src/test/java/org/apache/datasketches/memory/test/SpecificLeafTest.java
@@ -44,17 +44,17 @@ public class SpecificLeafTest {
   public void checkByteBufferLeafs() {
     int bytes = 128;
     ByteBuffer bb = ByteBuffer.allocate(bytes);
-    bb.order(Util.nativeByteOrder);
+    bb.order(Util.NATIVE_BYTE_ORDER);
 
-    Memory mem = Memory.wrap(bb).region(0, bytes, Util.nativeByteOrder);
+    Memory mem = Memory.wrap(bb).region(0, bytes, Util.NATIVE_BYTE_ORDER);
     assertTrue(ReflectUtil.isBBType(mem));
     assertTrue(mem.isReadOnly());
     checkCrossLeafTypeIds(mem);
-    Buffer buf = mem.asBuffer().region(0, bytes, Util.nativeByteOrder);
+    Buffer buf = mem.asBuffer().region(0, bytes, Util.NATIVE_BYTE_ORDER);
 
-    bb.order(Util.nonNativeByteOrder);
-    Memory mem2 = Memory.wrap(bb).region(0, bytes, Util.nonNativeByteOrder);
-    Buffer buf2 = mem2.asBuffer().region(0, bytes, Util.nonNativeByteOrder);
+    bb.order(Util.NON_NATIVE_BYTE_ORDER);
+    Memory mem2 = Memory.wrap(bb).region(0, bytes, Util.NON_NATIVE_BYTE_ORDER);
+    Buffer buf2 = mem2.asBuffer().region(0, bytes, Util.NON_NATIVE_BYTE_ORDER);
     Buffer buf3 = buf2.duplicate();
 
     assertTrue(ReflectUtil.isRegionType(mem));
@@ -72,14 +72,14 @@ public class SpecificLeafTest {
       assertTrue(ReflectUtil.isDirectType(wmem));
       assertFalse(wmem.isReadOnly());
       checkCrossLeafTypeIds(wmem);
-      WritableMemory nnwmem = wmem.writableRegion(0, bytes, Util.nonNativeByteOrder);
+      WritableMemory nnwmem = wmem.writableRegion(0, bytes, Util.NON_NATIVE_BYTE_ORDER);
 
-      Memory mem = wmem.region(0, bytes, Util.nativeByteOrder);
-      Buffer buf = mem.asBuffer().region(0, bytes, Util.nativeByteOrder);
+      Memory mem = wmem.region(0, bytes, Util.NATIVE_BYTE_ORDER);
+      Buffer buf = mem.asBuffer().region(0, bytes, Util.NATIVE_BYTE_ORDER);
 
 
-      Memory mem2 = nnwmem.region(0, bytes, Util.nonNativeByteOrder);
-      Buffer buf2 = mem2.asBuffer().region(0, bytes, Util.nonNativeByteOrder);
+      Memory mem2 = nnwmem.region(0, bytes, Util.NON_NATIVE_BYTE_ORDER);
+      Buffer buf2 = mem2.asBuffer().region(0, bytes, Util.NON_NATIVE_BYTE_ORDER);
       Buffer buf3 = buf2.duplicate();
 
       assertTrue(ReflectUtil.isRegionType(mem));
@@ -107,19 +107,19 @@ public class SpecificLeafTest {
 
     final long bytes = 128;
 
-    try (WritableMapHandle h = WritableMemory.writableMap(file, 0L, bytes, Util.nativeByteOrder)) {
+    try (WritableMapHandle h = WritableMemory.writableMap(file, 0L, bytes, Util.NATIVE_BYTE_ORDER)) {
       WritableMemory mem = h.getWritable(); //native mem
       assertTrue(ReflectUtil.isMapType(mem));
       assertFalse(mem.isReadOnly());
       checkCrossLeafTypeIds(mem);
-      Memory nnreg = mem.region(0, bytes, Util.nonNativeByteOrder);
+      Memory nnreg = mem.region(0, bytes, Util.NON_NATIVE_BYTE_ORDER);
 
-      Memory reg = mem.region(0, bytes, Util.nativeByteOrder);
-      Buffer buf = reg.asBuffer().region(0, bytes, Util.nativeByteOrder);
+      Memory reg = mem.region(0, bytes, Util.NATIVE_BYTE_ORDER);
+      Buffer buf = reg.asBuffer().region(0, bytes, Util.NATIVE_BYTE_ORDER);
       Buffer buf4 = buf.duplicate();
 
-      Memory reg2 = nnreg.region(0, bytes, Util.nonNativeByteOrder);
-      Buffer buf2 = reg2.asBuffer().region(0, bytes, Util.nonNativeByteOrder);
+      Memory reg2 = nnreg.region(0, bytes, Util.NON_NATIVE_BYTE_ORDER);
+      Buffer buf2 = reg2.asBuffer().region(0, bytes, Util.NON_NATIVE_BYTE_ORDER);
       Buffer buf3 = buf2.duplicate();
 
       assertTrue(ReflectUtil.isRegionType(reg));
@@ -138,14 +138,14 @@ public class SpecificLeafTest {
     assertTrue(ReflectUtil.isHeapType(mem));
     assertTrue(ReflectUtil.isReadOnlyType(mem));
     checkCrossLeafTypeIds(mem);
-    Memory nnreg = mem.region(0, bytes, Util.nonNativeByteOrder);
+    Memory nnreg = mem.region(0, bytes, Util.NON_NATIVE_BYTE_ORDER);
 
-    Memory reg = mem.region(0, bytes, Util.nativeByteOrder);
-    Buffer buf = reg.asBuffer().region(0, bytes, Util.nativeByteOrder);
+    Memory reg = mem.region(0, bytes, Util.NATIVE_BYTE_ORDER);
+    Buffer buf = reg.asBuffer().region(0, bytes, Util.NATIVE_BYTE_ORDER);
     Buffer buf4 = buf.duplicate();
 
-    Memory reg2 = nnreg.region(0, bytes, Util.nonNativeByteOrder);
-    Buffer buf2 = reg2.asBuffer().region(0, bytes, Util.nonNativeByteOrder);
+    Memory reg2 = nnreg.region(0, bytes, Util.NON_NATIVE_BYTE_ORDER);
+    Buffer buf2 = reg2.asBuffer().region(0, bytes, Util.NON_NATIVE_BYTE_ORDER);
     Buffer buf3 = buf2.duplicate();
 
     assertFalse(ReflectUtil.isRegionType(mem));
@@ -163,28 +163,33 @@ public class SpecificLeafTest {
     Buffer buf1 = reg1.asBuffer();
     assertTrue(ReflectUtil.isRegionType(buf1));
     assertTrue(ReflectUtil.isBufferType(buf1));
+    assertTrue(buf1.isReadOnly());
 
     Buffer buf2 = buf1.duplicate();
     assertTrue(ReflectUtil.isRegionType(buf2));
     assertTrue(ReflectUtil.isBufferType(buf2));
     assertTrue(ReflectUtil.isDuplicateType(buf2));
+    assertTrue(buf2.isReadOnly());
 
-    Memory mem2 = buf1.asMemory();
+    Memory mem2 = buf1.asMemory(); //
     assertTrue(ReflectUtil.isRegionType(mem2));
     assertFalse(ReflectUtil.isBufferType(mem2));
     assertFalse(ReflectUtil.isDuplicateType(mem2));
+    assertTrue(mem2.isReadOnly());
 
-    Buffer buf3 = buf1.duplicate(Util.nonNativeByteOrder);
+    Buffer buf3 = buf1.duplicate(Util.NON_NATIVE_BYTE_ORDER);
     assertTrue(ReflectUtil.isRegionType(buf3));
     assertTrue(ReflectUtil.isBufferType(buf3));
     assertTrue(ReflectUtil.isDuplicateType(buf3));
     assertTrue(ReflectUtil.isNonNativeType(buf3));
+    assertTrue(buf3.isReadOnly());
 
     Memory mem3 = buf3.asMemory();
     assertTrue(ReflectUtil.isRegionType(mem3));
     assertFalse(ReflectUtil.isBufferType(mem3));
-    assertFalse(ReflectUtil.isDuplicateType(mem3));
-    assertFalse(ReflectUtil.isNonNativeType(mem3));
+    assertTrue(ReflectUtil.isDuplicateType(mem3));
+    assertTrue(ReflectUtil.isNonNativeType(mem3));
+    assertTrue(mem3.isReadOnly());
   }
 
 }
diff --git a/datasketches-memory-java8-tests/src/test/java/org/apache/datasketches/memory/test/WritableMemoryTest.java b/datasketches-memory-java8-tests/src/test/java/org/apache/datasketches/memory/test/WritableMemoryTest.java
index 4e00273..f464bc2 100644
--- a/datasketches-memory-java8-tests/src/test/java/org/apache/datasketches/memory/test/WritableMemoryTest.java
+++ b/datasketches-memory-java8-tests/src/test/java/org/apache/datasketches/memory/test/WritableMemoryTest.java
@@ -28,9 +28,9 @@ import java.nio.ByteOrder;
 import java.util.concurrent.ThreadLocalRandom;
 
 import org.apache.datasketches.memory.Memory;
-import org.apache.datasketches.memory.internal.Util;
 import org.apache.datasketches.memory.WritableBuffer;
 import org.apache.datasketches.memory.WritableMemory;
+import org.apache.datasketches.memory.internal.Util;
 import org.testng.annotations.Test;
 
 @SuppressWarnings("javadoc")
@@ -161,11 +161,11 @@ public class WritableMemoryTest {
   @Test
   public void checkWrapWithBO() {
     WritableMemory wmem = WritableMemory.writableWrap(new byte[0], ByteOrder.BIG_ENDIAN);
-    boolean nativeBO = wmem.getTypeByteOrder() == Util.nativeByteOrder;
-    assertTrue(nativeBO); //remains true for ZeroSizeMemory
+    boolean nativeBO = wmem.getTypeByteOrder() == Util.NATIVE_BYTE_ORDER;
+    assertFalse(nativeBO);
     println("" + nativeBO);
     wmem = WritableMemory.writableWrap(new byte[8], ByteOrder.BIG_ENDIAN);
-    nativeBO = wmem.getTypeByteOrder() == Util.nativeByteOrder;
+    nativeBO = wmem.getTypeByteOrder() == Util.NATIVE_BYTE_ORDER;
     assertFalse(nativeBO);
     println("" + nativeBO);
   }
diff --git a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/BaseState.java b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/BaseState.java
index 47b2249..f7384ae 100644
--- a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/BaseState.java
+++ b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/BaseState.java
@@ -32,7 +32,7 @@ import org.apache.datasketches.memory.internal.BaseStateImpl;
  * @author Lee Rhodes
  */
 public interface BaseState {
-  static final MemoryRequestServer defaultMemReqSvr = new DefaultMemoryRequestServer();
+  static final MemoryRequestServer defaultMemReqSvr = null;//new DefaultMemoryRequestServer(); //or null.
 
   //Byte Order Related
 
diff --git a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/Buffer.java b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/Buffer.java
index 41b5224..2bbf4fe 100644
--- a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/Buffer.java
+++ b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/Buffer.java
@@ -19,37 +19,40 @@
 
 package org.apache.datasketches.memory;
 
+import static org.apache.datasketches.memory.internal.Util.negativeCheck;
+
 import java.nio.ByteBuffer;
 import java.nio.ByteOrder;
+import java.util.Objects;
 
-import org.apache.datasketches.memory.internal.BufferImpl;
+import org.apache.datasketches.memory.internal.BaseWritableBufferImpl;
 
 public interface Buffer extends BaseBuffer {
 
   //BYTE BUFFER
   /**
    * Accesses the given ByteBuffer for read-only operations. The returned Buffer object has the
-   * same byte order, as the given ByteBuffer, unless the capacity of the given ByteBuffer is zero,
-   * then byte order of the returned Buffer object (as well as backing storage) is unspecified.
-   * @param byteBuf the given ByteBuffer, must not be null.
+   * same byte order, as the given ByteBuffer.
+   * @param byteBuffer the given ByteBuffer, must not be null.
    * @return a new Buffer for read-only operations on the given ByteBuffer.
    */
-  static Buffer wrap(ByteBuffer byteBuf) {
-    return BufferImpl.wrap(byteBuf);
+  static Buffer wrap(ByteBuffer byteBuffer) {
+    return wrap(byteBuffer, byteBuffer.order());
   }
 
   /**
    * Accesses the given ByteBuffer for read-only operations. The returned Buffer object has
-   * the given byte order, ignoring the byte order of the given ByteBuffer. If the capacity of
-   * the given ByteBuffer is zero the byte order of the returned Buffer object
-   * (as well as backing storage) is unspecified.
-   * @param byteBuf the given ByteBuffer, must not be null
+   * the given byte order, ignoring the byte order of the given ByteBuffer.
+   * @param byteBuffer the given ByteBuffer, must not be null
    * @param byteOrder the byte order to be used, which may be independent of the byte order
    * state of the given ByteBuffer
    * @return a new Buffer for read-only operations on the given ByteBuffer.
    */
-  static Buffer wrap(ByteBuffer byteBuf, ByteOrder byteOrder) {
-    return BufferImpl.wrap(byteBuf, byteOrder);
+  static Buffer wrap(ByteBuffer byteBuffer, ByteOrder byteOrder) {
+    Objects.requireNonNull(byteBuffer, "byteBuffer must not be null");
+    Objects.requireNonNull(byteOrder, "byteOrder must not be null");
+    negativeCheck(byteBuffer.capacity(), "byteBuffer");
+    return BaseWritableBufferImpl.wrapByteBuffer(byteBuffer, true, byteOrder, null);
   }
 
   //DUPLICATES
@@ -65,8 +68,6 @@ public interface Buffer extends BaseBuffer {
    * <li>Returned object's <i>start</i>, <i>position</i> and <i>end</i> are mutable and
    * independent of this object's <i>start</i>, <i>position</i> and <i>end</i></li>
    * </ul>
-   * If this object's capacity is zero, the returned object is effectively immutable and
-   * the backing storage and byte order are unspecified.
    * @return a read-only duplicate view of this Buffer with the same but independent values of
    * <i>start</i>, <i>position</i> and <i>end</i>.
    */
@@ -84,14 +85,14 @@ public interface Buffer extends BaseBuffer {
    * <li>Returned object's <i>start</i>, <i>position</i> and <i>end</i> are mutable and
    * independent of this object's <i>start</i>, <i>position</i> and <i>end</i></li>
    * </ul>
-   * If this object's capacity is zero, the returned object is effectively immutable and
-   * the backing storage and byte order are unspecified.
    * @param byteOrder the given <i>ByteOrder</i>.
    * @return a read-only duplicate view of this Buffer with the same but independent values of
    * <i>start</i>, <i>position</i> and <i>end</i>.
    */
   Buffer duplicate(ByteOrder byteOrder);
 
+  //NO MAP
+
   //REGIONS
   /**
    * A region is a read-only view of this object.
@@ -104,8 +105,6 @@ public interface Buffer extends BaseBuffer {
    * <li>Returned object's <i>start</i>, <i>position</i> and <i>end</i> are mutable and
    * independent of this object's <i>start</i>, <i>position</i> and <i>end</i></li>
    * </ul>
-   * If this object's capacity is zero, the returned object is effectively immutable and
-   * the backing storage and byte order are unspecified.
    * @return a new <i>Buffer</i> representing the defined region based on the current
    * <i>position</i> and <i>end</i>.
    */
@@ -123,11 +122,6 @@ public interface Buffer extends BaseBuffer {
    * independent of this object's <i>start</i>, <i>position</i> and <i>end</i></li>
    * <li>Returned object's byte order = <i>byteOrder</i></li>
    * </ul>
-   * If this object's capacity is zero, the returned object is effectively immutable and
-   * the backing storage and byte order are unspecified.
-   *
-   * <p><b>Note: The Memory returned with </b><i>asMemory()</i> will have the originating
-   * <i>Memory</i> byte order.</p>
    *
    * @param offsetBytes the starting offset with respect to the origin of this <i>WritableBuffer</i>
    * @param capacityBytes the <i>capacity</i> of the returned region in bytes
@@ -135,18 +129,26 @@ public interface Buffer extends BaseBuffer {
    * @return a new <i>Buffer</i> representing the defined writable region
    * based on the current <i>position</i>, <i>end</i> and byteOrder.
    */
-  Buffer region(long offsetBytes, long capacityBytes,
-      ByteOrder byteOrder);
+  Buffer region(long offsetBytes, long capacityBytes, ByteOrder byteOrder);
 
-  //MEMORY
+  //AS MEMORY
   /**
    * Convert this Buffer to a Memory. The current <i>start</i>, <i>position</i> and <i>end</i>
    * are ignored.
-   * If this object's capacity is zero, the returned object is effectively immutable and
-   * the backing resource and byte order are unspecified.
    * @return Memory
    */
-  Memory asMemory();
+  default Memory asMemory() {
+    return asMemory(getTypeByteOrder());
+  }
+
+  /**
+   * Convert this Buffer to a Memory with the given byte order.
+   * The current <i>start</i>, <i>position</i> and <i>end</i> are ignored.
+   * @return Memory
+   */
+  Memory asMemory(ByteOrder byteOrder);
+
+  //NO ACCESS PRIMITIVE HEAP ARRAYS for readOnly
 
   //PRIMITIVE getX() and getXArray()
   /**
@@ -171,8 +173,7 @@ public interface Buffer extends BaseBuffer {
    * @param dstOffsetBooleans offset in array units
    * @param lengthBooleans number of array units to transfer
    */
-  void getBooleanArray(boolean[] dstArray, int dstOffsetBooleans,
-      int lengthBooleans);
+  void getBooleanArray(boolean[] dstArray, int dstOffsetBooleans, int lengthBooleans);
 
   /**
    * Gets the byte value at the current position.
diff --git a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/DefaultMemoryRequestServer.java b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/DefaultMemoryRequestServer.java
index 144bdcf..51c2d2b 100644
--- a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/DefaultMemoryRequestServer.java
+++ b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/DefaultMemoryRequestServer.java
@@ -19,8 +19,6 @@
 
 package org.apache.datasketches.memory;
 
-import org.apache.datasketches.memory.internal.WritableMemoryImpl;
-
 /**
  * This is a simple implementation of the MemoryRequestServer that creates space on the Java heap
  * for the requesting application. This capability is only available for direct, off-heap
@@ -45,7 +43,7 @@ import org.apache.datasketches.memory.internal.WritableMemoryImpl;
  *       memReqSvr = (memReqSvr == null) ? mem.getMemoryRequestServer() : memReqSvr;
  *
  *       //Request bigger memory
- *       WritableMemory newMem = memReqSvr.request(spaceNeeded);
+ *       WritableMemory newMem = memReqSvr.request(mem, spaceNeeded);
  *
  *       //Copy your data from the current memory to the new one and resize
  *       moveAndResize(mem, newMem);
@@ -55,7 +53,7 @@ import org.apache.datasketches.memory.internal.WritableMemoryImpl;
  *       // actually close the resource.
  *       memReqSvr.requestClose(mem, newMem);
  *
- *       mem = newMem; //update your reference to memoty
+ *       mem = newMem; //update your reference to memory
  *     }
  *
  *     //continue with the add process
@@ -74,8 +72,8 @@ public final class DefaultMemoryRequestServer implements MemoryRequestServer {
    * <p>By default this allocates new memory requests on the Java heap.
    */
   @Override
-  public WritableMemory request(final long capacityBytes) {
-    final WritableMemory wmem = WritableMemoryImpl.allocate((int)capacityBytes);
+  public WritableMemory request(final WritableMemory currentWritableMemory, final long capacityBytes) {
+    final WritableMemory wmem = WritableMemory.allocate((int)capacityBytes, currentWritableMemory.getTypeByteOrder());
     return wmem;
   }
 
diff --git a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/Handle.java b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/Handle.java
index c541282..92f0ca5 100644
--- a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/Handle.java
+++ b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/Handle.java
@@ -20,7 +20,7 @@
 package org.apache.datasketches.memory;
 
 /**
- * A handle for read-only resource.
+ * A handle for read-only Memory resource.
  *
  * <p>The purpose of a Handle is to
  * <ul><li>Provide a <i>strong reference</i> to an external <i>resource</i>.</li>
diff --git a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/Memory.java b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/Memory.java
index 1f50f3a..bcae763 100644
--- a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/Memory.java
+++ b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/Memory.java
@@ -20,83 +20,76 @@
 
 package org.apache.datasketches.memory;
 
+import static org.apache.datasketches.memory.internal.Util.negativeCheck;
+
 import java.io.File;
 import java.io.IOException;
 import java.nio.ByteBuffer;
 import java.nio.ByteOrder;
 import java.nio.channels.WritableByteChannel;
+import java.util.Objects;
 
-import org.apache.datasketches.memory.internal.MemoryImpl;
-import org.apache.datasketches.memory.internal.Util;
+import org.apache.datasketches.memory.internal.BaseWritableMemoryImpl;
+import org.apache.datasketches.memory.internal.Prim;
+import org.apache.datasketches.memory.internal.UnsafeUtil;
 
 public interface Memory extends BaseState {
 
-  //BYTE BUFFER
+  //BYTE BUFFERf
 
   /**
-   * Accesses the given ByteBuffer for read-only operations. The returned <i>Memory</i> object has
-   * the same byte order, as the given ByteBuffer, unless the capacity of the given ByteBuffer is
-   * zero, then byte order of the returned <i>Memory</i> object (as well as backing storage) is
-   * unspecified.
-   *
-   * <p><b>Note:</b> Always qualify this method with the class name, e.g.,
-   * <i>Memory.wrap(...)</i>.
-   * @param byteBuf the given ByteBuffer, must not be null
-   * @return a new <i>Memory</i> for read-only operations on the given ByteBuffer.
+   * Accesses the given <i>ByteBuffer</i> for read-only operations. The returned <i>Memory</i> object has
+   * the same byte order, as the given <i>ByteBuffer</i>.
+   * @param byteBuffer the given <i>ByteBuffer</i>. It must be non-null and with capacity >= 0.
+   * @return a new <i>Memory</i> for read-only operations on the given <i>ByteBuffer</i>.
    */
-  static Memory wrap(ByteBuffer byteBuf) {
-    return MemoryImpl.wrap(byteBuf);
+  static Memory wrap(ByteBuffer byteBuffer) {
+    return wrap(byteBuffer, byteBuffer.order());
   }
 
   /**
-   * Accesses the given ByteBuffer for read-only operations. The returned <i>Memory</i> object has
-   * the given byte order, ignoring the byte order of the given ByteBuffer.  If the capacity of the
-   * given ByteBuffer is zero the byte order of the returned <i>Memory</i> object (as well as
-   * backing storage) is unspecified.
-   *
-   * <p><b>Note:</b> Always qualify this method with the class name, e.g.,
-   * <i>Memory.wrap(...)</i>.
-   * @param byteBuf the given ByteBuffer, must not be null
-   * @param byteOrder the byte order to be used, whicn may be independent of the byte order
-   * state of the given ByteBuffer.
-   * @return a new <i>Memory</i> for read-only operations on the given ByteBuffer.
-   */
-  static Memory wrap(ByteBuffer byteBuf, ByteOrder byteOrder) {
-    return MemoryImpl.wrap(byteBuf, byteOrder);
+   * Accesses the given <i>ByteBuffer</i> for read-only operations. The returned <i>Memory</i> object has
+   * the given byte order, ignoring the byte order of the given <i>ByteBuffer</i> for future reads and writes.
+   * @param byteBuffer the given <i>ByteBuffer</i>. It must be non-null and with capacity >= 0.
+   * @param byteOrder the byte order to be used.  It must be non-null.
+   * @return a new <i>Memory</i> for read-only operations on the given <i>ByteBuffer</i>.
+   */
+  static Memory wrap(ByteBuffer byteBuffer, ByteOrder byteOrder) {
+    Objects.requireNonNull(byteBuffer, "byteBuffer must not be null");
+    Objects.requireNonNull(byteOrder, "byteOrder must not be null");
+    negativeCheck(byteBuffer.capacity(), "byteBuffer");
+    return BaseWritableMemoryImpl.wrapByteBuffer(byteBuffer, true, byteOrder, null);
   }
 
   //MAP
   /**
-   * Maps the entire given file into native-ordered Memory for read operations
-   * (including those &gt; 2GB).
-   * Calling this method is equivalent to calling {@link #map(File, long, long, ByteOrder)
-   * map(file, 0, file.length(), ByteOrder.nativeOrder())}.
-   *
-   * <p><b>Note:</b> Always qualify this method with the class name, e.g.,
-   * <i>Memory.map(...)</i>.
-   * @param file the given file to map
-   * @return <i>MapHandle</i> for managing the mapped Memory.
+   * Maps the entire given file into native-ordered <i>Memory</i> for read operations
+   * Calling this method is equivalent to calling
+   * {@link #map(File, long, long, ByteOrder) map(file, 0, file.length(), ByteOrder.nativeOrder())}.
+   * @param file the given file to map. It must be non-null, length >= 0, and readable.
+   * @return <i>MapHandle</i> for managing the mapped memory.
    * Please read Javadocs for {@link Handle}.
    */
   static MapHandle map(File file) {
-    return MemoryImpl.map(file, 0, file.length(), ByteOrder.nativeOrder());
+    return map(file, 0, file.length(), ByteOrder.nativeOrder());
   }
 
   /**
-   * Maps the specified portion of the given file into Memory for read operations
-   * (including those &gt; 2GB).
-   *
-   * <p><b>Note:</b> Always qualify this method with the class name, e.g.,
-   * <i>Memory.map(...)</i>.
-   * @param file the given file to map. It may not be null.
-   * @param fileOffsetBytes the position in the given file in bytes. It may not be negative.
-   * @param capacityBytes the size of the mapped Memory. It may not be negative or zero.
-   * @param byteOrder the byte order to be used for the mapped Memory. It may not be null.
-   * @return <i>MapHandle</i> for managing the mapped Memory.
+   * Maps the specified portion of the given file into <i>Memory</i> for read operations.
+   * @param file the given file to map. It must be non-null and readable.
+   * @param fileOffsetBytes the position in the given file in bytes. It must not be negative.
+   * @param capacityBytes the size of the mapped memory. It must not be negative.
+   * @param byteOrder the byte order to be used for the mapped memory. It must be non-null.
+   * @return <i>MapHandle</i> for managing the mapped memory.
    * Please read Javadocs for {@link Handle}.
    */
   static MapHandle map(File file, long fileOffsetBytes, long capacityBytes, ByteOrder byteOrder) {
-    return MemoryImpl.map(file, fileOffsetBytes, capacityBytes, byteOrder);
+    Objects.requireNonNull(file, "file must be non-null.");
+    Objects.requireNonNull(byteOrder, "byteOrder must be non-null.");
+    if (!file.canRead()) { throw new IllegalArgumentException("file must be readable."); }
+    negativeCheck(fileOffsetBytes, "fileOffsetBytes");
+    negativeCheck(capacityBytes, "capacityBytes");
+    return (MapHandle) BaseWritableMemoryImpl.wrapMap(file, fileOffsetBytes, capacityBytes, true, byteOrder);
   }
 
   //REGIONS
@@ -106,14 +99,14 @@ public interface Memory extends BaseState {
    * <li>Returned object's origin = this object's origin + offsetBytes</li>
    * <li>Returned object's capacity = capacityBytes</li>
    * </ul>
-   * If the given capacityBytes is zero, the returned object is effectively immutable and
-   * the backing storage and byte order are unspecified.
-   * @param offsetBytes the starting offset with respect to the origin of this Memory.
-   * @param capacityBytes the capacity of the region in bytes
+   * @param offsetBytes the starting offset with respect to the origin of this <i>Memory</i>. It must be >=0.
+   * @param capacityBytes the capacity of the region in bytes. It must be >= 0.
    * @return a new <i>Memory</i> representing the defined region based on the given
    * offsetBytes and capacityBytes.
    */
-  Memory region(long offsetBytes, long capacityBytes);
+  default Memory region(long offsetBytes, long capacityBytes) {
+    return region(offsetBytes, capacityBytes, ByteOrder.nativeOrder());
+  }
 
   /**
    * A region is a read-only view of this object.
@@ -122,11 +115,9 @@ public interface Memory extends BaseState {
    * <li>Returned object's capacity = <i>capacityBytes</i></li>
    * <li>Returned object's byte order = <i>byteOrder</i></li>
    * </ul>
-   * If the given capacityBytes is zero, the returned object is effectively immutable and
-   * the backing storage and byte order are unspecified.
-   * @param offsetBytes the starting offset with respect to the origin of this Memory.
-   * @param capacityBytes the capacity of the region in bytes
-   * @param byteOrder the given byte order
+   * @param offsetBytes the starting offset with respect to the origin of this Memory. It must be >=0.
+   * @param capacityBytes the capacity of the region in bytes. It must be >= 0.
+   * @param byteOrder the given byte order. It must be non-null.
    * @return a new <i>Memory</i> representing the defined region based on the given
    * offsetBytes, capacityBytes and byteOrder.
    */
@@ -143,11 +134,11 @@ public interface Memory extends BaseState {
    * <li>Returned object's <i>capacity</i> = this object's capacity</li>
    * <li>Returned object's <i>start</i>, <i>position</i> and <i>end</i> are mutable</li>
    * </ul>
-   * If this object's capacity is zero, the returned object is effectively immutable and
-   * the backing storage and byte order are unspecified.
    * @return a new <i>Buffer</i>
    */
-  Buffer asBuffer();
+  default Buffer asBuffer() {
+    return asBuffer(ByteOrder.nativeOrder());
+  }
 
   /**
    * Returns a new <i>Buffer</i> view of this object, with the given
@@ -160,179 +151,124 @@ public interface Memory extends BaseState {
    * <li>Returned object's <i>capacity</i> = this object's capacity</li>
    * <li>Returned object's <i>start</i>, <i>position</i> and <i>end</i> are mutable</li>
    * </ul>
-   * If this object's capacity is zero, the returned object is effectively immutable and
-   * the backing storage and byte order are unspecified.
    * @param byteOrder the given byte order
    * @return a new <i>Buffer</i> with the given byteOrder.
    */
   Buffer asBuffer(ByteOrder byteOrder);
 
-  //UNSAFE BYTE BUFFER VIEW
-  /**
-   * Returns the specified region of this Memory object as a new read-only {@link ByteBuffer}
-   * object. The {@link ByteOrder} of the returned {@code ByteBuffer} corresponds to the {@linkplain
-   * #getTypeByteOrder() byte order of this Memory}. The returned ByteBuffer's position is 0 and
-   * the limit is equal to the capacity.
-   *
-   * <p>If this Memory object is the result of wrapping non-byte Java arrays ({@link
-   * Memory#wrap(int[])}, {@link Memory#wrap(long[])}, etc.) this methods throws an {@link
-   * UnsupportedOperationException}.
-   *
-   * <p>The name of this method starts with "unsafe" because if this is a native managed Memory
-   * (e. g. obtained via {@link #map(File)} or {@link WritableMemory#allocateDirect(long)})), and
-   * the returned {@code ByteBuffer} object is used after the Memory is freed, it may cause a JVM
-   * crash. This is also possible for Memory objects themselves with some methods,
-   * but Memory's use-after-free is caught as an AssertionError, if assertions are enabled.
-   *
-   * @param offsetBytes the starting offset with respect to the origin of this Memory
-   * @param capacityBytes the capacity of the returned ByteBuffer
-   * @return a new read-only {@code ByteBuffer} to access the specified region.
-   * @throws UnsupportedOperationException if this method couldn't be viewed as ByteBuffer, because
-   * when it wraps a non-byte Java array.
-   */
-  ByteBuffer unsafeByteBufferView(long offsetBytes, int capacityBytes);
-
   //ACCESS PRIMITIVE HEAP ARRAYS for readOnly
   /**
-   * Wraps the given primitive array for read operations assuming native byte order. If the array
-   * size is zero, backing storage and byte order of the returned <i>Memory</i> object are
-   * unspecified.
-   *
-   * <p><b>Note:</b> Always qualify this method with the class name, e.g.,
-   * <i>Memory.wrap(...)</i>.
-   * @param arr the given primitive array.
+   * Wraps the given primitive array for read operations assuming native byte order.
+   * @param array the given primitive array.
    * @return a new <i>Memory</i> for read operations
    */
-  static Memory wrap(boolean[] arr) {
-    return MemoryImpl.wrap(arr);
+  static Memory wrap(byte[] array) {
+    Objects.requireNonNull(array, "array must be non-null");
+    return wrap(array, 0, array.length, ByteOrder.nativeOrder());
   }
 
   /**
-   * Wraps the given primitive array for read operations assuming native byte order. If the array
-   * size is zero, backing storage and byte order of the returned <i>Memory</i> object are
-   * unspecified.
-   *
-   * <p><b>Note:</b> Always qualify this method with the class name, e.g.,
-   * <i>Memory.wrap(...)</i>.
-   * @param arr the given primitive array.
+   * Wraps the given primitive array for read operations with the given byte order.
+   * @param array the given primitive array.
+   * @param byteOrder the byte order to be used
    * @return a new <i>Memory</i> for read operations
    */
-  static Memory wrap(byte[] arr) {
-    return MemoryImpl.wrap(arr, 0, arr.length, Util.nativeByteOrder);
+  static Memory wrap(byte[] array, ByteOrder byteOrder) {
+    return wrap(array, 0, array.length, byteOrder);
   }
 
   /**
-   * Wraps the given primitive array for read operations with the given byte order. If the array
-   * size is zero, backing storage and byte order of the returned <i>Memory</i> object are
-   * unspecified.
-   *
-   * <p><b>Note:</b> Always qualify this method with the class name, e.g.,
-   * <i>Memory.wrap(...)</i>.
-   * @param arr the given primitive array.
+   * Wraps the given primitive array for read operations with the given byte order.
+   * @param array the given primitive array.
+   * @param offsetBytes the byte offset into the given array
+   * @param lengthBytes the number of bytes to include from the given array
    * @param byteOrder the byte order to be used
    * @return a new <i>Memory</i> for read operations
    */
-  static Memory wrap(byte[] arr, ByteOrder byteOrder) {
-    return MemoryImpl.wrap(arr, 0, arr.length, byteOrder);
+  static Memory wrap(byte[] array, int offsetBytes, int lengthBytes, ByteOrder byteOrder) {
+    Objects.requireNonNull(array, "array must be non-null");
+    Objects.requireNonNull(byteOrder, "byteOrder must be non-null");
+    negativeCheck(offsetBytes, "offsetBytes");
+    negativeCheck(lengthBytes, "lengthBytes");
+    UnsafeUtil.checkBounds(offsetBytes, lengthBytes, array.length);
+    return BaseWritableMemoryImpl.wrapHeapArray(array, 0, lengthBytes, true, ByteOrder.nativeOrder(), null);
   }
 
   /**
-   * Wraps the given primitive array for read operations with the given byte order. If the given
-   * lengthBytes is zero, backing storage and byte order of the returned <i>Memory</i> object are
-   * unspecified.
-   *
-   * <p><b>Note:</b> Always qualify this method with the class name, e.g.,
-   * <i>Memory.wrap(...)</i>.
-   * @param arr the given primitive array.
-   * @param offsetBytes the byte offset into the given array
-   * @param lengthBytes the number of bytes to include from the given array
-   * @param byteOrder the byte order to be used
+   * Wraps the given primitive array for read operations assuming native byte order.
+   * @param array the given primitive array.
    * @return a new <i>Memory</i> for read operations
    */
-  static Memory wrap(byte[] arr, int offsetBytes, int lengthBytes,
-      ByteOrder byteOrder) {
-    return MemoryImpl.wrap(arr, offsetBytes, lengthBytes, byteOrder);
+  static Memory wrap(boolean[] array) {
+    Objects.requireNonNull(array, "array must be non-null");
+    final long lengthBytes = array.length << Prim.BOOLEAN.shift();
+    return BaseWritableMemoryImpl.wrapHeapArray(array, 0, lengthBytes, true, ByteOrder.nativeOrder(), null);
   }
 
   /**
-   * Wraps the given primitive array for read operations assuming native byte order. If the array
-   * size is zero, backing storage and byte order of the returned <i>Memory</i> object are unspecified.
-   *
-   * <p><b>Note:</b> Always qualify this method with the class name, e.g.,
-   * <i>Memory.wrap(...)</i>.
-   * @param arr the given primitive array.
+   * Wraps the given primitive array for read operations assuming native byte order.
+   * @param array the given primitive array.
    * @return a new <i>Memory</i> for read operations
    */
-  static Memory wrap(char[] arr) {
-    return MemoryImpl.wrap(arr);
+  static Memory wrap(char[] array) {
+    Objects.requireNonNull(array, "array must be non-null");
+    final long lengthBytes = array.length << Prim.CHAR.shift();
+    return BaseWritableMemoryImpl.wrapHeapArray(array, 0L, lengthBytes, true, ByteOrder.nativeOrder(), null);
   }
 
   /**
-   * Wraps the given primitive array for read operations assuming native byte order. If the array
-   * size is zero, backing storage and byte order of the returned <i>Memory</i> object are unspecified.
-   *
-   * <p><b>Note:</b> Always qualify this method with the class name, e.g.,
-   * <i>Memory.wrap(...)</i>.
-   * @param arr the given primitive array.
+   * Wraps the given primitive array for read operations assuming native byte order.
+   * @param array the given primitive array.
    * @return a new <i>Memory</i> for read operations
    */
-  static Memory wrap(short[] arr) {
-    return MemoryImpl.wrap(arr);
+  static Memory wrap(short[] array) {
+    Objects.requireNonNull(array, "arr must be non-null");
+    final long lengthBytes = array.length << Prim.SHORT.shift();
+    return BaseWritableMemoryImpl.wrapHeapArray(array, 0L, lengthBytes, true, ByteOrder.nativeOrder(), null);
   }
 
   /**
-   * Wraps the given primitive array for read operations assuming native byte order. If the array
-   * size is zero, backing storage and byte order of the returned <i>Memory</i> object are unspecified.
-   *
-   * <p><b>Note:</b> Always qualify this method with the class name, e.g.,
-   * <i>Memory.wrap(...)</i>.
-   * @param arr the given primitive array.
+   * Wraps the given primitive array for read operations assuming native byte order.
+   * @param array the given primitive array.
    * @return a new <i>Memory</i> for read operations
    */
-  static Memory wrap(int[] arr) {
-    return MemoryImpl.wrap(arr);
+  static Memory wrap(int[] array) {
+    Objects.requireNonNull(array, "arr must be non-null");
+    final long lengthBytes = array.length << Prim.INT.shift();
+    return BaseWritableMemoryImpl.wrapHeapArray(array, 0L, lengthBytes, true, ByteOrder.nativeOrder(), null);
   }
 
   /**
-   * Wraps the given primitive array for read operations assuming native byte order. If the array
-   * size is zero, backing storage and byte order of the returned <i>Memory</i> object are
-   * unspecified.
-   *
-   * <p><b>Note:</b> Always qualify this method with the class name, e.g.,
-   * <i>Memory.wrap(...)</i>.
-   * @param arr the given primitive array.
+   * Wraps the given primitive array for read operations assuming native byte order.
+   * @param array the given primitive array.
    * @return a new <i>Memory</i> for read operations
    */
-  static Memory wrap(long[] arr) {
-    return MemoryImpl.wrap(arr);
+  static Memory wrap(long[] array) {
+    Objects.requireNonNull(array, "arr must be non-null");
+    final long lengthBytes = array.length << Prim.LONG.shift();
+    return BaseWritableMemoryImpl.wrapHeapArray(array, 0L, lengthBytes, true, ByteOrder.nativeOrder(), null);
   }
 
   /**
-   * Wraps the given primitive array for read operations assuming native byte order. If the array
-   * size is zero, backing storage and byte order of the returned <i>Memory</i> object are
-   * unspecified.
-   *
-   * <p><b>Note:</b> Always qualify this method with the class name, e.g.,
-   * <i>Memory.wrap(...)</i>.
-   * @param arr the given primitive array.
+   * Wraps the given primitive array for read operations assuming native byte order.
+   * @param array the given primitive array.
    * @return a new <i>Memory</i> for read operations
    */
-  static Memory wrap(float[] arr) {
-    return MemoryImpl.wrap(arr);
+  static Memory wrap(float[] array) {
+    Objects.requireNonNull(array, "arr must be non-null");
+    final long lengthBytes = array.length << Prim.FLOAT.shift();
+    return BaseWritableMemoryImpl.wrapHeapArray(array, 0L, lengthBytes, true, ByteOrder.nativeOrder(), null);
   }
 
   /**
-   * Wraps the given primitive array for read operations assuming native byte order. If the array
-   * size is zero, backing storage and byte order of the returned <i>Memory</i> object are
-   * unspecified.
-   *
-   * <p><b>Note:</b> Always qualify this method with the class name, e.g.,
-   * <i>Memory.wrap(...)</i>.
-   * @param arr the given primitive array.
+   * Wraps the given primitive array for read operations assuming native byte order.
+   * @param array the given primitive array.
    * @return a new <i>Memory</i> for read operations
    */
-  static Memory wrap(double[] arr) {
-    return MemoryImpl.wrap(arr);
+  static Memory wrap(double[] array) {
+    Objects.requireNonNull(array, "arr must be non-null");
+    final long lengthBytes = array.length << Prim.DOUBLE.shift();
+    return BaseWritableMemoryImpl.wrapHeapArray(array, 0L, lengthBytes, true, ByteOrder.nativeOrder(), null);
   }
 
   //PRIMITIVE getX() and getXArray()
diff --git a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/MemoryRequestServer.java b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/MemoryRequestServer.java
index d61552f..fa0c20b 100644
--- a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/MemoryRequestServer.java
+++ b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/MemoryRequestServer.java
@@ -30,18 +30,21 @@ package org.apache.datasketches.memory;
 public interface MemoryRequestServer {
 
   /**
-   * Request new WritableMemory with the given capacity.
-   * @param capacityBytes The capacity being requested.
+   * Request new WritableMemory with the given capacity. The current Writable Memory will be used to
+   * determine the byte order of the returned WritableMemory and other checks.
+   * @param currentWritableMemory the current writableMemory of the client. It must be non-null.
+   * @param capacityBytes The capacity being requested. It must be >0.
+   *
    * @return new WritableMemory with the given capacity.
    */
-  WritableMemory request(long capacityBytes);
+  WritableMemory request(WritableMemory currentWritableMemory, long capacityBytes);
 
   /**
    * Request close the AutoCloseable resource.
    * This may be ignored depending on the application implementation.
-   * @param memToClose the relevant WritbleMemory to be considered for closing.
-   * @param newMemory the newly allocated WritableMemory. This is returned from the client
-   * for the convenience of the resource owner. It is optional and may be null.
+   * @param memToClose the relevant WritbleMemory to be considered for closing. It must be non-null.
+   * @param newMemory the newly allocated WritableMemory. It must be non-null.
+   * This is returned from the client to facilitate tracking for the convenience of the resource owner.
    */
   void requestClose(final WritableMemory memToClose, WritableMemory newMemory);
 
diff --git a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/ReadOnlyException.java b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/ReadOnlyException.java
similarity index 90%
rename from datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/ReadOnlyException.java
rename to datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/ReadOnlyException.java
index 5bc8391..3e14795 100644
--- a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/ReadOnlyException.java
+++ b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/ReadOnlyException.java
@@ -17,14 +17,14 @@
  * under the License.
  */
 
-package org.apache.datasketches.memory.internal;
+package org.apache.datasketches.memory;
 
 /**
  * The exception thrown when attempting to write into a read-only Resource.
  *
  * @author Praveenkumar Venkatesan
  */
-public class ReadOnlyException extends UnsupportedOperationException {
+public class ReadOnlyException extends MemoryException {
     private static final long serialVersionUID = 1L;
 
     /**
diff --git a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/WritableBuffer.java b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/WritableBuffer.java
index 9cfd4a5..877c43b 100644
--- a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/WritableBuffer.java
+++ b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/WritableBuffer.java
@@ -22,41 +22,47 @@ package org.apache.datasketches.memory;
 
 import java.nio.ByteBuffer;
 import java.nio.ByteOrder;
+import java.util.Objects;
 
-import org.apache.datasketches.memory.internal.WritableBufferImpl;
+import org.apache.datasketches.memory.internal.BaseWritableBufferImpl;
+import org.apache.datasketches.memory.internal.Util;
 
 public interface WritableBuffer extends Buffer {
 
   //BYTE BUFFER
   /**
-   * Accesses the given ByteBuffer for write operations. The returned WritableBuffer object has
-   * the same byte order, as the given ByteBuffer, unless the capacity of the given ByteBuffer is
-   * zero, then byte order of the returned WritableBuffer object, as well as backing storage and
-   * read-only status are unspecified.
-   * @param byteBuf the given ByteBuffer, must not be null.
-   * @return a new WritableBuffer for write operations on the given ByteBuffer.
+   * Accesses the given <i>ByteBuffer</i> for write operations. The returned <i>WritableBuffer</i> object has
+   * the same byte order, as the given <i>ByteBuffer</i>.
+   * @param byteBuf the given ByteBuffer. It must be non-null and with capacity >= 0.
+   * @return a new <i>WritableBuffer</i> for write operations on the given <i>ByteBuffer</i>.
    */
   static WritableBuffer writableWrap(ByteBuffer byteBuf) {
-    return WritableBufferImpl.writableWrap(byteBuf);
+    return writableWrap(byteBuf, byteBuf.order(), defaultMemReqSvr);
   }
 
   /**
-   * Accesses the given ByteBuffer for write operations. The returned WritableBuffer object has
-   * the given byte order, ignoring the byte order of the given ByteBuffer. If the capacity of
-   * the given ByteBuffer is zero the byte order of the returned WritableBuffer object
-   * (as well as backing storage) is unspecified.
-   * @param byteBuf the given ByteBuffer, must not be null
-   * @param byteOrder the byte order to be used, which may be independent of the byte order
-   * state of the given ByteBuffer
-   * @param memReqSvr A user-specified MemoryRequestServer.
-   * This is a callback mechanism for a user client to request a larger Memory.
-   * @return a new WritableBuffer for write operations on the given ByteBuffer.
+   * Accesses the given <i>ByteBuffer</i> for write operations. The returned <i>WritableBuffer</i> object has
+   * the given byte order, ignoring the byte order of the given <i>ByteBuffer</i> for future writes and following reads.
+   * However, this does not change the byte order of data already in the <i>ByteBuffer</i>.
+   * @param byteBuf the given ByteBuffer. It must be non-null and with capacity >= 0.
+   * @param byteOrder the byte order to be used.
+   * @param memReqSvr A user-specified <i>MemoryRequestServer</i>, which must not be null.
+   * This is a callback mechanism for a user client to request a larger <i>WritableBuffer</i>.
+   * @return a new <i>WritableBuffer</i> for write operations on the given <i>ByteBuffer</i>.
    */
   static WritableBuffer writableWrap(ByteBuffer byteBuf, ByteOrder byteOrder, MemoryRequestServer memReqSvr) {
-    MemoryRequestServer mReqSvr = (memReqSvr == null) ? defaultMemReqSvr : memReqSvr;
-    return WritableBufferImpl.writableWrap(byteBuf, byteOrder, mReqSvr);
+    Objects.requireNonNull(byteBuf, "ByteBuffer 'byteBuf' must not be null");
+    Objects.requireNonNull(byteOrder, "ByteOrder 'byteOrder' must not be null");
+    Util.negativeCheck(byteBuf.capacity(), "byteBuf.capacity");
+    if (byteBuf.isReadOnly()) {
+      throw new ReadOnlyException("Cannot create a WritableBuffer from a ReadOnly ByteBuffer.");
+    }
+    return BaseWritableBufferImpl.wrapByteBuffer(byteBuf, false, byteOrder, memReqSvr);
   }
 
+  // NO MAP
+  // NO ALLOCATE DIRECT
+
   //DUPLICATES
   /**
    * Returns a duplicate writable view of this Buffer with the same but independent values of
@@ -70,8 +76,6 @@ public interface WritableBuffer extends Buffer {
    * <li>Returned object's <i>start</i>, <i>position</i> and <i>end</i> are mutable and
    * independent of this object's <i>start</i>, <i>position</i> and <i>end</i></li>
    * </ul>
-   * If this object's capacity is zero, the returned object is effectively immutable and
-   * the backing storage and byte order are unspecified.
    * @return a duplicate writable view of this Buffer with the same but independent values of
    * <i>start</i>, <i>position</i> and <i>end</i>.
    */
@@ -89,15 +93,12 @@ public interface WritableBuffer extends Buffer {
    * <li>Returned object's <i>start</i>, <i>position</i> and <i>end</i> are mutable and
    * independent of this object's <i>start</i>, <i>position</i> and <i>end</i></li>
    * </ul>
-   * If this object's capacity is zero, the returned object is effectively immutable and
-   * the backing storage and byte order are unspecified.
    * @param byteOrder the given <i>ByteOrder</i>.
    * @return a duplicate writable view of this Buffer with the same but independent values of
    * <i>start</i>, <i>position</i> and <i>end</i>.
    */
   WritableBuffer writableDuplicate(ByteOrder byteOrder);
 
-
   //REGIONS
   /**
    * A writable region is a writable view of this object.
@@ -110,8 +111,6 @@ public interface WritableBuffer extends Buffer {
    * <li>Returned object's <i>start</i>, <i>position</i> and <i>end</i> are mutable and
    * independent of this object's <i>start</i>, <i>position</i> and <i>end</i></li>
    * </ul>
-   * If this object's capacity is zero, the returned object is effectively immutable and
-   * the backing storage and byte order are unspecified.
    * @return a new <i>WritableBuffer</i> representing the defined writable region.
    */
   WritableBuffer writableRegion();
@@ -128,8 +127,6 @@ public interface WritableBuffer extends Buffer {
    * independent of this object's <i>start</i>, <i>position</i> and <i>end</i></li>
    * <li>Returned object's byte order = <i>byteOrder</i></li>
    * </ul>
-   * If this object's capacity is zero, the returned object is effectively immutable and
-   * the backing storage and byte order are unspecified.
    *
    * <p><b>Note: </b><i>asWritableMemory()</i> and <i>asMemory()</i>
    * will return the originating <i>Memory</i> byte order.</p>
@@ -142,14 +139,28 @@ public interface WritableBuffer extends Buffer {
   WritableBuffer writableRegion(long offsetBytes, long capacityBytes,
       ByteOrder byteOrder);
 
-  //AS MEMORY
+  //AS WRITABLE MEMORY
   /**
    * Convert this WritableBuffer to a WritableMemory.
    * If this object's capacity is zero, the returned object is effectively immutable and
    * the backing storage and byte order are unspecified.
    * @return WritableMemory
    */
-  WritableMemory asWritableMemory();
+  default WritableMemory asWritableMemory() {
+    return asWritableMemory(ByteOrder.nativeOrder());
+  }
+
+  /**
+   * Convert this WritableBuffer to a WritableMemory with the given byte order.
+   * If this object's capacity is zero, the returned object is effectively immutable and
+   * the backing storage and byte order are unspecified.
+   * @return WritableMemory
+   */
+  WritableMemory asWritableMemory(ByteOrder byteOrder);
+
+  //NO ALLOCATE HEAP VIA AUTOMATIC BYTE ARRAY
+
+  //NO ACCESS PRIMITIVE HEAP ARRAYS for WRITE
 
   //PRIMITIVE putX() and putXArray()
   /**
@@ -345,6 +356,8 @@ public interface WritableBuffer extends Buffer {
    */
   void putShortArray(short[] srcArray, int srcOffsetShorts, int lengthShorts);
 
+  // NO ATOMIC METHODS
+
   //OTHER WRITE METHODS
   /**
    * Returns the primitive backing array, otherwise null.
@@ -357,6 +370,8 @@ public interface WritableBuffer extends Buffer {
    */
   void clear();
 
+  //NO clearBits(...)
+
   /**
    * Fills this Buffer from position to end with the given byte value.
    * The position will be set to <i>end</i>.
@@ -364,6 +379,10 @@ public interface WritableBuffer extends Buffer {
    */
   void fill(byte value);
 
+  //NO fill(offsetBytes, lengthBytes, value)
+
+  //NO setBits(...)
+
   //OTHER WRITABLE API METHODS
   /**
    * For ByteBuffer and Direct Memory backed resources only. Heap and Map backed resources will return null.
diff --git a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/WritableMemory.java b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/WritableMemory.java
index 350836f..889a5a8 100644
--- a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/WritableMemory.java
+++ b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/WritableMemory.java
@@ -20,120 +20,131 @@
 
 package org.apache.datasketches.memory;
 
+import static org.apache.datasketches.memory.internal.Util.negativeCheck;
+
 import java.io.File;
 import java.nio.ByteBuffer;
 import java.nio.ByteOrder;
+import java.util.Objects;
 
-import org.apache.datasketches.memory.internal.WritableMemoryImpl;
+import org.apache.datasketches.memory.internal.BaseWritableMemoryImpl;
+import org.apache.datasketches.memory.internal.Prim;
+import org.apache.datasketches.memory.internal.UnsafeUtil;
 
 public interface WritableMemory extends Memory {
 
   //BYTE BUFFER
   /**
-   * Accesses the given ByteBuffer for write operations. The returned WritableMemory object has
-   * the same byte order, as the given ByteBuffer, unless the capacity of the given ByteBuffer is
-   * zero, then byte order of the returned WritableMemory object, as well as backing storage and
-   * read-only status are unspecified.
-   * @param byteBuf the given ByteBuffer
-   * @return a new WritableMemory for write operations on the given ByteBuffer.
+   * Accesses the given <i>ByteBuffer</i> for write operations. The returned <i>WritableMemory</i> object has
+   * the same byte order, as the given <i>ByteBuffer</i>.
+   * @param byteBuffer the given <i>ByteBuffer</i>. It must be non-null, with capacity >= 0, and writable.
+   * @return a new <i>WritableMemory</i> for write operations on the given <i>ByteBuffer</i>.
+   */
+  static WritableMemory writableWrap(ByteBuffer byteBuffer) {
+    return writableWrap(byteBuffer, byteBuffer.order(), defaultMemReqSvr);
+  }
+
+  /**
+   * Accesses the given <i>ByteBuffer</i> for write operations. The returned <i>WritableMemory</i> object has
+   * the given byte order, ignoring the byte order of the given <i>ByteBuffer</i> for future writes and following reads.
+   * However, this does not change the byte order of data already in the <i>ByteBuffer</i>.
+   * @param byteBuffer the given <i>ByteBuffer</i>. It must be non-null, with capacity >= 0, and writable.
+   * @param byteOrder the byte order to be used. It must be non-null.
+   * @return a new <i>WritableMemory</i> for write operations on the given <i>ByteBuffer</i>.
    */
-  static WritableMemory writableWrap(ByteBuffer byteBuf) {
-    return WritableMemoryImpl.writableWrap(byteBuf);
+  static WritableMemory writableWrap(ByteBuffer byteBuffer, ByteOrder byteOrder) {
+    return writableWrap(byteBuffer, byteOrder, defaultMemReqSvr);
   }
 
   /**
-   * Accesses the given ByteBuffer for write operations. The returned WritableMemory object has
-   * the given byte order, ignoring the byte order of the given ByteBuffer. If the capacity of
-   * the given ByteBuffer is zero the byte order of the returned WritableMemory object
-   * (as well as backing storage) is unspecified.
-   * @param byteBuf the given ByteBuffer, must not be null
-   * @param byteOrder the byte order to be used when reading and writing to the ByteBuffer.
-   * This is independent of the byte order state of the given ByteBuffer.
-   * @param memReqSvr A user-specified MemoryRequestServer. If null, the DefaultMemoryRequestServer is used.
-   * This is a callback mechanism for a user client to request a larger Memory.
-   * @return a new WritableMemory for write operations on the given ByteBuffer.
-   */
-  static WritableMemory writableWrap(ByteBuffer byteBuf, ByteOrder byteOrder, MemoryRequestServer memReqSvr) {
-    MemoryRequestServer mReqSvr = (memReqSvr == null) ? defaultMemReqSvr : memReqSvr;
-    return WritableMemoryImpl.writableWrap(byteBuf, byteOrder, mReqSvr);
+   * Accesses the given <i>ByteBuffer</i> for write operations. The returned <i>WritableMemory</i> object has
+   * the given byte order, ignoring the byte order of the given <i>ByteBuffer</i> for future reads and writes.
+   * However, this does not change the byte order of data already in the <i>ByteBuffer</i>.
+   * @param byteBuffer the given <i>ByteBuffer</i>. It must be non-null, with capacity >= 0, and writable.
+   * @param byteOrder the byte order to be used. It must be non-null.
+   * @param memReqSvr A user-specified <i>MemoryRequestServer</i>, which may be null.
+   * This is a callback mechanism for a user client to request a larger <i>WritableMemory</i>.
+   * @return a new <i>WritableMemory</i> for write operations on the given <i>ByteBuffer</i>.
+   */
+  static WritableMemory writableWrap(ByteBuffer byteBuffer, ByteOrder byteOrder, MemoryRequestServer memReqSvr) {
+    Objects.requireNonNull(byteBuffer, "byteBuffer must be non-null");
+    Objects.requireNonNull(byteOrder, "byteOrder must be non-null");
+    negativeCheck(byteBuffer.capacity(), "byteBuffer");
+    if (byteBuffer.isReadOnly()) { throw new ReadOnlyException("byteBuffer must be writable."); }
+    return BaseWritableMemoryImpl.wrapByteBuffer(byteBuffer, false, byteOrder, memReqSvr);
   }
 
   //MAP
   /**
    * Maps the entire given file into native-ordered WritableMemory for write operations
-   * (including those &gt; 2GB). Calling this method is equivalent to calling
-   * {@link #writableMap(File, long, long, ByteOrder) map(file, 0, file.length(), ByteOrder.nativeOrder())}.
-   *
-   * <p><b>Note:</b> Always qualify this method with the class name, e.g.,
-   * <i>WritableMemory.map(...)</i>.
-   * @param file the given file to map
+   * Calling this method is equivalent to calling
+   * {@link #writableMap(File, long, long, ByteOrder) writableMap(file, 0, file.length(), ByteOrder.nativeOrder())}.
+   * @param file the given file to map. It must be non-null, with length > 0, and writable.
    * @return WritableMapHandle for managing the mapped Memory.
    * Please read Javadocs for {@link Handle}.
    */
   static WritableMapHandle writableMap(File file) {
-    return WritableMemoryImpl.writableMap(file);
+    return writableMap(file, 0, file.length(), ByteOrder.nativeOrder());
   }
 
   /**
-   * Maps the specified portion of the given file into Memory for write operations
-   * (including those &gt; 2GB).
+   * Maps the specified portion of the given file into Memory for write operations.
    *
    * <p><b>Note:</b> Always qualify this method with the class name, e.g.,
    * <i>WritableMemory.map(...)</i>.
-   * @param file the given file to map. It may not be null.
-   * @param fileOffsetBytes the position in the given file in bytes. It may not be negative.
-   * @param capacityBytes the size of the mapped Memory. It may not be negative or zero.
-   * @param byteOrder the byte order to be used for the given file. It may not be null.
+   * @param file the given file to map. It must be non-null and writable.
+   * @param fileOffsetBytes the position in the given file in bytes. It must not be negative.
+   * @param capacityBytes the size of the mapped Memory. It must not be negative.
+   * @param byteOrder the byte order to be used for the given file. It must be non-null.
    * @return WritableMapHandle for managing the mapped Memory.
    * Please read Javadocs for {@link Handle}.
    */
   static WritableMapHandle writableMap(File file, long fileOffsetBytes, long capacityBytes, ByteOrder byteOrder) {
-    return WritableMemoryImpl.writableMap(file, fileOffsetBytes, capacityBytes, byteOrder);
+    Objects.requireNonNull(file, "file must be non-null.");
+    Objects.requireNonNull(byteOrder, "byteOrder must be non-null.");
+    if (!file.canWrite()) { throw new ReadOnlyException("file must be writable."); }
+    negativeCheck(fileOffsetBytes, "fileOffsetBytes");
+    negativeCheck(capacityBytes, "capacityBytes");
+    return BaseWritableMemoryImpl.wrapMap(file, fileOffsetBytes, capacityBytes, false, byteOrder);
   }
 
   //ALLOCATE DIRECT
   /**
-   * Allocates and provides access to capacityBytes directly in native (off-heap) memory
-   * leveraging the WritableMemory API. Native byte order is assumed.
+   * Allocates and provides access to capacityBytes directly in native (off-heap) memory.
+   * Native byte order is assumed.
    * The allocated memory will be 8-byte aligned, but may not be page aligned.
-   * If capacityBytes is zero, byte order, backing storage and read-only status
-   * of the WritableMemory object, returned from {@link WritableHandle#getWritable()} are unspecified.
-   *
-   * <p>The default MemoryRequestServer, which allocates any request for memory onto the heap,
-   * will be used.</p>
    *
-   * <p><b>NOTE:</b> Native/Direct memory acquired using Unsafe may have garbage in it.
-   * It is the responsibility of the using class to clear this memory, if required,
+   * <p><b>NOTE:</b> Native/Direct memory acquired may have garbage in it.
+   * It is the responsibility of the using application to clear this memory, if required,
    * and to call <i>close()</i> when done.</p>
    *
-   * @param capacityBytes the size of the desired memory in bytes.
+   * @param capacityBytes the size of the desired memory in bytes. It must be >= 0.
    * @return WritableHandle for this off-heap resource.
    * Please read Javadocs for {@link Handle}.
    */
   static WritableHandle allocateDirect(long capacityBytes) {
-    return WritableMemoryImpl.allocateDirect(capacityBytes);
+    return allocateDirect(capacityBytes, ByteOrder.nativeOrder(), defaultMemReqSvr);
   }
 
   /**
-   * Allocates and provides access to capacityBytes directly in native (off-heap) memory
-   * leveraging the WritableMemory API. The allocated memory will be 8-byte aligned, but may not
-   * be page aligned. If capacityBytes is zero, byte order, backing storage and read-only status
-   * of the WritableMemory object, returned from {@link WritableHandle#get()} are unspecified.
+   * Allocates and provides access to capacityBytes directly in native (off-heap) memory.
+   * The allocated memory will be 8-byte aligned, but may not be page aligned.
    *
-   * <p><b>NOTE:</b> Native/Direct memory acquired using Unsafe may have garbage in it.
-   * It is the responsibility of the using class to clear this memory, if required,
+   * <p><b>NOTE:</b> Native/Direct memory acquired may have garbage in it.
+   * It is the responsibility of the using application to clear this memory, if required,
    * and to call <i>close()</i> when done.</p>
    *
-   * @param capacityBytes the size of the desired memory in bytes.
-   * @param byteOrder the given byte order
-   * @param memReqSvr A user-specified MemoryRequestServer.
+   * @param capacityBytes the size of the desired memory in bytes. It must be >= 0.
+   * @param byteOrder the given byte order. It must be non-null.
+   * @param memReqSvr A user-specified MemoryRequestServer, which may be null.
    * This is a callback mechanism for a user client of direct memory to request more memory.
    * @return WritableHandle for this off-heap resource.
    * Please read Javadocs for {@link Handle}.
    */
   static WritableHandle allocateDirect(long capacityBytes, ByteOrder byteOrder, MemoryRequestServer memReqSvr) {
-    MemoryRequestServer mReqSvr = (memReqSvr == null) ? defaultMemReqSvr : memReqSvr;
-    return WritableMemoryImpl.allocateDirect(capacityBytes, byteOrder, mReqSvr);
+    Objects.requireNonNull(byteOrder, "byteOrder must be non-null");
+    negativeCheck(capacityBytes, "capacityBytes");
+    return BaseWritableMemoryImpl.wrapDirect(capacityBytes, byteOrder, memReqSvr);
   }
 
   //REGIONS
@@ -145,14 +156,14 @@ public interface WritableMemory extends Memory {
    * <li>Returned object's origin = this objects' origin + <i>offsetBytes</i></li>
    * <li>Returned object's capacity = <i>capacityBytes</i></li>
    * </ul>
-   * If the given capacityBytes is zero, the returned object is effectively immutable and
-   * the backing storage and byte order are unspecified.
    *
-   * @param offsetBytes the starting offset with respect to this object.
-   * @param capacityBytes the capacity of the returned object in bytes.
+   * @param offsetBytes the starting offset with respect to this object. It must be >=0.
+   * @param capacityBytes the capacity of the returned object in bytes. It must be >= 0.
    * @return a new <i>WritableMemory</i> representing the defined writable region.
    */
-  WritableMemory writableRegion(long offsetBytes, long capacityBytes);
+  default WritableMemory writableRegion(long offsetBytes, long capacityBytes) {
+    return writableRegion(offsetBytes, capacityBytes, ByteOrder.nativeOrder());
+  }
 
   /**
    * A writable region is a writable view of this object.
@@ -163,17 +174,15 @@ public interface WritableMemory extends Memory {
    * <li>Returned object's capacity = <i>capacityBytes</i></li>
    * <li>Returned object's byte order = <i>byteOrder</i></li>
    * </ul>
-   * If the given capacityBytes is zero, the returned object is effectively immutable and
-   * the backing storage and byte order are unspecified.
    *
-   * @param offsetBytes the starting offset with respect to this object.
-   * @param capacityBytes the capacity of the returned object in bytes.
-   * @param byteOrder the given byte order
+   * @param offsetBytes the starting offset with respect to this object. It must be >=0.
+   * @param capacityBytes the capacity of the returned object in bytes. It must be >= 0.
+   * @param byteOrder the given byte order. It must be non-null.
    * @return a new <i>WritableMemory</i> representing the defined writable region.
    */
   WritableMemory writableRegion(long offsetBytes, long capacityBytes, ByteOrder byteOrder);
 
-  //AS BUFFER
+  //AS WRITABLE BUFFER
   /**
    * Returns a new <i>WritableBuffer</i> with a writable view of this object.
    * <ul>
@@ -184,11 +193,11 @@ public interface WritableMemory extends Memory {
    * <li>Returned object's <i>capacity</i> = this object's capacity</li>
    * <li>Returned object's <i>start</i>, <i>position</i> and <i>end</i> are mutable</li>
    * </ul>
-   * If this object's capacity is zero, the returned object is effectively immutable and
-   * the backing storage and byte order are unspecified.
    * @return a new <i>WritableBuffer</i> with a view of this WritableMemory
    */
-  WritableBuffer asWritableBuffer();
+  default WritableBuffer asWritableBuffer() {
+    return asWritableBuffer(getTypeByteOrder());
+  }
 
   /**
    * Returns a new <i>WritableBuffer</i> with a writable view of this object
@@ -201,8 +210,6 @@ public interface WritableMemory extends Memory {
    * <li>Returned object's <i>capacity</i> = this object's capacity</li>
    * <li>Returned object's <i>start</i>, <i>position</i> and <i>end</i> are mutable</li>
    * </ul>
-   * If this object's capacity is zero, the returned object is effectively immutable and
-   * the backing storage and byte order are unspecified.
    * @param byteOrder the given byte order
    * @return a new <i>WritableBuffer</i> with a view of this WritableMemory
    */
@@ -211,70 +218,79 @@ public interface WritableMemory extends Memory {
 
   //ALLOCATE HEAP VIA AUTOMATIC BYTE ARRAY
   /**
-   * Creates on-heap WritableMemory with the given capacity and the native byte order. If the given
-   * capacityBytes is zero, backing storage, byte order and read-only status of the returned
-   * WritableMemory object are unspecified.
-   * @param capacityBytes the given capacity in bytes.
+   * Creates on-heap WritableMemory with the given capacity and the native byte order.
+   * @param capacityBytes the given capacity in bytes. It must be >= 0.
    * @return a new WritableMemory for write operations on a new byte array.
    */
   static WritableMemory allocate(int capacityBytes) {
-    return WritableMemoryImpl.allocate(capacityBytes);
+    return allocate(capacityBytes, ByteOrder.nativeOrder(), defaultMemReqSvr);
   }
 
   /**
-   * Creates on-heap WritableMemory with the given capacity and the given byte order. If the given
-   * capacityBytes is zero, backing storage, byte order and read-only status of the returned
-   * WritableMemory object are unspecified.
-   * @param capacityBytes the given capacity in bytes.
-   * @param byteOrder the given byte order to allocate new Memory object with.
+   * Creates on-heap WritableMemory with the given capacity and the given byte order.
+   * @param capacityBytes the given capacity in bytes. It must be >= 0.
+   * @param byteOrder the given byte order to allocate new Memory object with. It must be non-null.
    * @return a new WritableMemory for write operations on a new byte array.
    */
   static WritableMemory allocate(int capacityBytes, ByteOrder byteOrder) {
-    return WritableMemoryImpl.allocate(capacityBytes, byteOrder);
+    return allocate(capacityBytes, byteOrder, defaultMemReqSvr);
   }
 
-  //ACCESS PRIMITIVE HEAP ARRAYS for write
   /**
-   * Wraps the given primitive array for write operations assuming native byte order. If the array
-   * size is zero, backing storage, byte order and read-only status of the returned WritableMemory
-   * object are unspecified.
+   * Creates on-heap WritableMemory with the given capacity and the given byte order.
+   * @param capacityBytes the given capacity in bytes. It must be >= 0.
+   * @param byteOrder the given byte order to allocate new Memory object with. It must be non-null.
+   * @param memReqSvr A user-specified <i>MemoryRequestServer</i>, which may be null.
+   * This is a callback mechanism for a user client to request a larger <i>WritableMemory</i>.
+   * @return a new WritableMemory for write operations on a new byte array.
+   */
+  static WritableMemory allocate(int capacityBytes, ByteOrder byteOrder, MemoryRequestServer memReqSvr) {
+    byte[] arr = new byte[capacityBytes];
+    negativeCheck(capacityBytes, "capacityBytes");
+    return writableWrap(arr, 0, capacityBytes, byteOrder, memReqSvr);
+  }
+
+
+  //ACCESS PRIMITIVE HEAP ARRAYS for WRITE
+
+  /**
+   * Wraps the given primitive array for write operations assuming native byte order.
    *
    * <p><b>Note:</b> Always qualify this method with the class name, e.g.,
    * <i>WritableMemory.wrap(...)</i>.
-   * @param arr the given primitive array.
+   * @param array the given primitive array. It must be non-null.
    * @return a new WritableMemory for write operations on the given primitive array.
    */
-  static WritableMemory writableWrap(boolean[] arr) {
-    return WritableMemoryImpl.writableWrap(arr);
+  static WritableMemory writableWrap(byte[] array) {
+    return writableWrap(array, 0, array.length, ByteOrder.nativeOrder(), defaultMemReqSvr);
   }
 
   /**
-   * Wraps the given primitive array for write operations assuming native byte order. If the array
-   * size is zero, backing storage, byte order and read-only status of the returned WritableMemory
-   * object are unspecified.
+   * Wraps the given primitive array for write operations with the given byte order.
    *
    * <p><b>Note:</b> Always qualify this method with the class name, e.g.,
    * <i>WritableMemory.wrap(...)</i>.
-   * @param arr the given primitive array.
+   * @param array the given primitive array. It must be non-null.
+   * @param byteOrder the byte order to be used. It must be non-null.
    * @return a new WritableMemory for write operations on the given primitive array.
    */
-  static WritableMemory writableWrap(byte[] arr) {
-    return WritableMemoryImpl.writableWrap(arr);
+  static WritableMemory writableWrap(byte[] array, ByteOrder byteOrder) {
+    return writableWrap(array, 0, array.length, byteOrder, defaultMemReqSvr);
   }
 
   /**
-   * Wraps the given primitive array for write operations with the given byte order. If the array
-   * size is zero, backing storage, byte order and read-only status of the returned WritableMemory
-   * object are unspecified.
+   * Wraps the given primitive array for write operations with the given byte order.
    *
    * <p><b>Note:</b> Always qualify this method with the class name, e.g.,
    * <i>WritableMemory.wrap(...)</i>.
-   * @param arr the given primitive array.
-   * @param byteOrder the byte order to be used
+   * @param array the given primitive array. It must be non-null.
+   * @param offsetBytes the byte offset into the given array. It must be >=0.
+   * @param lengthBytes the number of bytes to include from the given array. It must be >=0.
+   * @param byteOrder the byte order to be used. It must be non-null.
    * @return a new WritableMemory for write operations on the given primitive array.
    */
-  static WritableMemory writableWrap(byte[] arr, ByteOrder byteOrder) {
-    return WritableMemoryImpl.writableWrap(arr, byteOrder);
+  static WritableMemory writableWrap(byte[] array, int offsetBytes, int lengthBytes, ByteOrder byteOrder) {
+    return writableWrap(array, offsetBytes, lengthBytes, byteOrder, defaultMemReqSvr);
   }
 
   /**
@@ -284,99 +300,99 @@ public interface WritableMemory extends Memory {
    *
    * <p><b>Note:</b> Always qualify this method with the class name, e.g.,
    * <i>WritableMemory.wrap(...)</i>.
-   * @param arr the given primitive array.
-   * @param offsetBytes the byte offset into the given array
-   * @param lengthBytes the number of bytes to include from the given array
-   * @param byteOrder the byte order to be used
+   * @param array the given primitive array. It must be non-null.
+   * @param offsetBytes the byte offset into the given array. It must be >=0.
+   * @param lengthBytes the number of bytes to include from the given array. It must be >=0.
+   * @param byteOrder the byte order to be used. It must be non-null.
+   * @param memReqSvr A user-specified <i>MemoryRequestServer</i>, which may be null.
+   * This is a callback mechanism for a user client to request a larger <i>WritableMemory</i>.
    * @return a new WritableMemory for write operations on the given primitive array.
    */
-  static WritableMemory writableWrap(byte[] arr, int offsetBytes, int lengthBytes,
-      ByteOrder byteOrder) {
-    return WritableMemoryImpl.writableWrap(arr, offsetBytes, lengthBytes, byteOrder);
+  static WritableMemory writableWrap(byte[] array, int offsetBytes, int lengthBytes, ByteOrder byteOrder,
+      MemoryRequestServer memReqSvr) {
+    Objects.requireNonNull(array, "array must be non-null");
+    Objects.requireNonNull(byteOrder, "byteOrder must be non-null");
+    negativeCheck(offsetBytes, "offsetBytes");
+    negativeCheck(lengthBytes, "lengthBytes");
+    UnsafeUtil.checkBounds(offsetBytes, lengthBytes, array.length);
+    return BaseWritableMemoryImpl.wrapHeapArray(array, offsetBytes, lengthBytes, false, byteOrder, memReqSvr);
   }
 
   /**
-   * Wraps the given primitive array for write operations assuming native byte order. If the array
-   * size is zero, backing storage, byte order and read-only status of the returned WritableMemory
-   * object are unspecified.
-   *
-   * <p><b>Note:</b> Always qualify this method with the class name, e.g.,
-   * <i>WritableMemory.wrap(...)</i>.
-   * @param arr the given primitive array.
+   * Wraps the given primitive array for write operations assuming native byte order.
+   * @param array the given primitive array. It must be non-null.
    * @return a new WritableMemory for write operations on the given primitive array.
    */
-  static WritableMemory writableWrap(char[] arr) {
-    return WritableMemoryImpl.writableWrap(arr);
+  static WritableMemory writableWrap(boolean[] array) {
+    Objects.requireNonNull(array, "array must be non-null");
+    final long lengthBytes = array.length << Prim.BOOLEAN.shift();
+    return BaseWritableMemoryImpl.wrapHeapArray(array, 0, lengthBytes, false, ByteOrder.nativeOrder(), null);
   }
 
   /**
-   * Wraps the given primitive array for write operations assuming native byte order. If the array
-   * size is zero, backing storage, byte order and read-only status of the returned WritableMemory
-   * object are unspecified.
-   *
-   * <p><b>Note:</b> Always qualify this method with the class name, e.g.,
-   * <i>WritableMemory.wrap(...)</i>.
-   * @param arr the given primitive array.
+   * Wraps the given primitive array for write operations assuming native byte order.
+   * @param array the given primitive array.
    * @return a new WritableMemory for write operations on the given primitive array.
    */
-  static WritableMemory writableWrap(short[] arr) {
-    return WritableMemoryImpl.writableWrap(arr);
+  static WritableMemory writableWrap(char[] array) {
+    Objects.requireNonNull(array, "array must be non-null");
+    final long lengthBytes = array.length << Prim.CHAR.shift();
+    return BaseWritableMemoryImpl.wrapHeapArray(array, 0L, lengthBytes, false, ByteOrder.nativeOrder(), null);
   }
 
   /**
-   * Wraps the given primitive array for write operations assuming native byte order. If the array
-   * size is zero, backing storage, byte order and read-only status of the returned WritableMemory
-   * object are unspecified.
-   *
-   * <p><b>Note:</b> Always qualify this method with the class name, e.g.,
-   * <i>WritableMemory.wrap(...)</i>.
-   * @param arr the given primitive array.
+   * Wraps the given primitive array for write operations assuming native byte order.
+   * @param array the given primitive array.
    * @return a new WritableMemory for write operations on the given primitive array.
    */
-  static WritableMemory writableWrap(int[] arr) {
-    return WritableMemoryImpl.writableWrap(arr);
+  static WritableMemory writableWrap(short[] array) {
+    Objects.requireNonNull(array, "arr must be non-null");
+    final long lengthBytes = array.length << Prim.SHORT.shift();
+    return BaseWritableMemoryImpl.wrapHeapArray(array, 0L, lengthBytes, false, ByteOrder.nativeOrder(), null);
   }
 
   /**
-   * Wraps the given primitive array for write operations assuming native byte order. If the array
-   * size is zero, backing storage, byte order and read-only status of the returned WritableMemory
-   * object are unspecified.
-   *
-   * <p><b>Note:</b> Always qualify this method with the class name, e.g.,
-   * <i>WritableMemory.wrap(...)</i>.
-   * @param arr the given primitive array.
+   * Wraps the given primitive array for write operations assuming native byte order.
+   * @param array the given primitive array.
    * @return a new WritableMemory for write operations on the given primitive array.
    */
-  static WritableMemory writableWrap(long[] arr) {
-    return WritableMemoryImpl.writableWrap(arr);
+  static WritableMemory writableWrap(int[] array) {
+    Objects.requireNonNull(array, "arr must be non-null");
+    final long lengthBytes = array.length << Prim.INT.shift();
+    return BaseWritableMemoryImpl.wrapHeapArray(array, 0L, lengthBytes, false, ByteOrder.nativeOrder(), null);
   }
 
   /**
-   * Wraps the given primitive array for write operations assuming native byte order. If the array
-   * size is zero, backing storage, byte order and read-only status of the returned WritableMemory
-   * object are unspecified.
-   *
-   * <p><b>Note:</b> Always qualify this method with the class name, e.g.,
-   * <i>WritableMemory.wrap(...)</i>.
-   * @param arr the given primitive array.
+   * Wraps the given primitive array for write operations assuming native byte order.
+   * @param array the given primitive array.
    * @return a new WritableMemory for write operations on the given primitive array.
    */
-  static WritableMemory writableWrap(float[] arr) {
-    return WritableMemoryImpl.writableWrap(arr);
+  static WritableMemory writableWrap(long[] array) {
+    Objects.requireNonNull(array, "arr must be non-null");
+    final long lengthBytes = array.length << Prim.LONG.shift();
+    return BaseWritableMemoryImpl.wrapHeapArray(array, 0L, lengthBytes, false, ByteOrder.nativeOrder(), null);
   }
 
   /**
-   * Wraps the given primitive array for write operations assuming native byte order. If the array
-   * size is zero, backing storage, byte order and read-only status of the returned WritableMemory
-   * object are unspecified.
-   *
-   * <p><b>Note:</b> Always qualify this method with the class name, e.g.,
-   * <i>WritableMemory.wrap(...)</i>.
-   * @param arr the given primitive array.
+   * Wraps the given primitive array for write operations assuming native byte order.
+   * @param array the given primitive array.
+   * @return a new WritableMemory for write operations on the given primitive array.
+   */
+  static WritableMemory writableWrap(float[] array) {
+    Objects.requireNonNull(array, "arr must be non-null");
+    final long lengthBytes = array.length << Prim.FLOAT.shift();
+    return BaseWritableMemoryImpl.wrapHeapArray(array, 0L, lengthBytes, false, ByteOrder.nativeOrder(), null);
+  }
+
+  /**
+   * Wraps the given primitive array for write operations assuming native byte order.
+   * @param array the given primitive array.
    * @return a new WritableMemory for write operations on the given primitive array.
    */
-  static WritableMemory writableWrap(double[] arr) {
-    return WritableMemoryImpl.writableWrap(arr);
+  static WritableMemory writableWrap(double[] array) {
+    Objects.requireNonNull(array, "arr must be non-null");
+    final long lengthBytes = array.length << Prim.DOUBLE.shift();
+    return BaseWritableMemoryImpl.wrapHeapArray(array, 0L, lengthBytes, false, ByteOrder.nativeOrder(), null);
   }
   //END OF CONSTRUCTOR-TYPE METHODS
 
@@ -604,10 +620,9 @@ public interface WritableMemory extends Memory {
    * For ByteBuffer and Direct Memory backed resources only. Heap and Map backed resources will return null.
    * Gets the MemoryRequestServer object used by dynamic Memory-backed objects
    * to request additional memory.  To customize the actions of the MemoryRequestServer,
-   * extend the MemoryRequestServer interfact and
+   * extend the MemoryRequestServer interface and
    * set using {@link WritableMemory#allocateDirect(long, ByteOrder, MemoryRequestServer)}.
-   * If not explicity set, this returns the {@link DefaultMemoryRequestServer}.
-   * @return the MemoryRequestServer object (if direct memory) or null.
+   * @return the MemoryRequestServer object or null.
    */
   MemoryRequestServer getMemoryRequestServer();
 
diff --git a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/AllocateDirectWritableMap.java b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/AllocateDirectWritableMap.java
index 1cb93e1..6335076 100644
--- a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/AllocateDirectWritableMap.java
+++ b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/AllocateDirectWritableMap.java
@@ -23,6 +23,7 @@ import java.io.File;
 import java.io.IOException;
 import java.lang.reflect.InvocationTargetException;
 
+import org.apache.datasketches.memory.ReadOnlyException;
 import org.apache.datasketches.memory.WritableMap;
 
 /**
diff --git a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/BBNonNativeWritableBufferImpl.java b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/BBNonNativeWritableBufferImpl.java
index 88e3181..8fbce11 100644
--- a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/BBNonNativeWritableBufferImpl.java
+++ b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/BBNonNativeWritableBufferImpl.java
@@ -23,9 +23,10 @@ import java.nio.ByteBuffer;
 import java.nio.ByteOrder;
 
 import org.apache.datasketches.memory.MemoryRequestServer;
+import org.apache.datasketches.memory.WritableBuffer;
 
 /**
- * Implementation of {@link WritableBufferImpl} for ByteBuffer, non-native byte order.
+ * Implementation of {@link WritableBuffer} for ByteBuffer, non-native byte order.
  *
  * @author Roman Leventov
  * @author Lee Rhodes
@@ -35,7 +36,7 @@ final class BBNonNativeWritableBufferImpl extends NonNativeWritableBufferImpl {
   private final Object unsafeObj;
   private final long nativeBaseOffset; //used to compute cumBaseOffset
   private final ByteBuffer byteBuf; //holds a reference to a ByteBuffer until we are done with it.
-  private MemoryRequestServer memReqSvr = null; //cannot be final;
+  private final MemoryRequestServer memReqSvr;
   private final byte typeId;
 
   BBNonNativeWritableBufferImpl(
@@ -45,39 +46,44 @@ final class BBNonNativeWritableBufferImpl extends NonNativeWritableBufferImpl {
       final long capacityBytes,
       final int typeId,
       final ByteBuffer byteBuf,
-      final MemoryRequestServer memReqSvr,
-      final BaseWritableMemoryImpl originMemory) {
-    super(unsafeObj, nativeBaseOffset, regionOffset, capacityBytes, originMemory);
+      final MemoryRequestServer memReqSvr) {
+    super(unsafeObj, nativeBaseOffset, regionOffset, capacityBytes);
     this.unsafeObj = unsafeObj;
     this.nativeBaseOffset = nativeBaseOffset;
     this.byteBuf = byteBuf;
-    this.memReqSvr = (memReqSvr == null) ? defaultMemReqSvr : memReqSvr;
+    this.memReqSvr = memReqSvr;
     this.typeId = (byte) (id | (typeId & 0x7));
   }
 
   @Override
   BaseWritableBufferImpl toWritableRegion(final long offsetBytes, final long capacityBytes,
       final boolean readOnly, final ByteOrder byteOrder) {
-    final int type = typeId | REGION | (readOnly ? READONLY : 0);
+    final int type = setReadOnlyType(typeId, readOnly) | REGION;
     return Util.isNativeByteOrder(byteOrder)
         ? new BBWritableBufferImpl(
-          unsafeObj, nativeBaseOffset, getRegionOffset(offsetBytes), capacityBytes,
-          type, byteBuf, memReqSvr, originMemory)
+          unsafeObj, nativeBaseOffset, getRegionOffset(offsetBytes), capacityBytes, type, byteBuf, memReqSvr)
         : new BBNonNativeWritableBufferImpl(
-          unsafeObj, nativeBaseOffset, getRegionOffset(offsetBytes), capacityBytes,
-          type, byteBuf, memReqSvr, originMemory);
+          unsafeObj, nativeBaseOffset, getRegionOffset(offsetBytes), capacityBytes, type, byteBuf, memReqSvr);
   }
 
   @Override
   BaseWritableBufferImpl toDuplicate(final boolean readOnly, final ByteOrder byteOrder) {
-    final int type = typeId | DUPLICATE | (readOnly ? READONLY : 0);
+    final int type = setReadOnlyType(typeId, readOnly) | DUPLICATE;
     return Util.isNativeByteOrder(byteOrder)
         ? new BBWritableBufferImpl(
-            unsafeObj, nativeBaseOffset, getRegionOffset(), getCapacity(),
-            type, byteBuf, memReqSvr, originMemory)
+            unsafeObj, nativeBaseOffset, getRegionOffset(), getCapacity(), type, byteBuf, memReqSvr)
         : new BBNonNativeWritableBufferImpl(
-            unsafeObj, nativeBaseOffset, getRegionOffset(), getCapacity(),
-            type, byteBuf, memReqSvr, originMemory);
+            unsafeObj, nativeBaseOffset, getRegionOffset(), getCapacity(), type, byteBuf, memReqSvr);
+  }
+
+  @Override
+  BaseWritableMemoryImpl toWritableMemory(final boolean readOnly, final ByteOrder byteOrder) {
+    final int type = setReadOnlyType(typeId, readOnly);
+    return Util.isNativeByteOrder(byteOrder)
+        ? new BBWritableMemoryImpl(
+            unsafeObj, nativeBaseOffset, getRegionOffset(), getCapacity(), type, byteBuf, memReqSvr)
+        : new BBNonNativeWritableMemoryImpl(
+            unsafeObj, nativeBaseOffset, getRegionOffset(), getCapacity(), type, byteBuf, memReqSvr);
   }
 
   @Override
@@ -89,7 +95,7 @@ final class BBNonNativeWritableBufferImpl extends NonNativeWritableBufferImpl {
   @Override
   public MemoryRequestServer getMemoryRequestServer() {
     assertValid();
-    return memReqSvr; //cannot be null
+    return memReqSvr;
   }
 
   @Override
diff --git a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/BBNonNativeWritableMemoryImpl.java b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/BBNonNativeWritableMemoryImpl.java
index 5897271..60ed085 100644
--- a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/BBNonNativeWritableMemoryImpl.java
+++ b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/BBNonNativeWritableMemoryImpl.java
@@ -23,9 +23,10 @@ import java.nio.ByteBuffer;
 import java.nio.ByteOrder;
 
 import org.apache.datasketches.memory.MemoryRequestServer;
+import org.apache.datasketches.memory.WritableMemory;
 
 /**
- * Implementation of {@link WritableMemoryImpl} for ByteBuffer, non-native byte order.
+ * Implementation of {@link WritableMemory} for ByteBuffer, non-native byte order.
  *
  * @author Roman Leventov
  * @author Lee Rhodes
@@ -35,7 +36,7 @@ final class BBNonNativeWritableMemoryImpl extends NonNativeWritableMemoryImpl {
   private final Object unsafeObj;
   private final long nativeBaseOffset; //used to compute cumBaseOffset
   private final ByteBuffer byteBuf; //holds a reference to a ByteBuffer until we are done with it.
-  private MemoryRequestServer memReqSvr = null; //cannot be final;
+  private final MemoryRequestServer memReqSvr;
   private final byte typeId;
 
   BBNonNativeWritableMemoryImpl(
@@ -50,33 +51,29 @@ final class BBNonNativeWritableMemoryImpl extends NonNativeWritableMemoryImpl {
     this.unsafeObj = unsafeObj;
     this.nativeBaseOffset = nativeBaseOffset;
     this.byteBuf = byteBuf;
-    this.memReqSvr = (memReqSvr == null) ? defaultMemReqSvr : memReqSvr;
+    this.memReqSvr = memReqSvr;
     this.typeId = (byte) (id | (typeId & 0x7));
   }
 
   @Override
   BaseWritableMemoryImpl toWritableRegion(final long offsetBytes, final long capacityBytes,
       final boolean readOnly, final ByteOrder byteOrder) {
-    final int type = typeId | REGION | (readOnly ? READONLY : 0);
+    final int type = setReadOnlyType(typeId, readOnly) | REGION;
     return Util.isNativeByteOrder(byteOrder)
         ? new BBWritableMemoryImpl(
-            unsafeObj, nativeBaseOffset, getRegionOffset(offsetBytes), capacityBytes,
-            type, getByteBuffer(), memReqSvr)
+            unsafeObj, nativeBaseOffset, getRegionOffset(offsetBytes), capacityBytes, type, getByteBuffer(), memReqSvr)
         : new BBNonNativeWritableMemoryImpl(
-            unsafeObj, nativeBaseOffset, getRegionOffset(offsetBytes), capacityBytes,
-            type, getByteBuffer(), memReqSvr);
+            unsafeObj, nativeBaseOffset, getRegionOffset(offsetBytes), capacityBytes, type, getByteBuffer(), memReqSvr);
   }
 
   @Override
   BaseWritableBufferImpl toWritableBuffer(final boolean readOnly, final ByteOrder byteOrder) {
-    final int type = typeId | (readOnly ? READONLY : 0);
+    final int type = setReadOnlyType(typeId, readOnly);
     return Util.isNativeByteOrder(byteOrder)
         ? new BBWritableBufferImpl(
-            unsafeObj, nativeBaseOffset, getRegionOffset(), getCapacity(),
-            type, byteBuf, memReqSvr, this)
+            unsafeObj, nativeBaseOffset, getRegionOffset(), getCapacity(), type, byteBuf, memReqSvr)
         : new BBNonNativeWritableBufferImpl(
-            unsafeObj, nativeBaseOffset, getRegionOffset(), getCapacity(),
-            type, byteBuf, memReqSvr, this);
+            unsafeObj, nativeBaseOffset, getRegionOffset(), getCapacity(), type, byteBuf, memReqSvr);
   }
 
   @Override
@@ -88,7 +85,7 @@ final class BBNonNativeWritableMemoryImpl extends NonNativeWritableMemoryImpl {
   @Override
   public MemoryRequestServer getMemoryRequestServer() {
     assertValid();
-    return memReqSvr; //cannot be null
+    return memReqSvr;
   }
 
   @Override
diff --git a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/BBWritableBufferImpl.java b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/BBWritableBufferImpl.java
index 49933f0..0288488 100644
--- a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/BBWritableBufferImpl.java
+++ b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/BBWritableBufferImpl.java
@@ -23,9 +23,10 @@ import java.nio.ByteBuffer;
 import java.nio.ByteOrder;
 
 import org.apache.datasketches.memory.MemoryRequestServer;
+import org.apache.datasketches.memory.WritableBuffer;
 
 /**
- * Implementation of {@link WritableBufferImpl} for ByteBuffer, native byte order.
+ * Implementation of {@link WritableBuffer} for ByteBuffer, native byte order.
  *
  * @author Roman Leventov
  * @author Lee Rhodes
@@ -35,7 +36,7 @@ final class BBWritableBufferImpl extends NativeWritableBufferImpl {
   private final Object unsafeObj;
   private final long nativeBaseOffset; //used to compute cumBaseOffset
   private final ByteBuffer byteBuf; //holds a reference to a ByteBuffer until we are done with it.
-  private MemoryRequestServer memReqSvr = null; //cannot be final;
+  private final MemoryRequestServer memReqSvr;
   private final byte typeId;
 
   BBWritableBufferImpl(
@@ -45,39 +46,44 @@ final class BBWritableBufferImpl extends NativeWritableBufferImpl {
       final long capacityBytes,
       final int typeId,
       final ByteBuffer byteBuf,
-      final MemoryRequestServer memReqSvr,
-      final BaseWritableMemoryImpl originMemory) {
-    super(unsafeObj, nativeBaseOffset, regionOffset, capacityBytes, originMemory);
+      final MemoryRequestServer memReqSvr) {
+    super(unsafeObj, nativeBaseOffset, regionOffset, capacityBytes);
     this.unsafeObj = unsafeObj;
     this.nativeBaseOffset = nativeBaseOffset;
     this.byteBuf = byteBuf;
-    this.memReqSvr = (memReqSvr == null) ? defaultMemReqSvr : memReqSvr;
+    this.memReqSvr = memReqSvr;
     this.typeId = (byte) (id | (typeId & 0x7));
   }
 
   @Override
   BaseWritableBufferImpl toWritableRegion(final long offsetBytes, final long capacityBytes,
       final boolean readOnly, final ByteOrder byteOrder) {
-    final int type = typeId | REGION | (readOnly ? READONLY : 0);
+    final int type = setReadOnlyType(typeId, readOnly) | REGION;
     return Util.isNativeByteOrder(byteOrder)
         ? new BBWritableBufferImpl(
-            unsafeObj, nativeBaseOffset, getRegionOffset(offsetBytes), capacityBytes,
-            type, byteBuf, memReqSvr, originMemory)
+            unsafeObj, nativeBaseOffset, getRegionOffset(offsetBytes), capacityBytes, type, byteBuf, memReqSvr)
         : new BBNonNativeWritableBufferImpl(
-            unsafeObj, nativeBaseOffset, getRegionOffset(offsetBytes), capacityBytes,
-            type, byteBuf, memReqSvr, originMemory);
+            unsafeObj, nativeBaseOffset, getRegionOffset(offsetBytes), capacityBytes, type, byteBuf, memReqSvr);
   }
 
   @Override
   BaseWritableBufferImpl toDuplicate(final boolean readOnly, final ByteOrder byteOrder) {
-    final int type = typeId | DUPLICATE | (readOnly ? READONLY : 0);
+    final int type = setReadOnlyType(typeId, readOnly) | DUPLICATE;
     return Util.isNativeByteOrder(byteOrder)
         ? new BBWritableBufferImpl(
-            unsafeObj, nativeBaseOffset, getRegionOffset(), getCapacity(),
-            type, byteBuf, memReqSvr, originMemory)
+            unsafeObj, nativeBaseOffset, getRegionOffset(), getCapacity(), type, byteBuf, memReqSvr)
         : new BBNonNativeWritableBufferImpl(
-            unsafeObj, nativeBaseOffset, getRegionOffset(), getCapacity(),
-            type, byteBuf, memReqSvr, originMemory);
+            unsafeObj, nativeBaseOffset, getRegionOffset(), getCapacity(), type, byteBuf, memReqSvr);
+  }
+
+  @Override
+  BaseWritableMemoryImpl toWritableMemory(final boolean readOnly, final ByteOrder byteOrder) {
+    final int type = setReadOnlyType(typeId, readOnly);
+    return Util.isNativeByteOrder(byteOrder)
+        ? new BBWritableMemoryImpl(
+            unsafeObj, nativeBaseOffset, getRegionOffset(), getCapacity(), type, byteBuf, memReqSvr)
+        : new BBNonNativeWritableMemoryImpl(
+            unsafeObj, nativeBaseOffset, getRegionOffset(), getCapacity(), type, byteBuf, memReqSvr);
   }
 
   @Override
@@ -89,7 +95,7 @@ final class BBWritableBufferImpl extends NativeWritableBufferImpl {
   @Override
   public MemoryRequestServer getMemoryRequestServer() {
     assertValid();
-    return memReqSvr; //cannot be null
+    return memReqSvr;
   }
 
   @Override
diff --git a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/BBWritableMemoryImpl.java b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/BBWritableMemoryImpl.java
index 891a195..ad06dc9 100644
--- a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/BBWritableMemoryImpl.java
+++ b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/BBWritableMemoryImpl.java
@@ -23,9 +23,10 @@ import java.nio.ByteBuffer;
 import java.nio.ByteOrder;
 
 import org.apache.datasketches.memory.MemoryRequestServer;
+import org.apache.datasketches.memory.WritableMemory;
 
 /**
- * Implementation of {@link WritableMemoryImpl} for ByteBuffer, native byte order.
+ * Implementation of {@link WritableMemory} for ByteBuffer, native byte order.
  *
  * @author Roman Leventov
  * @author Lee Rhodes
@@ -35,7 +36,7 @@ final class BBWritableMemoryImpl extends NativeWritableMemoryImpl {
   private final Object unsafeObj;
   private final long nativeBaseOffset; //used to compute cumBaseOffset
   private final ByteBuffer byteBuf; //holds a reference to a ByteBuffer until we are done with it.
-  private MemoryRequestServer memReqSvr = null; //cannot be final;
+  private final MemoryRequestServer memReqSvr;
   private final byte typeId;
 
   BBWritableMemoryImpl(
@@ -50,33 +51,29 @@ final class BBWritableMemoryImpl extends NativeWritableMemoryImpl {
     this.unsafeObj = unsafeObj;
     this.nativeBaseOffset = nativeBaseOffset;
     this.byteBuf = byteBuf;
-    this.memReqSvr = (memReqSvr == null) ? defaultMemReqSvr : memReqSvr;
+    this.memReqSvr = memReqSvr;
     this.typeId = (byte) (id | (typeId & 0x7));
   }
 
   @Override
   BaseWritableMemoryImpl toWritableRegion(final long offsetBytes, final long capacityBytes,
       final boolean readOnly, final ByteOrder byteOrder) {
-    final int type = typeId | REGION | (readOnly ? READONLY : 0);
+    final int type = setReadOnlyType(typeId, readOnly) | REGION;
     return Util.isNativeByteOrder(byteOrder)
         ? new BBWritableMemoryImpl(
-            unsafeObj, nativeBaseOffset, getRegionOffset(offsetBytes), capacityBytes,
-            type, getByteBuffer(), memReqSvr)
+            unsafeObj, nativeBaseOffset, getRegionOffset(offsetBytes), capacityBytes, type, getByteBuffer(), memReqSvr)
         : new BBNonNativeWritableMemoryImpl(
-            unsafeObj, nativeBaseOffset, getRegionOffset(offsetBytes), capacityBytes,
-            type, getByteBuffer(), memReqSvr);
+            unsafeObj, nativeBaseOffset, getRegionOffset(offsetBytes), capacityBytes, type, getByteBuffer(), memReqSvr);
   }
 
   @Override
   BaseWritableBufferImpl toWritableBuffer(final boolean readOnly, final ByteOrder byteOrder) {
-    final int type = typeId | (readOnly ? READONLY : 0);
+    final int type = setReadOnlyType(typeId, readOnly);
     return Util.isNativeByteOrder(byteOrder)
         ? new BBWritableBufferImpl(
-            unsafeObj, nativeBaseOffset, getRegionOffset(), getCapacity(),
-            type, byteBuf, memReqSvr, this)
+            unsafeObj, nativeBaseOffset, getRegionOffset(), getCapacity(), type, byteBuf, memReqSvr)
         : new BBNonNativeWritableBufferImpl(
-            unsafeObj, nativeBaseOffset, getRegionOffset(), getCapacity(),
-            type, byteBuf, memReqSvr, this);
+            unsafeObj, nativeBaseOffset, getRegionOffset(), getCapacity(), type, byteBuf, memReqSvr);
   }
 
   @Override
@@ -88,7 +85,7 @@ final class BBWritableMemoryImpl extends NativeWritableMemoryImpl {
   @Override
   public MemoryRequestServer getMemoryRequestServer() {
     assertValid();
-    return memReqSvr; //cannot be null
+    return memReqSvr;
   }
 
   @Override
diff --git a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/BaseBufferImpl.java b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/BaseBufferImpl.java
index 52d9ae5..7bc1340 100644
--- a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/BaseBufferImpl.java
+++ b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/BaseBufferImpl.java
@@ -20,6 +20,7 @@
 package org.apache.datasketches.memory.internal;
 
 import org.apache.datasketches.memory.BaseBuffer;
+import org.apache.datasketches.memory.ReadOnlyException;
 
 /**
  * A new positional API. This is different from and simpler than Java BufferImpl positional approach.
diff --git a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/BaseStateImpl.java b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/BaseStateImpl.java
index fe82f17..c3271f6 100644
--- a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/BaseStateImpl.java
+++ b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/BaseStateImpl.java
@@ -30,6 +30,7 @@ import java.util.concurrent.atomic.AtomicLong;
 
 import org.apache.datasketches.memory.BaseState;
 import org.apache.datasketches.memory.MemoryRequestServer;
+import org.apache.datasketches.memory.ReadOnlyException;
 
 /**
  * Keeps key configuration state for MemoryImpl and BufferImpl plus some common static variables
@@ -46,14 +47,14 @@ public abstract class BaseStateImpl implements BaseState {
   static final AtomicLong currentDirectMemoryMapAllocations_ = new AtomicLong();
   static final AtomicLong currentDirectMemoryMapAllocated_ = new AtomicLong();
 
-
-
   //class type IDs. Do not change the bit orders
+  //The first 3 bits are set dynamically
   // 0000 0XXX
   static final int READONLY = 1;
   static final int REGION = 2;
   static final int DUPLICATE = 4;
 
+  //The following 4 bits are set by the 16 leaf nodes
   // 000X X000
   static final int HEAP = 0;
   static final int DIRECT = 1 << 3;
@@ -100,7 +101,7 @@ public abstract class BaseStateImpl implements BaseState {
 
   @Override
   public final ByteOrder getTypeByteOrder() {
-    return isNonNativeType() ? Util.nonNativeByteOrder : Util.nativeByteOrder;
+    return isNonNativeType() ? Util.NON_NATIVE_BYTE_ORDER : Util.NATIVE_BYTE_ORDER;
   }
 
   /**
@@ -112,13 +113,13 @@ public abstract class BaseStateImpl implements BaseState {
     if (byteOrder == null) {
       throw new IllegalArgumentException("ByteOrder parameter cannot be null.");
     }
-    return Util.nativeByteOrder == byteOrder;
+    return Util.NATIVE_BYTE_ORDER == byteOrder;
   }
 
   @Override
   public final boolean isByteOrderCompatible(final ByteOrder byteOrder) {
     final ByteOrder typeBO = getTypeByteOrder();
-    return typeBO == Util.nativeByteOrder && typeBO == byteOrder;
+    return typeBO == Util.NATIVE_BYTE_ORDER && typeBO == byteOrder;
   }
 
   @Override
@@ -294,21 +295,34 @@ public abstract class BaseStateImpl implements BaseState {
     }
   }
 
-  //TYPE ID CHECKS
+  //TYPE ID Management
   final boolean isReadOnlyType() {
     return (getTypeId() & READONLY) > 0;
   }
 
-  final boolean isBufferType() {
-    return (getTypeId() & BUFFER) > 0;
+  final static byte setReadOnlyType(byte type, boolean readOnly) {
+    return (byte)((type & ~1) | (readOnly ? READONLY : 0));
+  }
+
+  final boolean isRegionType() {
+    return (getTypeId() & REGION) > 0;
+  }
+
+  final static byte setRegionType(byte type, boolean region) {
+    return (byte)((type & ~2) | (region ? REGION : 0));
   }
 
   final boolean isDuplicateType() {
     return (getTypeId() & DUPLICATE) > 0;
   }
 
-  final boolean isRegionType() {
-    return (getTypeId() & REGION) > 0;
+  final static byte setDuplicateType(byte type, boolean duplicate) {
+    return (byte)((type & ~4) | (duplicate ? DUPLICATE : 0));
+  }
+
+  //The following are set by the leaf nodes
+  final boolean isBufferType() {
+    return (getTypeId() & BUFFER) > 0;
   }
 
   final boolean isNonNativeType() {
@@ -331,6 +345,7 @@ public abstract class BaseStateImpl implements BaseState {
     return (getTypeId() >>> 3 & 3) == 3;
   }
 
+
   //TO STRING
   //For debugging
   public static final String typeDecode(final int typeId) {
@@ -424,7 +439,7 @@ public abstract class BaseStateImpl implements BaseState {
     sb.append("Valid               : ").append(state.isValid()).append(LS);
     sb.append("Read Only           : ").append(state.isReadOnly()).append(LS);
     sb.append("Type Byte Order     : ").append(state.getTypeByteOrder().toString()).append(LS);
-    sb.append("Native Byte Order   : ").append(Util.nativeByteOrder.toString()).append(LS);
+    sb.append("Native Byte Order   : ").append(Util.NATIVE_BYTE_ORDER.toString()).append(LS);
     sb.append("JDK Runtime Version : ").append(UnsafeUtil.JDK).append(LS);
     //Data detail
     sb.append("Data, littleEndian  :  0  1  2  3  4  5  6  7");
diff --git a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/BaseWritableBufferImpl.java b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/BaseWritableBufferImpl.java
index 06d2d3d..59b4855 100644
--- a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/BaseWritableBufferImpl.java
+++ b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/BaseWritableBufferImpl.java
@@ -30,9 +30,16 @@ import static org.apache.datasketches.memory.internal.UnsafeUtil.ARRAY_SHORT_IND
 import static org.apache.datasketches.memory.internal.UnsafeUtil.checkBounds;
 import static org.apache.datasketches.memory.internal.UnsafeUtil.unsafe;
 
+import java.nio.ByteBuffer;
 import java.nio.ByteOrder;
+import java.util.Objects;
 
 import org.apache.datasketches.memory.Buffer;
+import org.apache.datasketches.memory.Memory;
+import org.apache.datasketches.memory.MemoryRequestServer;
+import org.apache.datasketches.memory.ReadOnlyException;
+import org.apache.datasketches.memory.WritableBuffer;
+import org.apache.datasketches.memory.WritableMemory;
 
 /*
  * Developer notes: The heavier methods, such as put/get arrays, duplicate, region, clear, fill,
@@ -48,65 +55,71 @@ import org.apache.datasketches.memory.Buffer;
  */
 
 /**
- * Common base of native-ordered and non-native-ordered {@link WritableBufferImpl} implementations.
+ * Common base of native-ordered and non-native-ordered {@link WritableBuffer} implementations.
  * Contains methods which are agnostic to the byte order.
  */
 @SuppressWarnings("restriction")
-abstract class BaseWritableBufferImpl extends WritableBufferImpl {
-  final BaseWritableMemoryImpl originMemory;
-
-  //Static variable for cases where byteBuf/array sizes are zero
-  final static NativeWritableBufferImpl ZERO_SIZE_BUFFER;
-
-  static {
-    final BaseWritableMemoryImpl mem = BaseWritableMemoryImpl.ZERO_SIZE_MEMORY;
-    ZERO_SIZE_BUFFER = new HeapWritableBufferImpl(new byte[0], 0L, 0L, READONLY, mem);
-  }
+public abstract class BaseWritableBufferImpl extends BaseBufferImpl implements WritableBuffer {
 
   //Pass-through ctor
   BaseWritableBufferImpl(final Object unsafeObj, final long nativeBaseOffset,
-      final long regionOffset, final long capacityBytes,
-      final BaseWritableMemoryImpl originMemory) {
+      final long regionOffset, final long capacityBytes) {
     super(unsafeObj, nativeBaseOffset, regionOffset, capacityBytes);
-    this.originMemory = originMemory;
+  }
+
+  public static BaseWritableBufferImpl wrapHeapArray(final Object arr, final long offsetBytes, final long lengthBytes,
+      final boolean localReadOnly, final ByteOrder byteOrder, final MemoryRequestServer memReqSvr) {
+    final int typeId = localReadOnly ? READONLY : 0;
+    return Util.isNativeByteOrder(byteOrder)
+        ? new HeapWritableBufferImpl(arr, offsetBytes, lengthBytes, typeId, memReqSvr)
+        : new HeapNonNativeWritableBufferImpl(arr, offsetBytes, lengthBytes, typeId, memReqSvr);
+  }
+
+  public static BaseWritableBufferImpl wrapByteBuffer(
+      final ByteBuffer byteBuf, final boolean localReadOnly, final ByteOrder byteOrder,
+      final MemoryRequestServer memReqSvr) {
+    final AccessByteBuffer abb = new AccessByteBuffer(byteBuf);
+    final int typeId = (abb.resourceReadOnly || localReadOnly) ? READONLY : 0;
+    return Util.isNativeByteOrder(byteOrder)
+        ? new BBWritableBufferImpl(abb.unsafeObj, abb.nativeBaseOffset,
+            abb.regionOffset, abb.capacityBytes, typeId, byteBuf, memReqSvr)
+        : new BBNonNativeWritableBufferImpl(abb.unsafeObj, abb.nativeBaseOffset,
+            abb.regionOffset, abb.capacityBytes,  typeId, byteBuf, memReqSvr);
   }
 
   //REGIONS
   @Override
-  public BufferImpl region() {
+  public Buffer region() {
     return writableRegionImpl(getPosition(), getEnd() - getPosition(), true, getTypeByteOrder());
   }
 
   @Override
-  public BufferImpl region(final long offsetBytes, final long capacityBytes,
-      final ByteOrder byteOrder) {
-    final BufferImpl buf = writableRegionImpl(offsetBytes, capacityBytes, true, byteOrder);
+  public Buffer region(final long offsetBytes, final long capacityBytes, final ByteOrder byteOrder) {
+    final WritableBuffer buf = writableRegionImpl(offsetBytes, capacityBytes, true, byteOrder);
     buf.setAndCheckStartPositionEnd(0, 0, capacityBytes);
     return buf;
   }
 
   @Override
-  public WritableBufferImpl writableRegion() {
+  public WritableBuffer writableRegion() {
     return writableRegionImpl(getPosition(), getEnd() - getPosition(), false, getTypeByteOrder());
   }
 
   @Override
-  public WritableBufferImpl writableRegion(final long offsetBytes, final long capacityBytes,
-      final ByteOrder byteOrder) {
-    final WritableBufferImpl wbuf = writableRegionImpl(offsetBytes, capacityBytes, false, byteOrder);
+  public WritableBuffer writableRegion(final long offsetBytes, final long capacityBytes, final ByteOrder byteOrder) {
+    final WritableBuffer wbuf = writableRegionImpl(offsetBytes, capacityBytes, false, byteOrder);
     wbuf.setAndCheckStartPositionEnd(0, 0, capacityBytes);
     return wbuf;
   }
 
-  WritableBufferImpl writableRegionImpl(final long offsetBytes, final long capacityBytes,
+  WritableBuffer writableRegionImpl(final long offsetBytes, final long capacityBytes,
       final boolean localReadOnly, final ByteOrder byteOrder) {
-    if (capacityBytes == 0) { return ZERO_SIZE_BUFFER; }
     if (isReadOnly() && !localReadOnly) {
-      throw new ReadOnlyException("Writable region of a read-only BufferImpl is not allowed.");
+      throw new ReadOnlyException("Writable region of a read-only Buffer is not allowed.");
     }
     checkValidAndBounds(offsetBytes, capacityBytes);
     final boolean readOnly = isReadOnly() || localReadOnly;
-    final WritableBufferImpl wbuf = toWritableRegion(offsetBytes, capacityBytes, readOnly, byteOrder);
+    final WritableBuffer wbuf = toWritableRegion(offsetBytes, capacityBytes, readOnly, byteOrder);
     wbuf.setStartPositionEnd(0, 0, capacityBytes);
     return wbuf;
   }
@@ -116,52 +129,62 @@ abstract class BaseWritableBufferImpl extends WritableBufferImpl {
 
   //DUPLICATES
   @Override
-  public BufferImpl duplicate() {
+  public Buffer duplicate() {
     return writableDuplicateImpl(true, getTypeByteOrder());
   }
 
   @Override
-  public BufferImpl duplicate(final ByteOrder byteOrder) {
+  public Buffer duplicate(final ByteOrder byteOrder) {
     return writableDuplicateImpl(true, byteOrder);
   }
 
   @Override
-  public WritableBufferImpl writableDuplicate() {
+  public WritableBuffer writableDuplicate() {
     return writableDuplicateImpl(false, getTypeByteOrder());
   }
 
   @Override
-  public WritableBufferImpl writableDuplicate(final ByteOrder byteOrder) {
+  public WritableBuffer writableDuplicate(final ByteOrder byteOrder) {
     return writableDuplicateImpl(false, byteOrder);
   }
 
-  WritableBufferImpl writableDuplicateImpl(final boolean localReadOnly, final ByteOrder byteOrder) {
+  WritableBuffer writableDuplicateImpl(final boolean localReadOnly, final ByteOrder byteOrder) {
     if (isReadOnly() && !localReadOnly) {
-      throw new ReadOnlyException("Writable duplicate of a read-only BufferImpl is not allowed.");
+      throw new ReadOnlyException("Writable duplicate of a read-only Buffer is not allowed.");
     }
     final boolean readOnly = isReadOnly() || localReadOnly;
-    final WritableBufferImpl wbuf = toDuplicate(readOnly, byteOrder);
+    final WritableBuffer wbuf = toDuplicate(readOnly, byteOrder);
     wbuf.setStartPositionEnd(getStart(), getPosition(), getEnd());
     return wbuf;
   }
 
   abstract BaseWritableBufferImpl toDuplicate(boolean readOnly, ByteOrder byteOrder);
 
-  //MEMORY
+  //AS MEMORY
   @Override
-  public MemoryImpl asMemory() {
-    return originMemory;
+  public Memory asMemory(final ByteOrder byteOrder) {
+    return asWritableMemory(true, byteOrder);
   }
 
   @Override
-  public WritableMemoryImpl asWritableMemory() {
-    if (isReadOnly()) {
-      throw new ReadOnlyException("Converting a read-only BufferImpl to a writable MemoryImpl is not allowed.");
+  public WritableMemory asWritableMemory(final ByteOrder byteOrder) {
+    return asWritableMemory(false, byteOrder);
+  }
+
+  WritableMemory asWritableMemory(final boolean localReadOnly, final ByteOrder byteOrder) {
+    Objects.requireNonNull(byteOrder, "byteOrder must be non-null");
+    if (isReadOnly() && !localReadOnly) {
+      throw new ReadOnlyException(
+          "Converting a read-only Buffer to a writable Memory is not allowed.");
     }
-    return originMemory;
+    final boolean readOnly = isReadOnly() || localReadOnly;
+    final WritableMemory wmem = toWritableMemory(readOnly, byteOrder);
+    return wmem;
   }
 
-  //PRIMITIVE getX() and getArray()
+  abstract BaseWritableMemoryImpl toWritableMemory(boolean readOnly, ByteOrder byteOrder);
+
+  //PRIMITIVE getX() and getXArray()
   @Override
   public final boolean getBoolean() {
     final long pos = getPosition();
@@ -276,7 +299,7 @@ abstract class BaseWritableBufferImpl extends WritableBufferImpl {
    * the positional values. Switch to MemoryImpl view to do copyTo.
    */
 
-  //PRIMITIVE putX() and putXArray()
+  //PRIMITIVE putX() and putXArray() implementations
   @Override
   public final void putBoolean(final boolean value) {
     final long pos = getPosition();
diff --git a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/BaseWritableMemoryImpl.java b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/BaseWritableMemoryImpl.java
index f40192d..097a405 100644
--- a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/BaseWritableMemoryImpl.java
+++ b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/BaseWritableMemoryImpl.java
@@ -29,16 +29,21 @@ import static org.apache.datasketches.memory.internal.UnsafeUtil.ARRAY_LONG_INDE
 import static org.apache.datasketches.memory.internal.UnsafeUtil.ARRAY_SHORT_INDEX_SCALE;
 import static org.apache.datasketches.memory.internal.UnsafeUtil.checkBounds;
 import static org.apache.datasketches.memory.internal.UnsafeUtil.unsafe;
+import static org.apache.datasketches.memory.internal.Util.negativeCheck;
 
 import java.io.File;
 import java.io.IOException;
 import java.nio.ByteBuffer;
 import java.nio.ByteOrder;
 import java.nio.channels.WritableByteChannel;
+import java.util.Objects;
 
+import org.apache.datasketches.memory.Buffer;
 import org.apache.datasketches.memory.Memory;
 import org.apache.datasketches.memory.MemoryRequestServer;
+import org.apache.datasketches.memory.ReadOnlyException;
 import org.apache.datasketches.memory.Utf8CodingException;
+import org.apache.datasketches.memory.WritableBuffer;
 import org.apache.datasketches.memory.WritableHandle;
 import org.apache.datasketches.memory.WritableMapHandle;
 import org.apache.datasketches.memory.WritableMemory;
@@ -56,21 +61,17 @@ import org.apache.datasketches.memory.WritableMemory;
  */
 
 /**
- * Common base of native-ordered and non-native-ordered {@link WritableMemoryImpl} implementations.
+ * Common base of native-ordered and non-native-ordered {@link WritableMemory} implementations.
  * Contains methods which are agnostic to the byte order.
  */
 @SuppressWarnings("restriction")
-abstract class BaseWritableMemoryImpl extends WritableMemoryImpl {
+public abstract class BaseWritableMemoryImpl extends BaseStateImpl implements WritableMemory {
 
   //1KB of empty bytes for speedy clear()
   private final static byte[] EMPTY_BYTES;
 
-  //Static variable for cases where byteBuf/array/direct sizes are zero
-  final static BaseWritableMemoryImpl ZERO_SIZE_MEMORY;
-
   static {
     EMPTY_BYTES = new byte[1024];
-    ZERO_SIZE_MEMORY = new HeapWritableMemoryImpl(new byte[0], 0L, 0L, READONLY);
   }
 
   //Pass-through ctor
@@ -79,22 +80,19 @@ abstract class BaseWritableMemoryImpl extends WritableMemoryImpl {
     super(unsafeObj, nativeBaseOffset, regionOffset, capacityBytes);
   }
 
-  static BaseWritableMemoryImpl wrapHeapArray(final Object arr, final long offsetBytes,
-      final long lengthBytes, final boolean localReadOnly, final ByteOrder byteOrder) {
-    if (lengthBytes == 0) { return BaseWritableMemoryImpl.ZERO_SIZE_MEMORY; }
+  public static BaseWritableMemoryImpl wrapHeapArray(final Object arr, final long offsetBytes, final long lengthBytes,
+      final boolean localReadOnly, final ByteOrder byteOrder, final MemoryRequestServer memReqSvr) {
+
     final int typeId = localReadOnly ? READONLY : 0;
     return Util.isNativeByteOrder(byteOrder)
-        ? new HeapWritableMemoryImpl(arr, offsetBytes, lengthBytes, typeId)
-        : new HeapNonNativeWritableMemoryImpl(arr, offsetBytes, lengthBytes, typeId);
+        ? new HeapWritableMemoryImpl(arr, offsetBytes, lengthBytes, typeId, memReqSvr)
+        : new HeapNonNativeWritableMemoryImpl(arr, offsetBytes, lengthBytes, typeId, memReqSvr);
   }
 
-  static BaseWritableMemoryImpl wrapByteBuffer(
+  public static BaseWritableMemoryImpl wrapByteBuffer(
       final ByteBuffer byteBuf, final boolean localReadOnly, final ByteOrder byteOrder,
       final MemoryRequestServer memReqSvr) {
     final AccessByteBuffer abb = new AccessByteBuffer(byteBuf);
-    if (abb.resourceReadOnly && !localReadOnly) {
-      throw new ReadOnlyException("ByteBuffer is Read Only");
-    }
     final int typeId = (abb.resourceReadOnly || localReadOnly) ? READONLY : 0;
     return Util.isNativeByteOrder(byteOrder)
         ? new BBWritableMemoryImpl(abb.unsafeObj, abb.nativeBaseOffset,
@@ -104,15 +102,10 @@ abstract class BaseWritableMemoryImpl extends WritableMemoryImpl {
   }
 
   @SuppressWarnings("resource")
-  static WritableMapHandle wrapMap(final File file, final long fileOffsetBytes,
+  public static WritableMapHandle wrapMap(final File file, final long fileOffsetBytes,
       final long capacityBytes, final boolean localReadOnly, final ByteOrder byteOrder) {
-
     final AllocateDirectWritableMap dirWMap =
         new AllocateDirectWritableMap(file, fileOffsetBytes, capacityBytes, localReadOnly);
-    if (dirWMap.resourceReadOnly && !localReadOnly) {
-      dirWMap.close();
-      throw new ReadOnlyException("File is Read Only");
-    }
     final int typeId = (dirWMap.resourceReadOnly || localReadOnly) ? READONLY : 0;
     final BaseWritableMemoryImpl wmem = Util.isNativeByteOrder(byteOrder)
         ? new MapWritableMemoryImpl(dirWMap.nativeBaseOffset, 0L, capacityBytes,
@@ -123,12 +116,8 @@ abstract class BaseWritableMemoryImpl extends WritableMemoryImpl {
   }
 
   @SuppressWarnings("resource")
-  static WritableHandle wrapDirect(final long capacityBytes,
+  public static WritableHandle wrapDirect(final long capacityBytes,
       final ByteOrder byteOrder, final MemoryRequestServer memReqSvr) {
-    if (capacityBytes <= 0) {
-      throw new IllegalArgumentException(
-          "Capacity bytes should be positive, " + capacityBytes + " given");
-    }
     final AllocateDirect direct = new AllocateDirect(capacityBytes);
     final int typeId = 0; //direct is never read-only on construction
     final BaseWritableMemoryImpl wmem = Util.isNativeByteOrder(byteOrder)
@@ -141,59 +130,27 @@ abstract class BaseWritableMemoryImpl extends WritableMemoryImpl {
     return handle;
   }
 
-  //UNSAFE BYTE BUFFER VIEW FOR DIRECT MEMORY ONLY
-  @Override
-  public ByteBuffer unsafeByteBufferView(final long offsetBytes, final int capacityBytes) {
-    checkValidAndBounds(offsetBytes, capacityBytes);
-    final long cumOffset = getCumulativeOffset(offsetBytes);
-    final Object unsafeObj = getUnsafeObject();
-    final ByteBuffer result;
-    if (unsafeObj == null) {
-      result = AccessByteBuffer.getDummyReadOnlyDirectByteBuffer(cumOffset, capacityBytes);
-    } else if (unsafeObj instanceof byte[]) {
-      final int arrayOffset = (int) (cumOffset - ARRAY_BYTE_BASE_OFFSET);
-      result = ByteBuffer.wrap((byte[]) unsafeObj, arrayOffset, capacityBytes)
-          .slice().asReadOnlyBuffer();
-    } else {
-      throw new UnsupportedOperationException(
-          "This MemoryImpl object is the result of wrapping a "
-              + unsafeObj.getClass().getSimpleName()
-              + " array, it could not be viewed as a ByteBuffer.");
-    }
-    result.order(getTypeByteOrder());
-    return result;
-  }
-
   //REGIONS
   @Override
-  public MemoryImpl region(final long offsetBytes, final long capacityBytes) {
-    return writableRegionImpl(offsetBytes, capacityBytes, true, getTypeByteOrder());
-  }
-
-  @Override
-  public MemoryImpl region(final long offsetBytes, final long capacityBytes, final ByteOrder byteOrder) {
+  public Memory region(final long offsetBytes, final long capacityBytes, final ByteOrder byteOrder) {
     return writableRegionImpl(offsetBytes, capacityBytes, true, byteOrder);
   }
 
   @Override
-  public WritableMemoryImpl writableRegion(final long offsetBytes, final long capacityBytes) {
-    return writableRegionImpl(offsetBytes, capacityBytes, false, getTypeByteOrder());
-  }
-
-  @Override
-  public WritableMemoryImpl writableRegion(final long offsetBytes, final long capacityBytes,
-      final ByteOrder byteOrder) {
+  public WritableMemory writableRegion(final long offsetBytes, final long capacityBytes, final ByteOrder byteOrder) {
     return writableRegionImpl(offsetBytes, capacityBytes, false, byteOrder);
   }
 
-  WritableMemoryImpl writableRegionImpl(final long offsetBytes, final long capacityBytes,
+  WritableMemory writableRegionImpl(final long offsetBytes, final long capacityBytes,
       final boolean localReadOnly, final ByteOrder byteOrder) {
-    if (capacityBytes == 0) { return ZERO_SIZE_MEMORY; }
     if (isReadOnly() && !localReadOnly) {
-      throw new ReadOnlyException("Writable region of a read-only MemoryImpl is not allowed.");
+      throw new ReadOnlyException("Writable region of a read-only Memory is not allowed.");
     }
-    final boolean readOnly = isReadOnly() || localReadOnly;
+    negativeCheck(offsetBytes, "offsetBytes must be >= 0");
+    negativeCheck(capacityBytes, "capacityBytes must be >= 0");
+    Objects.requireNonNull(byteOrder, "byteOrder must be non-null.");
     checkValidAndBounds(offsetBytes, capacityBytes);
+    final boolean readOnly = isReadOnly() || localReadOnly;
     return toWritableRegion(offsetBytes, capacityBytes, readOnly, byteOrder);
   }
 
@@ -202,39 +159,30 @@ abstract class BaseWritableMemoryImpl extends WritableMemoryImpl {
 
   //AS BUFFER
   @Override
-  public BufferImpl asBuffer() {
-    return asWritableBuffer(true, getTypeByteOrder());
-  }
-
-  @Override
-  public BufferImpl asBuffer(final ByteOrder byteOrder) {
+  public Buffer asBuffer(final ByteOrder byteOrder) {
     return asWritableBuffer(true, byteOrder);
   }
 
   @Override
-  public WritableBufferImpl asWritableBuffer() {
-    return asWritableBuffer(false, getTypeByteOrder());
-  }
-
-  @Override
-  public WritableBufferImpl asWritableBuffer(final ByteOrder byteOrder) {
+  public WritableBuffer asWritableBuffer(final ByteOrder byteOrder) {
     return asWritableBuffer(false, byteOrder);
   }
 
-  WritableBufferImpl asWritableBuffer(final boolean localReadOnly, final ByteOrder byteOrder) {
+  WritableBuffer asWritableBuffer(final boolean localReadOnly, final ByteOrder byteOrder) {
+    Objects.requireNonNull(byteOrder, "byteOrder must be non-null");
     if (isReadOnly() && !localReadOnly) {
       throw new ReadOnlyException(
-          "Converting a read-only MemoryImpl to a writable BufferImpl is not allowed.");
+          "Converting a read-only Memory to a writable Buffer is not allowed.");
     }
     final boolean readOnly = isReadOnly() || localReadOnly;
-    final WritableBufferImpl wbuf = toWritableBuffer(readOnly, byteOrder);
+    final WritableBuffer wbuf = toWritableBuffer(readOnly, byteOrder);
     wbuf.setStartPositionEnd(0, 0, getCapacity());
     return wbuf;
   }
 
   abstract BaseWritableBufferImpl toWritableBuffer(boolean readOnly, ByteOrder byteOrder);
 
-  //PRIMITIVE getX() and getXArray() ENDIAN INDEPENDENT
+  //PRIMITIVE getX() and getXArray()
   @Override
   public final boolean getBoolean(final long offsetBytes) {
     assertValidAndBoundsForRead(offsetBytes, ARRAY_BOOLEAN_INDEX_SCALE);
@@ -340,8 +288,8 @@ abstract class BaseWritableMemoryImpl extends WritableMemoryImpl {
     } else if (getUnsafeObject() == null) {
       writeDirectMemoryTo(offsetBytes, lengthBytes, out);
     } else {
-      // MemoryImpl is backed by some array that is not byte[], for example int[], long[], etc.
-      // We don't have other choice as to do extra intermediate copy.
+      // Memory is backed by some array that is not byte[], for example int[], long[], etc.
+      // We don't have the choice to do an extra intermediate copy.
       writeToWithExtraCopy(offsetBytes, lengthBytes, out);
     }
   }
diff --git a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/BufferImpl.java b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/BufferImpl.java
deleted file mode 100644
index a9a1106..0000000
--- a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/BufferImpl.java
+++ /dev/null
@@ -1,162 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you 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.apache.datasketches.memory.internal;
-
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-
-import org.apache.datasketches.memory.Buffer;
-
-/**
- * Provides read-only, positional primitive and primitive array methods to any of the four resources
- * mentioned in the package level documentation.
- *
- * @author Roman Leventov
- * @author Lee Rhodes
- *
- * @see org.apache.datasketches.memory.internal
- */
-public abstract class BufferImpl extends BaseBufferImpl implements Buffer {
-
-  //Pass-through ctor
-  BufferImpl(final Object unsafeObj, final long nativeBaseOffset,
-      final long regionOffset, final long capacityBytes) {
-    super(unsafeObj, nativeBaseOffset, regionOffset, capacityBytes);
-  }
-
-  //BYTE BUFFER
-  public static BufferImpl wrap(final ByteBuffer byteBuf) {
-    return wrap(byteBuf, byteBuf.order());
-  }
-
-  public static BufferImpl wrap(final ByteBuffer byteBuf, final ByteOrder byteOrder) {
-    final BaseWritableMemoryImpl wmem =
-        BaseWritableMemoryImpl.wrapByteBuffer(byteBuf, true, byteOrder, defaultMemReqSvr);
-    final WritableBufferImpl wbuf = wmem.asWritableBuffer(true, byteOrder);
-    wbuf.setStartPositionEnd(0, byteBuf.position(), byteBuf.limit());
-    return wbuf;
-  }
-
-  //MAP
-  //Use MemoryImpl for mapping files and then call asBuffer()
-
-  //DUPLICATES
-  @Override
-  public abstract BufferImpl duplicate();
-
-  @Override
-  public abstract BufferImpl duplicate(ByteOrder byteOrder);
-
-  //REGIONS
-  @Override
-  public abstract BufferImpl region();
-
-  @Override
-  public abstract BufferImpl region(long offsetBytes, long capacityBytes,
-      ByteOrder byteOrder);
-
-  //MEMORY
-  @Override
-  public abstract MemoryImpl asMemory();
-
-  //ACCESS PRIMITIVE HEAP ARRAYS for readOnly
-  // use MemoryImpl or WritableMemoryImpl and then asBuffer().
-  //END OF CONSTRUCTOR-TYPE METHODS
-
-  //PRIMITIVE getX() and getXArray()
-  @Override
-  public abstract boolean getBoolean();
-
-  @Override
-  public abstract boolean getBoolean(long offsetBytes);
-
-  @Override
-  public abstract void getBooleanArray(boolean[] dstArray, int dstOffsetBooleans,
-      int lengthBooleans);
-
-  @Override
-  public abstract byte getByte();
-
-  @Override
-  public abstract byte getByte(long offsetBytes);
-
-  @Override
-  public abstract void getByteArray(byte[] dstArray, int dstOffsetBytes, int lengthBytes);
-
-  @Override
-  public abstract char getChar();
-
-  @Override
-  public abstract char getChar(long offsetBytes);
-
-  @Override
-  public abstract void getCharArray(char[] dstArray, int dstOffsetChars, int lengthChars);
-
-  @Override
-  public abstract double getDouble();
-
-  @Override
-  public abstract double getDouble(long offsetBytes);
-
-  @Override
-  public abstract void getDoubleArray(double[] dstArray, int dstOffsetDoubles, int lengthDoubles);
-
-  @Override
-  public abstract float getFloat();
-
-  @Override
-  public abstract float getFloat(long offsetBytes);
-
-  @Override
-  public abstract void getFloatArray(float[] dstArray, int dstOffsetFloats, int lengthFloats);
-
-  @Override
-  public abstract int getInt();
-
-  @Override
-  public abstract int getInt(long offsetBytes);
-
-  @Override
-  public abstract void getIntArray(int[] dstArray, int dstOffsetInts, int lengthInts);
-
-  @Override
-  public abstract long getLong();
-
-  @Override
-  public abstract long getLong(long offsetBytes);
-
-  @Override
-  public abstract void getLongArray(long[] dstArray, int dstOffsetLongs, int lengthLongs);
-
-  @Override
-  public abstract short getShort();
-
-  @Override
-  public abstract short getShort(long offsetBytes);
-
-  @Override
-  public abstract void getShortArray(short[] dstArray, int dstOffsetShorts, int lengthShorts);
-
-  //SPECIAL PRIMITIVE READ METHODS: compareTo
-  @Override
-  public abstract int compareTo(long thisOffsetBytes, long thisLengthBytes, Buffer that,
-          long thatOffsetBytes, long thatLengthBytes);
-
-}
diff --git a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/DirectNonNativeWritableBufferImpl.java b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/DirectNonNativeWritableBufferImpl.java
index 457870f..3b0a183 100644
--- a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/DirectNonNativeWritableBufferImpl.java
+++ b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/DirectNonNativeWritableBufferImpl.java
@@ -22,9 +22,10 @@ package org.apache.datasketches.memory.internal;
 import java.nio.ByteOrder;
 
 import org.apache.datasketches.memory.MemoryRequestServer;
+import org.apache.datasketches.memory.WritableBuffer;
 
 /**
- * Implementation of {@link WritableBufferImpl} for direct memory, non-native byte order.
+ * Implementation of {@link WritableBuffer} for direct memory, non-native byte order.
  *
  * @author Roman Leventov
  * @author Lee Rhodes
@@ -33,7 +34,7 @@ final class DirectNonNativeWritableBufferImpl extends NonNativeWritableBufferImp
   private static final int id = BUFFER | NONNATIVE | DIRECT;
   private final long nativeBaseOffset; //used to compute cumBaseOffset
   private final StepBoolean valid; //a reference only
-  private MemoryRequestServer memReqSvr = null; //cannot be final;
+  private final MemoryRequestServer memReqSvr;
   private final byte typeId;
 
   DirectNonNativeWritableBufferImpl(
@@ -42,45 +43,49 @@ final class DirectNonNativeWritableBufferImpl extends NonNativeWritableBufferImp
       final long capacityBytes,
       final int typeId,
       final StepBoolean valid,
-      final MemoryRequestServer memReqSvr,
-      final BaseWritableMemoryImpl originMemory) {
-    super(null, nativeBaseOffset, regionOffset, capacityBytes, originMemory);
+      final MemoryRequestServer memReqSvr) {
+    super(null, nativeBaseOffset, regionOffset, capacityBytes);
     this.nativeBaseOffset = nativeBaseOffset;
     this.valid = valid;
-    assert memReqSvr != null;
-    this.memReqSvr = memReqSvr; //should not be null
+    this.memReqSvr = memReqSvr;
     this.typeId = (byte) (id | (typeId & 0x7));
   }
 
   @Override
   BaseWritableBufferImpl toWritableRegion(final long offsetBytes, final long capacityBytes,
       final boolean readOnly, final ByteOrder byteOrder) {
-    final int type = typeId | REGION | (readOnly ? READONLY : 0);
+    final int type = setReadOnlyType(typeId, readOnly) | REGION;
     return Util.isNativeByteOrder(byteOrder)
         ? new DirectWritableBufferImpl(
-            nativeBaseOffset, getRegionOffset(offsetBytes), capacityBytes,
-            type, valid, memReqSvr, originMemory)
+            nativeBaseOffset, getRegionOffset(offsetBytes), capacityBytes, type, valid, memReqSvr)
         : new DirectNonNativeWritableBufferImpl(
-            nativeBaseOffset, getRegionOffset(offsetBytes), capacityBytes,
-            type, valid, memReqSvr, originMemory);
+            nativeBaseOffset, getRegionOffset(offsetBytes), capacityBytes, type, valid, memReqSvr);
   }
 
   @Override
   BaseWritableBufferImpl toDuplicate(final boolean readOnly, final ByteOrder byteOrder) {
-    final int type = typeId | DUPLICATE | (readOnly ? READONLY : 0);
+    final int type = setReadOnlyType(typeId, readOnly) | DUPLICATE;
     return Util.isNativeByteOrder(byteOrder)
         ? new DirectWritableBufferImpl(
-            nativeBaseOffset, getRegionOffset(), getCapacity(),
-            type, valid, memReqSvr, originMemory)
+            nativeBaseOffset, getRegionOffset(), getCapacity(), type, valid, memReqSvr)
         : new DirectNonNativeWritableBufferImpl(
-            nativeBaseOffset, getRegionOffset(), getCapacity(),
-            type, valid, memReqSvr, originMemory);
+            nativeBaseOffset, getRegionOffset(), getCapacity(), type, valid, memReqSvr);
+  }
+
+  @Override
+  BaseWritableMemoryImpl toWritableMemory(final boolean readOnly, final ByteOrder byteOrder) {
+    final int type = setReadOnlyType(typeId, readOnly);
+    return Util.isNativeByteOrder(byteOrder)
+        ? new DirectWritableMemoryImpl(
+            nativeBaseOffset, getRegionOffset(), getCapacity(), type, valid, memReqSvr)
+        : new DirectNonNativeWritableMemoryImpl(
+            nativeBaseOffset, getRegionOffset(), getCapacity(), type, valid, memReqSvr);
   }
 
   @Override
   public MemoryRequestServer getMemoryRequestServer() {
     assertValid();
-    return memReqSvr; //cannot be null
+    return memReqSvr;
   }
 
   @Override
diff --git a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/DirectNonNativeWritableMemoryImpl.java b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/DirectNonNativeWritableMemoryImpl.java
index 48b92eb..7be7e74 100644
--- a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/DirectNonNativeWritableMemoryImpl.java
+++ b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/DirectNonNativeWritableMemoryImpl.java
@@ -22,9 +22,10 @@ package org.apache.datasketches.memory.internal;
 import java.nio.ByteOrder;
 
 import org.apache.datasketches.memory.MemoryRequestServer;
+import org.apache.datasketches.memory.WritableMemory;
 
 /**
- * Implementation of {@link WritableMemoryImpl} for direct memory, non-native byte order.
+ * Implementation of {@link WritableMemory} for direct memory, non-native byte order.
  *
  * @author Roman Leventov
  * @author Lee Rhodes
@@ -33,7 +34,7 @@ final class DirectNonNativeWritableMemoryImpl extends NonNativeWritableMemoryImp
   private static final int id = MEMORY | NONNATIVE | DIRECT;
   private final long nativeBaseOffset; //used to compute cumBaseOffset
   private final StepBoolean valid; //a reference only
-  private MemoryRequestServer memReqSvr = null; //cannot be final;
+  private final MemoryRequestServer memReqSvr;
   private final byte typeId;
 
   DirectNonNativeWritableMemoryImpl(
@@ -46,39 +47,35 @@ final class DirectNonNativeWritableMemoryImpl extends NonNativeWritableMemoryImp
     super(null, nativeBaseOffset, regionOffset, capacityBytes);
     this.nativeBaseOffset = nativeBaseOffset;
     this.valid = valid;
-    this.memReqSvr = (memReqSvr == null) ? defaultMemReqSvr : memReqSvr;
+    this.memReqSvr = memReqSvr;
     this.typeId = (byte) (id | (typeId & 0x7));
   }
 
   @Override
   BaseWritableMemoryImpl toWritableRegion(final long offsetBytes, final long capacityBytes,
       final boolean readOnly, final ByteOrder byteOrder) {
-    final int type = typeId | REGION | (readOnly ? READONLY : 0);
+    final int type = setReadOnlyType(typeId, readOnly) | REGION;
     return Util.isNativeByteOrder(byteOrder)
         ? new DirectWritableMemoryImpl(
-            nativeBaseOffset, getRegionOffset(offsetBytes), capacityBytes,
-            type, valid, memReqSvr)
+            nativeBaseOffset, getRegionOffset(offsetBytes), capacityBytes, type, valid, memReqSvr)
         : new DirectNonNativeWritableMemoryImpl(
-            nativeBaseOffset, getRegionOffset(offsetBytes), capacityBytes,
-            type, valid, memReqSvr);
+            nativeBaseOffset, getRegionOffset(offsetBytes), capacityBytes, type, valid, memReqSvr);
   }
 
   @Override
   BaseWritableBufferImpl toWritableBuffer(final boolean readOnly, final ByteOrder byteOrder) {
-    final int type = typeId | (readOnly ? READONLY : 0);
+    final int type = setReadOnlyType(typeId, readOnly);
     return Util.isNativeByteOrder(byteOrder)
         ? new DirectWritableBufferImpl(
-            nativeBaseOffset, getRegionOffset(), getCapacity(),
-            type, valid, memReqSvr, this)
+            nativeBaseOffset, getRegionOffset(), getCapacity(), type, valid, memReqSvr)
         : new DirectNonNativeWritableBufferImpl(
-            nativeBaseOffset, getRegionOffset(), getCapacity(),
-            type, valid, memReqSvr, this);
+            nativeBaseOffset, getRegionOffset(), getCapacity(), type, valid, memReqSvr);
   }
 
   @Override
   public MemoryRequestServer getMemoryRequestServer() {
     assertValid();
-    return memReqSvr; //cannot be null
+    return memReqSvr;
   }
 
   @Override
diff --git a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/DirectWritableBufferImpl.java b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/DirectWritableBufferImpl.java
index e7048a6..84e7d5e 100644
--- a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/DirectWritableBufferImpl.java
+++ b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/DirectWritableBufferImpl.java
@@ -22,9 +22,10 @@ package org.apache.datasketches.memory.internal;
 import java.nio.ByteOrder;
 
 import org.apache.datasketches.memory.MemoryRequestServer;
+import org.apache.datasketches.memory.WritableBuffer;
 
 /**
- * Implementation of {@link WritableBufferImpl} for direct memory, native byte order.
+ * Implementation of {@link WritableBuffer} for direct memory, native byte order.
  *
  * @author Roman Leventov
  * @author Lee Rhodes
@@ -33,7 +34,7 @@ final class DirectWritableBufferImpl extends NativeWritableBufferImpl {
   private static final int id = BUFFER | NATIVE | DIRECT;
   private final long nativeBaseOffset; //used to compute cumBaseOffset
   private final StepBoolean valid; //a reference only
-  private MemoryRequestServer memReqSvr = null; //cannot be final;
+  private final MemoryRequestServer memReqSvr;
   private final byte typeId;
 
   DirectWritableBufferImpl(
@@ -42,45 +43,49 @@ final class DirectWritableBufferImpl extends NativeWritableBufferImpl {
       final long capacityBytes,
       final int typeId,
       final StepBoolean valid,
-      final MemoryRequestServer memReqSvr,
-      final BaseWritableMemoryImpl originMemory) {
-    super(null, nativeBaseOffset, regionOffset, capacityBytes, originMemory);
+      final MemoryRequestServer memReqSvr) {
+    super(null, nativeBaseOffset, regionOffset, capacityBytes);
     this.nativeBaseOffset = nativeBaseOffset;
     this.valid = valid;
-    assert memReqSvr != null;
-    this.memReqSvr = memReqSvr; //should not be null
+    this.memReqSvr = memReqSvr;
     this.typeId = (byte) (id | (typeId & 0x7));
   }
 
   @Override
   BaseWritableBufferImpl toWritableRegion(final long offsetBytes, final long capacityBytes,
       final boolean readOnly, final ByteOrder byteOrder) {
-    final int type = typeId | REGION | (readOnly ? READONLY : 0);
+    final int type = setReadOnlyType(typeId, readOnly) | REGION;
     return Util.isNativeByteOrder(byteOrder)
         ? new DirectWritableBufferImpl(
-            nativeBaseOffset, getRegionOffset(offsetBytes), capacityBytes,
-            type, valid, memReqSvr, originMemory)
+            nativeBaseOffset, getRegionOffset(offsetBytes), capacityBytes, type, valid, memReqSvr)
         : new DirectNonNativeWritableBufferImpl(
-            nativeBaseOffset, getRegionOffset(offsetBytes), capacityBytes,
-            type, valid, memReqSvr, originMemory);
+            nativeBaseOffset, getRegionOffset(offsetBytes), capacityBytes, type, valid, memReqSvr);
   }
 
   @Override
   BaseWritableBufferImpl toDuplicate(final boolean readOnly, final ByteOrder byteOrder) {
-    final int type = typeId | DUPLICATE | (readOnly ? READONLY : 0);
+    final int type = setReadOnlyType(typeId, readOnly) | DUPLICATE;
     return Util.isNativeByteOrder(byteOrder)
         ? new DirectWritableBufferImpl(
-            nativeBaseOffset, getRegionOffset(), getCapacity(),
-            type, valid, memReqSvr, originMemory)
+            nativeBaseOffset, getRegionOffset(), getCapacity(), type, valid, memReqSvr)
         : new DirectNonNativeWritableBufferImpl(
-            nativeBaseOffset, getRegionOffset(), getCapacity(),
-            type, valid, memReqSvr, originMemory);
+            nativeBaseOffset, getRegionOffset(), getCapacity(), type, valid, memReqSvr);
+  }
+
+  @Override
+  BaseWritableMemoryImpl toWritableMemory(final boolean readOnly, final ByteOrder byteOrder) {
+    final int type = setReadOnlyType(typeId, readOnly);
+    return Util.isNativeByteOrder(byteOrder)
+        ? new DirectWritableMemoryImpl(
+            nativeBaseOffset, getRegionOffset(), getCapacity(), type, valid, memReqSvr)
+        : new DirectNonNativeWritableMemoryImpl(
+            nativeBaseOffset, getRegionOffset(), getCapacity(), type, valid, memReqSvr);
   }
 
   @Override
   public MemoryRequestServer getMemoryRequestServer() {
     assertValid();
-    return memReqSvr; //cannot be null
+    return memReqSvr;
   }
 
   @Override
diff --git a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/DirectWritableMemoryImpl.java b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/DirectWritableMemoryImpl.java
index c79f896..68a3461 100644
--- a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/DirectWritableMemoryImpl.java
+++ b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/DirectWritableMemoryImpl.java
@@ -22,9 +22,10 @@ package org.apache.datasketches.memory.internal;
 import java.nio.ByteOrder;
 
 import org.apache.datasketches.memory.MemoryRequestServer;
+import org.apache.datasketches.memory.WritableMemory;
 
 /**
- * Implementation of {@link WritableMemoryImpl} for direct memory, native byte order.
+ * Implementation of {@link WritableMemory} for direct memory, native byte order.
  *
  * @author Roman Leventov
  * @author Lee Rhodes
@@ -33,7 +34,7 @@ final class DirectWritableMemoryImpl extends NativeWritableMemoryImpl {
   private static final int id = MEMORY | NATIVE | DIRECT;
   private final long nativeBaseOffset; //used to compute cumBaseOffset
   private final StepBoolean valid; //a reference only
-  private MemoryRequestServer memReqSvr = null; //cannot be final;
+  private final MemoryRequestServer memReqSvr;
   private final byte typeId;
 
   DirectWritableMemoryImpl(
@@ -46,39 +47,35 @@ final class DirectWritableMemoryImpl extends NativeWritableMemoryImpl {
     super(null, nativeBaseOffset, regionOffset, capacityBytes);
     this.nativeBaseOffset = nativeBaseOffset;
     this.valid = valid;
-    this.memReqSvr = (memReqSvr == null) ? defaultMemReqSvr : memReqSvr;
+    this.memReqSvr = memReqSvr;
     this.typeId = (byte) (id | (typeId & 0x7));
   }
 
   @Override
   BaseWritableMemoryImpl toWritableRegion(final long offsetBytes, final long capacityBytes,
       final boolean readOnly, final ByteOrder byteOrder) {
-    final int type = typeId | REGION | (readOnly ? READONLY : 0);
+    final int type = setReadOnlyType(typeId, readOnly) | REGION;
     return Util.isNativeByteOrder(byteOrder)
         ? new DirectWritableMemoryImpl(
-            nativeBaseOffset, getRegionOffset(offsetBytes), capacityBytes,
-            type, valid, memReqSvr)
+            nativeBaseOffset, getRegionOffset(offsetBytes), capacityBytes, type, valid, memReqSvr)
         : new DirectNonNativeWritableMemoryImpl(
-            nativeBaseOffset, getRegionOffset(offsetBytes), capacityBytes,
-            type, valid, memReqSvr);
+            nativeBaseOffset, getRegionOffset(offsetBytes), capacityBytes, type, valid, memReqSvr);
   }
 
   @Override
   BaseWritableBufferImpl toWritableBuffer(final boolean readOnly, final ByteOrder byteOrder) {
-    final int type = typeId | (readOnly ? READONLY : 0);
+    final int type = setReadOnlyType(typeId, readOnly);
     return Util.isNativeByteOrder(byteOrder)
         ? new DirectWritableBufferImpl(
-            nativeBaseOffset, getRegionOffset(), getCapacity(),
-            type, valid, memReqSvr, this)
+            nativeBaseOffset, getRegionOffset(), getCapacity(), type, valid, memReqSvr)
         : new DirectNonNativeWritableBufferImpl(
-            nativeBaseOffset, getRegionOffset(), getCapacity(),
-            type, valid, memReqSvr, this);
+            nativeBaseOffset, getRegionOffset(), getCapacity(), type, valid, memReqSvr);
   }
 
   @Override
   public MemoryRequestServer getMemoryRequestServer() {
     assertValid();
-    return memReqSvr; //cannot be null
+    return memReqSvr;
   }
 
   @Override
diff --git a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/HeapNonNativeWritableBufferImpl.java b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/HeapNonNativeWritableBufferImpl.java
index efddbe0..1a324f7 100644
--- a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/HeapNonNativeWritableBufferImpl.java
+++ b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/HeapNonNativeWritableBufferImpl.java
@@ -22,9 +22,10 @@ package org.apache.datasketches.memory.internal;
 import java.nio.ByteOrder;
 
 import org.apache.datasketches.memory.MemoryRequestServer;
+import org.apache.datasketches.memory.WritableBuffer;
 
 /**
- * Implementation of {@link WritableBufferImpl} for heap-based, non-native byte order.
+ * Implementation of {@link WritableBuffer} for heap-based, non-native byte order.
  *
  * @author Roman Leventov
  * @author Lee Rhodes
@@ -32,6 +33,7 @@ import org.apache.datasketches.memory.MemoryRequestServer;
 final class HeapNonNativeWritableBufferImpl extends NonNativeWritableBufferImpl {
   private static final int id = BUFFER | NONNATIVE | HEAP;
   private final Object unsafeObj;
+  private final MemoryRequestServer memReqSvr;
   private final byte typeId;
 
   HeapNonNativeWritableBufferImpl(
@@ -39,40 +41,47 @@ final class HeapNonNativeWritableBufferImpl extends NonNativeWritableBufferImpl
       final long regionOffset,
       final long capacityBytes,
       final int typeId,
-      final BaseWritableMemoryImpl originMemory) {
-    super(unsafeObj, 0L, regionOffset, capacityBytes, originMemory);
+      final MemoryRequestServer memReqSvr) {
+    super(unsafeObj, 0L, regionOffset, capacityBytes);
     this.unsafeObj = unsafeObj;
+    this.memReqSvr = memReqSvr;
     this.typeId = (byte) (id | (typeId & 0x7));
   }
 
   @Override
   BaseWritableBufferImpl toWritableRegion(final long offsetBytes, final long capacityBytes,
       final boolean readOnly, final ByteOrder byteOrder) {
-    final int type = typeId | REGION | (readOnly ? READONLY : 0);
+    final int type = setReadOnlyType(typeId, readOnly) | REGION;
     return Util.isNativeByteOrder(byteOrder)
         ? new HeapWritableBufferImpl(
-            unsafeObj, getRegionOffset(offsetBytes), capacityBytes,
-            type, originMemory)
+            unsafeObj, getRegionOffset(offsetBytes), capacityBytes, type, memReqSvr)
         : new HeapNonNativeWritableBufferImpl(
-            unsafeObj, getRegionOffset(offsetBytes), capacityBytes,
-            type, originMemory);
+            unsafeObj, getRegionOffset(offsetBytes), capacityBytes, type, memReqSvr);
   }
 
   @Override
   BaseWritableBufferImpl toDuplicate(final boolean readOnly, final ByteOrder byteOrder) {
-    final int type = typeId | DUPLICATE | (readOnly ? READONLY : 0);
+    final int type = setReadOnlyType(typeId, readOnly) | DUPLICATE;
     return Util.isNativeByteOrder(byteOrder)
         ? new HeapWritableBufferImpl(
-            unsafeObj, getRegionOffset(), getCapacity(),
-            type, originMemory)
+            unsafeObj, getRegionOffset(), getCapacity(), type, memReqSvr)
         : new HeapNonNativeWritableBufferImpl(
-            unsafeObj, getRegionOffset(), getCapacity(),
-            type, originMemory);
+            unsafeObj, getRegionOffset(), getCapacity(), type, memReqSvr);
+  }
+
+  @Override
+  BaseWritableMemoryImpl toWritableMemory(final boolean readOnly, final ByteOrder byteOrder) {
+    final int type = setReadOnlyType(typeId, readOnly);
+    return Util.isNativeByteOrder(byteOrder)
+        ? new HeapWritableMemoryImpl(
+            unsafeObj, getRegionOffset(), getCapacity(), type, memReqSvr)
+        : new HeapNonNativeWritableMemoryImpl(
+            unsafeObj, getRegionOffset(), getCapacity(), type, memReqSvr);
   }
 
   @Override
   public MemoryRequestServer getMemoryRequestServer() {
-    return null;
+    return memReqSvr;
   }
 
   @Override
diff --git a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/HeapNonNativeWritableMemoryImpl.java b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/HeapNonNativeWritableMemoryImpl.java
index 769f9fd..91702c5 100644
--- a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/HeapNonNativeWritableMemoryImpl.java
+++ b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/HeapNonNativeWritableMemoryImpl.java
@@ -22,9 +22,10 @@ package org.apache.datasketches.memory.internal;
 import java.nio.ByteOrder;
 
 import org.apache.datasketches.memory.MemoryRequestServer;
+import org.apache.datasketches.memory.WritableMemory;
 
 /**
- * Implementation of {@link WritableMemoryImpl} for heap-based, non-native byte order.
+ * Implementation of {@link WritableMemory} for heap-based, non-native byte order.
  *
  * @author Roman Leventov
  * @author Lee Rhodes
@@ -32,46 +33,45 @@ import org.apache.datasketches.memory.MemoryRequestServer;
 final class HeapNonNativeWritableMemoryImpl extends NonNativeWritableMemoryImpl {
   private static final int id = MEMORY | NONNATIVE | HEAP;
   private final Object unsafeObj;
+  private final MemoryRequestServer memReqSvr;
   private final byte typeId;
 
   HeapNonNativeWritableMemoryImpl(
       final Object unsafeObj,
       final long regionOffset,
       final long capacityBytes,
-      final int typeId) {
+      final int typeId,
+      final MemoryRequestServer memReqSvr) {
     super(unsafeObj, 0L, regionOffset, capacityBytes);
     this.unsafeObj = unsafeObj;
+    this.memReqSvr = memReqSvr;
     this.typeId = (byte) (id | (typeId & 0x7));
   }
 
   @Override
   BaseWritableMemoryImpl toWritableRegion(final long offsetBytes, final long capacityBytes,
       final boolean readOnly, final ByteOrder byteOrder) {
-    final int type = typeId | REGION | (readOnly ? READONLY : 0);
+    final int type = setReadOnlyType(typeId, readOnly) | REGION;
     return Util.isNativeByteOrder(byteOrder)
         ? new HeapWritableMemoryImpl(
-            unsafeObj, getRegionOffset(offsetBytes), capacityBytes,
-            type)
+            unsafeObj, getRegionOffset(offsetBytes), capacityBytes, type, memReqSvr)
         : new HeapNonNativeWritableMemoryImpl(
-            unsafeObj, getRegionOffset(offsetBytes), capacityBytes,
-            type);
+            unsafeObj, getRegionOffset(offsetBytes), capacityBytes, type, memReqSvr);
   }
 
   @Override
   BaseWritableBufferImpl toWritableBuffer(final boolean readOnly, final ByteOrder byteOrder) {
-    final int type = typeId | (readOnly ? READONLY : 0);
+    final int type = setReadOnlyType(typeId, readOnly);
     return Util.isNativeByteOrder(byteOrder)
         ? new HeapWritableBufferImpl(
-            unsafeObj, getRegionOffset(), getCapacity(),
-            type, this)
+            unsafeObj, getRegionOffset(), getCapacity(), type, memReqSvr)
         : new HeapNonNativeWritableBufferImpl(
-            unsafeObj, getRegionOffset(), getCapacity(),
-            type, this);
+            unsafeObj, getRegionOffset(), getCapacity(), type, memReqSvr);
   }
 
   @Override
   public MemoryRequestServer getMemoryRequestServer() {
-    return null;
+    return memReqSvr;
   }
 
   @Override
diff --git a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/HeapWritableBufferImpl.java b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/HeapWritableBufferImpl.java
index 3085868..033ad87 100644
--- a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/HeapWritableBufferImpl.java
+++ b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/HeapWritableBufferImpl.java
@@ -22,9 +22,10 @@ package org.apache.datasketches.memory.internal;
 import java.nio.ByteOrder;
 
 import org.apache.datasketches.memory.MemoryRequestServer;
+import org.apache.datasketches.memory.WritableBuffer;
 
 /**
- * Implementation of {@link WritableBufferImpl} for heap-based, native byte order.
+ * Implementation of {@link WritableBuffer} for heap-based, native byte order.
  *
  * @author Roman Leventov
  * @author Lee Rhodes
@@ -32,6 +33,7 @@ import org.apache.datasketches.memory.MemoryRequestServer;
 final class HeapWritableBufferImpl extends NativeWritableBufferImpl {
   private static final int id = BUFFER | NATIVE | HEAP;
   private final Object unsafeObj;
+  private final MemoryRequestServer memReqSvr;
   private final byte typeId;
 
   HeapWritableBufferImpl(
@@ -39,40 +41,47 @@ final class HeapWritableBufferImpl extends NativeWritableBufferImpl {
       final long regionOffset,
       final long capacityBytes,
       final int typeId,
-      final BaseWritableMemoryImpl originMemory) {
-    super(unsafeObj, 0L, regionOffset, capacityBytes, originMemory);
+      final MemoryRequestServer memReqSvr) {
+    super(unsafeObj, 0L, regionOffset, capacityBytes);
     this.unsafeObj = unsafeObj;
+    this.memReqSvr = memReqSvr;
     this.typeId = (byte) (id | (typeId & 0x7));
   }
 
   @Override
   BaseWritableBufferImpl toWritableRegion(final long offsetBytes, final long capacityBytes,
       final boolean readOnly, final ByteOrder byteOrder) {
-    final int type = typeId | REGION | (readOnly ? READONLY : 0);
+    final int type = setReadOnlyType(typeId, readOnly) | REGION;
     return Util.isNativeByteOrder(byteOrder)
         ? new HeapWritableBufferImpl(
-            unsafeObj, getRegionOffset(offsetBytes), capacityBytes,
-            type, originMemory)
+            unsafeObj, getRegionOffset(offsetBytes), capacityBytes, type, memReqSvr)
         : new HeapNonNativeWritableBufferImpl(
-            unsafeObj, getRegionOffset(offsetBytes), capacityBytes,
-            type, originMemory);
+            unsafeObj, getRegionOffset(offsetBytes), capacityBytes, type, memReqSvr);
   }
 
   @Override
   BaseWritableBufferImpl toDuplicate(final boolean readOnly, final ByteOrder byteOrder) {
-    final int type = typeId | DUPLICATE | (readOnly ? READONLY : 0);
+    final int type = setReadOnlyType(typeId, readOnly) | DUPLICATE;
     return Util.isNativeByteOrder(byteOrder)
         ? new HeapWritableBufferImpl(
-            unsafeObj, getRegionOffset(), getCapacity(),
-            type, originMemory)
+            unsafeObj, getRegionOffset(), getCapacity(), type, memReqSvr)
         : new HeapNonNativeWritableBufferImpl(
-            unsafeObj, getRegionOffset(), getCapacity(),
-            type, originMemory);
+            unsafeObj, getRegionOffset(), getCapacity(), type, memReqSvr);
+  }
+
+  @Override
+  BaseWritableMemoryImpl toWritableMemory(final boolean readOnly, final ByteOrder byteOrder) {
+    final int type = setReadOnlyType(typeId, readOnly);
+    return Util.isNativeByteOrder(byteOrder)
+        ? new HeapWritableMemoryImpl(
+            unsafeObj, getRegionOffset(), getCapacity(), type, memReqSvr)
+        : new HeapNonNativeWritableMemoryImpl(
+            unsafeObj, getRegionOffset(), getCapacity(), type, memReqSvr);
   }
 
   @Override
   public MemoryRequestServer getMemoryRequestServer() {
-    return null;
+    return memReqSvr;
   }
 
   @Override
diff --git a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/HeapWritableMemoryImpl.java b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/HeapWritableMemoryImpl.java
index 0e7fa93..9f6a9ca 100644
--- a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/HeapWritableMemoryImpl.java
+++ b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/HeapWritableMemoryImpl.java
@@ -22,9 +22,10 @@ package org.apache.datasketches.memory.internal;
 import java.nio.ByteOrder;
 
 import org.apache.datasketches.memory.MemoryRequestServer;
+import org.apache.datasketches.memory.WritableMemory;
 
 /**
- * Implementation of {@link WritableMemoryImpl} for heap-based, native byte order.
+ * Implementation of {@link WritableMemory} for heap-based, native byte order.
  *
  * @author Roman Leventov
  * @author Lee Rhodes
@@ -32,46 +33,47 @@ import org.apache.datasketches.memory.MemoryRequestServer;
 final class HeapWritableMemoryImpl extends NativeWritableMemoryImpl {
   private static final int id = MEMORY | NATIVE | HEAP;
   private final Object unsafeObj;
+  private final MemoryRequestServer memReqSvr;
   private final byte typeId;
 
+
   HeapWritableMemoryImpl(
       final Object unsafeObj,
       final long regionOffset,
       final long capacityBytes,
-      final int typeId) {
+      final int typeId,
+      final MemoryRequestServer memReqSvr) {
     super(unsafeObj, 0L, regionOffset, capacityBytes);
     this.unsafeObj = unsafeObj;
+    this.memReqSvr = memReqSvr;
     this.typeId = (byte) (id | (typeId & 0x7));
+
   }
 
   @Override
   BaseWritableMemoryImpl toWritableRegion(final long offsetBytes, final long capacityBytes,
       final boolean readOnly, final ByteOrder byteOrder) {
-    final int type = typeId | REGION | (readOnly ? READONLY : 0);
+    final int type = setReadOnlyType(typeId, readOnly) | REGION;
     return Util.isNativeByteOrder(byteOrder)
         ? new HeapWritableMemoryImpl(
-            unsafeObj, getRegionOffset(offsetBytes), capacityBytes,
-            type)
+            unsafeObj, getRegionOffset(offsetBytes), capacityBytes, type, memReqSvr)
         : new HeapNonNativeWritableMemoryImpl(
-            unsafeObj, getRegionOffset(offsetBytes), capacityBytes,
-            type);
+            unsafeObj, getRegionOffset(offsetBytes), capacityBytes, type, memReqSvr);
   }
 
   @Override
   BaseWritableBufferImpl toWritableBuffer(final boolean readOnly, final ByteOrder byteOrder) {
-    final int type = typeId | (readOnly ? READONLY : 0);
+    final int type = setReadOnlyType(typeId, readOnly);
     return Util.isNativeByteOrder(byteOrder)
         ? new HeapWritableBufferImpl(
-            unsafeObj, getRegionOffset(), getCapacity(),
-            type, this)
+            unsafeObj, getRegionOffset(), getCapacity(), type, memReqSvr)
         : new HeapNonNativeWritableBufferImpl(
-            unsafeObj, getRegionOffset(), getCapacity(),
-            type, this);
+            unsafeObj, getRegionOffset(), getCapacity(), type, memReqSvr);
   }
 
   @Override
   public MemoryRequestServer getMemoryRequestServer() {
-    return null;
+    return memReqSvr;
   }
 
   @Override
diff --git a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/MapNonNativeWritableBufferImpl.java b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/MapNonNativeWritableBufferImpl.java
index 9140928..31a4f1f 100644
--- a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/MapNonNativeWritableBufferImpl.java
+++ b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/MapNonNativeWritableBufferImpl.java
@@ -22,9 +22,10 @@ package org.apache.datasketches.memory.internal;
 import java.nio.ByteOrder;
 
 import org.apache.datasketches.memory.MemoryRequestServer;
+import org.apache.datasketches.memory.WritableBuffer;
 
 /**
- * Implementation of {@link WritableBufferImpl} for map memory, non-native byte order.
+ * Implementation of {@link WritableBuffer} for map memory, non-native byte order.
  *
  * @author Roman Leventov
  * @author Lee Rhodes
@@ -40,9 +41,8 @@ final class MapNonNativeWritableBufferImpl extends NonNativeWritableBufferImpl {
       final long regionOffset,
       final long capacityBytes,
       final int typeId,
-      final StepBoolean valid,
-      final BaseWritableMemoryImpl originMemory) {
-    super(null, nativeBaseOffset, regionOffset, capacityBytes, originMemory);
+      final StepBoolean valid) {
+    super(null, nativeBaseOffset, regionOffset, capacityBytes);
     this.nativeBaseOffset = nativeBaseOffset;
     this.valid = valid;
     this.typeId = (byte) (id | (typeId & 0x7));
@@ -51,26 +51,32 @@ final class MapNonNativeWritableBufferImpl extends NonNativeWritableBufferImpl {
   @Override
   BaseWritableBufferImpl toWritableRegion(final long offsetBytes, final long capacityBytes,
       final boolean readOnly, final ByteOrder byteOrder) {
-    final int type = REGION | (readOnly ? READONLY : 0);
+    final int type = setReadOnlyType(typeId, readOnly) | REGION;
     return Util.isNativeByteOrder(byteOrder)
         ? new MapWritableBufferImpl(
-            nativeBaseOffset, getRegionOffset(offsetBytes), capacityBytes,
-            type, valid, originMemory)
+            nativeBaseOffset, getRegionOffset(offsetBytes), capacityBytes, type, valid)
         : new MapNonNativeWritableBufferImpl(
-            nativeBaseOffset, getRegionOffset(offsetBytes), capacityBytes,
-            type, valid, originMemory);
+            nativeBaseOffset, getRegionOffset(offsetBytes), capacityBytes, type, valid);
   }
 
   @Override
   BaseWritableBufferImpl toDuplicate(final boolean readOnly, final ByteOrder byteOrder) {
-    final int type = DUPLICATE | (readOnly ? READONLY : 0);
+    final int type = setReadOnlyType(typeId, readOnly) | DUPLICATE;
     return Util.isNativeByteOrder(byteOrder)
         ? new MapWritableBufferImpl(
-            nativeBaseOffset, getRegionOffset(), getCapacity(),
-            type, valid, originMemory)
+            nativeBaseOffset, getRegionOffset(), getCapacity(), type, valid)
         : new MapNonNativeWritableBufferImpl(
-            nativeBaseOffset, getRegionOffset(), getCapacity(),
-            type, valid, originMemory);
+            nativeBaseOffset, getRegionOffset(), getCapacity(), type, valid);
+  }
+
+  @Override
+  BaseWritableMemoryImpl toWritableMemory(final boolean readOnly, final ByteOrder byteOrder) {
+    final int type = setReadOnlyType(typeId, readOnly);
+    return Util.isNativeByteOrder(byteOrder)
+        ? new MapWritableMemoryImpl(
+            nativeBaseOffset, getRegionOffset(), getCapacity(), type, valid)
+        : new MapNonNativeWritableMemoryImpl(
+            nativeBaseOffset, getRegionOffset(), getCapacity(), type, valid);
   }
 
   @Override
diff --git a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/MapNonNativeWritableMemoryImpl.java b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/MapNonNativeWritableMemoryImpl.java
index d972659..5305e5f 100644
--- a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/MapNonNativeWritableMemoryImpl.java
+++ b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/MapNonNativeWritableMemoryImpl.java
@@ -22,9 +22,10 @@ package org.apache.datasketches.memory.internal;
 import java.nio.ByteOrder;
 
 import org.apache.datasketches.memory.MemoryRequestServer;
+import org.apache.datasketches.memory.WritableMemory;
 
 /**
- * Implementation of {@link WritableMemoryImpl} for map memory, non-native byte order.
+ * Implementation of {@link WritableMemory} for map memory, non-native byte order.
  *
  * @author Roman Leventov
  * @author Lee Rhodes
@@ -50,26 +51,22 @@ final class MapNonNativeWritableMemoryImpl extends NonNativeWritableMemoryImpl {
   @Override
   BaseWritableMemoryImpl toWritableRegion(final long offsetBytes, final long capacityBytes,
       final boolean readOnly, final ByteOrder byteOrder) {
-    final int type = typeId | REGION | (readOnly ? READONLY : 0);
+    final int type = setReadOnlyType(typeId, readOnly) | REGION;
     return Util.isNativeByteOrder(byteOrder)
         ? new MapWritableMemoryImpl(
-            nativeBaseOffset, getRegionOffset(offsetBytes), capacityBytes,
-            type, valid)
+            nativeBaseOffset, getRegionOffset(offsetBytes), capacityBytes, type, valid)
         : new MapNonNativeWritableMemoryImpl(
-            nativeBaseOffset, getRegionOffset(offsetBytes), capacityBytes,
-            type, valid);
+            nativeBaseOffset, getRegionOffset(offsetBytes), capacityBytes, type, valid);
   }
 
   @Override
   BaseWritableBufferImpl toWritableBuffer(final boolean readOnly, final ByteOrder byteOrder) {
-    final int type = typeId | (readOnly ? READONLY : 0);
+    final int type = setReadOnlyType(typeId, readOnly);
     return Util.isNativeByteOrder(byteOrder)
         ? new MapWritableBufferImpl(
-            nativeBaseOffset, getRegionOffset(), getCapacity(),
-            type, valid, this)
+            nativeBaseOffset, getRegionOffset(), getCapacity(), type, valid)
         : new MapNonNativeWritableBufferImpl(
-            nativeBaseOffset, getRegionOffset(), getCapacity(),
-            type, valid, this);
+            nativeBaseOffset, getRegionOffset(), getCapacity(), type, valid);
   }
 
   @Override
diff --git a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/MapWritableBufferImpl.java b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/MapWritableBufferImpl.java
index ecbb28c..9f7c35c 100644
--- a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/MapWritableBufferImpl.java
+++ b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/MapWritableBufferImpl.java
@@ -22,9 +22,10 @@ package org.apache.datasketches.memory.internal;
 import java.nio.ByteOrder;
 
 import org.apache.datasketches.memory.MemoryRequestServer;
+import org.apache.datasketches.memory.WritableBuffer;
 
 /**
- * Implementation of {@link WritableBufferImpl} for map memory, native byte order.
+ * Implementation of {@link WritableBuffer} for map memory, native byte order.
  *
  * @author Roman Leventov
  * @author Lee Rhodes
@@ -40,9 +41,8 @@ final class MapWritableBufferImpl extends NativeWritableBufferImpl {
       final long regionOffset,
       final long capacityBytes,
       final int typeId,
-      final StepBoolean valid,
-      final BaseWritableMemoryImpl originMemory) {
-    super(null, nativeBaseOffset, regionOffset, capacityBytes, originMemory);
+      final StepBoolean valid) {
+    super(null, nativeBaseOffset, regionOffset, capacityBytes);
     this.nativeBaseOffset = nativeBaseOffset;
     this.valid = valid;
     this.typeId = (byte) (id | (typeId & 0x7));
@@ -51,26 +51,32 @@ final class MapWritableBufferImpl extends NativeWritableBufferImpl {
   @Override
   BaseWritableBufferImpl toWritableRegion(final long offsetBytes, final long capacityBytes,
       final boolean readOnly, final ByteOrder byteOrder) {
-    final int type = typeId | REGION | (readOnly ? READONLY : 0);
+    final int type = setReadOnlyType(typeId, readOnly) | REGION;
     return Util.isNativeByteOrder(byteOrder)
         ? new MapWritableBufferImpl(
-            nativeBaseOffset, getRegionOffset(offsetBytes), capacityBytes,
-            type, valid, originMemory)
+            nativeBaseOffset, getRegionOffset(offsetBytes), capacityBytes, type, valid)
         : new MapNonNativeWritableBufferImpl(
-            nativeBaseOffset, getRegionOffset(offsetBytes), capacityBytes,
-            type, valid, originMemory);
+            nativeBaseOffset, getRegionOffset(offsetBytes), capacityBytes, type, valid);
   }
 
   @Override
   BaseWritableBufferImpl toDuplicate(final boolean readOnly, final ByteOrder byteOrder) {
-    final int type = typeId | DUPLICATE | (readOnly ? READONLY : 0);
+    final int type = setReadOnlyType(typeId, readOnly) | DUPLICATE;
     return Util.isNativeByteOrder(byteOrder)
         ? new MapWritableBufferImpl(
-            nativeBaseOffset, getRegionOffset(), getCapacity(),
-            type, valid, originMemory)
+            nativeBaseOffset, getRegionOffset(), getCapacity(), type, valid)
         : new MapNonNativeWritableBufferImpl(
-            nativeBaseOffset, getRegionOffset(), getCapacity(),
-            type, valid, originMemory);
+            nativeBaseOffset, getRegionOffset(), getCapacity(), type, valid);
+  }
+
+  @Override
+  BaseWritableMemoryImpl toWritableMemory(final boolean readOnly, final ByteOrder byteOrder) {
+    final int type = setReadOnlyType(typeId, readOnly);
+    return Util.isNativeByteOrder(byteOrder)
+        ? new MapWritableMemoryImpl(
+            nativeBaseOffset, getRegionOffset(), getCapacity(), type, valid)
+        : new MapNonNativeWritableMemoryImpl(
+            nativeBaseOffset, getRegionOffset(), getCapacity(), type, valid);
   }
 
   @Override
diff --git a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/MapWritableMemoryImpl.java b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/MapWritableMemoryImpl.java
index 15cac79..184c1a6 100644
--- a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/MapWritableMemoryImpl.java
+++ b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/MapWritableMemoryImpl.java
@@ -22,9 +22,10 @@ package org.apache.datasketches.memory.internal;
 import java.nio.ByteOrder;
 
 import org.apache.datasketches.memory.MemoryRequestServer;
+import org.apache.datasketches.memory.WritableMemory;
 
 /**
- * Implementation of {@link WritableMemoryImpl} for map memory, native byte order.
+ * Implementation of {@link WritableMemory} for map memory, native byte order.
  *
  * @author Roman Leventov
  * @author Lee Rhodes
@@ -50,26 +51,22 @@ final class MapWritableMemoryImpl extends NativeWritableMemoryImpl {
   @Override
   BaseWritableMemoryImpl toWritableRegion(final long offsetBytes, final long capacityBytes,
       final boolean readOnly, final ByteOrder byteOrder) {
-    final int type = typeId | REGION | (readOnly ? READONLY : 0);
+    final int type = setReadOnlyType(typeId, readOnly) | REGION;
     return Util.isNativeByteOrder(byteOrder)
         ? new MapWritableMemoryImpl(
-            nativeBaseOffset, getRegionOffset(offsetBytes), capacityBytes,
-            type, valid)
+            nativeBaseOffset, getRegionOffset(offsetBytes), capacityBytes, type, valid)
         : new MapNonNativeWritableMemoryImpl(
-            nativeBaseOffset, getRegionOffset(offsetBytes), capacityBytes,
-            type, valid);
+            nativeBaseOffset, getRegionOffset(offsetBytes), capacityBytes, type, valid);
   }
 
   @Override
   BaseWritableBufferImpl toWritableBuffer(final boolean readOnly, final ByteOrder byteOrder) {
-    final int type = typeId | (readOnly ? READONLY : 0);
+    final int type = setReadOnlyType(typeId, readOnly);
     return Util.isNativeByteOrder(byteOrder)
         ? new MapWritableBufferImpl(
-            nativeBaseOffset, getRegionOffset(), getCapacity(),
-            type, valid, this)
+            nativeBaseOffset, getRegionOffset(), getCapacity(), type, valid)
         : new MapNonNativeWritableBufferImpl(
-            nativeBaseOffset, getRegionOffset(), getCapacity(),
-            type, valid, this);
+            nativeBaseOffset, getRegionOffset(), getCapacity(), type, valid);
   }
 
   @Override
diff --git a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/MemoryImpl.java b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/MemoryImpl.java
deleted file mode 100644
index aaaac73..0000000
--- a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/MemoryImpl.java
+++ /dev/null
@@ -1,225 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you 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.apache.datasketches.memory.internal;
-
-import static org.apache.datasketches.memory.internal.Util.negativeCheck;
-import static org.apache.datasketches.memory.internal.Util.nullCheck;
-import static org.apache.datasketches.memory.internal.Util.zeroCheck;
-
-import java.io.File;
-import java.io.IOException;
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-import java.nio.channels.WritableByteChannel;
-
-import org.apache.datasketches.memory.MapHandle;
-import org.apache.datasketches.memory.Memory;
-import org.apache.datasketches.memory.Utf8CodingException;
-import org.apache.datasketches.memory.WritableMemory;
-
-/**
- * Provides read-only primitive and primitive array methods to any of the four resources
- * mentioned in the package level documentation.
- *
- * @author Roman Leventov
- * @author Lee Rhodes
- *
- * @see org.apache.datasketches.memory.internal
- */
-public abstract class MemoryImpl extends BaseStateImpl implements Memory {
-
-  //Pass-through ctor
-  MemoryImpl(final Object unsafeObj, final long nativeBaseOffset, final long regionOffset,
-      final long capacityBytes) {
-    super(unsafeObj, nativeBaseOffset, regionOffset, capacityBytes);
-  }
-
-  //BYTE BUFFER
-  public static MemoryImpl wrap(final ByteBuffer byteBuf) {
-    return BaseWritableMemoryImpl.wrapByteBuffer(byteBuf, true, byteBuf.order(), defaultMemReqSvr);
-  }
-
-  public static MemoryImpl wrap(final ByteBuffer byteBuf, final ByteOrder byteOrder) {
-    return BaseWritableMemoryImpl.wrapByteBuffer(byteBuf, true, byteOrder, defaultMemReqSvr);
-  }
-
-  //MAP
-  public static MapHandle map(final File file) {
-    return map(file, 0, file.length(), ByteOrder.nativeOrder());
-  }
-
-  public static MapHandle map(final File file, final long fileOffsetBytes, final long capacityBytes,
-      final ByteOrder byteOrder) {
-    zeroCheck(capacityBytes, "Capacity");
-    nullCheck(file, "file is null");
-    negativeCheck(fileOffsetBytes, "File offset is negative");
-    return (MapHandle) BaseWritableMemoryImpl.wrapMap(file, fileOffsetBytes, capacityBytes, true, byteOrder);
-  }
-
-  //REGIONS
-  @Override
-  public abstract MemoryImpl region(long offsetBytes, long capacityBytes);
-
-  @Override
-  public abstract MemoryImpl region(long offsetBytes, long capacityBytes, ByteOrder byteOrder);
-
-  //AS BUFFER
-  @Override
-  public abstract BufferImpl asBuffer();
-
-  @Override
-  public abstract BufferImpl asBuffer(ByteOrder byteOrder);
-
-  //UNSAFE BYTE BUFFER VIEW
-  @Override
-  public abstract ByteBuffer unsafeByteBufferView(long offsetBytes, int capacityBytes);
-
-  //ACCESS PRIMITIVE HEAP ARRAYS for readOnly
-  public static Memory wrap(final boolean[] arr) {
-    final long lengthBytes = arr.length << Prim.BOOLEAN.shift();
-    return BaseWritableMemoryImpl.wrapHeapArray(arr, 0L, lengthBytes, true,
-        Util.nativeByteOrder);
-  }
-
-  public static Memory wrap(final byte[] arr) {
-    return MemoryImpl.wrap(arr, 0, arr.length, Util.nativeByteOrder);
-  }
-
-  public static Memory wrap(final byte[] arr, final ByteOrder byteOrder) {
-    return MemoryImpl.wrap(arr, 0, arr.length, byteOrder);
-  }
-
-  public static Memory wrap(final byte[] arr, final int offsetBytes, final int lengthBytes,
-      final ByteOrder byteOrder) {
-    UnsafeUtil.checkBounds(offsetBytes, lengthBytes, arr.length);
-    return BaseWritableMemoryImpl.wrapHeapArray(arr, 0L, lengthBytes, true, byteOrder);
-  }
-
-  public static Memory wrap(final char[] arr) {
-    final long lengthBytes = arr.length << Prim.CHAR.shift();
-    return BaseWritableMemoryImpl.wrapHeapArray(arr, 0L, lengthBytes, true, Util.nativeByteOrder);
-  }
-
-  public static Memory wrap(final short[] arr) {
-    final long lengthBytes = arr.length << Prim.SHORT.shift();
-    return BaseWritableMemoryImpl.wrapHeapArray(arr, 0L, lengthBytes, true, Util.nativeByteOrder);
-  }
-
-  public static Memory wrap(final int[] arr) {
-    final long lengthBytes = arr.length << Prim.INT.shift();
-    return BaseWritableMemoryImpl.wrapHeapArray(arr, 0L, lengthBytes, true, Util.nativeByteOrder);
-  }
-
-  public static Memory wrap(final long[] arr) {
-    final long lengthBytes = arr.length << Prim.LONG.shift();
-    return BaseWritableMemoryImpl.wrapHeapArray(arr, 0L, lengthBytes, true, Util.nativeByteOrder);
-  }
-
-  public static Memory wrap(final float[] arr) {
-    final long lengthBytes = arr.length << Prim.FLOAT.shift();
-    return BaseWritableMemoryImpl.wrapHeapArray(arr, 0L, lengthBytes, true, Util.nativeByteOrder);
-  }
-
-  public static Memory wrap(final double[] arr) {
-    final long lengthBytes = arr.length << Prim.DOUBLE.shift();
-    return BaseWritableMemoryImpl.wrapHeapArray(arr, 0L, lengthBytes, true, Util.nativeByteOrder);
-  }
-
-  //PRIMITIVE getX() and getXArray()
-
-  @Override
-  public abstract boolean getBoolean(long offsetBytes);
-
-  @Override
-  public abstract void getBooleanArray(long offsetBytes, boolean[] dstArray, int dstOffsetBooleans,
-      int lengthBooleans);
-
-  @Override
-  public abstract byte getByte(long offsetBytes);
-
-  @Override
-  public abstract void getByteArray(long offsetBytes, byte[] dstArray, int dstOffsetBytes,
-      int lengthBytes);
-
-  @Override
-  public abstract char getChar(long offsetBytes);
-
-  @Override
-  public abstract void getCharArray(long offsetBytes, char[] dstArray, int dstOffsetChars,
-      int lengthChars);
-
-  @Override
-  public abstract int getCharsFromUtf8(long offsetBytes, int utf8LengthBytes, Appendable dst)
-      throws IOException, Utf8CodingException;
-
-  @Override
-  public abstract int getCharsFromUtf8(final long offsetBytes, final int utf8LengthBytes,
-      final StringBuilder dst) throws Utf8CodingException;
-
-  @Override
-  public abstract double getDouble(long offsetBytes);
-
-  @Override
-  public abstract void getDoubleArray(long offsetBytes, double[] dstArray, int dstOffsetDoubles,
-      int lengthDoubles);
-
-  @Override
-  public abstract float getFloat(long offsetBytes);
-
-  @Override
-  public abstract void getFloatArray(long offsetBytes, float[] dstArray, int dstOffsetFloats,
-      int lengthFloats);
-
-  @Override
-  public abstract int getInt(long offsetBytes);
-
-  @Override
-  public abstract void getIntArray(long offsetBytes, int[] dstArray, int dstOffsetInts,
-      int lengthInts);
-
-  @Override
-  public abstract long getLong(long offsetBytes);
-
-  @Override
-  public abstract void getLongArray(long offsetBytes, long[] dstArray, int dstOffsetLongs,
-      int lengthLongs);
-
-  @Override
-  public abstract short getShort(long offsetBytes);
-
-  @Override
-  public abstract void getShortArray(long offsetBytes, short[] dstArray, int dstOffsetShorts,
-      int lengthShorts);
-
-  //SPECIAL PRIMITIVE READ METHODS: compareTo, copyTo, writeTo
-  @Override
-  public abstract int compareTo(long thisOffsetBytes, long thisLengthBytes, Memory that,
-      long thatOffsetBytes, long thatLengthBytes);
-
-  @Override
-  public abstract void copyTo(long srcOffsetBytes, WritableMemory destination, long dstOffsetBytes,
-      long lengthBytes);
-
-
-  @Override
-  public abstract void writeTo(long offsetBytes, long lengthBytes, WritableByteChannel out)
-      throws IOException;
-
-}
diff --git a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/NativeWritableBufferImpl.java b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/NativeWritableBufferImpl.java
index 0f6c207..e9bdd31 100644
--- a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/NativeWritableBufferImpl.java
+++ b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/NativeWritableBufferImpl.java
@@ -36,6 +36,8 @@ import static org.apache.datasketches.memory.internal.UnsafeUtil.SHORT_SHIFT;
 import static org.apache.datasketches.memory.internal.UnsafeUtil.checkBounds;
 import static org.apache.datasketches.memory.internal.UnsafeUtil.unsafe;
 
+import org.apache.datasketches.memory.WritableBuffer;
+
 /*
  * Developer notes: The heavier methods, such as put/get arrays, duplicate, region, clear, fill,
  * compareTo, etc., use hard checks (check*() and incrementAndCheck*() methods), which execute at
@@ -50,7 +52,7 @@ import static org.apache.datasketches.memory.internal.UnsafeUtil.unsafe;
  */
 
 /**
- * Implementation of {@link WritableBufferImpl} for native endian byte order. Non-native variant is
+ * Implementation of {@link WritableBuffer} for native endian byte order. Non-native variant is
  * {@link NonNativeWritableBufferImpl}.
  * @author Roman Leventov
  * @author Lee Rhodes
@@ -60,8 +62,8 @@ abstract class NativeWritableBufferImpl extends BaseWritableBufferImpl {
 
   //Pass-through ctor
   NativeWritableBufferImpl(final Object unsafeObj, final long nativeBaseOffset, final long regionOffset,
-      final long capacityBytes, final BaseWritableMemoryImpl originMemory) {
-    super(unsafeObj, nativeBaseOffset, regionOffset, capacityBytes, originMemory);
+      final long capacityBytes) {
+    super(unsafeObj, nativeBaseOffset, regionOffset, capacityBytes);
   }
 
   //PRIMITIVE getX() and getXArray()
diff --git a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/NativeWritableMemoryImpl.java b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/NativeWritableMemoryImpl.java
index 375fa83..3530f98 100644
--- a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/NativeWritableMemoryImpl.java
+++ b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/NativeWritableMemoryImpl.java
@@ -37,6 +37,8 @@ import static org.apache.datasketches.memory.internal.UnsafeUtil.SHORT_SHIFT;
 import static org.apache.datasketches.memory.internal.UnsafeUtil.checkBounds;
 import static org.apache.datasketches.memory.internal.UnsafeUtil.unsafe;
 
+import org.apache.datasketches.memory.WritableMemory;
+
 /*
  * Developer notes: The heavier methods, such as put/get arrays, duplicate, region, clear, fill,
  * compareTo, etc., use hard checks (checkValid*() and checkBounds()), which execute at runtime and
@@ -50,7 +52,7 @@ import static org.apache.datasketches.memory.internal.UnsafeUtil.unsafe;
  */
 
 /**
- * Implementation of {@link WritableMemoryImpl} for native endian byte order. Non-native variant is
+ * Implementation of {@link WritableMemory} for native endian byte order. Non-native variant is
  * {@link NonNativeWritableMemoryImpl}.
  * @author Roman Leventov
  * @author Lee Rhodes
diff --git a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/NonNativeWritableBufferImpl.java b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/NonNativeWritableBufferImpl.java
index 49dfcb4..25e37aa 100644
--- a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/NonNativeWritableBufferImpl.java
+++ b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/NonNativeWritableBufferImpl.java
@@ -29,6 +29,8 @@ import static org.apache.datasketches.memory.internal.UnsafeUtil.LONG_SHIFT;
 import static org.apache.datasketches.memory.internal.UnsafeUtil.SHORT_SHIFT;
 import static org.apache.datasketches.memory.internal.UnsafeUtil.unsafe;
 
+import org.apache.datasketches.memory.WritableBuffer;
+
 /*
  * Developer notes: The heavier methods, such as put/get arrays, duplicate, region, clear, fill,
  * compareTo, etc., use hard checks (check*() and incrementAndCheck*() methods), which execute at
@@ -43,7 +45,7 @@ import static org.apache.datasketches.memory.internal.UnsafeUtil.unsafe;
  */
 
 /**
- * Implementation of {@link WritableBufferImpl} for non-native endian byte order. Native variant is
+ * Implementation of {@link WritableBuffer} for non-native endian byte order. Native variant is
  * {@link NativeWritableBufferImpl}.
  * @author Roman Leventov
  * @author Lee Rhodes
@@ -53,8 +55,8 @@ abstract class NonNativeWritableBufferImpl extends BaseWritableBufferImpl {
 
   //Pass-through ctor
   NonNativeWritableBufferImpl(final Object unsafeObj, final long nativeBaseOffset, final long regionOffset,
-      final long capacityBytes, final BaseWritableMemoryImpl originMemory) {
-    super(unsafeObj, nativeBaseOffset, regionOffset, capacityBytes, originMemory);
+      final long capacityBytes) {
+    super(unsafeObj, nativeBaseOffset, regionOffset, capacityBytes);
   }
 
   //PRIMITIVE getX() and getXArray()
diff --git a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/NonNativeWritableMemoryImpl.java b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/NonNativeWritableMemoryImpl.java
index 7f6913b..93ff62d 100644
--- a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/NonNativeWritableMemoryImpl.java
+++ b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/NonNativeWritableMemoryImpl.java
@@ -30,6 +30,8 @@ import static org.apache.datasketches.memory.internal.UnsafeUtil.LONG_SHIFT;
 import static org.apache.datasketches.memory.internal.UnsafeUtil.SHORT_SHIFT;
 import static org.apache.datasketches.memory.internal.UnsafeUtil.unsafe;
 
+import org.apache.datasketches.memory.WritableMemory;
+
 /*
  * Developer notes: The heavier methods, such as put/get arrays, duplicate, region, clear, fill,
  * compareTo, etc., use hard checks (checkValid*() and checkBounds()), which execute at runtime and
@@ -43,7 +45,7 @@ import static org.apache.datasketches.memory.internal.UnsafeUtil.unsafe;
  */
 
 /**
- * Implementation of {@link WritableMemoryImpl} for non-native endian byte order. Native variant is
+ * Implementation of {@link WritableMemory} for non-native endian byte order. Native variant is
  * {@link NativeWritableMemoryImpl}.
  * @author Roman Leventov
  * @author Lee Rhodes
diff --git a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/Utf8.java b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/Utf8.java
index 2a95a86..d8fb52d 100644
--- a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/Utf8.java
+++ b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/Utf8.java
@@ -28,11 +28,13 @@ import java.io.IOException;
 import java.nio.BufferOverflowException;
 import java.nio.CharBuffer;
 
+import org.apache.datasketches.memory.Memory;
 import org.apache.datasketches.memory.Utf8CodingException;
+import org.apache.datasketches.memory.WritableMemory;
 
 /**
- * Encoding and decoding implementations of {@link WritableMemoryImpl#putCharsToUtf8} and
- * {@link MemoryImpl#getCharsFromUtf8}.
+ * Encoding and decoding implementations of {@link WritableMemory#putCharsToUtf8} and
+ * {@link Memory#getCharsFromUtf8}.
  *
  * <p>This is specifically designed to reduce the production of intermediate objects (garbage),
  * thus significantly reducing pressure on the JVM Garbage Collector.
diff --git a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/Util.java b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/Util.java
index 8552f6b..415ad07 100644
--- a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/Util.java
+++ b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/Util.java
@@ -38,10 +38,15 @@ public final class Util {
   public static final String LS = System.getProperty("line.separator");
 
   //Byte Order related
-  public static final ByteOrder nativeByteOrder = ByteOrder.nativeOrder();
-  public static final ByteOrder nonNativeByteOrder = nativeByteOrder == ByteOrder.LITTLE_ENDIAN
+  public static final ByteOrder NATIVE_BYTE_ORDER = ByteOrder.nativeOrder();
+  public static final ByteOrder NON_NATIVE_BYTE_ORDER = NATIVE_BYTE_ORDER == ByteOrder.LITTLE_ENDIAN
       ? ByteOrder.BIG_ENDIAN : ByteOrder.LITTLE_ENDIAN;
 
+  public static ByteOrder otherByteOrder(ByteOrder order) {
+    return (order == NATIVE_BYTE_ORDER) ? NON_NATIVE_BYTE_ORDER : NATIVE_BYTE_ORDER;
+  }
+
+
   /**
    * Don't use sun.misc.Unsafe#copyMemory to copy blocks of memory larger than this
    * threshold, because internally it doesn't have safepoint polls, that may cause long
@@ -63,7 +68,7 @@ public final class Util {
    * @return the Native Byte Order
    */
   public static final ByteOrder getNativeByteOrder() {
-    return nativeByteOrder;
+    return NATIVE_BYTE_ORDER;
   }
 
   /**
@@ -75,7 +80,7 @@ public final class Util {
     if (byteOrder == null) {
       throw new IllegalArgumentException("ByteOrder parameter cannot be null.");
     }
-    return Util.nativeByteOrder == byteOrder;
+    return Util.NATIVE_BYTE_ORDER == byteOrder;
   }
 
 
@@ -289,19 +294,19 @@ public final class Util {
 
   public static final void zeroCheck(final long value, final String arg) {
     if (value <= 0) {
-      throw new IllegalArgumentException("The argument " + arg + " may not be negative or zero.");
+      throw new IllegalArgumentException("The argument '" + arg + "' may not be negative or zero.");
     }
   }
 
   public static final void negativeCheck(final long value, final String arg) {
     if (value < 0) {
-      throw new IllegalArgumentException("The argument " + arg + " may not be negative.");
+      throw new IllegalArgumentException("The argument '" + arg + "' may not be negative.");
     }
   }
 
   public static final void nullCheck(final Object obj, final String arg) {
     if (obj == null) {
-      throw new IllegalArgumentException("The argument " + arg + " may not be null.");
+      throw new IllegalArgumentException("The argument '" + arg + "' may not be null.");
     }
   }
 
diff --git a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/WritableBufferImpl.java b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/WritableBufferImpl.java
deleted file mode 100644
index 020e5a4..0000000
--- a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/WritableBufferImpl.java
+++ /dev/null
@@ -1,170 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you 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.apache.datasketches.memory.internal;
-
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-
-import org.apache.datasketches.memory.MemoryRequestServer;
-import org.apache.datasketches.memory.WritableBuffer;
-
-/**
- * Provides read and write, positional primitive and primitive array access to any of the four
- * resources mentioned at the package level.
- *
- * @author Roman Leventov
- * @author Lee Rhodes
- */
-public abstract class WritableBufferImpl extends BufferImpl implements WritableBuffer {
-
-  //Pass-through ctor
-  WritableBufferImpl(final Object unsafeObj, final long nativeBaseOffset,
-      final long regionOffset, final long capacityBytes) {
-    super(unsafeObj, nativeBaseOffset, regionOffset, capacityBytes);
-  }
-
-  //BYTE BUFFER
-  public static WritableBufferImpl writableWrap(final ByteBuffer byteBuf) {
-    return writableWrap(byteBuf, byteBuf.order(), defaultMemReqSvr);
-  }
-
-  public static WritableBufferImpl writableWrap(final ByteBuffer byteBuf, final ByteOrder byteOrder,
-      final MemoryRequestServer memReqSvr) {
-    final BaseWritableMemoryImpl wmem =
-        BaseWritableMemoryImpl.wrapByteBuffer(byteBuf, false, byteOrder, memReqSvr);
-    final WritableBufferImpl wbuf = wmem.asWritableBuffer(false, byteOrder);
-    wbuf.setStartPositionEnd(0, byteBuf.position(), byteBuf.limit());
-    return wbuf;
-  }
-
-  //MAP
-  //Use WritableMemoryImpl for mapping files and then asWritableBuffer()
-
-  //ALLOCATE DIRECT
-  //Use WritableMemoryImpl to allocate direct memory and then asWritableBuffer().
-
-  //DUPLICATES
-  @Override
-  public abstract WritableBufferImpl writableDuplicate();
-
-  @Override
-  public abstract WritableBufferImpl writableDuplicate(ByteOrder byteOrder);
-
-  //REGIONS
-  @Override
-  public abstract WritableBufferImpl writableRegion();
-
-  @Override
-  public abstract WritableBufferImpl writableRegion(long offsetBytes, long capacityBytes,
-      ByteOrder byteOrder);
-
-  //AS MEMORY
-  @Override
-  public abstract WritableMemoryImpl asWritableMemory();
-
-  //ACCESS PRIMITIVE HEAP ARRAYS for write
-  //use WritableMemoryImpl and then asWritableBuffer().
-  //END OF CONSTRUCTOR-TYPE METHODS
-
-  //PRIMITIVE putX() and putXArray()
-  @Override
-  public abstract void putBoolean(boolean value);
-
-  @Override
-  public abstract void putBoolean(long offsetBytes, boolean value);
-
-  @Override
-  public abstract void putBooleanArray(boolean[] srcArray, int srcOffsetBooleans,
-      int lengthBooleans);
-
-  @Override
-  public abstract void putByte(byte value);
-
-  @Override
-  public abstract void putByte(long offsetBytes, byte value);
-
-  @Override
-  public abstract void putByteArray(byte[] srcArray, int srcOffsetBytes, int lengthBytes);
-
-  @Override
-  public abstract void putChar(char value);
-
-  @Override
-  public abstract void putChar(long offsetBytes, char value);
-
-  @Override
-  public abstract void putCharArray(char[] srcArray, int srcOffsetChars, int lengthChars);
-
-  @Override
-  public abstract void putDouble(double value);
-
-  @Override
-  public abstract void putDouble(long offsetBytes, double value);
-
-  @Override
-  public abstract void putDoubleArray(double[] srcArray, int srcOffsetDoubles, int lengthDoubles);
-
-  @Override
-  public abstract void putFloat(float value);
-
-  @Override
-  public abstract void putFloat(long offsetBytes, float value);
-
-  @Override
-  public abstract void putFloatArray(float[] srcArray, int srcOffsetFloats, int lengthFloats);
-
-  @Override
-  public abstract void putInt(int value);
-
-  @Override
-  public abstract void putInt(long offsetBytes, int value);
-
-  @Override
-  public abstract void putIntArray(int[] srcArray, int srcOffsetInts, int lengthInts);
-
-  @Override
-  public abstract void putLong(long value);
-
-  @Override
-  public abstract void putLong(long offsetBytes, long value);
-
-  @Override
-  public abstract void putLongArray(long[] srcArray, int srcOffsetLongs, int lengthLongs);
-
-  @Override
-  public abstract void putShort(short value);
-
-  @Override
-  public abstract void putShort(long offsetBytes, short value);
-
-  @Override
-  public abstract void putShortArray(short[] srcArray, int srcOffsetShorts, int lengthShorts);
-
-  //OTHER WRITE METHODS
-  @Override
-  public abstract Object getArray();
-
-  @Override
-  public abstract void clear();
-
-  @Override
-  public abstract void fill(byte value);
-
-}
diff --git a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/WritableMapHandleImpl.java b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/WritableMapHandleImpl.java
index 6a82a44..7683bf7 100644
--- a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/WritableMapHandleImpl.java
+++ b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/WritableMapHandleImpl.java
@@ -34,7 +34,8 @@ import org.apache.datasketches.memory.WritableMemory;
 public final class WritableMapHandleImpl extends MapHandleImpl
     implements WritableMapHandle {
 
-  WritableMapHandleImpl(final AllocateDirectWritableMap dirWmap,
+  WritableMapHandleImpl(
+      final AllocateDirectWritableMap dirWmap,
       final BaseWritableMemoryImpl wMem) {
     super(dirWmap, wMem);
   }
diff --git a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/WritableMemoryImpl.java b/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/WritableMemoryImpl.java
deleted file mode 100644
index 9c68a4e..0000000
--- a/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/WritableMemoryImpl.java
+++ /dev/null
@@ -1,254 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you 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.apache.datasketches.memory.internal;
-
-import static org.apache.datasketches.memory.internal.Util.negativeCheck;
-import static org.apache.datasketches.memory.internal.Util.nullCheck;
-import static org.apache.datasketches.memory.internal.Util.zeroCheck;
-
-import java.io.File;
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-
-import org.apache.datasketches.memory.MemoryRequestServer;
-import org.apache.datasketches.memory.WritableHandle;
-import org.apache.datasketches.memory.WritableMapHandle;
-import org.apache.datasketches.memory.WritableMemory;
-
-
-/**
- * Provides read and write primitive and primitive array access to any of the four resources
- * mentioned at the package level.
- *
- * @author Roman Leventov
- * @author Lee Rhodes
- */
-public abstract class WritableMemoryImpl extends MemoryImpl implements WritableMemory {
-
-  //Pass-through ctor
-  WritableMemoryImpl(final Object unsafeObj, final long nativeBaseOffset, final long regionOffset,
-      final long capacityBytes) {
-    super(unsafeObj, nativeBaseOffset, regionOffset, capacityBytes);
-  }
-
-  //BYTE BUFFER
-  public static WritableMemoryImpl writableWrap(final ByteBuffer byteBuf) {
-    return BaseWritableMemoryImpl.wrapByteBuffer(byteBuf, false, byteBuf.order(), defaultMemReqSvr);
-  }
-
-  public static WritableMemoryImpl writableWrap(final ByteBuffer byteBuf, final ByteOrder byteOrder,
-      final MemoryRequestServer memReqSvr) {
-    return BaseWritableMemoryImpl.wrapByteBuffer(byteBuf, false, byteOrder, memReqSvr);
-  }
-
-  //MAP
-  public static WritableMapHandle writableMap(final File file) {
-    return WritableMemoryImpl.writableMap(file, 0, file.length(), Util.nativeByteOrder);
-  }
-
-  public static WritableMapHandle writableMap(final File file, final long fileOffsetBytes,
-      final long capacityBytes, final ByteOrder byteOrder) {
-    zeroCheck(capacityBytes, "Capacity");
-    nullCheck(file, "file is null");
-    negativeCheck(fileOffsetBytes, "File offset is negative");
-    return BaseWritableMemoryImpl
-        .wrapMap(file, fileOffsetBytes, capacityBytes, false, byteOrder);
-  }
-
-  //ALLOCATE DIRECT
-  public static WritableHandle allocateDirect(final long capacityBytes) {
-    return allocateDirect(capacityBytes, ByteOrder.nativeOrder(), defaultMemReqSvr);
-  }
-
-  public static WritableHandle allocateDirect(final long capacityBytes, final ByteOrder byteOrder,
-      final MemoryRequestServer memReqSvr) {
-    return BaseWritableMemoryImpl.wrapDirect(capacityBytes, byteOrder, memReqSvr);
-  }
-
-  //REGIONS
-  @Override
-  public abstract WritableMemoryImpl writableRegion(long offsetBytes, long capacityBytes);
-
-  @Override
-  public abstract WritableMemoryImpl writableRegion(long offsetBytes, long capacityBytes,
-      ByteOrder byteOrder);
-
-  //AS BUFFER
-  @Override
-  public abstract WritableBufferImpl asWritableBuffer();
-
-  @Override
-  public abstract WritableBufferImpl asWritableBuffer(ByteOrder byteOrder);
-
-  //ALLOCATE HEAP VIA AUTOMATIC BYTE ARRAY
-  public static WritableMemoryImpl allocate(final int capacityBytes) {
-    final byte[] arr = new byte[capacityBytes];
-    return writableWrap(arr, Util.nativeByteOrder);
-  }
-
-  public static WritableMemoryImpl allocate(final int capacityBytes, final ByteOrder byteOrder) {
-    final byte[] arr = new byte[capacityBytes];
-    return writableWrap(arr, byteOrder);
-  }
-
-  //ACCESS PRIMITIVE HEAP ARRAYS for write
-  public static WritableMemoryImpl writableWrap(final boolean[] arr) {
-    final long lengthBytes = arr.length << Prim.BOOLEAN.shift();
-    return BaseWritableMemoryImpl.wrapHeapArray(arr, 0L, lengthBytes, false, Util.nativeByteOrder);
-  }
-
-  public static WritableMemoryImpl writableWrap(final byte[] arr) {
-    return WritableMemoryImpl.writableWrap(arr, 0, arr.length, Util.nativeByteOrder);
-  }
-
-  public static WritableMemoryImpl writableWrap(final byte[] arr, final ByteOrder byteOrder) {
-    return WritableMemoryImpl.writableWrap(arr, 0, arr.length, byteOrder);
-  }
-
-  public static WritableMemoryImpl writableWrap(final byte[] arr, final int offsetBytes, final int lengthBytes,
-      final ByteOrder byteOrder) {
-    UnsafeUtil.checkBounds(offsetBytes, lengthBytes, arr.length);
-    return BaseWritableMemoryImpl.wrapHeapArray(arr, 0L, lengthBytes, false, byteOrder);
-  }
-
-  public static WritableMemoryImpl writableWrap(final char[] arr) {
-    final long lengthBytes = arr.length << Prim.CHAR.shift();
-    return BaseWritableMemoryImpl.wrapHeapArray(arr, 0L, lengthBytes, false, Util.nativeByteOrder);
-  }
-
-  public static WritableMemoryImpl writableWrap(final short[] arr) {
-    final long lengthBytes = arr.length << Prim.SHORT.shift();
-    return BaseWritableMemoryImpl.wrapHeapArray(arr, 0L, lengthBytes, false, Util.nativeByteOrder);
-  }
-
-  public static WritableMemoryImpl writableWrap(final int[] arr) {
-    final long lengthBytes = arr.length << Prim.INT.shift();
-    return BaseWritableMemoryImpl.wrapHeapArray(arr, 0L, lengthBytes, false, Util.nativeByteOrder);
-  }
-
-  public static WritableMemoryImpl writableWrap(final long[] arr) {
-    final long lengthBytes = arr.length << Prim.LONG.shift();
-    return BaseWritableMemoryImpl.wrapHeapArray(arr, 0L, lengthBytes, false, Util.nativeByteOrder);
-  }
-
-  public static WritableMemoryImpl writableWrap(final float[] arr) {
-    final long lengthBytes = arr.length << Prim.FLOAT.shift();
-    return BaseWritableMemoryImpl.wrapHeapArray(arr, 0L, lengthBytes, false, Util.nativeByteOrder);
-  }
-
-  public static WritableMemoryImpl writableWrap(final double[] arr) {
-    final long lengthBytes = arr.length << Prim.DOUBLE.shift();
-    return BaseWritableMemoryImpl.wrapHeapArray(arr, 0L, lengthBytes, false, Util.nativeByteOrder);
-  }
-  //END OF CONSTRUCTOR-TYPE METHODS
-
-  //PRIMITIVE putX() and putXArray()
-  @Override
-  public abstract void putBoolean(long offsetBytes, boolean value);
-
-  @Override
-  public abstract void putBooleanArray(long offsetBytes, boolean[] srcArray, int srcOffsetBooleans,
-          int lengthBooleans);
-
-  @Override
-  public abstract void putByte(long offsetBytes, byte value);
-
-  @Override
-  public abstract void putByteArray(long offsetBytes, byte[] srcArray, int srcOffsetBytes,
-          int lengthBytes);
-
-  @Override
-  public abstract void putChar(long offsetBytes, char value);
-
-  @Override
-  public abstract void putCharArray(long offsetBytes, char[] srcArray, int srcOffsetChars,
-          int lengthChars);
-
-  @Override
-  public abstract long putCharsToUtf8(long offsetBytes, CharSequence src);
-
-  @Override
-  public abstract void putDouble(long offsetBytes, double value);
-
-  @Override
-  public abstract void putDoubleArray(long offsetBytes, double[] srcArray,
-          final int srcOffsetDoubles, final int lengthDoubles);
-
-  @Override
-  public abstract void putFloat(long offsetBytes, float value);
-
-  @Override
-  public abstract void putFloatArray(long offsetBytes, float[] srcArray,
-          final int srcOffsetFloats, final int lengthFloats);
-
-  @Override
-  public abstract void putInt(long offsetBytes, int value);
-
-  @Override
-  public abstract void putIntArray(long offsetBytes, int[] srcArray,
-          final int srcOffsetInts, final int lengthInts);
-
-  @Override
-  public abstract void putLong(long offsetBytes, long value);
-
-  @Override
-  public abstract void putLongArray(long offsetBytes, long[] srcArray,
-          final int srcOffsetLongs, final int lengthLongs);
-
-  @Override
-  public abstract void putShort(long offsetBytes, short value);
-
-  @Override
-  public abstract void putShortArray(long offsetBytes, short[] srcArray,
-          final int srcOffsetShorts, final int lengthShorts);
-
-  //Atomic Methods
-  @Override
-  public abstract long getAndAddLong(long offsetBytes, long delta);
-
-  @Override
-  public abstract boolean compareAndSwapLong(long offsetBytes, long expect, long update);
-
-  @Override
-  public abstract long getAndSetLong(long offsetBytes, long newValue);
-
-  //OTHER WRITE METHODS
-  @Override
-  public abstract Object getArray();
-
-  @Override
-  public abstract void clear();
-
-  @Override
-  public abstract void clear(long offsetBytes, long lengthBytes);
-
-  @Override
-  public abstract void clearBits(long offsetBytes, byte bitMask);
-
-  @Override
-  public abstract void fill(byte value);
-
-  @Override
-  public abstract void fill(long offsetBytes, long lengthBytes, byte value);
-
-  @Override
-  public abstract void setBits(long offsetBytes, byte bitMask);
-
-}

---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@datasketches.apache.org
For additional commands, e-mail: commits-help@datasketches.apache.org