diff --git a/hat/examples/experiments/src/main/java/experiments/Cascade.java b/hat/examples/experiments/src/main/java/experiments/Cascade.java
deleted file mode 100644
index dd7c72d9176..00000000000
--- a/hat/examples/experiments/src/main/java/experiments/Cascade.java
+++ /dev/null
@@ -1,164 +0,0 @@
-/*
- * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package experiments;
-
-import hat.ifacemapper.Schema;
-import hat.buffer.Buffer;
-
-public interface Cascade extends Buffer {
-    int width();
-
-    void width(int width);
-
-    int height();
-
-    void height(int height);
-
-    interface Feature extends Buffer.StructChild {
-        int id();
-
-        float threshold();
-
-        void id(int id);
-
-        void threshold(float threshold);
-
-        interface LinkOrValue extends Buffer.StructChild {
-            interface Anon extends Buffer.UnionChild {
-                int featureId();
-
-                void featureId(int featureId);
-
-                float value();
-
-                void value(float value);
-            }
-
-            boolean hasValue();
-
-            void hasValue(boolean hasValue);
-
-            Anon anon();
-        }
-
-        LinkOrValue left();
-
-        LinkOrValue right();
-
-        interface Rect extends Buffer.StructChild {
-            byte x();
-
-            byte y();
-
-            byte width();
-
-            byte height();
-
-            float weight();
-
-            void x(byte x);
-
-            void y(byte y);
-
-            void width(byte width);
-
-            void height(byte height);
-
-            void weight(float height);
-        }
-
-        Rect rect(long idx);
-    }
-
-    int featureCount();
-
-    void featureCount(int featureCount);
-    Feature feature(long idx);
-
-    interface Stage extends Buffer.StructChild {
-        float threshold();
-
-        short firstTreeId();
-
-        short treeCount();
-
-        int id();
-
-        void id(int id);
-
-        void threshold(float threshold);
-
-        void firstTreeId(short firstTreeId);
-
-        void treeCount(short treeCount);
-    }
-
-    int stageCount();
-
-     void stageCount(int stageCount);
-    Stage stage(long idx);
-
-    interface Tree extends Buffer.StructChild {
-        void id(int id);
-
-        void firstFeatureId(short firstFeatureId);
-
-        void featureCount(short featureCount);
-
-        int id();
-
-        short firstFeatureId();
-
-        short featureCount();
-    }
-
-    int treeCount();
-
-       void treeCount(int treeCount);
-    Tree tree(long idx);
-
-
-    Schema<Cascade> schema = Schema.of(Cascade.class, cascade -> cascade
-            .fields("width", "height")
-            .arrayLen("featureCount").array("feature", feature -> feature
-                    .fields("id", "threshold")
-                    .fields("left", "right", linkOrValue -> linkOrValue
-                            .field("hasValue")
-                            .pad(3)
-                            .field("anon", anon -> anon.fields("featureId", "value"))
-                    )
-                    .array("rect", 3, rect -> rect.fields("x", "y", "width", "height", "weight"))
-            )
-            .arrayLen("treeCount").array("tree", tree -> tree.fields("id", "featureCount", "firstFeatureId"))
-            .arrayLen("stageCount").array("stage", stage -> stage.fields("id", "threshold", "treeCount", "firstTreeId"))
-    );
-
-    public static void main(String[] args) {
-        Cascade.schema.toText(t -> System.out.print(t));
-        var cascade = Cascade.schema.allocate( 10, 10, 10);
-        cascade.featureCount(10);
-        System.out.println(Buffer.getLayout(cascade));
-    }
-}
diff --git a/hat/examples/experiments/src/main/java/experiments/ForTests.java b/hat/examples/experiments/src/main/java/experiments/ForTests.java
index 55794934161..c1753fec7a8 100644
--- a/hat/examples/experiments/src/main/java/experiments/ForTests.java
+++ b/hat/examples/experiments/src/main/java/experiments/ForTests.java
@@ -65,7 +65,8 @@ public static void main(String[] args) {
                 //  Backend.JAVA_MULTITHREADED
                 (backend) -> backend.getClass().getSimpleName().startsWith("OpenCL")
         );
-        var a = F32Array.create(accelerator, 100);
+        var a = F32Array.schema.allocate(accelerator, 100);
+        a.length(100);
         accelerator.compute(
                 cc -> Compute.compute(cc, a)
         );
diff --git a/hat/examples/experiments/src/main/java/experiments/LambdaTest.java b/hat/examples/experiments/src/main/java/experiments/LambdaTest.java
index df7ff0c40b7..745ca4e914a 100644
--- a/hat/examples/experiments/src/main/java/experiments/LambdaTest.java
+++ b/hat/examples/experiments/src/main/java/experiments/LambdaTest.java
@@ -14,7 +14,8 @@ public static void main(String[] args) {
         Accelerator accelerator = new Accelerator(MethodHandles.lookup(), Backend.FIRST_NATIVE);
 
         // TODO: create a test case for these **/
-        S32Array s32Array = S32Array.create(accelerator, 10);
+        S32Array s32Array = S32Array.schema.allocate(accelerator, 10);
+        s32Array.length(10);
 /*
             accelerator.compute(cc->ccargS32Array) -> {
                 var range = cc.accelerator.range(argS32Array.length());
diff --git a/hat/examples/experiments/src/main/java/experiments/ResultTable.java b/hat/examples/experiments/src/main/java/experiments/ResultTable.java
deleted file mode 100644
index bb990ef0691..00000000000
--- a/hat/examples/experiments/src/main/java/experiments/ResultTable.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package experiments;
-
-import hat.ifacemapper.Schema;
-import hat.buffer.Buffer;
-import hat.buffer.BufferAllocator;
-import hat.ifacemapper.SegmentMapper;
-
-import java.lang.foreign.Arena;
-
-public interface ResultTable extends Buffer{
-    interface Result extends Buffer.StructChild {
-        float x();
-        void x(float x);
-        float y();
-        void y(float y);
-        float width();
-        void width(float width);
-        float height();
-        void height(float height);
-    }
-    void atomicResultTableCount(int count);
-    int atomicResultTableCount();
-    int length();
-    Result result(long idx);
-    Schema<ResultTable> schema = Schema.of(ResultTable.class, resultTable->resultTable
-            .atomic("atomicResultTableCount")
-            .arrayLen("length").array("result", array->array.fields("x","y","width","height"))
-    );
-
-    public static void main(String[] args) {
-        BufferAllocator bufferAllocator = new BufferAllocator() {
-            public <T extends Buffer> T allocate(SegmentMapper<T> s) {
-                return s.allocate(Arena.global());
-            }
-        };
-        ResultTable.schema.toText(t->System.out.print(t));
-        System.out.println();
-        var boundLayout = new Schema.BoundSchema<>(ResultTable.schema, 1000);
-        System.out.println(boundLayout.groupLayout);
-        System.out.println("[i4(length)i4(atomicResultTableCount)[1000:[f4(x)f4(y)f4(width)f4(height)](Result)](result)](ResultTable)");
-       // var boundSchema = ResultTable.schema.allocate(bufferAllocator, 100);
-
-      //  var resultTable = ResultTable.schema.allocate(bufferAllocator, 100).instance;
-      //  int resultTableLen = resultTable.length();
-      //  System.out.println(Buffer.getLayout(resultTable));
-    }
-
-}
diff --git a/hat/examples/experiments/src/main/java/experiments/Features.java b/hat/examples/experiments/src/main/java/experiments/S08x3ImageTest.java
similarity index 59%
rename from hat/examples/experiments/src/main/java/experiments/Features.java
rename to hat/examples/experiments/src/main/java/experiments/S08x3ImageTest.java
index b593bc26675..01cf092c7b6 100644
--- a/hat/examples/experiments/src/main/java/experiments/Features.java
+++ b/hat/examples/experiments/src/main/java/experiments/S08x3ImageTest.java
@@ -24,38 +24,18 @@
  */
 package experiments;
 
