diff --git a/staticlibs/device/android/net/util/Struct.java b/staticlibs/device/android/net/util/Struct.java
deleted file mode 100644
index 03f5f22..0000000
--- a/staticlibs/device/android/net/util/Struct.java
+++ /dev/null
@@ -1,384 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.util;
-
-import android.annotation.NonNull;
-
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Modifier;
-import java.math.BigInteger;
-import java.nio.BufferUnderflowException;
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-import java.util.concurrent.ConcurrentHashMap;
-
-/**
- * Define a generic class that helps to parse the structured message.
- *
- * Example usage:
- *
- *    // C-style NduserOption message header definition in the kernel:
- *    struct nduseroptmsg {
- *        unsigned char nduseropt_family;
- *        unsigned char nduseropt_pad1;
- *        unsigned short nduseropt_opts_len;
- *        int nduseropt_ifindex;
- *        __u8 nduseropt_icmp_type;
- *        __u8 nduseropt_icmp_code;
- *        unsigned short nduseropt_pad2;
- *        unsigned int nduseropt_pad3;
- *    }
- *
- *    - Declare a subclass with explicit constructor or not which extends from this class to parse
- *      NduserOption header from raw bytes array.
- *
- *    - Option w/ explicit constructor:
- *      static class NduserOptHeaderMessage extends Struct {
- *          @Field(order = 0, type = Type.U8, padding = 1)
- *          final short family;
- *          @Field(order = 1, type = Type.U16)
- *          final int len;
- *          @Field(order = 2, type = Type.S32)
- *          final int ifindex;
- *          @Field(order = 3, type = Type.U8)
- *          final short type;
- *          @Field(order = 4, type = Type.U8, padding = 6)
- *          final short code;
- *
- *          NduserOptHeaderMessage(final short family, final int len, final int ifindex,
- *                  final short type, final short code) {
- *              this.family = family;
- *              this.len = len;
- *              this.ifindex = ifindex;
- *              this.type = type;
- *              this.code = code;
- *          }
- *      }
- *
- *      - Option w/o explicit constructor:
- *        static class NduserOptHeaderMessage extends Struct {
- *            @Field(order = 0, type = Type.U8, padding = 1)
- *            short family;
- *            @Field(order = 1, type = Type.U16)
- *            int len;
- *            @Field(order = 2, type = Type.S32)
- *            int ifindex;
- *            @Field(order = 3, type = Type.U8)
- *            short type;
- *            @Field(order = 4, type = Type.U8, padding = 6)
- *            short code;
- *        }
- *
- *    - Parse the target message and refer the members.
- *      final ByteBuffer buf = ByteBuffer.wrap(RAW_BYTES_ARRAY);
- *      buf.order(ByteOrder.nativeOrder());
- *      final NduserOptHeaderMessage nduserHdrMsg = Struct.parse(NduserOptHeaderMessage.class, buf);
- *      assertEquals(10, nduserHdrMsg.family);
- */
-public class Struct {
-    public enum Type {
-        U8,        // unsigned byte,  size = 1 byte
-        U16,       // unsigned short, size = 2 bytes
-        U32,       // unsigned int,   size = 4 bytes
-        U64,       // unsigned long,  size = 8 bytes
-        S8,        // signed byte,    size = 1 byte
-        S16,       // signed short,   size = 2 bytes
-        S32,       // signed int,     size = 4 bytes
-        S64,       // signed long,    size = 8 bytes
-        BE16,      // unsigned short in network order, size = 2 bytes
-        BE32,      // unsigned int in network order,   size = 4 bytes
-        BE64,      // unsigned long in network order,  size = 8 bytes
-        ByteArray, // byte array with predefined length
-    }
-
-    /**
-     * Indicate that the field marked with this annotation will automatically be managed by this
-     * class (e.g., will be parsed by #parse).
-     *
-     * order:     The placeholder associated with each field, consecutive order starting from zero.
-     * type:      The primitive data type listed in above Type enumeration.
-     * padding:   Padding bytes appear after the field for alignment.
-     * arraysize: The length of byte array.
-     *
-     * Annotation associated with field MUST have order and type properties at least, padding
-     * and arraysize properties depend on the specific usage, if these properties are absence,
-     * then default value 0 will be applied.
-     */
-    @Retention(RetentionPolicy.RUNTIME)
-    @Target(ElementType.FIELD)
-    public @interface Field {
-        int order();
-        Type type();
-        int padding() default 0;
-        int arraysize() default 0;
-    }
-
-    private static class FieldInfo {
-        @NonNull
-        public final Field annotation;
-        @NonNull
-        public final java.lang.reflect.Field field;
-
-        FieldInfo(final Field annotation, final java.lang.reflect.Field field) {
-            this.annotation = annotation;
-            this.field = field;
-        }
-    }
-    private static ConcurrentHashMap<Class, FieldInfo[]> sFieldCache = new ConcurrentHashMap();
-
-    private static void checkAnnotationType(final Type type, final Class fieldType) {
-        switch (type) {
-            case U8:
-            case S16:
-                if (fieldType == Short.TYPE) return;
-                break;
-            case U16:
-            case S32:
-            case BE16:
-                if (fieldType == Integer.TYPE) return;
-                break;
-            case U32:
-            case S64:
-            case BE32:
-                if (fieldType == Long.TYPE) return;
-                break;
-            case U64:
-            case BE64:
-                if (fieldType == BigInteger.class || fieldType == Long.TYPE) return;
-                break;
-            case S8:
-                if (fieldType == Byte.TYPE) return;
-                break;
-            case ByteArray:
-                if (fieldType == byte[].class) return;
-                break;
-            default:
-                throw new IllegalArgumentException("Unknown type" + type);
-        }
-        throw new IllegalArgumentException("Invalid primitive data type: " + fieldType
-                + "for annotation type: " + type);
-    }
-
-    private static boolean isStructSubclass(final Class clazz) {
-        return clazz != null && Struct.class.isAssignableFrom(clazz) && Struct.class != clazz;
-    }
-
-    private static int getAnnotationFieldCount(final Class clazz) {
-        int count = 0;
-        for (java.lang.reflect.Field field : clazz.getDeclaredFields()) {
-            if (field.isAnnotationPresent(Field.class)) count++;
-        }
-        return count;
-    }
-
-    private static boolean matchModifier(final FieldInfo[] fields, boolean immutable) {
-        for (FieldInfo fi : fields) {
-            if (Modifier.isFinal(fi.field.getModifiers()) != immutable) return false;
-        }
-        return true;
-    }
-
-    private static boolean hasBothMutableAndImmutableFields(final FieldInfo[] fields) {
-        return !matchModifier(fields, true /* immutable */)
-                && !matchModifier(fields, false /* mutable */);
-    }
-
-    private static boolean matchConstructor(final Constructor cons, final FieldInfo[] fields) {
-        final Class[] paramTypes = cons.getParameterTypes();
-        if (paramTypes.length != fields.length) return false;
-        for (int i = 0; i < paramTypes.length; i++) {
-            if (!paramTypes[i].equals(fields[i].field.getType())) return false;
-        }
-        return true;
-    }
-
-    private static BigInteger readBigInteger(final ByteBuffer buf) {
-        // The magnitude argument of BigInteger constructor is a byte array in big-endian order.
-        // If ByteBuffer is read in little-endian, reverse the order of the bytes is required;
-        // if ByteBuffer is read in big-endian, then just keep it as-is.
-        final byte[] input = new byte[8];
-        for (int i = 0; i < 8; i++) {
-            input[(buf.order() == ByteOrder.LITTLE_ENDIAN ? input.length - 1 - i : i)] = buf.get();
-        }
-        return new BigInteger(1, input);
-    }
-
-    private static Object getFieldValue(final ByteBuffer buf, final FieldInfo fieldInfo)
-            throws BufferUnderflowException {
-        final Object value;
-        checkAnnotationType(fieldInfo.annotation.type(), fieldInfo.field.getType());
-        switch (fieldInfo.annotation.type()) {
-            case U8:
-                value = (short) (buf.get() & 0xFF);
-                break;
-            case U16:
-                value = (int) (buf.getShort() & 0xFFFF);
-                break;
-            case U32:
-                value = (long) (buf.getInt() & 0xFFFFFFFFL);
-                break;
-            case U64:
-                if (fieldInfo.field.getType() == BigInteger.class) {
-                    value = readBigInteger(buf);
-                } else {
-                    value = buf.getLong();
-                }
-                break;
-            case S8:
-                value = buf.get();
-                break;
-            case S16:
-                value = buf.getShort();
-                break;
-            case S32:
-                value = buf.getInt();
-                break;
-            case S64:
-                value = buf.getLong();
-                break;
-            case BE16:
-                if (buf.order() == ByteOrder.LITTLE_ENDIAN) {
-                    value = (int) (Short.reverseBytes(buf.getShort()) & 0xFFFF);
-                } else {
-                    value = (int) (buf.getShort() & 0xFFFF);
-                }
-                break;
-            case BE32:
-                if (buf.order() == ByteOrder.LITTLE_ENDIAN) {
-                    value = (long) (Integer.reverseBytes(buf.getInt()) & 0xFFFFFFFFL);
-                } else {
-                    value = (long) (buf.getInt() & 0xFFFFFFFFL);
-                }
-                break;
-            case BE64:
-                if (fieldInfo.field.getType() == BigInteger.class) {
-                    value = readBigInteger(buf);
-                } else {
-                    if (buf.order() == ByteOrder.LITTLE_ENDIAN) {
-                        value = Long.reverseBytes(buf.getLong());
-                    } else {
-                        value = buf.getLong();
-                    }
-                }
-                break;
-            case ByteArray:
-                final byte[] array = new byte[fieldInfo.annotation.arraysize()];
-                buf.get(array);
-                value = array;
-                break;
-            default:
-                throw new IllegalArgumentException("Unknown type:" + fieldInfo.annotation.type());
-        }
-
-        // Skip the padding data for alignment if any.
-        if (fieldInfo.annotation.padding() > 0) {
-            buf.position(buf.position() + fieldInfo.annotation.padding());
-        }
-        return value;
-    }
-
-    private static FieldInfo[] getClassFieldInfo(final Class clazz) {
-        if (!isStructSubclass(clazz)) {
-            throw new IllegalArgumentException(clazz.getName() + " is not a subclass of "
-                    + Struct.class.getName());
-        }
-
-        final FieldInfo[] cachedAnnotationFields = sFieldCache.get(clazz);
-        if (cachedAnnotationFields != null) {
-            return cachedAnnotationFields;
-        }
-
-        // Since array returned from Class#getDeclaredFields doesn't guarantee the actual order
-        // of field appeared in the class, that is a problem when parsing raw data read from
-        // ByteBuffer. Store the fields appeared by the order() defined in the Field annotation.
-        final FieldInfo[] annotationFields = new FieldInfo[getAnnotationFieldCount(clazz)];
-        for (java.lang.reflect.Field field : clazz.getDeclaredFields()) {
-            if (Modifier.isStatic(field.getModifiers())) continue;
-
-            final Field annotation = field.getAnnotation(Field.class);
-            if (annotation == null) {
-                throw new IllegalArgumentException("Field " + field.getName()
-                        + " is missing the " + Field.class.getSimpleName()
-                        + " annotation");
-            }
-            if (annotation.order() < 0 || annotation.order() >= annotationFields.length) {
-                throw new IllegalArgumentException("Annotation order: " + annotation.order()
-                        + " is negative or non-consecutive");
-            }
-            if (annotationFields[annotation.order()] != null) {
-                throw new IllegalArgumentException("Duplicated annotation order: "
-                        + annotation.order());
-            }
-            annotationFields[annotation.order()] = new FieldInfo(annotation, field);
-        }
-        sFieldCache.putIfAbsent(clazz, annotationFields);
-        return annotationFields;
-    }
-
-    /**
-     * Parse raw data from ByteBuffer according to the pre-defined annotation rule and return
-     * the type-variable object which is subclass of Struct class.
-     *
-     * TODO:
-     * 1. Support subclass inheritance.
-     * 2. Introduce annotation processor to enforce the subclass naming schema.
-     */
-    public static <T> T parse(final Class<T> clazz, final ByteBuffer buf) {
-        try {
-            final FieldInfo[] foundFields = getClassFieldInfo(clazz);
-            if (hasBothMutableAndImmutableFields(foundFields)) {
-                throw new IllegalArgumentException("Class has both immutable and mutable fields");
-            }
-
-            Constructor<?> constructor = null;
-            Constructor<?> defaultConstructor = null;
-            final Constructor<?>[] constructors = clazz.getDeclaredConstructors();
-            for (Constructor cons : constructors) {
-                if (matchConstructor(cons, foundFields)) constructor = cons;
-                if (cons.getParameterTypes().length == 0) defaultConstructor = cons;
-            }
-
-            if (constructor == null && defaultConstructor == null) {
-                throw new IllegalArgumentException("Fail to find available constructor");
-            }
-            if (constructor != null) {
-                final Object[] args = new Object[foundFields.length];
-                for (int i = 0; i < args.length; i++) {
-                    args[i] = getFieldValue(buf, foundFields[i]);
-                }
-                return (T) constructor.newInstance(args);
-            }
-
-            final Object instance = defaultConstructor.newInstance();
-            for (FieldInfo fi : foundFields) {
-                fi.field.set(instance, getFieldValue(buf, fi));
-            }
-            return (T) instance;
-        } catch (IllegalAccessException
-                | InvocationTargetException
-                | InstantiationException e) {
-            throw new IllegalArgumentException("Fail to create a instance from constructor", e);
-        } catch (BufferUnderflowException e) {
-            throw new IllegalArgumentException("Fail to read raw data from ByteBuffer", e);
-        }
-    }
-}
diff --git a/staticlibs/device/com/android/net/module/util/Struct.java b/staticlibs/device/com/android/net/module/util/Struct.java
new file mode 100644
index 0000000..bc8761a
--- /dev/null
+++ b/staticlibs/device/com/android/net/module/util/Struct.java
@@ -0,0 +1,588 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.net.module.util;
+
+import android.annotation.NonNull;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Modifier;
+import java.math.BigInteger;
+import java.nio.BufferUnderflowException;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * Define a generic class that helps to parse the structured message.
+ *
+ * Example usage:
+ *
+ *    // C-style NduserOption message header definition in the kernel:
+ *    struct nduseroptmsg {
+ *        unsigned char nduseropt_family;
+ *        unsigned char nduseropt_pad1;
+ *        unsigned short nduseropt_opts_len;
+ *        int nduseropt_ifindex;
+ *        __u8 nduseropt_icmp_type;
+ *        __u8 nduseropt_icmp_code;
+ *        unsigned short nduseropt_pad2;
+ *        unsigned int nduseropt_pad3;
+ *    }
+ *
+ *    - Declare a subclass with explicit constructor or not which extends from this class to parse
+ *      NduserOption header from raw bytes array.
+ *
+ *    - Option w/ explicit constructor:
+ *      static class NduserOptHeaderMessage extends Struct {
+ *          @Field(order = 0, type = Type.U8, padding = 1)
+ *          final short family;
+ *          @Field(order = 1, type = Type.U16)
+ *          final int len;
+ *          @Field(order = 2, type = Type.S32)
+ *          final int ifindex;
+ *          @Field(order = 3, type = Type.U8)
+ *          final short type;
+ *          @Field(order = 4, type = Type.U8, padding = 6)
+ *          final short code;
+ *
+ *          NduserOptHeaderMessage(final short family, final int len, final int ifindex,
+ *                  final short type, final short code) {
+ *              this.family = family;
+ *              this.len = len;
+ *              this.ifindex = ifindex;
+ *              this.type = type;
+ *              this.code = code;
+ *          }
+ *      }
+ *
+ *      - Option w/o explicit constructor:
+ *        static class NduserOptHeaderMessage extends Struct {
+ *            @Field(order = 0, type = Type.U8, padding = 1)
+ *            short family;
+ *            @Field(order = 1, type = Type.U16)
+ *            int len;
+ *            @Field(order = 2, type = Type.S32)
+ *            int ifindex;
+ *            @Field(order = 3, type = Type.U8)
+ *            short type;
+ *            @Field(order = 4, type = Type.U8, padding = 6)
+ *            short code;
+ *        }
+ *
+ *    - Parse the target message and refer the members.
+ *      final ByteBuffer buf = ByteBuffer.wrap(RAW_BYTES_ARRAY);
+ *      buf.order(ByteOrder.nativeOrder());
+ *      final NduserOptHeaderMessage nduserHdrMsg = Struct.parse(NduserOptHeaderMessage.class, buf);
+ *      assertEquals(10, nduserHdrMsg.family);
+ */
+public class Struct {
+    public enum Type {
+        U8,        // unsigned byte,  size = 1 byte
+        U16,       // unsigned short, size = 2 bytes
+        U32,       // unsigned int,   size = 4 bytes
+        U63,       // unsigned long(MSB: 0), size = 8 bytes
+        U64,       // unsigned long,  size = 8 bytes
+        S8,        // signed byte,    size = 1 byte
+        S16,       // signed short,   size = 2 bytes
+        S32,       // signed int,     size = 4 bytes
+        S64,       // signed long,    size = 8 bytes
+        UBE16,     // unsigned short in network order, size = 2 bytes
+        UBE32,     // unsigned int in network order,   size = 4 bytes
+        UBE63,     // unsigned long(MSB: 0) in network order, size = 8 bytes
+        UBE64,     // unsigned long in network order,  size = 8 bytes
+        ByteArray, // byte array with predefined length
+    }
+
+    /**
+     * Indicate that the field marked with this annotation will automatically be managed by this
+     * class (e.g., will be parsed by #parse).
+     *
+     * order:     The placeholder associated with each field, consecutive order starting from zero.
+     * type:      The primitive data type listed in above Type enumeration.
+     * padding:   Padding bytes appear after the field for alignment.
+     * arraysize: The length of byte array.
+     *
+     * Annotation associated with field MUST have order and type properties at least, padding
+     * and arraysize properties depend on the specific usage, if these properties are absent,
+     * then default value 0 will be applied.
+     */
+    @Retention(RetentionPolicy.RUNTIME)
+    @Target(ElementType.FIELD)
+    public @interface Field {
+        int order();
+        Type type();
+        int padding() default 0;
+        int arraysize() default 0;
+    }
+
+    private static class FieldInfo {
+        @NonNull
+        public final Field annotation;
+        @NonNull
+        public final java.lang.reflect.Field field;
+
+        FieldInfo(final Field annotation, final java.lang.reflect.Field field) {
+            this.annotation = annotation;
+            this.field = field;
+        }
+    }
+    private static ConcurrentHashMap<Class, FieldInfo[]> sFieldCache = new ConcurrentHashMap();
+
+    private static void checkAnnotationType(final Field annotation, final Class fieldType) {
+        switch (annotation.type()) {
+            case U8:
+            case S16:
+                if (fieldType == Short.TYPE) return;
+                break;
+            case U16:
+            case S32:
+            case UBE16:
+                if (fieldType == Integer.TYPE) return;
+                break;
+            case U32:
+            case U63:
+            case S64:
+            case UBE32:
+            case UBE63:
+                if (fieldType == Long.TYPE) return;
+                break;
+            case U64:
+            case UBE64:
+                if (fieldType == BigInteger.class) return;
+                break;
+            case S8:
+                if (fieldType == Byte.TYPE) return;
+                break;
+            case ByteArray:
+                if (fieldType != byte[].class) break;
+                if (annotation.arraysize() <= 0) {
+                    throw new IllegalArgumentException("Invalid ByteArray size: "
+                            + annotation.arraysize());
+                }
+                return;
+            default:
+                throw new IllegalArgumentException("Unknown type" + annotation.type());
+        }
+        throw new IllegalArgumentException("Invalid primitive data type: " + fieldType
+                + " for annotation type: " + annotation.type());
+    }
+
+    private static int getFieldLength(final Field annotation) {
+        int length = 0;
+        switch (annotation.type()) {
+            case U8:
+            case S8:
+                length = 1;
+                break;
+            case U16:
+            case S16:
+            case UBE16:
+                length = 2;
+                break;
+            case U32:
+            case S32:
+            case UBE32:
+                length = 4;
+                break;
+            case U63:
+            case U64:
+            case S64:
+            case UBE63:
+            case UBE64:
+                length = 8;
+                break;
+            case ByteArray:
+                length = annotation.arraysize();
+                break;
+            default:
+                throw new IllegalArgumentException("Unknown type" + annotation.type());
+        }
+        return length + annotation.padding();
+    }
+
+    private static boolean isStructSubclass(final Class clazz) {
+        return clazz != null && Struct.class.isAssignableFrom(clazz) && Struct.class != clazz;
+    }
+
+    private static int getAnnotationFieldCount(final Class clazz) {
+        int count = 0;
+        for (java.lang.reflect.Field field : clazz.getDeclaredFields()) {
+            if (field.isAnnotationPresent(Field.class)) count++;
+        }
+        return count;
+    }
+
+    private static boolean allFieldsFinal(final FieldInfo[] fields, boolean immutable) {
+        for (FieldInfo fi : fields) {
+            if (Modifier.isFinal(fi.field.getModifiers()) != immutable) return false;
+        }
+        return true;
+    }
+
+    private static boolean hasBothMutableAndImmutableFields(final FieldInfo[] fields) {
+        return !allFieldsFinal(fields, true /* immutable */)
+                && !allFieldsFinal(fields, false /* mutable */);
+    }
+
+    private static boolean matchConstructor(final Constructor cons, final FieldInfo[] fields) {
+        final Class[] paramTypes = cons.getParameterTypes();
+        if (paramTypes.length != fields.length) return false;
+        for (int i = 0; i < paramTypes.length; i++) {
+            if (!paramTypes[i].equals(fields[i].field.getType())) return false;
+        }
+        return true;
+    }
+
+    /**
+     * Read U64/UBE64 type data from ByteBuffer and output a BigInteger instance.
+     *
+     * @param buf The byte buffer to read.
+     * @param type The annotation type.
+     *
+     * The magnitude argument of BigInteger constructor is a byte array in big-endian order.
+     * If BigInteger data is read from the byte buffer in little-endian, reverse the order of
+     * the bytes is required; if BigInteger data is read from the byte buffer in big-endian,
+     * then just keep it as-is.
+     */
+    private static BigInteger readBigInteger(final ByteBuffer buf, final Type type) {
+        final byte[] input = new byte[8];
+        boolean reverseBytes = (type == Type.U64 && buf.order() == ByteOrder.LITTLE_ENDIAN);
+        for (int i = 0; i < 8; i++) {
+            input[reverseBytes ? input.length - 1 - i : i] = buf.get();
+        }
+        return new BigInteger(1, input);
+    }
+
+    /**
+     * Get the last 8 bytes of a byte array. If there are less than 8 bytes,
+     * the first bytes are replaced with zeroes.
+     */
+    private static byte[] getLast8Bytes(final byte[] input) {
+        final byte[] tmp = new byte[8];
+        System.arraycopy(
+                input,
+                Math.max(0, input.length - 8), // srcPos: read at most last 8 bytes
+                tmp,
+                Math.max(0, 8 - input.length), // dstPos: pad output with that many zeroes
+                Math.min(8, input.length));    // length
+        return tmp;
+    }
+
+    /**
+     * Convert U64/UBE64 type data interpreted by BigInteger class to bytes array, output are
+     * always 8 bytes.
+     *
+     * @param bigInteger The number to convert.
+     * @param order Indicate ByteBuffer is read as little-endian or big-endian.
+     * @param type The annotation U64 type.
+     *
+     * BigInteger#toByteArray returns a byte array containing the 2's complement representation
+     * of this BigInteger, in big-endian. If annotation type is U64 and ByteBuffer is read as
+     * little-endian, then reversing the order of the bytes is required.
+     */
+    private static byte[] bigIntegerToU64Bytes(final BigInteger bigInteger, final ByteOrder order,
+            final Type type) {
+        final byte[] bigIntegerBytes = bigInteger.toByteArray();
+        final byte[] output = getLast8Bytes(bigIntegerBytes);
+
+        if (type == Type.U64 && order == ByteOrder.LITTLE_ENDIAN) {
+            for (int i = 0; i < 4; i++) {
+                byte tmp = output[i];
+                output[i] = output[7 - i];
+                output[7 - i] = tmp;
+            }
+        }
+        return output;
+    }
+
+    private static Object getFieldValue(final ByteBuffer buf, final FieldInfo fieldInfo)
+            throws BufferUnderflowException {
+        final Object value;
+        checkAnnotationType(fieldInfo.annotation, fieldInfo.field.getType());
+        switch (fieldInfo.annotation.type()) {
+            case U8:
+                value = (short) (buf.get() & 0xFF);
+                break;
+            case U16:
+                value = (int) (buf.getShort() & 0xFFFF);
+                break;
+            case U32:
+                value = (long) (buf.getInt() & 0xFFFFFFFFL);
+                break;
+            case U64:
+                value = readBigInteger(buf, Type.U64);
+                break;
+            case S8:
+                value = buf.get();
+                break;
+            case S16:
+                value = buf.getShort();
+                break;
+            case S32:
+                value = buf.getInt();
+                break;
+            case U63:
+            case S64:
+                value = buf.getLong();
+                break;
+            case UBE16:
+                if (buf.order() == ByteOrder.LITTLE_ENDIAN) {
+                    value = (int) (Short.reverseBytes(buf.getShort()) & 0xFFFF);
+                } else {
+                    value = (int) (buf.getShort() & 0xFFFF);
+                }
+                break;
+            case UBE32:
+                if (buf.order() == ByteOrder.LITTLE_ENDIAN) {
+                    value = (long) (Integer.reverseBytes(buf.getInt()) & 0xFFFFFFFFL);
+                } else {
+                    value = (long) (buf.getInt() & 0xFFFFFFFFL);
+                }
+                break;
+            case UBE63:
+                if (buf.order() == ByteOrder.LITTLE_ENDIAN) {
+                    value = Long.reverseBytes(buf.getLong());
+                } else {
+                    value = buf.getLong();
+                }
+                break;
+            case UBE64:
+                value = readBigInteger(buf, Type.UBE64);
+                break;
+            case ByteArray:
+                final byte[] array = new byte[fieldInfo.annotation.arraysize()];
+                buf.get(array);
+                value = array;
+                break;
+            default:
+                throw new IllegalArgumentException("Unknown type:" + fieldInfo.annotation.type());
+        }
+
+        // Skip the padding data for alignment if any.
+        if (fieldInfo.annotation.padding() > 0) {
+            buf.position(buf.position() + fieldInfo.annotation.padding());
+        }
+        return value;
+    }
+
+    private static void putFieldValue(final ByteBuffer output, final FieldInfo fieldInfo,
+            final Object value) throws BufferUnderflowException {
+        switch (fieldInfo.annotation.type()) {
+            case U8:
+                output.put((byte) (((short) value) & 0xFF));
+                break;
+            case U16:
+                output.putShort((short) (((int) value) & 0xFFFF));
+                break;
+            case U32:
+                output.putInt((int) (((long) value) & 0xFFFFFFFFL));
+                break;
+            case U63:
+                output.putLong((long) value);
+                break;
+            case U64:
+                output.put(bigIntegerToU64Bytes((BigInteger) value, output.order(), Type.U64));
+                break;
+            case S8:
+                output.put((byte) value);
+                break;
+            case S16:
+                output.putShort((short) value);
+                break;
+            case S32:
+                output.putInt((int) value);
+                break;
+            case S64:
+                output.putLong((long) value);
+                break;
+            case UBE16:
+                if (output.order() == ByteOrder.LITTLE_ENDIAN) {
+                    output.putShort(Short.reverseBytes((short) (((int) value) & 0xFFFF)));
+                } else {
+                    output.putShort((short) (((int) value) & 0xFFFF));
+                }
+                break;
+            case UBE32:
+                if (output.order() == ByteOrder.LITTLE_ENDIAN) {
+                    output.putInt(Integer.reverseBytes(
+                            (int) (((long) value) & 0xFFFFFFFFL)));
+                } else {
+                    output.putInt((int) (((long) value) & 0xFFFFFFFFL));
+                }
+                break;
+            case UBE63:
+                if (output.order() == ByteOrder.LITTLE_ENDIAN) {
+                    output.putLong(Long.reverseBytes((long) value));
+                } else {
+                    output.putLong((long) value);
+                }
+                break;
+            case UBE64:
+                output.put(bigIntegerToU64Bytes((BigInteger) value, output.order(), Type.UBE64));
+                break;
+            case ByteArray:
+                output.put((byte[]) value);
+                break;
+            default:
+                throw new IllegalArgumentException("Unknown type:" + fieldInfo.annotation.type());
+        }
+
+        // padding zero after field value for alignment.
+        for (int i = 0; i < fieldInfo.annotation.padding(); i++) output.put((byte) 0);
+    }
+
+    private static FieldInfo[] getClassFieldInfo(final Class clazz) {
+        if (!isStructSubclass(clazz)) {
+            throw new IllegalArgumentException(clazz.getName() + " is not a subclass of "
+                    + Struct.class.getName());
+        }
+
+        final FieldInfo[] cachedAnnotationFields = sFieldCache.get(clazz);
+        if (cachedAnnotationFields != null) {
+            return cachedAnnotationFields;
+        }
+
+        // Since array returned from Class#getDeclaredFields doesn't guarantee the actual order
+        // of field appeared in the class, that is a problem when parsing raw data read from
+        // ByteBuffer. Store the fields appeared by the order() defined in the Field annotation.
+        final FieldInfo[] annotationFields = new FieldInfo[getAnnotationFieldCount(clazz)];
+        for (java.lang.reflect.Field field : clazz.getDeclaredFields()) {
+            if (Modifier.isStatic(field.getModifiers())) continue;
+
+            final Field annotation = field.getAnnotation(Field.class);
+            if (annotation == null) {
+                throw new IllegalArgumentException("Field " + field.getName()
+                        + " is missing the " + Field.class.getSimpleName()
+                        + " annotation");
+            }
+            if (annotation.order() < 0 || annotation.order() >= annotationFields.length) {
+                throw new IllegalArgumentException("Annotation order: " + annotation.order()
+                        + " is negative or non-consecutive");
+            }
+            if (annotationFields[annotation.order()] != null) {
+                throw new IllegalArgumentException("Duplicated annotation order: "
+                        + annotation.order());
+            }
+            annotationFields[annotation.order()] = new FieldInfo(annotation, field);
+        }
+        sFieldCache.putIfAbsent(clazz, annotationFields);
+        return annotationFields;
+    }
+
+    /**
+     * Parse raw data from ByteBuffer according to the pre-defined annotation rule and return
+     * the type-variable object which is subclass of Struct class.
+     *
+     * TODO:
+     * 1. Support subclass inheritance.
+     * 2. Introduce annotation processor to enforce the subclass naming schema.
+     */
+    public static <T> T parse(final Class<T> clazz, final ByteBuffer buf) {
+        try {
+            final FieldInfo[] foundFields = getClassFieldInfo(clazz);
+            if (hasBothMutableAndImmutableFields(foundFields)) {
+                throw new IllegalArgumentException("Class has both final and non-final fields");
+            }
+
+            Constructor<?> constructor = null;
+            Constructor<?> defaultConstructor = null;
+            final Constructor<?>[] constructors = clazz.getDeclaredConstructors();
+            for (Constructor cons : constructors) {
+                if (matchConstructor(cons, foundFields)) constructor = cons;
+                if (cons.getParameterTypes().length == 0) defaultConstructor = cons;
+            }
+
+            if (constructor == null && defaultConstructor == null) {
+                throw new IllegalArgumentException("Fail to find available constructor");
+            }
+            if (constructor != null) {
+                final Object[] args = new Object[foundFields.length];
+                for (int i = 0; i < args.length; i++) {
+                    args[i] = getFieldValue(buf, foundFields[i]);
+                }
+                return (T) constructor.newInstance(args);
+            }
+
+            final Object instance = defaultConstructor.newInstance();
+            for (FieldInfo fi : foundFields) {
+                fi.field.set(instance, getFieldValue(buf, fi));
+            }
+            return (T) instance;
+        } catch (IllegalAccessException | InvocationTargetException | InstantiationException e) {
+            throw new IllegalArgumentException("Fail to create a instance from constructor", e);
+        } catch (BufferUnderflowException e) {
+            throw new IllegalArgumentException("Fail to read raw data from ByteBuffer", e);
+        }
+    }
+
+    private static int getSizeInternal(final FieldInfo[] fieldInfos) {
+        int size = 0;
+        for (FieldInfo fi : fieldInfos) {
+            size += getFieldLength(fi.annotation);
+        }
+        return size;
+    }
+
+    private void writeToByteBufferInternal(final ByteBuffer output, final FieldInfo[] fieldInfos) {
+        for (FieldInfo fi : fieldInfos) {
+            try {
+                putFieldValue(output, fi, fi.field.get(this));
+            } catch (IllegalAccessException e) {
+                throw new IllegalArgumentException("Fail to get the field value from instance", e);
+            } catch (BufferUnderflowException e) {
+                throw new IllegalArgumentException("Fail to fill raw data to ByteBuffer", e);
+            }
+        }
+    }
+
+    /**
+     * Get the size of Struct subclass object.
+     */
+    public static <T extends Struct> int getSize(final Class<T> clazz) {
+        final FieldInfo[] fieldInfos = getClassFieldInfo(clazz);
+        return getSizeInternal(fieldInfos);
+    }
+
+    /**
+     * Convert the parsed Struct subclass object to ByteBuffer.
+     *
+     * @param output ByteBuffer passed-in from the caller.
+     */
+    public final void writeToByteBuffer(final ByteBuffer output) {
+        final FieldInfo[] fieldInfos = getClassFieldInfo(this.getClass());
+        writeToByteBufferInternal(output, fieldInfos);
+    }
+
+    /**
+     * Convert the parsed Struct subclass object to byte array.
+     *
+     * @param order indicate ByteBuffer is outputted as little-endian or big-endian.
+     */
+    public final byte[] writeToBytes(final ByteOrder order) {
+        final FieldInfo[] fieldInfos = getClassFieldInfo(this.getClass());
+        final byte[] output = new byte[getSizeInternal(fieldInfos)];
+        final ByteBuffer buffer = ByteBuffer.wrap(output);
+        buffer.order(order);
+        writeToByteBufferInternal(buffer, fieldInfos);
+        return output;
+    }
+}
diff --git a/staticlibs/tests/unit/src/android/net/util/StructTest.java b/staticlibs/tests/unit/src/com/android/net/module/util/StructTest.java
similarity index 63%
rename from staticlibs/tests/unit/src/android/net/util/StructTest.java
rename to staticlibs/tests/unit/src/com/android/net/module/util/StructTest.java
index 5ca278a..1b03e75 100644
--- a/staticlibs/tests/unit/src/android/net/util/StructTest.java
+++ b/staticlibs/tests/unit/src/com/android/net/module/util/StructTest.java
@@ -14,27 +14,29 @@
  * limitations under the License.
  */
 
