class WillDataValueType extends BasicDataType<Will> {

        private final StringDataType stringDataType = new StringDataType();
        private final WillOptionsDataValueType willOptionsDataType = new WillOptionsDataValueType();

        @Override
        public int getMemory(Will will) {<FILL_FUNCTION_BODY>}

        @Override
        public void write(WriteBuffer buff, Will will) {
            stringDataType.write(buff, will.topic);
            buff.putInt(will.payload.length);
            buff.put(will.payload);

            // MSB retained, LSB QoS
            byte retained = will.retained ? (byte) 0x10 : 0x00;
            byte qos = (byte) (will.qos.value() & 0x0F);
            buff.put((byte) (retained & qos));
            buff.putInt(will.delayInterval);
            buff.putLong(will.expireAt().map(Instant::toEpochMilli).orElse(UNDEFINED_INSTANT));
            if (will.properties.notEmpty()) {
                willOptionsDataType.write(buff, will.properties);
            }
        }

        @Override
        public Will read(ByteBuffer buff) {
            final String topic = stringDataType.read(buff);
            final int payloadLength = buff.getInt();
            final byte[] payload = new byte[payloadLength];
            buff.get(payload);
            final byte rawFlags = buff.get();
            // MSB retained, LSB QoS
            final byte qos = (byte) (rawFlags & 0x0F);
            final boolean retained = ((rawFlags >> 4) & 0x0F) > 0;
            final int willDelayInterval = buff.getInt();
            Will will = new Will(topic, payload, MqttQoS.valueOf(qos), retained, willDelayInterval);

            final long expiresAt = buff.getLong();
            if (expiresAt != UNDEFINED_INSTANT) {
                will = new Will(will, Instant.ofEpochMilli(expiresAt));
            }

            final WillOptions options = willOptionsDataType.read(buff);
            if (options != null && options.notEmpty()) {
                will = new Will(will, options);
            }

            return will;
        }

        @Override
        public Will[] createStorage(int i) {
            return new Will[i];
        }
    }

            return stringDataType.getMemory(will.topic) +
                4 + /* payload length */
                will.payload.length +
                1 /* retained + qos */;
        
<no_super_class>