-import hat.buffer.CompleteBuffer;
-
-import java.lang.foreign.MemoryLayout;
-import java.lang.foreign.StructLayout;
-
-import static java.lang.foreign.ValueLayout.JAVA_FLOAT;
-import static java.lang.foreign.ValueLayout.JAVA_INT;
-
-public interface Features extends CompleteBuffer {
-
-    StructLayout linkOrValue = MemoryLayout.structLayout(
-            JAVA_INT.withName("featureId"),
-            JAVA_FLOAT.withName("value")
-    ).withName("LinkOrValue");
-
-    StructLayout featureLayout = MemoryLayout.structLayout(
-            linkOrValue.withName("left"),
-            linkOrValue.withName("right")
-    ).withName("Feature");
-
-
-    /*
-     typedef struct LinkOrValue_s{
-         int featureId;
-         float value;
-     } LinkOrValue_t;
-
-     typedef struct Feature_s{
-         LinkOrValue_t left;
-         LinkOrvalue_t right;
-     } Feature_t;
-
-     */
+import hat.buffer.Buffer;
+import hat.buffer.S08x3RGBImage;
+import hat.ifacemapper.Schema;
+
+public class S08x3ImageTest implements Buffer {
+
+    public static void main(String[] args) {
+        var boundSchema = S08x3RGBImage.schema.boundSchema( 100,100);
+        System.out.println(boundSchema.groupLayout);
+        var rgbS08x3Image = boundSchema.allocate(Schema.GlobalArenaAllocator);
+        rgbS08x3Image.width(100);
+        rgbS08x3Image.height(100);
+    }
 
 }
diff --git a/hat/examples/experiments/src/main/java/experiments/S32ArrayTest.java b/hat/examples/experiments/src/main/java/experiments/S32ArrayTest.java
index ca015e0c3d0..e732d475e03 100644
--- a/hat/examples/experiments/src/main/java/experiments/S32ArrayTest.java
+++ b/hat/examples/experiments/src/main/java/experiments/S32ArrayTest.java
@@ -24,13 +24,15 @@
  */
 package experiments;
 
+import hat.buffer.S32Array2D;
 import hat.ifacemapper.Schema;
 import hat.buffer.Buffer;
 
 public class S32ArrayTest implements Buffer {
 
     public static void main(String[] args) {
-        hat.buffer.S32Array os32  = hat.buffer.S32Array.create(Schema.GlobalArenaAllocator, 100);
+        hat.buffer.S32Array os32  = hat.buffer.S32Array.schema.allocate( 100);
+        os32.length(100);
         System.out.println("Layout from hat S32Array "+ Buffer.getLayout(os32));
 
         var s32Array = S32Array.schema.allocate( 100);
@@ -39,7 +41,7 @@ public static void main(String[] args) {
         System.out.println(s23ArrayLen);
 
         System.out.println("Layout from schema "+Buffer.getLayout(s32Array));
-        ResultTable.schema.toText(t->System.out.print(t));
+        S32Array2D.schema.toText(t->System.out.print(t));
     }
 
 }
diff --git a/hat/examples/experiments/src/main/java/experiments/SchemaLayoutTest.java b/hat/examples/experiments/src/main/java/experiments/SchemaLayoutTest.java
deleted file mode 100644
index 4806590e5f2..00000000000
--- a/hat/examples/experiments/src/main/java/experiments/SchemaLayoutTest.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright (c) 2024 Intel Corporation. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-
-package experiments;
-
-
-import hat.ifacemapper.Schema;
-import hat.buffer.Buffer;
-import hat.buffer.BufferAllocator;
-import hat.ifacemapper.SegmentMapper;
-
-import java.lang.foreign.Arena;
-
-public class SchemaLayoutTest {
-
-    public static void main(String[] args) {
-        BufferAllocator bufferAllocator= new BufferAllocator() {
-            public <T extends Buffer> T allocate(SegmentMapper<T> s) {return s.allocate(Arena.global());}
-        };
-        hat.buffer.S32Array os32  = hat.buffer.S32Array.create(bufferAllocator,100);
-        System.out.println("Layout from hat S32Array "+ Buffer.getLayout(os32));
-
-        var s32Array = S32Array.schema.allocate(bufferAllocator, 100);
-        int s23ArrayLen = s32Array.length();
-        System.out.println("Layout from schema "+Buffer.getLayout(s32Array));
-        ResultTable.schema.toText(t->System.out.print(t));
-
-        var resultTable = ResultTable.schema.allocate(bufferAllocator, 100);
-        int resultTableLen = resultTable.length();
-        System.out.println(Buffer.getLayout(resultTable));
-
-
-        Cascade.schema.toText(t->System.out.print(t));
-        var boundLayout = new Schema.BoundSchema<>(Cascade.schema,10,10,10);
-        System.out.println(boundLayout.groupLayout);
-        var cascade = Cascade.schema.allocate(bufferAllocator,10,10,10);
-
-        System.out.println(Buffer.getLayout(cascade));
-        //var layout = Cascade.schema.field.layout();
-
-   //     System.out.println(layout);
-    }
-}
-
diff --git a/hat/examples/experiments/src/main/java/experiments/spirv/GetBackend.java b/hat/examples/experiments/src/main/java/experiments/spirv/GetBackend.java
index fc2f7a0eab6..892a4b866a3 100644
--- a/hat/examples/experiments/src/main/java/experiments/spirv/GetBackend.java
+++ b/hat/examples/experiments/src/main/java/experiments/spirv/GetBackend.java
@@ -92,9 +92,12 @@ public static void main(String[] args) {
         Accelerator accelerator = new Accelerator(MethodHandles.lookup(), (backend) ->
                 backend.getClass().getSimpleName().startsWith("Spirv")
         );
-        var a = F32Array.create(accelerator, 100);
-        var b = F32Array.create(accelerator, 100);
-        var c = F32Array.create(accelerator, 100);
+        var a = F32Array.schema.allocate(accelerator, 100);
+        a.length(100);
+        var b = F32Array.schema.allocate(accelerator, 100);
+        b.length(100);
+        var c = F32Array.schema.allocate(accelerator, 100);
+        c.length(100);
         accelerator.compute(cc -> MatrixMultiply.compute(cc, a, b, c, 100));
     }
 
diff --git a/hat/examples/experiments/src/main/java/experiments/spirv/MatrixMultiply.java b/hat/examples/experiments/src/main/java/experiments/spirv/MatrixMultiply.java
index 67f87406203..fba9f330701 100644
--- a/hat/examples/experiments/src/main/java/experiments/spirv/MatrixMultiply.java
+++ b/hat/examples/experiments/src/main/java/experiments/spirv/MatrixMultiply.java
@@ -111,9 +111,14 @@ public static void main(String[] args) {
         int size = 10;  // works
         float[] arrA = new float[size * size];
         float[] arrB = new float[size * size];
-        var a = F32Array.create(accelerator, arrA);
-        var b = F32Array.create(accelerator, arrB);
-        var c = F32Array.create(accelerator, new float[size * size]);
+        var a = F32Array.schema.allocate(accelerator, arrA.length);
+        a.length(arrA.length);
+        a.copyFrom(arrA);
+        var b = F32Array.schema.allocate(accelerator, arrB.length);
+        b.length(arrB.length);
+        b.copyFrom(arrB);
+        var c = F32Array.schema.allocate(accelerator, size * size);
+        c.length(size*size);
         System.out.print(c.schema());
         accelerator.compute(
                 cc -> MatrixMultiplyCompute.compute(cc, a, b, c, size)
diff --git a/hat/examples/mandel/src/main/java/mandel/MandelCompute.java b/hat/examples/mandel/src/main/java/mandel/MandelCompute.java
index 8b79c1b4743..6eba1c3c09d 100644
--- a/hat/examples/mandel/src/main/java/mandel/MandelCompute.java
+++ b/hat/examples/mandel/src/main/java/mandel/MandelCompute.java
@@ -63,12 +63,12 @@ public static void mandel(KernelContext kc, S32Array2D s32Array2D, S32Array pall
     static public void compute(final ComputeContext computeContext, S32Array pallete, S32Array2D s32Array2D, float x, float y, float scale) {
 
         computeContext.dispatchKernel(
-                s32Array2D.size(), //0..S32Array2D.size()
+                s32Array2D.width()*s32Array2D.height(), //0..S32Array2D.size()
                 kc -> MandelCompute.mandel(kc, s32Array2D, pallete, x, y, scale));
     }
 
     public static void main(String[] args) {
-        boolean headless = true;//Boolean.getBoolean("headless") ||( args.length>0 && args[0].equals("--headless"));
+        boolean headless = Boolean.getBoolean("headless") ||( args.length>0 && args[0].equals("--headless"));
 
         final int width = 1024;
         final int height = 1024;
@@ -80,7 +80,9 @@ public static void main(String[] args) {
 
         Accelerator accelerator = new Accelerator(MethodHandles.lookup(), Backend.FIRST);
 
-        S32Array2D s32Array2D = S32Array2D.create(accelerator, width, height);
+        S32Array2D s32Array2D = S32Array2D.schema.allocate(accelerator, width, height);
+        s32Array2D.width(width);
+        s32Array2D.height(height);
 
         int[] palletteArray = new int[maxIterations];
 
@@ -96,7 +98,9 @@ public static void main(String[] args) {
                 palletteArray[i] = Color.HSBtoRGB(h, 1f, b);
             }
         }
-        S32Array pallette = S32Array.create(accelerator, palletteArray);
+        S32Array pallette = S32Array.schema.allocate(accelerator, palletteArray.length);
+        pallette.length(palletteArray.length);
+        pallette.copyfrom(palletteArray);
 
         accelerator.compute(cc -> MandelCompute.compute(cc, pallette, s32Array2D, originX, originY, defaultScale));
 
diff --git a/hat/examples/mandel/src/main/java/mandel/MandelViewer.java b/hat/examples/mandel/src/main/java/mandel/MandelViewer.java
index 61aa9643395..ffc15eecabf 100644
--- a/hat/examples/mandel/src/main/java/mandel/MandelViewer.java
+++ b/hat/examples/mandel/src/main/java/mandel/MandelViewer.java
@@ -114,7 +114,7 @@ public void waitForDoorbell() {
 
         public void syncWithRGB(S32Array2D s32Array2D) {
             long offset = Buffer.getLayout(s32Array2D).byteOffset(MemoryLayout.PathElement.groupElement("array"));
-            MemorySegment.copy(Buffer.getMemorySegment(s32Array2D), JAVA_INT, offset, ((DataBufferInt) image.getRaster().getDataBuffer()).getData(), 0, s32Array2D.size());
+            MemorySegment.copy(Buffer.getMemorySegment(s32Array2D), JAVA_INT, offset, ((DataBufferInt) image.getRaster().getDataBuffer()).getData(), 0, s32Array2D.width()*s32Array2D.height());
             this.repaint();
         }
 
diff --git a/hat/examples/mandel/src/main/java/mandel/buffers/RgbaS32Image.java b/hat/examples/mandel/src/main/java/mandel/buffers/RgbaS32Image.java
deleted file mode 100644
index d8dfb13315c..00000000000
--- a/hat/examples/mandel/src/main/java/mandel/buffers/RgbaS32Image.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package mandel.buffers;
-
-import hat.buffer.BufferAllocator;
-import hat.buffer.ImageBuffer;
-
-import java.awt.image.BufferedImage;
-import java.lang.foreign.StructLayout;
-
-import static java.lang.foreign.ValueLayout.JAVA_SHORT;
-
-public interface RgbaS32Image extends ImageBuffer {
-    StructLayout layout =  ImageBuffer.createLayout(RgbaS32Image.class,JAVA_SHORT);
-    private static RgbaS32Image create(BufferAllocator bufferAllocator, int width, int height) {
-        return ImageBuffer.create(bufferAllocator, RgbaS32Image.class, layout,width, height, BufferedImage.TYPE_INT_ARGB, 1);
-    }
-
-    static RgbaS32Image create(BufferAllocator bufferAllocator, BufferedImage bufferedImage) {
-        return create(bufferAllocator, bufferedImage.getWidth(), bufferedImage.getHeight()).syncFromRaster(bufferedImage);
-
-    }
-
-    short data(long idx);
-
-    void data(long idx, short v);
-
-    default short get(int x, int y) {
-        return data((long) y * width() + x);
-    }
-
-    default void set(int x, int y, short v) {
-        data((long) y * width() + x, v);
-    }
-}
diff --git a/hat/examples/squares/src/main/java/squares/Squares.java b/hat/examples/squares/src/main/java/squares/Squares.java
index c079a4d6c95..31ad85d0c32 100644
--- a/hat/examples/squares/src/main/java/squares/Squares.java
+++ b/hat/examples/squares/src/main/java/squares/Squares.java
@@ -58,7 +58,8 @@ public static void square(ComputeContext cc, S32Array s32Array) {
     public static void main(String[] args) {
         var lookup = java.lang.invoke.MethodHandles.lookup();
         var accelerator = new Accelerator(lookup, Backend.FIRST);//new JavaMultiThreadedBackend());
-        var arr = S32Array.create(accelerator, 32);
+        var arr = S32Array.schema.allocate(accelerator, 32);
+        arr.length(32);
         for (int i = 0; i < arr.length(); i++) {
             arr.array(i, i);
         }
diff --git a/hat/examples/violajones/src/main/java/violajones/HaarViewer.java b/hat/examples/violajones/src/main/java/violajones/HaarViewer.java
index 30708f12052..f4d78aa39f3 100644
--- a/hat/examples/violajones/src/main/java/violajones/HaarViewer.java
+++ b/hat/examples/violajones/src/main/java/violajones/HaarViewer.java
@@ -25,12 +25,11 @@
 package violajones;
 
 
-import hat.Accelerator;
 import hat.buffer.BufferAllocator;
 import hat.buffer.F32Array2D;
 import hat.buffer.S32Array;
-import violajones.buffers.GreyU16Image;
-import violajones.buffers.RgbS08x3Image;
+import hat.buffer.U16GreyImage;
+import hat.buffer.S08x3RGBImage;
 import violajones.ifaces.Cascade;
 import violajones.ifaces.ResultTable;
 import violajones.ifaces.ScaleTable;
@@ -51,15 +50,15 @@
 
 public class HaarViewer extends JFrame {
     final BufferedImage image;
-    final RgbS08x3Image rgbS08x3Image;
+    final S08x3RGBImage s08X3RGBImage;
 
 
     public static class IntegralWindow {
         final double integralScale = .25;
         BufferedImage integral;
         BufferedImage integralSq;
-        GreyU16Image integralImageU16;
-        GreyU16Image integralSqImageU16;
+        U16GreyImage integralImageU16;
+        U16GreyImage integralSqImageU16;
         JComponent integralImageView;
         JComponent integralSqImageView;
         final F32Array2D integralImageF32;
@@ -74,8 +73,8 @@ public IntegralWindow(Container container, BufferAllocator bufferAllocator, F32A
                 int height = this.integralImageF32.height();
                 this.integral = new BufferedImage(width, height, BufferedImage.TYPE_USHORT_GRAY);
                 this.integralSq = new BufferedImage(width, height, BufferedImage.TYPE_USHORT_GRAY);
-                this.integralImageU16 = GreyU16Image.create(bufferAllocator, integral);
-                this.integralSqImageU16 = GreyU16Image.create(bufferAllocator, integralSq);
+                this.integralImageU16 = U16GreyImage.schema.allocate(bufferAllocator,integral.getWidth(),integral.getHeight());//create(bufferAllocator, integral);
+                this.integralSqImageU16 = U16GreyImage.schema.allocate(bufferAllocator, integral.getWidth(),integral.getHeight());
                 this.integralImageView = new JComponent() {
                     @Override
                     public void paint(Graphics g) {
@@ -172,14 +171,14 @@ public void showIntegrals() {
 
     public HaarViewer(BufferAllocator bufferAllocator,
                       BufferedImage image,
-                      RgbS08x3Image rgbS08x3Image,
+                      S08x3RGBImage s08X3RGBImage,
                       Cascade cascade,
                       F32Array2D integralImageF32,
                       F32Array2D integralSqImageF32
     ) {
         super("HaarViz");
         this.image = image;
-        this.rgbS08x3Image = rgbS08x3Image;
+        this.s08X3RGBImage = s08X3RGBImage;
         this.cascade = cascade;
 
         this.setLayout(new BorderLayout());
diff --git a/hat/examples/violajones/src/main/java/violajones/ViolaJonesCompute.java b/hat/examples/violajones/src/main/java/violajones/ViolaJonesCompute.java
index f757b4966fb..e1837052b94 100644
--- a/hat/examples/violajones/src/main/java/violajones/ViolaJonesCompute.java
+++ b/hat/examples/violajones/src/main/java/violajones/ViolaJonesCompute.java
@@ -30,7 +30,7 @@
 import org.xml.sax.SAXException;
 import violajones.attic.ViolaJones;
 import violajones.attic.ViolaJonesRaw;
-import violajones.buffers.RgbS08x3Image;
+import hat.buffer.S08x3RGBImage;
 import violajones.ifaces.Cascade;
 import violajones.ifaces.ResultTable;
 import violajones.ifaces.ScaleTable;
@@ -67,7 +67,12 @@ public static void main(String[] args) throws IOException, ParserConfigurationEx
                 xmlCascade.treeCount()
         ).copyFrom(xmlCascade);
 
-        RgbS08x3Image rgbImage = RgbS08x3Image.create(accelerator, nasa1996);
+        S08x3RGBImage rgbImage = S08x3RGBImage.schema.allocate(accelerator, nasa1996.getWidth(),nasa1996.getHeight());
+        rgbImage.width(nasa1996.getWidth());
+        rgbImage.height(nasa1996.getHeight());
+      //  rgbImage.elementsPerPixel(3);
+      //  rgbImage.bufferedImageType(BufferedImage.TYPE_INT_RGB);
+        rgbImage.syncFromRaster(nasa1996);
         ResultTable resultTable = ResultTable.schema.allocate(1000);
         resultTable.length(1000);
 
diff --git a/hat/examples/violajones/src/main/java/violajones/ViolaJonesCoreCompute.java b/hat/examples/violajones/src/main/java/violajones/ViolaJonesCoreCompute.java
index 0b258aa2b06..9e4771a0209 100644
--- a/hat/examples/violajones/src/main/java/violajones/ViolaJonesCoreCompute.java
+++ b/hat/examples/violajones/src/main/java/violajones/ViolaJonesCoreCompute.java
@@ -24,25 +24,16 @@
  */
 package violajones;
 
-import hat.Accelerator;
 import hat.ComputeContext;
 import hat.KernelContext;
-import hat.backend.Backend;
-import hat.buffer.S32Array;
 import hat.buffer.F32Array2D;
-import org.xml.sax.SAXException;
-import violajones.attic.ViolaJones;
-import violajones.attic.ViolaJonesRaw;
-import violajones.buffers.RgbS08x3Image;
+import hat.buffer.S08x3RGBImage;
+import hat.buffer.S32Array;
 import violajones.ifaces.Cascade;
 import violajones.ifaces.ResultTable;
 import violajones.ifaces.ScaleTable;
 
-import javax.imageio.ImageIO;
-import javax.xml.parsers.ParserConfigurationException;
 import java.awt.image.BufferedImage;
-import java.io.IOException;
-import java.lang.invoke.MethodHandles;
 import java.lang.runtime.CodeReflection;
 
 public class ViolaJonesCoreCompute {
@@ -58,7 +49,7 @@ public static int grey(int r, int g, int b) {
     }
 
     @CodeReflection
-    public static void rgbToGrey(int id, RgbS08x3Image rgbImage, F32Array2D greyImage) {
+    public static void rgbToGrey(int id, S08x3RGBImage rgbImage, F32Array2D greyImage) {
         byte r = rgbImage.data(id * 3 + 0);
         byte g = rgbImage.data(id * 3 + 1);
         byte b = rgbImage.data(id * 3 + 2);
@@ -68,7 +59,7 @@ public static void rgbToGrey(int id, RgbS08x3Image rgbImage, F32Array2D greyImag
     /*
      * A pure java implementation so no @CodeReflection
      */
-    static long javaRgbToGreyScale(RgbS08x3Image rgb, F32Array2D grey) {
+    static long javaRgbToGreyScale(S08x3RGBImage rgb, F32Array2D grey) {
         long start = System.currentTimeMillis();
         int size = grey.width() * grey.height();
 
@@ -80,7 +71,7 @@ static long javaRgbToGreyScale(RgbS08x3Image rgb, F32Array2D grey) {
     }
 
     @CodeReflection
-    public static void rgbToGreyKernel(KernelContext kc, RgbS08x3Image rgbImage, F32Array2D greyImage) {
+    public static void rgbToGreyKernel(KernelContext kc, S08x3RGBImage rgbImage, F32Array2D greyImage) {
         if (kc.x < kc.maxX){
            rgbToGrey(kc.x, rgbImage, greyImage);
         }
@@ -311,18 +302,27 @@ public static void findFeaturesKernel(KernelContext kc,
         }
     }
 
+    static F32Array2D createF32Array2D(ComputeContext cc,int width, int height){
+        F32Array2D f32Array2D = F32Array2D.schema.allocate(cc, width, height);
+        f32Array2D.width(width);
+        f32Array2D.height(height);
+        return f32Array2D;
+    }
+
     @CodeReflection
-    static public void compute(final ComputeContext cc, Cascade cascade, BufferedImage bufferedImage, RgbS08x3Image rgbS08x3Image, ResultTable resultTable, ScaleTable scaleTable) {
+    static public void compute(final ComputeContext cc, Cascade cascade, BufferedImage bufferedImage, S08x3RGBImage s08X3RGBImage, ResultTable resultTable, ScaleTable scaleTable) {
         long start = System.currentTimeMillis();
-        int width = rgbS08x3Image.width();
+        int width = s08X3RGBImage.width();
+
+        int height = s08X3RGBImage.height();
+        F32Array2D greyImage = createF32Array2D(cc, width, height);
 
-        int height = rgbS08x3Image.height();
-        F32Array2D greyImage = F32Array2D.create(cc, width, height);
         //javaRgbToGreyScale(rgbS08x3Image, greyImage);
 
-        cc.dispatchKernel(width * height, kc -> rgbToGreyKernel(kc, rgbS08x3Image, greyImage));
-        F32Array2D integralImage = F32Array2D.create(cc, width, height);
-        F32Array2D integralSqImage = F32Array2D.create(cc, width, height);
+        cc.dispatchKernel(width * height, kc -> rgbToGreyKernel(kc, s08X3RGBImage, greyImage));
+        F32Array2D integralImage = createF32Array2D(cc, width, height);
+
+        F32Array2D integralSqImage = createF32Array2D(cc, width, height);
 
         //javaCreateIntegralImage(greyImage, integralImage, integralSqImage);
 
diff --git a/hat/examples/violajones/src/main/java/violajones/attic/CoreJavaViolaJones.java b/hat/examples/violajones/src/main/java/violajones/attic/CoreJavaViolaJones.java
index d10b389d40f..e737b5029c0 100644
--- a/hat/examples/violajones/src/main/java/violajones/attic/CoreJavaViolaJones.java
+++ b/hat/examples/violajones/src/main/java/violajones/attic/CoreJavaViolaJones.java
@@ -25,7 +25,7 @@
 package violajones.attic;
 
 import hat.buffer.F32Array2D;
-import violajones.buffers.RgbS08x3Image;
+import hat.buffer.S08x3RGBImage;
 
 import java.lang.foreign.MemorySegment;
 
@@ -50,7 +50,7 @@ public static void rgbToGreyKernel(int id, byte[] rgbBytes, int[] greyInts) {
     }
 
 
-    public static void rgbToGreyKernel(int id, RgbS08x3Image rgbImage, F32Array2D floatImage) {
+    public static void rgbToGreyKernel(int id, S08x3RGBImage rgbImage, F32Array2D floatImage) {
         byte r = rgbImage.data(id * 3L + 0);
         byte g = rgbImage.data(id * 3L + 1);
         byte b = rgbImage.data(id * 3L + 2);
@@ -143,7 +143,7 @@ static long rgbToGreyScale(byte[] rgb, int[] grey) {
         return System.currentTimeMillis() - start;
     }
 
-    static long rgbToGreyScale(RgbS08x3Image rgb, F32Array2D grey) {
+    static long rgbToGreyScale(S08x3RGBImage rgb, F32Array2D grey) {
         long start = System.currentTimeMillis();
         int size = grey.width() * grey.height();
 
diff --git a/hat/examples/violajones/src/main/java/violajones/attic/ViolaJones.java b/hat/examples/violajones/src/main/java/violajones/attic/ViolaJones.java
index eb2d12b6136..4f339101802 100644
--- a/hat/examples/violajones/src/main/java/violajones/attic/ViolaJones.java
+++ b/hat/examples/violajones/src/main/java/violajones/attic/ViolaJones.java
@@ -32,7 +32,7 @@
 import org.xml.sax.SAXException;
 import violajones.HaarViewer;
 import violajones.XMLHaarCascadeModel;
-import violajones.buffers.RgbS08x3Image;
+import hat.buffer.S08x3RGBImage;
 import violajones.ifaces.Cascade;
 import violajones.ifaces.ResultTable;
 import violajones.ifaces.ScaleTable;
@@ -56,7 +56,13 @@ public static void main(String[] _args) throws IOException, ParserConfigurationE
    //     Cascade cascade = Cascade.create(accelerator, xmlHaarCascade);
         var cascade = Cascade.schema.allocate(accelerator,xmlCascade.featureCount(),xmlCascade.stageCount(),xmlCascade.treeCount()).copyFrom(xmlCascade);
 
-        var rgbImage = RgbS08x3Image.create(accelerator, nasa);
+        S08x3RGBImage rgbImage = S08x3RGBImage.schema.allocate(accelerator, nasa.getWidth(),nasa.getHeight());
+        rgbImage.width(nasa.getWidth());
+        rgbImage.height(nasa.getHeight());
+       // rgbImage.elementsPerPixel(3);
+       // rgbImage.bufferedImageType(BufferedImage.TYPE_INT_RGB);
+
+       // var rgbImage = RgbS08x3Image.create(accelerator, nasa);
 
         var width = nasa.getWidth();
         var height = nasa.getHeight();
@@ -68,9 +74,15 @@ public static void main(String[] _args) throws IOException, ParserConfigurationE
         scaleTable.applyConstraints(constraints);
 
 
-        var greyImageF32 = F32Array2D.create(accelerator, width, height);
-        var integralImageF32 = F32Array2D.create(accelerator, width, height);
-        var integralSqImageF32 = F32Array2D.create(accelerator, width, height);
+        var greyImageF32 = F32Array2D.schema.allocate(accelerator, width, height);
+        greyImageF32.width(width);
+        greyImageF32.height(height);
+        var integralImageF32 = F32Array2D.schema.allocate(accelerator, width, height);
+        integralImageF32.width(width);
+        integralImageF32.height(height);
+        var integralSqImageF32 = F32Array2D.schema.allocate(accelerator, width, height);
+        integralSqImageF32.width(width);
+        integralSqImageF32.height(height);
         var resultTable = ResultTable.schema.allocate(accelerator, 1000);
         resultTable.length(1000);
         resultTable.atomicResultTableCount(0);
diff --git a/hat/examples/violajones/src/main/java/violajones/buffers/RgbS08x3Image.java b/hat/examples/violajones/src/main/java/violajones/buffers/RgbS08x3Image.java
deleted file mode 100644
index 13c60b106e9..00000000000
--- a/hat/examples/violajones/src/main/java/violajones/buffers/RgbS08x3Image.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package violajones.buffers;
-
-import hat.buffer.BufferAllocator;
-import hat.buffer.ImageBuffer;
-import java.awt.image.BufferedImage;
-import java.lang.foreign.StructLayout;
-
-import static java.lang.foreign.ValueLayout.JAVA_BYTE;
-
-public interface RgbS08x3Image extends ImageBuffer {
-    StructLayout layout =  ImageBuffer.createLayout(RgbS08x3Image.class,JAVA_BYTE);
-
-    private static RgbS08x3Image create(BufferAllocator bufferAllocator, int width, int height) {
-        return ImageBuffer.create(bufferAllocator, RgbS08x3Image.class,layout, width, height, BufferedImage.TYPE_INT_RGB, 3);
-    }
-
-    static RgbS08x3Image create(BufferAllocator bufferAllocator, BufferedImage bufferedImage) {
-        return create(bufferAllocator, bufferedImage.getWidth(), bufferedImage.getHeight()).syncFromRaster(bufferedImage);
-
-    }
-    byte data(long idx);
-
-    void data(long idx, byte v);
-
-}
diff --git a/hat/examples/violajones/src/main/java/violajones/ifaces/ResultTable.java b/hat/examples/violajones/src/main/java/violajones/ifaces/ResultTable.java
index 164fd63769d..99a7b572600 100644
--- a/hat/examples/violajones/src/main/java/violajones/ifaces/ResultTable.java
+++ b/hat/examples/violajones/src/main/java/violajones/ifaces/ResultTable.java
@@ -27,16 +27,6 @@
 import hat.buffer.IncompleteBuffer;
 import hat.ifacemapper.Schema;
 import hat.buffer.Buffer;
-import hat.buffer.BufferAllocator;
-import hat.buffer.Table;
-import hat.ifacemapper.SegmentMapper;
-
-import java.lang.foreign.MemoryLayout;
-import java.lang.foreign.StructLayout;
-import java.lang.invoke.MethodHandles;
-
-import static java.lang.foreign.ValueLayout.JAVA_FLOAT;
-import static java.lang.foreign.ValueLayout.JAVA_INT;
 
 public interface ResultTable extends IncompleteBuffer  {
 
diff --git a/hat/examples/violajones/src/main/java/violajones/ifaces/ScaleTable.java b/hat/examples/violajones/src/main/java/violajones/ifaces/ScaleTable.java
index 20a165efdfc..58027c6d741 100644
--- a/hat/examples/violajones/src/main/java/violajones/ifaces/ScaleTable.java
+++ b/hat/examples/violajones/src/main/java/violajones/ifaces/ScaleTable.java
@@ -28,16 +28,6 @@
 import hat.buffer.IncompleteBuffer;
 import hat.ifacemapper.Schema;
 import hat.buffer.Buffer;
-import hat.buffer.BufferAllocator;
-import hat.buffer.Table;
-import hat.ifacemapper.SegmentMapper;
-
-import java.lang.foreign.MemoryLayout;
-import java.lang.foreign.StructLayout;
-import java.lang.invoke.MethodHandles;
-
-import static java.lang.foreign.ValueLayout.JAVA_FLOAT;
-import static java.lang.foreign.ValueLayout.JAVA_INT;
 
 public interface ScaleTable extends IncompleteBuffer {
     interface Scale extends Buffer.StructChild {
diff --git a/hat/hat/src/main/java/hat/buffer/Array.java b/hat/hat/src/main/java/hat/buffer/Array.java
deleted file mode 100644
index 361cf24e0ff..00000000000
--- a/hat/hat/src/main/java/hat/buffer/Array.java
+++ /dev/null
@@ -1,4 +0,0 @@
-package hat.buffer;
-
-public interface Array extends IncompleteBuffer {
-}
diff --git a/hat/hat/src/main/java/hat/buffer/Array1D.java b/hat/hat/src/main/java/hat/buffer/Array1D.java
deleted file mode 100644
index cdfc9191366..00000000000
--- a/hat/hat/src/main/java/hat/buffer/Array1D.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package hat.buffer;
-
-import hat.Accelerator;
-import hat.ifacemapper.SegmentMapper;
-
-import java.lang.foreign.MemoryLayout;
-import java.lang.foreign.MemorySegment;
-import java.lang.foreign.StructLayout;
-import java.lang.invoke.MethodHandles;
-
-import static java.lang.foreign.ValueLayout.JAVA_INT;
-
-public interface Array1D extends Array {
-    static <T extends Array1D> StructLayout getLayout(Class<T> clazz, MemoryLayout memoryLayout) {
-        return MemoryLayout.structLayout(
-                JAVA_INT.withName("length"),
-                MemoryLayout.sequenceLayout(0, memoryLayout).withName("array")
-        ).withName(clazz.getSimpleName());
-    }
-
-    static <T extends Array1D> T create(BufferAllocator bufferAllocator, Class<T> clazz, StructLayout structLayout, int length) {
-
-        T buffer = bufferAllocator.allocate(SegmentMapper.ofIncomplete(MethodHandles.lookup(), clazz, structLayout,length));
-        Buffer.setLength(buffer,length);
-        return buffer;
-    }
-
-
-    int length();
-
-
-}
diff --git a/hat/hat/src/main/java/hat/buffer/Array2D.java b/hat/hat/src/main/java/hat/buffer/Array2D.java
deleted file mode 100644
index c3869c27264..00000000000
--- a/hat/hat/src/main/java/hat/buffer/Array2D.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package hat.buffer;
-
-import hat.Accelerator;
-import hat.ifacemapper.SegmentMapper;
-
-import java.lang.foreign.MemoryLayout;
-import java.lang.foreign.MemorySegment;
-import java.lang.foreign.StructLayout;
-import java.lang.invoke.MethodHandles;
-
-import static java.lang.foreign.ValueLayout.JAVA_INT;
-
-public interface Array2D extends Array {
-    static <T extends Array2D> StructLayout getLayout(Class<T> iface, MemoryLayout memoryLayout) {
-        return MemoryLayout.structLayout(
-                JAVA_INT.withName("width"),
-                JAVA_INT.withName("height"),
-                MemoryLayout.sequenceLayout(0, memoryLayout).withName("array")
-        ).withName(iface.getSimpleName());
-    }
-
-    static <T extends Array2D> T create(BufferAllocator bufferAllocator, Class<T> clazz, StructLayout structLayout,int width, int height) {
-
-        T buffer = bufferAllocator.allocate(SegmentMapper.ofIncomplete(MethodHandles.lookup(), clazz, structLayout, (long) width * height));
-        MemorySegment segment = Buffer.getMemorySegment(buffer);
-        segment.set(JAVA_INT, structLayout.byteOffset(MemoryLayout.PathElement.groupElement("width")), width);
-        segment.set(JAVA_INT, structLayout.byteOffset(MemoryLayout.PathElement.groupElement("height")), height);
-        return buffer;
-    }
-
-    int width();
-
-    int height();
-
-    default int size() {
-        return width() * height();
-    }
-}
diff --git a/hat/hat/src/main/java/hat/buffer/F32Array.java b/hat/hat/src/main/java/hat/buffer/F32Array.java
index ec59c3b8b50..9917bcd3bb1 100644
--- a/hat/hat/src/main/java/hat/buffer/F32Array.java
+++ b/hat/hat/src/main/java/hat/buffer/F32Array.java
@@ -25,21 +25,20 @@
 package hat.buffer;
 
 import hat.Accelerator;
+import hat.ifacemapper.Schema;
 
 import java.lang.foreign.MemorySegment;
 import java.lang.foreign.StructLayout;
 
 import static java.lang.foreign.ValueLayout.JAVA_FLOAT;
+import static java.lang.foreign.ValueLayout.JAVA_INT;
 
-public interface F32Array extends Array1D {
-    StructLayout layout  = Array1D.getLayout(F32Array.class, JAVA_FLOAT);
-    static F32Array create(BufferAllocator bufferAllocator, int length) {
-        return Array1D.create(bufferAllocator, F32Array.class,layout, length);
-    }
+public interface F32Array extends IncompleteBuffer {
 
-    static F32Array create(BufferAllocator bufferAllocator, float[] source) {
-        return create(bufferAllocator, source.length).copyFrom(source);
-    }
+    int length();
+    void length(int i);
+    Schema<F32Array> schema = Schema.of(F32Array.class, s32Array->s32Array
+            .arrayLen("length").array("array"));
 
     float array(long idx);
 
diff --git a/hat/hat/src/main/java/hat/buffer/F32Array2D.java b/hat/hat/src/main/java/hat/buffer/F32Array2D.java
index 2384914b2c8..eed09aafc8e 100644
--- a/hat/hat/src/main/java/hat/buffer/F32Array2D.java
+++ b/hat/hat/src/main/java/hat/buffer/F32Array2D.java
@@ -25,17 +25,21 @@
 package hat.buffer;
 
 import hat.Accelerator;
+import hat.ifacemapper.Schema;
 
 import java.lang.foreign.StructLayout;
 
 import static java.lang.foreign.ValueLayout.JAVA_FLOAT;
 import static java.lang.foreign.ValueLayout.JAVA_INT;
 
-public interface F32Array2D extends Array2D {
-    StructLayout layout  = Array2D.getLayout(F32Array2D.class, JAVA_FLOAT);
-    static F32Array2D create(BufferAllocator bufferAllocator, int width, int height) {
-        return Array2D.create(bufferAllocator, F32Array2D.class, layout, width, height);
-    }
+public interface F32Array2D extends IncompleteBuffer {
+    int width();
+    void height(int i);
+    int height();
+    void width(int i);
+    Schema<F32Array2D> schema = Schema.of(F32Array2D.class, s32Array->s32Array
+            .arrayLen("width","height").stride(1).array("array"));
+
     float array(long idx);
 
     void array(long idx, float v);
diff --git a/hat/hat/src/main/java/hat/buffer/ImageBuffer.java b/hat/hat/src/main/java/hat/buffer/ImageBuffer.java
deleted file mode 100644
index ff9c6a279e4..00000000000
--- a/hat/hat/src/main/java/hat/buffer/ImageBuffer.java
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package hat.buffer;
-
-import hat.Accelerator;
-import hat.ifacemapper.SegmentMapper;
-
-import java.awt.image.BufferedImage;
-import java.awt.image.DataBuffer;
-import java.awt.image.DataBufferByte;
-import java.awt.image.DataBufferInt;
-import java.awt.image.DataBufferUShort;
-import java.lang.foreign.MemoryLayout;
-import java.lang.foreign.MemorySegment;
-import java.lang.foreign.StructLayout;
-import java.lang.foreign.ValueLayout;
-import java.lang.invoke.MethodHandles;
-
-import static java.lang.foreign.ValueLayout.JAVA_BYTE;
-import static java.lang.foreign.ValueLayout.JAVA_INT;
-import static java.lang.foreign.ValueLayout.JAVA_SHORT;
-
-public interface ImageBuffer extends IncompleteBuffer {
-    static StructLayout createLayout(Class iface, ValueLayout valueLayout) {
-        return MemoryLayout.structLayout(
-                JAVA_INT.withName("width"),
-                JAVA_INT.withName("height"),
-                JAVA_INT.withName("elementsPerPixel"),
-                JAVA_INT.withName("bufferedImageType"),
-                MemoryLayout.sequenceLayout(0, valueLayout).withName("data")
-        ).withName(iface.getSimpleName());
-    }
-    /* BufferedImage types
-                 TYPE_INT_RGB, TYPE_INT_ARGB, TYPE_INT_ARGB_PRE, TYPE_INT_BGR,
-                  TYPE_3BYTE_BGR, TYPE_4BYTE_ABGR, TYPE_4BYTE_ABGR_PRE, TYPE_BYTE_GRAY,
-                   TYPE_BYTE_BINARY, TYPE_BYTE_INDEXED, TYPE_USHORT_GRAY,
-                    TYPE_USHORT_565_RGB, TYPE_USHORT_555_RGB, TYPE_CUSTOM
-
-     */
-    static <T extends ImageBuffer> T create(BufferAllocator bufferAllocator, Class<T> iface,StructLayout structLayout, int width, int height, int bufferedImageType, int elementsPerPixel) {
-        T rgba = bufferAllocator.allocate(SegmentMapper.ofIncomplete(MethodHandles.lookup(), iface, structLayout, width * height * elementsPerPixel));
-        MemorySegment segment = Buffer.getMemorySegment(rgba);
-        segment.set(JAVA_INT, structLayout.byteOffset(MemoryLayout.PathElement.groupElement("width")), width);
-        segment.set(JAVA_INT, structLayout.byteOffset(MemoryLayout.PathElement.groupElement("height")), height);
-        segment.set(JAVA_INT, structLayout.byteOffset(MemoryLayout.PathElement.groupElement("elementsPerPixel")), elementsPerPixel);
-        segment.set(JAVA_INT, structLayout.byteOffset(MemoryLayout.PathElement.groupElement("bufferedImageType")), bufferedImageType);
-        return rgba;
-    }
-
-    int elementsPerPixel();
-
-    // void elementsPerPixel(int elementsPerPixel);
-
-    int bufferedImageType();
-
-    // void bufferedImageType(int bufferedImageType);
-    @SuppressWarnings("unchecked")
-    default <T extends ImageBuffer> T syncToRasterDataBuffer(DataBuffer dataBuffer) { // int[], byte[], short[]
-        switch (dataBuffer) {
-            case DataBufferUShort arr ->
-                    MemorySegment.copy(Buffer.getMemorySegment(this), JAVA_SHORT, 16L, arr.getData(), 0, arr.getData().length);
-            case DataBufferInt arr ->
-                    MemorySegment.copy(Buffer.getMemorySegment(this), JAVA_INT, 16L, arr.getData(), 0, arr.getData().length);
-            case DataBufferByte arr ->
-                    MemorySegment.copy(Buffer.getMemorySegment(this), JAVA_BYTE, 16L, arr.getData(), 0, arr.getData().length);
-            default -> throw new IllegalStateException("Unexpected value: " + dataBuffer);
-        }
-        return (T) this;
-    }
-
-    default <T extends ImageBuffer> T syncToRaster(BufferedImage bufferedImage) { // int[], byte[], short[]
-        return syncToRasterDataBuffer(bufferedImage.getRaster().getDataBuffer());
-    }
-
-    @SuppressWarnings("unchecked")
-    default <T extends ImageBuffer> T syncFromRasterDataBuffer(DataBuffer dataBuffer) { // int[], byte[], short[]
-        switch (dataBuffer) {
-            case DataBufferInt arr ->
-                    MemorySegment.copy(arr.getData(), 0, Buffer.getMemorySegment(this), JAVA_INT, 16L, arr.getData().length);
-            case DataBufferByte arr ->
-                    MemorySegment.copy(arr.getData(), 0, Buffer.getMemorySegment(this), JAVA_BYTE, 16L, arr.getData().length);
-            case DataBufferUShort arr ->
-                    MemorySegment.copy(arr.getData(), 0, Buffer.getMemorySegment(this), JAVA_SHORT, 16L, arr.getData().length);
-            default -> throw new IllegalStateException("Unexpected value: " + dataBuffer);
-        }
-        return (T) this;
-    }
-
-    default <T extends ImageBuffer> T syncFromRaster(BufferedImage bufferedImage) { // int[], byte[], short[]
-        return syncFromRasterDataBuffer(bufferedImage.getRaster().getDataBuffer());
-    }
-
-    int width();
-
-    int height();
-
-    default int size() {
-        return width() * height();
-    }
-}
diff --git a/hat/hat/src/main/java/hat/buffer/ImageIfaceBuffer.java b/hat/hat/src/main/java/hat/buffer/ImageIfaceBuffer.java
new file mode 100644
index 00000000000..88e390f0a50
--- /dev/null
+++ b/hat/hat/src/main/java/hat/buffer/ImageIfaceBuffer.java
@@ -0,0 +1,50 @@
+package hat.buffer;
+
+import java.awt.image.BufferedImage;
+import java.awt.image.DataBuffer;
+import java.awt.image.DataBufferByte;
+import java.awt.image.DataBufferInt;
+import java.awt.image.DataBufferUShort;
+import java.lang.foreign.MemorySegment;
+
+import static java.lang.foreign.ValueLayout.JAVA_BYTE;
+import static java.lang.foreign.ValueLayout.JAVA_INT;
+import static java.lang.foreign.ValueLayout.JAVA_SHORT;
+
+public interface ImageIfaceBuffer<T extends ImageIfaceBuffer<?>> extends IncompleteBuffer {
+    @SuppressWarnings("unchecked")
+    default T syncFromRasterDataBuffer(DataBuffer dataBuffer) { // int[], byte[], short[]
+        switch (dataBuffer) {
+            case DataBufferInt arr ->
+                    MemorySegment.copy(arr.getData(), 0, Buffer.getMemorySegment(this), JAVA_INT, 16L, arr.getData().length);
+            case DataBufferByte arr ->
+                    MemorySegment.copy(arr.getData(), 0, Buffer.getMemorySegment(this), JAVA_BYTE, 16L, arr.getData().length);
+            case DataBufferUShort arr ->
+                    MemorySegment.copy(arr.getData(), 0, Buffer.getMemorySegment(this), JAVA_SHORT, 16L, arr.getData().length);
+            default -> throw new IllegalStateException("Unexpected value: " + dataBuffer);
+        }
+        return (T)this;
+    }
+
+    default T syncFromRaster(BufferedImage bufferedImage) { // int[], byte[], short[]
+        return syncFromRasterDataBuffer(bufferedImage.getRaster().getDataBuffer());
+    }
+
+    @SuppressWarnings("unchecked")
+    default T syncToRasterDataBuffer(DataBuffer dataBuffer) { // int[], byte[], short[]
+        switch (dataBuffer) {
+            case DataBufferUShort arr ->
+                    MemorySegment.copy(Buffer.getMemorySegment(this), JAVA_SHORT, 16L, arr.getData(), 0, arr.getData().length);
+            case DataBufferInt arr ->
+                    MemorySegment.copy(Buffer.getMemorySegment(this), JAVA_INT, 16L, arr.getData(), 0, arr.getData().length);
+            case DataBufferByte arr ->
+                    MemorySegment.copy(Buffer.getMemorySegment(this), JAVA_BYTE, 16L, arr.getData(), 0, arr.getData().length);
+            default -> throw new IllegalStateException("Unexpected value: " + dataBuffer);
+        }
+        return (T) this;
+    }
+
+    default T syncToRaster(BufferedImage bufferedImage) { // int[], byte[], short[]
+        return syncToRasterDataBuffer(bufferedImage.getRaster().getDataBuffer());
+    }
+}
diff --git a/hat/hat/src/main/java/hat/buffer/S08x3RGBImage.java b/hat/hat/src/main/java/hat/buffer/S08x3RGBImage.java
new file mode 100644
index 00000000000..be1d0639b00
--- /dev/null
+++ b/hat/hat/src/main/java/hat/buffer/S08x3RGBImage.java
@@ -0,0 +1,16 @@
+package hat.buffer;
+
+import hat.ifacemapper.Schema;
+
+public interface S08x3RGBImage extends ImageIfaceBuffer<S08x3RGBImage> {
+    byte data(long idx);
+    void data(long idx, byte v);
+    int width();
+    void width(int width);
+    int height();
+    void height(int height);
+    Schema<S08x3RGBImage> schema = Schema.of(S08x3RGBImage.class, s -> s
+            .arrayLen("width", "height").stride(3).array("data")
+    );
+
+}
diff --git a/hat/hat/src/main/java/hat/buffer/S32Array.java b/hat/hat/src/main/java/hat/buffer/S32Array.java
index f76d0e61272..521dd9e84f8 100644
--- a/hat/hat/src/main/java/hat/buffer/S32Array.java
+++ b/hat/hat/src/main/java/hat/buffer/S32Array.java
@@ -25,6 +25,7 @@
 package hat.buffer;
 
 import hat.Accelerator;
+import hat.ifacemapper.Schema;
 
 import java.lang.foreign.MemorySegment;
 import java.lang.foreign.StructLayout;
@@ -32,27 +33,22 @@
 import static java.lang.foreign.ValueLayout.JAVA_FLOAT;
 import static java.lang.foreign.ValueLayout.JAVA_INT;
 
-public interface S32Array extends Array1D {
-    StructLayout layout  = Array1D.getLayout(S32Array.class, JAVA_INT);
-    static S32Array create(BufferAllocator bufferAllocator, int length) {
-        return Array1D.create(bufferAllocator, S32Array.class,layout, length);
-    }
-
-    static S32Array create(BufferAllocator bufferAllocator, int[] source) {
-        return create(bufferAllocator, source.length).copyfrom(source);
-    }
+public interface S32Array extends IncompleteBuffer {
 
+    int length();
+    void length(int i);
     int array(long idx);
+    void array(long idx, int i);
+    Schema<S32Array> schema = Schema.of(S32Array.class, s32Array->s32Array
+            .arrayLen("length").array("array"));
 
-    void array(long idx, int f);
-
-    default S32Array copyfrom(int[] floats) {
-        MemorySegment.copy(floats, 0, Buffer.getMemorySegment(this), JAVA_INT, 4, length());
+    default S32Array copyfrom(int[] ints) {
+        MemorySegment.copy(ints, 0, Buffer.getMemorySegment(this), JAVA_INT, 4, length());
         return this;
     }
 
-    default S32Array copyTo(int[] floats) {
-        MemorySegment.copy(Buffer.getMemorySegment(this), JAVA_INT, 4, floats, 0, length());
+    default S32Array copyTo(int[] ints) {
+        MemorySegment.copy(Buffer.getMemorySegment(this), JAVA_INT, 4, ints, 0, length());
         return this;
     }
 }
diff --git a/hat/hat/src/main/java/hat/buffer/S32Array2D.java b/hat/hat/src/main/java/hat/buffer/S32Array2D.java
index 80d83c32268..62a9a7bc178 100644
--- a/hat/hat/src/main/java/hat/buffer/S32Array2D.java
+++ b/hat/hat/src/main/java/hat/buffer/S32Array2D.java
@@ -25,17 +25,20 @@
 package hat.buffer;
 
 import hat.Accelerator;
+import hat.ifacemapper.Schema;
 
 import java.lang.foreign.StructLayout;
 
 import static java.lang.foreign.ValueLayout.JAVA_INT;
 
-public interface S32Array2D extends Array2D {
-    StructLayout layout  = Array2D.getLayout(S32Array2D.class, JAVA_INT);
-    static S32Array2D create(BufferAllocator bufferAllocator, int width, int height) {
-        return Array2D.create(bufferAllocator, S32Array2D.class, layout, width, height);
-    }
+public interface S32Array2D extends IncompleteBuffer {
 
+    int width();
+    void height(int i);
+    int height();
+    void width(int i);
+    Schema<S32Array2D> schema = Schema.of(S32Array2D.class, s32Array->s32Array
+            .arrayLen("width","height").stride(1).array("array"));
     int array(long idx);
 
     void array(long idx, int i);
diff --git a/hat/hat/src/main/java/hat/buffer/Table.java b/hat/hat/src/main/java/hat/buffer/S32RGBAImage.java
similarity index 75%
rename from hat/hat/src/main/java/hat/buffer/Table.java
rename to hat/hat/src/main/java/hat/buffer/S32RGBAImage.java
index 652b3ebc881..82f9816e37d 100644
--- a/hat/hat/src/main/java/hat/buffer/Table.java
+++ b/hat/hat/src/main/java/hat/buffer/S32RGBAImage.java
@@ -23,6 +23,19 @@
  * questions.
  */
 package hat.buffer;
-public interface Table<T> extends IncompleteBuffer {
-    int length();
+
+import hat.ifacemapper.Schema;
+
+public interface S32RGBAImage extends ImageIfaceBuffer<S32RGBAImage> {
+    int data(long idx);
+
+    void data(long idx, int v);
+
+    int width();
+    void width(int width);
+    int height();
+    void height(int height);
+    Schema<S32RGBAImage> schema = Schema.of(S32RGBAImage.class, s -> s
+            .arrayLen("width", "height").stride(1).array("data")
+    );
 }
diff --git a/hat/examples/violajones/src/main/java/violajones/buffers/GreyU16Image.java b/hat/hat/src/main/java/hat/buffer/U16GreyImage.java
similarity index 60%
rename from hat/examples/violajones/src/main/java/violajones/buffers/GreyU16Image.java
rename to hat/hat/src/main/java/hat/buffer/U16GreyImage.java
index 0f05fd56f48..33275fed9d4 100644
--- a/hat/examples/violajones/src/main/java/violajones/buffers/GreyU16Image.java
+++ b/hat/hat/src/main/java/hat/buffer/U16GreyImage.java
@@ -22,24 +22,19 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
-package violajones.buffers;
+package hat.buffer;
 
-import hat.buffer.BufferAllocator;
-import hat.buffer.ImageBuffer;
+import hat.ifacemapper.Schema;
 
-import java.awt.image.BufferedImage;
-import java.lang.foreign.StructLayout;
-
-import static java.lang.foreign.ValueLayout.JAVA_SHORT;
-
-public interface GreyU16Image extends ImageBuffer {
-    StructLayout layout =  ImageBuffer.createLayout(GreyU16Image.class,JAVA_SHORT);
-    private static GreyU16Image create(BufferAllocator bufferAllocator, int width, int height) {
-        return ImageBuffer.create(bufferAllocator, GreyU16Image.class, layout,width, height, BufferedImage.TYPE_USHORT_GRAY, 1);
-    }
-    static GreyU16Image create(BufferAllocator bufferAllocator, BufferedImage bufferedImage) {
-        return create(bufferAllocator, bufferedImage.getWidth(), bufferedImage.getHeight()).syncFromRaster(bufferedImage);
-    }
+public interface U16GreyImage extends ImageIfaceBuffer<U16GreyImage> {
     short data(long idx);
     void data(long idx, short v);
+    int width();
+    void width(int width);
+    int height();
+    void height(int height);
+    Schema<U16GreyImage> schema = Schema.of(U16GreyImage.class, s -> s
+            .arrayLen("width", "height").stride(1).array("data")
+    );
+
 }
diff --git a/hat/hat/src/main/java/hat/ifacemapper/Schema.java b/hat/hat/src/main/java/hat/ifacemapper/Schema.java
index d13381a06ba..b8f138a0630 100644
--- a/hat/hat/src/main/java/hat/ifacemapper/Schema.java
+++ b/hat/hat/src/main/java/hat/ifacemapper/Schema.java
@@ -498,22 +498,25 @@ public TypeSchemaNode array(String name, int len, Consumer<TypeSchemaNode> paren
                 return this;
             }
 
-            private TypeSchemaNode fieldControlledArray(String name, ArrayLen arrayLen) {
-                addField(new FieldControlledArray(this,  modeOf(type, name), typeOf(type, name),name, arrayLen));
+            private TypeSchemaNode fieldControlledArray(String name, List<ArrayLen> arrayLenFields, int stride) {
+                addField(new FieldControlledArray(this,  modeOf(type, name), typeOf(type, name),name, arrayLenFields, stride));
                 return this;
             }
 
             public static class ArrayBuildState {
                 TypeSchemaNode typeSchemaNode;
-                ArrayLen arrayLenField;
-
+                List<ArrayLen> arrayLenFields;
+                int stride=1;
                 public TypeSchemaNode array(String name) {
-                    return typeSchemaNode.fieldControlledArray(name, arrayLenField);
+                    return typeSchemaNode.fieldControlledArray(name, arrayLenFields, stride);
+                }
+                public ArrayBuildState stride(int stride) {
+                    this.stride = stride;
+                    return this;
                 }
-
                 public TypeSchemaNode array(String name, Consumer<TypeSchemaNode> parentFieldConsumer) {
                     Class<?> arrayType = typeOf(typeSchemaNode.type, name);
-                    this.typeSchemaNode.fieldControlledArray(name, arrayLenField);
+                    this.typeSchemaNode.fieldControlledArray(name, arrayLenFields, stride);
                     TypeSchemaNode typeSchemaNode =isStruct(arrayType)
                             ?new SchemaNode.Struct(this.typeSchemaNode, arrayType)
                             :new SchemaNode.Union(this.typeSchemaNode,arrayType);
@@ -522,16 +525,20 @@ public TypeSchemaNode array(String name, Consumer<TypeSchemaNode> parentFieldCon
                     return this.typeSchemaNode;
                 }
 
-                ArrayBuildState(TypeSchemaNode typeSchemaNode, ArrayLen arrayLenField) {
+                ArrayBuildState(TypeSchemaNode typeSchemaNode, List<ArrayLen> arrayLenFields) {
                     this.typeSchemaNode = typeSchemaNode;
-                    this.arrayLenField = arrayLenField;
+                    this.arrayLenFields = arrayLenFields;
                 }
             }
 
-            public ArrayBuildState arrayLen(String arrayLenFieldName) {
-                var arrayLenField = new ArrayLen(this, modeOf(type, arrayLenFieldName), typeOf(type, arrayLenFieldName),arrayLenFieldName );
-                addField(arrayLenField);
-                return new ArrayBuildState(this, arrayLenField);
+            public ArrayBuildState arrayLen(String ... arrayLenFieldNames) {
+                 List<ArrayLen> arrayLenFields = new ArrayList<>();
+                 Arrays.stream(arrayLenFieldNames).forEach(arrayLenFieldName-> {
+                    var arrayLenField = new ArrayLen(this, modeOf(type, arrayLenFieldName), typeOf(type, arrayLenFieldName), arrayLenFieldName);
+                    addField(arrayLenField);
+                    arrayLenFields.add(arrayLenField);
+                });
+                return new ArrayBuildState(this, arrayLenFields);
             }
 
             public void flexArray(String name) {
@@ -626,22 +633,29 @@ void collectLayouts(LayoutToBoundFieldTreeNode layoutToFieldBindingNode) {
         }
 
         public static final class FieldControlledArray extends Array {
-            ArrayLen arrayLen;
-
-            FieldControlledArray(TypeSchemaNode parent,   Mode mode, Class<?> type,String name, ArrayLen arrayLen) {
+            List<ArrayLen> arrayLenFields;
+            int stride;
+            FieldControlledArray(TypeSchemaNode parent,   Mode mode, Class<?> type,String name, List<ArrayLen> arrayLenFields, int stride) {
                 super(parent, mode, type, name);
-                this.arrayLen = arrayLen;
+                this.arrayLenFields = arrayLenFields;
+                this.stride = stride;
             }
 
             @Override
             public void toText(String indent, Consumer<String> stringConsumer) {
-                stringConsumer.accept(indent + name + "[" + mode+":"+type + "] where len defined by " + arrayLen.type);
+                stringConsumer.accept(indent + name + "[" + mode+":"+type + "] where len defined by " + arrayLenFields);
             }
 
             @Override
             void collectLayouts(LayoutToBoundFieldTreeNode layoutToFieldBindingNode) {
+                // We have more than one ArrayLen
+                int i=stride;
+                for (int c = 0 ; c<arrayLenFields.size(); c++ ){
+                   var v =  layoutToFieldBindingNode.takeArrayLen();
+                   i*=v;
+                }
                 layoutToFieldBindingNode.bind(this, MemoryLayout.sequenceLayout(
-                        layoutToFieldBindingNode.takeArrayLen(),
+                       i,// layoutToFieldBindingNode.takeArrayLen(),
                         parent.getLayout(type, layoutToFieldBindingNode).withName(type.getSimpleName())
                 ).withName(name));
             }
diff --git a/hat/hat/src/main/test/hat/SquaresTest.java b/hat/hat/src/main/test/hat/SquaresTest.java
index eb8dda908d2..27c0baf678f 100644
--- a/hat/hat/src/main/test/hat/SquaresTest.java
+++ b/hat/hat/src/main/test/hat/SquaresTest.java
@@ -66,7 +66,8 @@ public static void square(ComputeContext cc, S32Array s32Array) {
        void    testSquares(){
         var lookup = java.lang.invoke.MethodHandles.lookup();
         var accelerator = new Accelerator(lookup, new JavaMultiThreadedBackend());
-        var arr = S32Array.create(accelerator, 32);
+        var arr = S32Array.schema.allocate(accelerator, 32);
+        arr.length(32);
         for (int i = 0; i < arr.length(); i++) {
             arr.array(i, i);
         }