-package android.net.util;
+package com.android.net.module.util;
 
 import static com.android.testutils.MiscAsserts.assertThrows;
 
+import static org.junit.Assert.assertArrayEquals;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertTrue;
 
 import android.net.IpPrefix;
-import android.net.util.Struct.Field;
-import android.net.util.Struct.Type;
 
 import androidx.test.filters.SmallTest;
 import androidx.test.runner.AndroidJUnit4;
 
 import com.android.internal.util.HexDump;
+import com.android.net.module.util.Struct.Field;
+import com.android.net.module.util.Struct.Type;
 
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
 import java.math.BigInteger;
 import java.net.InetAddress;
+import java.nio.BufferOverflowException;
 import java.nio.ByteBuffer;
 import java.nio.ByteOrder;
 import java.util.Arrays;
@@ -46,8 +48,8 @@
     // IPv6, 0 bytes of options, ifindex 15715755: 0x00efcdab, type 134 (RA), code 0, padding.
     private static final String HDR_EMPTY = "0a00" + "0000" + "abcdef00" + "8600000000000000";
 
-    // BE16: 0xfeff, BE32: 0xfeffffff, BE64: 0xfffffffffffffffe, 0x7effffffffffffff
-    private static final String NETWORK_ORDER_MSG = "feff" + "feffffff" + "fffffffffffffffe"
+    // UBE16: 0xfeff, UBE32: 0xfeffffff, UBE64: 0xfeffffffffffffff, UBE63: 0x7effffffffffffff
+    private static final String NETWORK_ORDER_MSG = "feff" + "feffffff" + "feffffffffffffff"
             + "7effffffffffffff";
 
     // S8: 0x7f, S16: 0x7fff, S32: 0x7fffffff, S64: 0x7fffffffffffffff
@@ -65,9 +67,10 @@
     // PREF64 option, 2001:db8:3:4:5:6::/96, lifetime: 10064
     private static final String OPT_PREF64 = "2750" + "20010db80003000400050006";
 
-    private <T> T doParsingMessageTest(final String hexString, Class<T> clazz) {
+    private <T> T doParsingMessageTest(final String hexString, final Class<T> clazz,
+            final ByteOrder order) {
         final ByteBuffer buf = toByteBuffer(hexString);
-        buf.order(ByteOrder.LITTLE_ENDIAN);
+        buf.order(order);
         return Struct.parse(clazz, buf);
     }
 
@@ -102,12 +105,16 @@
         assertEquals(15715755, msg.mIfindex);
         assertEquals(134, msg.mIcmpType);
         assertEquals(0, msg.mIcmpCode);
+
+        assertEquals(16, Struct.getSize(HeaderMsgWithConstructor.class));
+        assertArrayEquals(toByteBuffer(HDR_EMPTY).array(),
+                msg.writeToBytes(ByteOrder.LITTLE_ENDIAN));
     }
 
     @Test
     public void testClassWithExplicitConstructor() {
         final HeaderMsgWithConstructor msg = doParsingMessageTest(HDR_EMPTY,
-                HeaderMsgWithConstructor.class);
+                HeaderMsgWithConstructor.class, ByteOrder.LITTLE_ENDIAN);
         verifyHeaderParsing(msg);
     }
 
@@ -128,14 +135,18 @@
     }
 
     @Test
-    public void testClassWithDefaultConstrcutor() {
+    public void testClassWithDefaultConstructor() {
         final HeaderMsgWithoutConstructor msg = doParsingMessageTest(HDR_EMPTY,
-                HeaderMsgWithoutConstructor.class);
+                HeaderMsgWithoutConstructor.class, ByteOrder.LITTLE_ENDIAN);
         assertEquals(10, msg.mFamily);
         assertEquals(0, msg.mLen);
         assertEquals(15715755, msg.mIfindex);
         assertEquals(134, msg.mIcmpType);
         assertEquals(0, msg.mIcmpCode);
+
+        assertEquals(16, Struct.getSize(HeaderMsgWithoutConstructor.class));
+        assertArrayEquals(toByteBuffer(HDR_EMPTY).array(),
+                msg.writeToBytes(ByteOrder.LITTLE_ENDIAN));
     }
 
     static class HeaderMessage {
@@ -177,32 +188,36 @@
     }
 
     static class NetworkOrderMessage extends Struct {
-        @Field(order = 0, type = Type.BE16)
-        final int mBE16;
-        @Field(order = 1, type = Type.BE32)
-        final long mBE32;
-        @Field(order = 2, type = Type.BE64)
-        final BigInteger mBE64;
-        @Field(order = 3, type = Type.BE64)
-        final long mBE63;
+        @Field(order = 0, type = Type.UBE16)
+        final int mUBE16;
+        @Field(order = 1, type = Type.UBE32)
+        final long mUBE32;
+        @Field(order = 2, type = Type.UBE64)
+        final BigInteger mUBE64;
+        @Field(order = 3, type = Type.UBE63)
+        final long mUBE63;
 
         NetworkOrderMessage(final int be16, final long be32, final BigInteger be64,
                 final long be63) {
-            mBE16 = be16;
-            mBE32 = be32;
-            mBE64 = be64;
-            mBE63 = be63;
+            mUBE16 = be16;
+            mUBE32 = be32;
+            mUBE64 = be64;
+            mUBE63 = be63;
         }
     }
 
     @Test
     public void testNetworkOrder() {
         final NetworkOrderMessage msg = doParsingMessageTest(NETWORK_ORDER_MSG,
-                NetworkOrderMessage.class);
-        assertEquals(65279, msg.mBE16);
-        assertEquals(4278190079L, msg.mBE32);
-        assertEquals(new BigInteger("18374686479671623679"), msg.mBE64);
-        assertEquals(9151314442816847871L, msg.mBE63);
+                NetworkOrderMessage.class, ByteOrder.LITTLE_ENDIAN);
+        assertEquals(65279, msg.mUBE16);
+        assertEquals(4278190079L, msg.mUBE32);
+        assertEquals(new BigInteger("18374686479671623679"), msg.mUBE64);
+        assertEquals(9151314442816847871L, msg.mUBE63);
+
+        assertEquals(22, Struct.getSize(NetworkOrderMessage.class));
+        assertArrayEquals(toByteBuffer(NETWORK_ORDER_MSG).array(),
+                msg.writeToBytes(ByteOrder.LITTLE_ENDIAN));
     }
 
     static class UnsignedDataMessage extends Struct {
@@ -213,11 +228,11 @@
         @Field(order = 2, type = Type.U32)
         final long mU32;
         @Field(order = 3, type = Type.U64)
-        final BigInteger mU64; // represent U64 with BigInteger.
-        @Field(order = 4, type = Type.U64)
-        final long mU63;  // represent U63 with long primitive.
-        @Field(order = 5, type = Type.U64)
-        final long mLU64; // represent U64 with long primitive.
+        final BigInteger mU64;
+        @Field(order = 4, type = Type.U63)
+        final long mU63;
+        @Field(order = 5, type = Type.U63)
+        final long mLU64; // represent U64 data with U63 type
 
         UnsignedDataMessage(final short u8, final int u16, final long u32, final BigInteger u64,
                 final long u63, final long lu64) {
@@ -233,13 +248,57 @@
     @Test
     public void testUnsignedData() {
         final UnsignedDataMessage msg = doParsingMessageTest(UNSIGNED_DATA,
-                UnsignedDataMessage.class);
+                UnsignedDataMessage.class, ByteOrder.LITTLE_ENDIAN);
         assertEquals(255, msg.mU8);
         assertEquals(65535, msg.mU16);
         assertEquals(4294967295L, msg.mU32);
         assertEquals(new BigInteger("18446744073709551615"), msg.mU64);
         assertEquals(9223372036854775807L, msg.mU63);
         assertEquals(-1L, msg.mLU64);
+
+        assertEquals(31, Struct.getSize(UnsignedDataMessage.class));
+        assertArrayEquals(toByteBuffer(UNSIGNED_DATA).array(),
+                msg.writeToBytes(ByteOrder.LITTLE_ENDIAN));
+    }
+
+    static class U64DataMessage extends Struct {
+        @Field(order = 0, type = Type.U64) long mU64;
+    }
+
+    @Test
+    public void testInvalidType_U64WithLongPrimitive() {
+        assertThrows(IllegalArgumentException.class,
+                () -> Struct.parse(U64DataMessage.class, toByteBuffer("ffffffffffffffff")));
+    }
+
+    // BigInteger U64: 0x0000000000001234, BigInteger UBE64: 0x0000000000001234, BigInteger U64: 0
+    private static final String SMALL_VALUE_BIGINTEGER = "3412000000000000" + "0000000000001234"
+            + "0000000000000000";
+
+    static class SmallValueBigInteger extends Struct {
+        @Field(order = 0, type = Type.U64) final BigInteger mSmallValue;
+        @Field(order = 1, type = Type.UBE64) final BigInteger mBSmallValue;
+        @Field(order = 2, type = Type.U64) final BigInteger mZero;
+
+        SmallValueBigInteger(final BigInteger smallValue, final BigInteger bSmallValue,
+                final BigInteger zero) {
+            mSmallValue = smallValue;
+            mBSmallValue = bSmallValue;
+            mZero = zero;
+        }
+    }
+
+    @Test
+    public void testBigIntegerSmallValueOrZero() {
+        final SmallValueBigInteger msg = doParsingMessageTest(SMALL_VALUE_BIGINTEGER,
+                SmallValueBigInteger.class, ByteOrder.LITTLE_ENDIAN);
+        assertEquals(new BigInteger("4660"), msg.mSmallValue);
+        assertEquals(new BigInteger("4660"), msg.mBSmallValue);
+        assertEquals(new BigInteger("0"), msg.mZero);
+
+        assertEquals(24, Struct.getSize(SmallValueBigInteger.class));
+        assertArrayEquals(toByteBuffer(SMALL_VALUE_BIGINTEGER).array(),
+                msg.writeToBytes(ByteOrder.LITTLE_ENDIAN));
     }
 
     static class SignedDataMessage extends Struct {
@@ -262,21 +321,30 @@
 
     @Test
     public void testSignedPositiveData() {
-        final SignedDataMessage msg = doParsingMessageTest(SIGNED_DATA, SignedDataMessage.class);
+        final SignedDataMessage msg = doParsingMessageTest(SIGNED_DATA, SignedDataMessage.class,
+                ByteOrder.LITTLE_ENDIAN);
         assertEquals(127, msg.mS8);
         assertEquals(32767, msg.mS16);
         assertEquals(2147483647, msg.mS32);
         assertEquals(9223372036854775807L, msg.mS64);
+
+        assertEquals(15, Struct.getSize(SignedDataMessage.class));
+        assertArrayEquals(toByteBuffer(SIGNED_DATA).array(),
+                msg.writeToBytes(ByteOrder.LITTLE_ENDIAN));
     }
 
     @Test
     public void testSignedNegativeData() {
         final SignedDataMessage msg = doParsingMessageTest(SIGNED_NEGATIVE_DATA,
-                SignedDataMessage.class);
+                SignedDataMessage.class, ByteOrder.LITTLE_ENDIAN);
         assertEquals(-127, msg.mS8);
         assertEquals(-32767, msg.mS16);
         assertEquals(-2147483647, msg.mS32);
         assertEquals(-9223372036854775807L, msg.mS64);
+
+        assertEquals(15, Struct.getSize(SignedDataMessage.class));
+        assertArrayEquals(toByteBuffer(SIGNED_NEGATIVE_DATA).array(),
+                msg.writeToBytes(ByteOrder.LITTLE_ENDIAN));
     }
 
     static class HeaderMessageWithDuplicateOrder extends Struct {
@@ -360,7 +428,7 @@
     }
 
     static class PrefixMessage extends Struct {
-        @Field(order = 0, type = Type.BE16)
+        @Field(order = 0, type = Type.UBE16)
         final int mLifetime;
         @Field(order = 1, type = Type.ByteArray, arraysize = 12)
         final byte[] mPrefix;
@@ -379,11 +447,35 @@
         final IpPrefix prefix = new IpPrefix(addr, 96);
         assertEquals(10064, msg.mLifetime);
         assertTrue(prefix.equals(new IpPrefix("2001:db8:3:4:5:6::/96")));
+
+        assertEquals(14, Struct.getSize(PrefixMessage.class));
+        assertArrayEquals(toByteBuffer(OPT_PREF64).array(),
+                msg.writeToBytes(ByteOrder.LITTLE_ENDIAN));
+    }
+
+    static class PrefixMessageWithZeroLengthArray extends Struct {
+        @Field(order = 0, type = Type.UBE16)
+        final int mLifetime;
+        @Field(order = 1, type = Type.ByteArray, arraysize = 0)
+        final byte[] mPrefix;
+
+        PrefixMessageWithZeroLengthArray(final int lifetime, final byte[] prefix) {
+            mLifetime = lifetime;
+            mPrefix = prefix;
+        }
+    }
+
+    @Test
+    public void testInvalidClass_ZeroLengthByteArray() {
+        final ByteBuffer buf = toByteBuffer(OPT_PREF64);
+        assertThrows(IllegalArgumentException.class,
+                () -> Struct.parse(PrefixMessageWithZeroLengthArray.class, buf));
     }
 
     @Test
     public void testPrefixArrayField() throws Exception {
-        final PrefixMessage msg = doParsingMessageTest(OPT_PREF64, PrefixMessage.class);
+        final PrefixMessage msg = doParsingMessageTest(OPT_PREF64, PrefixMessage.class,
+                ByteOrder.LITTLE_ENDIAN);
         verifyPrefixByteArrayParsing(msg);
     }
 
@@ -441,12 +533,16 @@
     @Test
     public void testStaticConstantField() {
         final HeaderMsgWithStaticConstant msg = doParsingMessageTest(HDR_EMPTY,
-                HeaderMsgWithStaticConstant.class);
+                HeaderMsgWithStaticConstant.class, ByteOrder.LITTLE_ENDIAN);
         assertEquals(10, msg.mFamily);
         assertEquals(0, msg.mLen);
         assertEquals(15715755, msg.mIfindex);
         assertEquals(134, msg.mIcmpType);
         assertEquals(0, msg.mIcmpCode);
+
+        assertEquals(16, Struct.getSize(HeaderMsgWithStaticConstant.class));
+        assertArrayEquals(toByteBuffer(HDR_EMPTY).array(),
+                msg.writeToBytes(ByteOrder.LITTLE_ENDIAN));
     }
 
     static class MismatchedConstructor extends Struct {
@@ -481,23 +577,89 @@
     @Test
     public void testClassWithTwoConstructors() {
         final ClassWithTwoConstructors msg = doParsingMessageTest("1234" + "5678",
-                ClassWithTwoConstructors.class);
+                ClassWithTwoConstructors.class, ByteOrder.LITTLE_ENDIAN);
         assertEquals(13330 /* 0x3412 */, msg.mInt1);
         assertEquals(30806 /* 0x7856 */, msg.mInt2);
+
+        assertEquals(4, Struct.getSize(ClassWithTwoConstructors.class));
+        assertArrayEquals(toByteBuffer("1234" + "5678").array(),
+                msg.writeToBytes(ByteOrder.LITTLE_ENDIAN));
+    }
+
+    @Test
+    public void testInvalidOutputByteBuffer_ZeroCapacity() {
+        final ByteBuffer output = ByteBuffer.allocate(0);
+        output.order(ByteOrder.LITTLE_ENDIAN);
+        final HeaderMsgWithConstructor msg = doParsingMessageTest(HDR_EMPTY,
+                HeaderMsgWithConstructor.class, ByteOrder.LITTLE_ENDIAN);
+        assertThrows(BufferOverflowException.class, () -> msg.writeToByteBuffer(output));
+    }
+
+    @Test
+    public void testConsecutiveWrites() {
+        final HeaderMsgWithConstructor msg1 = doParsingMessageTest(HDR_EMPTY,
+                HeaderMsgWithConstructor.class, ByteOrder.LITTLE_ENDIAN);
+        final PrefixMessage msg2 = doParsingMessageTest(OPT_PREF64, PrefixMessage.class,
+                ByteOrder.LITTLE_ENDIAN);
+
+        int size = Struct.getSize(HeaderMsgWithConstructor.class)
+                + Struct.getSize(PrefixMessage.class);
+        final ByteBuffer output = ByteBuffer.allocate(size);
+        output.order(ByteOrder.LITTLE_ENDIAN);
+
+        msg1.writeToByteBuffer(output);
+        msg2.writeToByteBuffer(output);
+        output.flip();
+
+        final ByteBuffer concat = ByteBuffer.allocate(size).put(toByteBuffer(HDR_EMPTY))
+                .put(toByteBuffer(OPT_PREF64));
+        assertArrayEquals(output.array(), concat.array());
     }
 
     @Test
     public void testClassesParsedFromCache() throws Exception {
         for (int i = 0; i < 100; i++) {
-            final HeaderMsgWithConstructor msg1 =
-                    doParsingMessageTest(HDR_EMPTY, HeaderMsgWithConstructor.class);
+            final HeaderMsgWithConstructor msg1 = doParsingMessageTest(HDR_EMPTY,
+                    HeaderMsgWithConstructor.class, ByteOrder.LITTLE_ENDIAN);
             verifyHeaderParsing(msg1);
 
-            final PrefixMessage msg2 = doParsingMessageTest(OPT_PREF64, PrefixMessage.class);
+            final PrefixMessage msg2 = doParsingMessageTest(OPT_PREF64, PrefixMessage.class,
+                    ByteOrder.LITTLE_ENDIAN);
             verifyPrefixByteArrayParsing(msg2);
         }
     }
 
+    static class BigEndianDataMessage extends Struct {
+        @Field(order = 0, type = Type.S32) int mInt1;
+        @Field(order = 1, type = Type.S32) int mInt2;
+        @Field(order = 2, type = Type.UBE16) int mInt3;
+        @Field(order = 3, type = Type.U16) int mInt4;
+        @Field(order = 4, type = Type.U64) BigInteger mBigInteger1;
+        @Field(order = 5, type = Type.UBE64) BigInteger mBigInteger2;
+        @Field(order = 6, type = Type.S64) long mLong;
+    }
+
+    private static final String BIG_ENDIAN_DATA = "00000001" + "fffffffe" + "fffe" + "fffe"
+            + "ff00004500002301" + "ff00004500002301" + "ff00004500002301";
+
+    @Test
+    public void testBigEndianByteBuffer() {
+        final BigEndianDataMessage msg = doParsingMessageTest(BIG_ENDIAN_DATA,
+                BigEndianDataMessage.class, ByteOrder.BIG_ENDIAN);
+
+        assertEquals(1, msg.mInt1);
+        assertEquals(-2, msg.mInt2);
+        assertEquals(65534, msg.mInt3);
+        assertEquals(65534, msg.mInt4);
+        assertEquals(new BigInteger("18374686776024376065"), msg.mBigInteger1);
+        assertEquals(new BigInteger("18374686776024376065"), msg.mBigInteger2);
+        assertEquals(0xff00004500002301L, msg.mLong);
+
+        assertEquals(36, Struct.getSize(BigEndianDataMessage.class));
+        assertArrayEquals(toByteBuffer(BIG_ENDIAN_DATA).array(),
+                msg.writeToBytes(ByteOrder.BIG_ENDIAN));
+    }
+
     private ByteBuffer toByteBuffer(final String hexString) {
         return ByteBuffer.wrap(HexDump.hexStringToByteArray(hexString));
     }
