You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@isis.apache.org by da...@apache.org on 2012/12/05 00:41:08 UTC

[13/52] [partial] ISIS-188: consolidating isis-core

http://git-wip-us.apache.org/repos/asf/isis/blob/e4735c72/framework/core/metamodel/src/main/java/org/apache/isis/core/commons/encoding/FieldType.java
----------------------------------------------------------------------
diff --git a/framework/core/metamodel/src/main/java/org/apache/isis/core/commons/encoding/FieldType.java b/framework/core/metamodel/src/main/java/org/apache/isis/core/commons/encoding/FieldType.java
new file mode 100644
index 0000000..da00cb9
--- /dev/null
+++ b/framework/core/metamodel/src/main/java/org/apache/isis/core/commons/encoding/FieldType.java
@@ -0,0 +1,1360 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.isis.core.commons.encoding;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.Serializable;
+import java.lang.reflect.Array;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.log4j.Logger;
+
+/**
+ * Typesafe writing and reading of fields, providing some level of integrity
+ * checking of encoded messages.
+ * 
+ * <p>
+ * The {@link #write(DataOutputExtended, Object)} writes out field type and then
+ * the data for that field type. The field type is represented by this
+ * enumberation, with the {@link FieldType#getIdx() index} being what is written
+ * to the stream (hence of type <tt>byte</tt> to keep small).
+ * 
+ * <p>
+ * Conversely, the {@link #read(DataInputExtended)} reads the field type and
+ * then the data for that field type.
+ */
+public abstract class FieldType<T> {
+
+    private static Logger LOG = Logger.getLogger(FieldType.class);
+
+    private static String LOG_INDENT = ". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ";
+    private static final int NULL_BIT = 64; // 2 to the 6
+
+    private static Map<Byte, FieldType<?>> cache = new HashMap<Byte, FieldType<?>>();
+    private static int next = 0;
+
+    static enum Indenting {
+        INDENT_ONLY, INDENT_AND_OUTDENT;
+    }
+
+    public static FieldType<Boolean> BOOLEAN = new FieldType<Boolean>((byte) next++, Boolean.class, Indenting.INDENT_ONLY) {
+        @Override
+        protected void doWrite(final DataOutputExtended output, final Boolean value) throws IOException {
+            try {
+                if (LOG.isDebugEnabled()) {
+                    log(this, new StringBuilder().append(value));
+                }
+                final DataOutputStream outputStream = output.getDataOutputStream();
+                outputStream.writeBoolean(value);
+            } finally {
+                if (LOG.isDebugEnabled()) {
+                    unlog(this);
+                }
+            }
+        }
+
+        @Override
+        protected Boolean doRead(final DataInputExtended input) throws IOException {
+            try {
+                final DataInputStream inputStream = input.getDataInputStream();
+                final boolean value = inputStream.readBoolean();
+                if (LOG.isDebugEnabled()) {
+                    log(this, new StringBuilder().append(value));
+                }
+                return value;
+            } finally {
+                if (LOG.isDebugEnabled()) {
+                    unlog(this);
+                }
+            }
+        }
+    };
+
+    public static FieldType<boolean[]> BOOLEAN_ARRAY = new FieldType<boolean[]>((byte) next++, boolean[].class, Indenting.INDENT_AND_OUTDENT) {
+        @Override
+        protected void doWrite(final DataOutputExtended output, final boolean[] values) throws IOException {
+            try {
+                final StringBuilder buf = new StringBuilder();
+                final DataOutputStream outputStream = output.getDataOutputStream();
+                outputStream.writeInt(values.length);
+                if (LOG.isDebugEnabled()) {
+                    buf.append("length: ").append(values.length);
+                }
+                for (int i = 0; i < values.length; i++) {
+                    outputStream.writeBoolean(values[i]);
+                    if (LOG.isDebugEnabled()) {
+                        buf.append(i == 0 ? ": " : ", ");
+                        buf.append(values[i]);
+                    }
+                }
+                if (LOG.isDebugEnabled()) {
+                    log(this, buf);
+                }
+            } finally {
+                if (LOG.isDebugEnabled()) {
+                    unlog(this);
+                }
+            }
+        }
+
+        @Override
+        protected boolean[] doRead(final DataInputExtended input) throws IOException {
+            try {
+                final StringBuilder buf = new StringBuilder();
+                final DataInputStream inputStream = input.getDataInputStream();
+                final int length = inputStream.readInt();
+                if (LOG.isDebugEnabled()) {
+                    buf.append("length: ").append(length);
+                }
+                final boolean[] values = new boolean[length];
+                for (int i = 0; i < values.length; i++) {
+                    values[i] = inputStream.readBoolean();
+                    if (LOG.isDebugEnabled()) {
+                        buf.append(i == 0 ? ": " : ", ");
+                        buf.append(values[i]);
+                    }
+                }
+                if (LOG.isDebugEnabled()) {
+                    log(this, buf);
+                }
+                return values;
+            } finally {
+                if (LOG.isDebugEnabled()) {
+                    unlog(this);
+                }
+            }
+        }
+    };
+
+    public static FieldType<Byte> BYTE = new FieldType<Byte>((byte) next++, Byte.class, Indenting.INDENT_ONLY) {
+        @Override
+        protected void doWrite(final DataOutputExtended output, final Byte value) throws IOException {
+            try {
+                if (LOG.isDebugEnabled()) {
+                    log(this, new StringBuilder().append(value));
+                }
+                final DataOutputStream outputStream = output.getDataOutputStream();
+                outputStream.writeByte(value.byteValue());
+            } finally {
+                if (LOG.isDebugEnabled()) {
+                    unlog(this);
+                }
+            }
+        }
+
+        @Override
+        protected Byte doRead(final DataInputExtended input) throws IOException {
+            try {
+                final DataInputStream inputStream = input.getDataInputStream();
+                final byte value = inputStream.readByte();
+                if (LOG.isDebugEnabled()) {
+                    log(this, new StringBuilder().append(value));
+                }
+                return value;
+            } finally {
+                if (LOG.isDebugEnabled()) {
+                    unlog(this);
+                }
+            }
+        }
+    };
+
+    public static FieldType<byte[]> BYTE_ARRAY = new FieldType<byte[]>((byte) next++, byte[].class, Indenting.INDENT_AND_OUTDENT) {
+        @Override
+        protected void doWrite(final DataOutputExtended output, final byte[] values) throws IOException {
+            try {
+                final DataOutputStream outputStream = output.getDataOutputStream();
+                final int length = values.length;
+                outputStream.writeInt(length);
+                if (LOG.isDebugEnabled()) {
+                    log(this, new StringBuilder().append("length:").append(length).append(" [BYTE ARRAY]"));
+                }
+
+                // rather than looping through the array,
+                // we take advantage of optimization built into DataOutputStream
+                outputStream.write(values);
+            } finally {
+                if (LOG.isDebugEnabled()) {
+                    unlog(this);
+                }
+            }
+        }
+
+        @Override
+        protected byte[] doRead(final DataInputExtended input) throws IOException {
+            try {
+                final DataInputStream inputStream = input.getDataInputStream();
+                final int length = inputStream.readInt();
+                if (LOG.isDebugEnabled()) {
+                    final StringBuilder msg = new StringBuilder().append("length:").append(length).append(" [BYTE ARRAY]");
+                    log(this, msg);
+                }
+
+                final byte[] bytes = new byte[length];
+                readBytes(inputStream, bytes);
+                return bytes;
+            } finally {
+                if (LOG.isDebugEnabled()) {
+                    unlog(this);
+                }
+            }
+        }
+
+        // rather than looping through the array,
+        // we take advantage of optimization built into DataInputStream
+        private void readBytes(final DataInputStream inputStream, final byte[] bytes) throws IOException {
+            inputStream.read(bytes);
+        }
+    };
+
+    public static FieldType<Short> SHORT = new FieldType<Short>((byte) next++, Short.class, Indenting.INDENT_ONLY) {
+        @Override
+        protected void doWrite(final DataOutputExtended output, final Short value) throws IOException {
+            try {
+                if (LOG.isDebugEnabled()) {
+                    log(this, new StringBuilder().append(value));
+                }
+                final DataOutputStream outputStream = output.getDataOutputStream();
+                outputStream.writeShort(value.shortValue());
+            } finally {
+                if (LOG.isDebugEnabled()) {
+                    unlog(this);
+                }
+            }
+        }
+
+        @Override
+        protected Short doRead(final DataInputExtended input) throws IOException {
+            try {
+                final DataInputStream inputStream = input.getDataInputStream();
+                final short value = inputStream.readShort();
+                if (LOG.isDebugEnabled()) {
+                    log(this, new StringBuilder().append(value));
+                }
+                return value;
+            } finally {
+                if (LOG.isDebugEnabled()) {
+                    unlog(this);
+                }
+            }
+        }
+    };
+
+    public static FieldType<short[]> SHORT_ARRAY = new FieldType<short[]>((byte) next++, short[].class, Indenting.INDENT_AND_OUTDENT) {
+        @Override
+        protected void doWrite(final DataOutputExtended output, final short[] values) throws IOException {
+            try {
+                final StringBuilder buf = new StringBuilder();
+                final DataOutputStream outputStream = output.getDataOutputStream();
+                outputStream.writeInt(values.length);
+                if (LOG.isDebugEnabled()) {
+                    buf.append("length: ").append(values.length);
+                }
+
+                for (int i = 0; i < values.length; i++) {
+                    outputStream.writeShort(values[i]);
+                    if (LOG.isDebugEnabled()) {
+                        buf.append(i == 0 ? ": " : ", ");
+                        buf.append(values[i]);
+                    }
+                }
+                if (LOG.isDebugEnabled()) {
+                    log(this, buf);
+                }
+            } finally {
+                if (LOG.isDebugEnabled()) {
+                    unlog(this);
+                }
+            }
+        }
+
+        @Override
+        protected short[] doRead(final DataInputExtended input) throws IOException {
+            try {
+                final StringBuilder buf = new StringBuilder();
+                final DataInputStream inputStream = input.getDataInputStream();
+                final int length = inputStream.readInt();
+                if (LOG.isDebugEnabled()) {
+                    buf.append("length: ").append(length);
+                }
+
+                final short[] values = new short[length];
+                for (int i = 0; i < values.length; i++) {
+                    values[i] = inputStream.readShort();
+                    if (LOG.isDebugEnabled()) {
+                        buf.append(i == 0 ? ": " : ", ");
+                        buf.append(values[i]);
+                    }
+                }
+                if (LOG.isDebugEnabled()) {
+                    log(this, buf);
+                }
+                return values;
+            } finally {
+                if (LOG.isDebugEnabled()) {
+                    unlog(this);
+                }
+            }
+        }
+    };
+
+    public static FieldType<Integer> INTEGER = new FieldType<Integer>((byte) next++, Integer.class, Indenting.INDENT_ONLY) {
+        @Override
+        protected void doWrite(final DataOutputExtended output, final Integer value) throws IOException {
+            try {
+                if (LOG.isDebugEnabled()) {
+                    log(this, new StringBuilder().append(value));
+                }
+                final DataOutputStream outputStream = output.getDataOutputStream();
+                outputStream.writeInt(value.intValue());
+            } finally {
+                if (LOG.isDebugEnabled()) {
+                    unlog(this);
+                }
+            }
+        }
+
+        @Override
+        protected Integer doRead(final DataInputExtended input) throws IOException {
+            try {
+                final DataInputStream inputStream = input.getDataInputStream();
+                final int value = inputStream.readInt();
+                if (LOG.isDebugEnabled()) {
+                    log(this, new StringBuilder().append(value));
+                }
+                return value;
+            } finally {
+                if (LOG.isDebugEnabled()) {
+                    unlog(this);
+                }
+            }
+        }
+    };
+
+    public static FieldType<Integer> UNSIGNED_BYTE = new FieldType<Integer>((byte) next++, Integer.class, Indenting.INDENT_ONLY) {
+        @Override
+        protected void doWrite(final DataOutputExtended output, final Integer value) throws IOException {
+            try {
+                if (LOG.isDebugEnabled()) {
+                    log(this, new StringBuilder().append(value));
+                }
+                final DataOutputStream outputStream = output.getDataOutputStream();
+                outputStream.writeByte(value);
+            } finally {
+                if (LOG.isDebugEnabled()) {
+                    unlog(this);
+                }
+            }
+        }
+
+        @Override
+        protected Integer doRead(final DataInputExtended input) throws IOException {
+            try {
+                final DataInputStream inputStream = input.getDataInputStream();
+                final int value = inputStream.readUnsignedByte();
+                if (LOG.isDebugEnabled()) {
+                    log(this, new StringBuilder().append(value));
+                }
+                return value;
+            } finally {
+                if (LOG.isDebugEnabled()) {
+                    unlog(this);
+                }
+            }
+        }
+    };
+
+    public static FieldType<Integer> UNSIGNED_SHORT = new FieldType<Integer>((byte) next++, Integer.class, Indenting.INDENT_ONLY) {
+        @Override
+        protected void doWrite(final DataOutputExtended output, final Integer value) throws IOException {
+            try {
+                if (LOG.isDebugEnabled()) {
+                    log(this, new StringBuilder().append(value));
+                }
+                final DataOutputStream outputStream = output.getDataOutputStream();
+                outputStream.writeShort(value);
+            } finally {
+                if (LOG.isDebugEnabled()) {
+                    unlog(this);
+                }
+            }
+        }
+
+        @Override
+        protected Integer doRead(final DataInputExtended input) throws IOException {
+            try {
+                final DataInputStream inputStream = input.getDataInputStream();
+                final int value = inputStream.readUnsignedShort();
+                if (LOG.isDebugEnabled()) {
+                    log(this, new StringBuilder().append(value));
+                }
+                return value;
+            } finally {
+                if (LOG.isDebugEnabled()) {
+                    unlog(this);
+                }
+            }
+        }
+    };
+
+    public static FieldType<int[]> INTEGER_ARRAY = new FieldType<int[]>((byte) next++, int[].class, Indenting.INDENT_AND_OUTDENT) {
+        @Override
+        protected void doWrite(final DataOutputExtended output, final int[] values) throws IOException {
+            try {
+                final StringBuilder buf = new StringBuilder();
+                final DataOutputStream outputStream = output.getDataOutputStream();
+                outputStream.writeInt(values.length);
+                if (LOG.isDebugEnabled()) {
+                    buf.append("length: ").append(values.length);
+                }
+
+                for (int i = 0; i < values.length; i++) {
+                    outputStream.writeInt(values[i]);
+                    if (LOG.isDebugEnabled()) {
+                        buf.append(i == 0 ? ": " : ", ");
+                        buf.append(values[i]);
+                    }
+                }
+                if (LOG.isDebugEnabled()) {
+                    log(this, buf);
+                }
+            } finally {
+                if (LOG.isDebugEnabled()) {
+                    unlog(this);
+                }
+            }
+        }
+
+        @Override
+        protected int[] doRead(final DataInputExtended input) throws IOException {
+            try {
+                final StringBuilder buf = new StringBuilder();
+                final DataInputStream inputStream = input.getDataInputStream();
+                final int length = inputStream.readInt();
+                if (LOG.isDebugEnabled()) {
+                    buf.append("length: ").append(length);
+                }
+
+                final int[] values = new int[length];
+                for (int i = 0; i < values.length; i++) {
+                    values[i] = inputStream.readInt();
+                    if (LOG.isDebugEnabled()) {
+                        buf.append(i == 0 ? ": " : ", ");
+                        buf.append(values[i]);
+                    }
+                }
+                if (LOG.isDebugEnabled()) {
+                    log(this, buf);
+                }
+                return values;
+            } finally {
+                if (LOG.isDebugEnabled()) {
+                    unlog(this);
+                }
+            }
+        }
+    };
+
+    public static FieldType<Long> LONG = new FieldType<Long>((byte) next++, Long.class, Indenting.INDENT_ONLY) {
+        @Override
+        protected void doWrite(final DataOutputExtended output, final Long value) throws IOException {
+            try {
+                if (LOG.isDebugEnabled()) {
+                    log(this, new StringBuilder().append(value));
+                }
+                final DataOutputStream outputStream = output.getDataOutputStream();
+                outputStream.writeLong(value.intValue());
+            } finally {
+                if (LOG.isDebugEnabled()) {
+                    unlog(this);
+                }
+            }
+        }
+
+        @Override
+        protected Long doRead(final DataInputExtended input) throws IOException {
+            try {
+                final DataInputStream inputStream = input.getDataInputStream();
+                final long value = inputStream.readLong();
+                if (LOG.isDebugEnabled()) {
+                    log(this, new StringBuilder().append(value));
+                }
+                return value;
+            } finally {
+                if (LOG.isDebugEnabled()) {
+                    unlog(this);
+                }
+            }
+        }
+    };
+    public static FieldType<long[]> LONG_ARRAY = new FieldType<long[]>((byte) next++, long[].class, Indenting.INDENT_AND_OUTDENT) {
+        @Override
+        protected void doWrite(final DataOutputExtended output, final long[] values) throws IOException {
+            try {
+                final StringBuilder buf = new StringBuilder();
+                final DataOutputStream outputStream = output.getDataOutputStream();
+                outputStream.writeInt(values.length);
+                if (LOG.isDebugEnabled()) {
+                    buf.append("length: ").append(values.length);
+                }
+
+                for (int i = 0; i < values.length; i++) {
+                    outputStream.writeLong(values[i]);
+                    if (LOG.isDebugEnabled()) {
+                        buf.append(i == 0 ? ": " : ", ");
+                        buf.append(values[i]);
+                    }
+                }
+                if (LOG.isDebugEnabled()) {
+                    log(this, buf);
+                }
+            } finally {
+                if (LOG.isDebugEnabled()) {
+                    unlog(this);
+                }
+            }
+        }
+
+        @Override
+        protected long[] doRead(final DataInputExtended input) throws IOException {
+            try {
+                final StringBuilder buf = new StringBuilder();
+
+                final DataInputStream inputStream = input.getDataInputStream();
+                final int length = inputStream.readInt();
+                if (LOG.isDebugEnabled()) {
+                    buf.append("length: ").append(length);
+                }
+
+                final long[] values = new long[length];
+                for (int i = 0; i < values.length; i++) {
+                    values[i] = inputStream.readLong();
+                    if (LOG.isDebugEnabled()) {
+                        buf.append(i == 0 ? ": " : ", ");
+                        buf.append(values[i]);
+                    }
+                }
+                if (LOG.isDebugEnabled()) {
+                    log(this, buf);
+                }
+                return values;
+            } finally {
+                if (LOG.isDebugEnabled()) {
+                    unlog(this);
+                }
+            }
+        }
+    };
+
+    public static FieldType<Character> CHAR = new FieldType<Character>((byte) next++, Character.class, Indenting.INDENT_ONLY) {
+        @Override
+        protected void doWrite(final DataOutputExtended output, final Character value) throws IOException {
+            try {
+                if (LOG.isDebugEnabled()) {
+                    log(this, new StringBuilder().append(value));
+                }
+                final DataOutputStream outputStream = output.getDataOutputStream();
+                outputStream.writeLong(value.charValue());
+            } finally {
+                if (LOG.isDebugEnabled()) {
+                    unlog(this);
+                }
+            }
+        }
+
+        @Override
+        protected Character doRead(final DataInputExtended input) throws IOException {
+            try {
+                final DataInputStream inputStream = input.getDataInputStream();
+                final char value = inputStream.readChar();
+                if (LOG.isDebugEnabled()) {
+                    log(this, new StringBuilder().append(value));
+                }
+                return value;
+            } finally {
+                if (LOG.isDebugEnabled()) {
+                    unlog(this);
+                }
+            }
+        }
+    };
+
+    public static FieldType<char[]> CHAR_ARRAY = new FieldType<char[]>((byte) next++, char[].class, Indenting.INDENT_AND_OUTDENT) {
+        // TODO: could perhaps optimize by writing out as a string
+        @Override
+        protected void doWrite(final DataOutputExtended output, final char[] values) throws IOException {
+            try {
+                final StringBuilder buf = new StringBuilder();
+                final DataOutputStream outputStream = output.getDataOutputStream();
+                outputStream.writeInt(values.length);
+                if (LOG.isDebugEnabled()) {
+                    buf.append("length: ").append(values.length);
+                }
+
+                for (int i = 0; i < values.length; i++) {
+                    outputStream.writeChar(values[i]);
+                    if (LOG.isDebugEnabled()) {
+                        buf.append(i == 0 ? ": " : ", ");
+                        buf.append(values[i]);
+                    }
+                }
+                if (LOG.isDebugEnabled()) {
+                    log(this, buf);
+                }
+            } finally {
+                if (LOG.isDebugEnabled()) {
+                    unlog(this);
+                }
+            }
+        }
+
+        @Override
+        protected char[] doRead(final DataInputExtended input) throws IOException {
+            try {
+                final StringBuilder buf = new StringBuilder();
+                final DataInputStream inputStream = input.getDataInputStream();
+                final int length = inputStream.readInt();
+                if (LOG.isDebugEnabled()) {
+                    buf.append("length: ").append(length);
+                }
+
+                final char[] values = new char[length];
+                for (int i = 0; i < values.length; i++) {
+                    if (LOG.isDebugEnabled()) {
+                        buf.append(i == 0 ? ": " : ", ");
+                        buf.append(values[i]);
+                    }
+                    values[i] = inputStream.readChar();
+                }
+                if (LOG.isDebugEnabled()) {
+                    log(this, buf);
+                }
+                return values;
+            } finally {
+                if (LOG.isDebugEnabled()) {
+                    unlog(this);
+                }
+            }
+        }
+    };
+
+    public static FieldType<Float> FLOAT = new FieldType<Float>((byte) next++, Float.class, Indenting.INDENT_ONLY) {
+        @Override
+        protected void doWrite(final DataOutputExtended output, final Float value) throws IOException {
+            try {
+                if (LOG.isDebugEnabled()) {
+                    log(this, new StringBuilder().append(value));
+                }
+                final DataOutputStream outputStream = output.getDataOutputStream();
+                outputStream.writeFloat(value);
+            } finally {
+                if (LOG.isDebugEnabled()) {
+                    unlog(this);
+                }
+            }
+        }
+
+        @Override
+        protected Float doRead(final DataInputExtended input) throws IOException {
+            try {
+                final DataInputStream inputStream = input.getDataInputStream();
+                final float value = inputStream.readFloat();
+                if (LOG.isDebugEnabled()) {
+                    log(this, new StringBuilder().append(value));
+                }
+                return value;
+            } finally {
+                if (LOG.isDebugEnabled()) {
+                    unlog(this);
+                }
+            }
+        }
+    };
+
+    public static FieldType<float[]> FLOAT_ARRAY = new FieldType<float[]>((byte) next++, float[].class, Indenting.INDENT_AND_OUTDENT) {
+        @Override
+        protected void doWrite(final DataOutputExtended output, final float[] values) throws IOException {
+            try {
+                final StringBuilder buf = new StringBuilder();
+                final DataOutputStream outputStream = output.getDataOutputStream();
+                outputStream.writeInt(values.length);
+                if (LOG.isDebugEnabled()) {
+                    buf.append("length: ").append(values.length);
+                }
+
+                for (int i = 0; i < values.length; i++) {
+                    outputStream.writeFloat(values[i]);
+                    if (LOG.isDebugEnabled()) {
+                        buf.append(i == 0 ? ": " : ", ");
+                        buf.append(values[i]);
+                    }
+                }
+                if (LOG.isDebugEnabled()) {
+                    log(this, buf);
+                }
+            } finally {
+                if (LOG.isDebugEnabled()) {
+                    unlog(this);
+                }
+            }
+        }
+
+        @Override
+        protected float[] doRead(final DataInputExtended input) throws IOException {
+            try {
+                final StringBuilder buf = new StringBuilder();
+                final DataInputStream inputStream = input.getDataInputStream();
+                final int length = inputStream.readInt();
+                if (LOG.isDebugEnabled()) {
+                    buf.append("length: ").append(length);
+                }
+
+                final float[] values = new float[length];
+                for (int i = 0; i < values.length; i++) {
+                    values[i] = inputStream.readFloat();
+                    if (LOG.isDebugEnabled()) {
+                        buf.append(i == 0 ? ": " : ", ");
+                        buf.append(values[i]);
+                    }
+                }
+                if (LOG.isDebugEnabled()) {
+                    log(this, buf);
+                }
+                return values;
+            } finally {
+                if (LOG.isDebugEnabled()) {
+                    unlog(this);
+                }
+            }
+        }
+    };
+
+    public static FieldType<Double> DOUBLE = new FieldType<Double>((byte) next++, Double.class, Indenting.INDENT_ONLY) {
+        @Override
+        protected void doWrite(final DataOutputExtended output, final Double value) throws IOException {
+            try {
+                if (LOG.isDebugEnabled()) {
+                    log(this, new StringBuilder().append(value));
+                }
+                final DataOutputStream outputStream = output.getDataOutputStream();
+                outputStream.writeDouble(value);
+            } finally {
+                if (LOG.isDebugEnabled()) {
+                    unlog(this);
+                }
+            }
+        }
+
+        @Override
+        protected Double doRead(final DataInputExtended input) throws IOException {
+            try {
+                final DataInputStream inputStream = input.getDataInputStream();
+                final double value = inputStream.readDouble();
+                if (LOG.isDebugEnabled()) {
+                    log(this, new StringBuilder().append(value));
+                }
+                return value;
+            } finally {
+                if (LOG.isDebugEnabled()) {
+                    unlog(this);
+                }
+            }
+        }
+    };
+
+    public static FieldType<double[]> DOUBLE_ARRAY = new FieldType<double[]>((byte) next++, double[].class, Indenting.INDENT_AND_OUTDENT) {
+        @Override
+        protected void doWrite(final DataOutputExtended output, final double[] values) throws IOException {
+            try {
+                final StringBuilder buf = new StringBuilder();
+                final DataOutputStream outputStream = output.getDataOutputStream();
+                outputStream.writeInt(values.length);
+                if (LOG.isDebugEnabled()) {
+                    buf.append("length: ").append(values.length);
+                }
+
+                for (int i = 0; i < values.length; i++) {
+                    outputStream.writeDouble(values[i]);
+                    if (LOG.isDebugEnabled()) {
+                        buf.append(i == 0 ? ": " : ", ");
+                        buf.append(values[i]);
+                    }
+                }
+                if (LOG.isDebugEnabled()) {
+                    log(this, buf);
+                }
+            } finally {
+                if (LOG.isDebugEnabled()) {
+                    unlog(this);
+                }
+            }
+        }
+
+        @Override
+        protected double[] doRead(final DataInputExtended input) throws IOException {
+            try {
+                final StringBuilder buf = new StringBuilder();
+                final DataInputStream inputStream = input.getDataInputStream();
+                final int length = inputStream.readInt();
+                if (LOG.isDebugEnabled()) {
+                    buf.append("length: ").append(length);
+                }
+
+                final double[] values = new double[length];
+                for (int i = 0; i < values.length; i++) {
+                    values[i] = inputStream.readDouble();
+                    if (LOG.isDebugEnabled()) {
+                        buf.append(i == 0 ? ": " : ", ");
+                        buf.append(values[i]);
+                    }
+                }
+                if (LOG.isDebugEnabled()) {
+                    log(this, buf);
+                }
+                return values;
+            } finally {
+                if (LOG.isDebugEnabled()) {
+                    unlog(this);
+                }
+            }
+        }
+    };
+
+    public static FieldType<String> STRING = new FieldType<String>((byte) next++, String.class, Indenting.INDENT_ONLY) {
+        @Override
+        protected void doWrite(final DataOutputExtended output, final String value) throws IOException {
+            try {
+                if (LOG.isDebugEnabled()) {
+                    log(this, new StringBuilder().append(value));
+                }
+                final DataOutputStream outputStream = output.getDataOutputStream();
+                outputStream.writeUTF(value);
+            } finally {
+                if (LOG.isDebugEnabled()) {
+                    unlog(this);
+                }
+            }
+        }
+
+        @Override
+        protected String doRead(final DataInputExtended input) throws IOException {
+            try {
+                final DataInputStream inputStream = input.getDataInputStream();
+                final String value = inputStream.readUTF();
+                if (LOG.isDebugEnabled()) {
+                    log(this, new StringBuilder().append(value));
+                }
+                return value;
+            } finally {
+                if (LOG.isDebugEnabled()) {
+                    unlog(this);
+                }
+            }
+        }
+    };
+    public static FieldType<String[]> STRING_ARRAY = new FieldType<String[]>((byte) next++, String[].class, Indenting.INDENT_AND_OUTDENT) {
+        @Override
+        protected void doWrite(final DataOutputExtended output, final String[] values) throws IOException {
+            try {
+                final StringBuilder buf = new StringBuilder();
+                final DataOutputStream outputStream = output.getDataOutputStream();
+                outputStream.writeInt(values.length);
+                if (LOG.isDebugEnabled()) {
+                    buf.append("length: ").append(values.length);
+                }
+
+                for (int i = 0; i < values.length; i++) {
+                    // using FieldType to write out takes care of null handling
+                    FieldType.STRING.write(output, values[i]);
+                    if (LOG.isDebugEnabled()) {
+                        buf.append(i == 0 ? ": " : ", ");
+                        buf.append(values[i]);
+                    }
+                }
+                if (LOG.isDebugEnabled()) {
+                    log(this, buf);
+                }
+            } finally {
+                if (LOG.isDebugEnabled()) {
+                    unlog(this);
+                }
+            }
+        }
+
+        @Override
+        protected String[] doRead(final DataInputExtended input) throws IOException {
+            try {
+                final StringBuilder buf = new StringBuilder();
+                final DataInputStream inputStream = input.getDataInputStream();
+                final int length = inputStream.readInt();
+                if (LOG.isDebugEnabled()) {
+                    buf.append("length: ").append(length);
+                }
+
+                final String[] values = new String[length];
+                for (int i = 0; i < values.length; i++) {
+                    // using FieldType to read in takes care of null handling
+                    values[i] = FieldType.STRING.read(input);
+                    if (LOG.isDebugEnabled()) {
+                        buf.append(i == 0 ? ": " : ", ");
+                        buf.append(values[i]);
+                    }
+                }
+                if (LOG.isDebugEnabled()) {
+                    log(this, buf);
+                }
+                return values;
+            } finally {
+                if (LOG.isDebugEnabled()) {
+                    unlog(this);
+                }
+            }
+        }
+    };
+
+    public static FieldType<Encodable> ENCODABLE = new FieldType<Encodable>((byte) next++, Encodable.class, Indenting.INDENT_AND_OUTDENT) {
+        @Override
+        protected void doWrite(final DataOutputExtended output, final Encodable encodable) throws IOException {
+            try {
+                // write out class
+                final String className = encodable.getClass().getName();
+                if (LOG.isDebugEnabled()) {
+                    log(this, new StringBuilder().append(className));
+                }
+                output.writeUTF(className);
+
+                // recursively encode
+                encodable.encode(output);
+            } finally {
+                if (LOG.isDebugEnabled()) {
+                    unlog(this);
+                }
+            }
+        }
+
+        @Override
+        protected Encodable doRead(final DataInputExtended input) throws IOException {
+            try {
+                // read in class name ...
+                final String className = input.readUTF();
+                if (LOG.isDebugEnabled()) {
+                    log(this, new StringBuilder().append(className));
+                }
+
+                Class<?> cls;
+                try {
+                    // ...obtain constructor
+                    cls = Thread.currentThread().getContextClassLoader().loadClass(className);
+
+                    final Constructor<?> constructor = cls.getConstructor(new Class[] { DataInputExtended.class });
+
+                    // recursively decode
+                    return (Encodable) constructor.newInstance(new Object[] { input });
+                } catch (final ClassNotFoundException ex) {
+                    throw new FailedToDecodeException(ex);
+                } catch (final IllegalArgumentException ex) {
+                    throw new FailedToDecodeException(ex);
+                } catch (final InstantiationException ex) {
+                    throw new FailedToDecodeException(ex);
+                } catch (final IllegalAccessException ex) {
+                    throw new FailedToDecodeException(ex);
+                } catch (final InvocationTargetException ex) {
+                    throw new FailedToDecodeException(ex);
+                } catch (final SecurityException ex) {
+                    throw new FailedToDecodeException(ex);
+                } catch (final NoSuchMethodException ex) {
+                    throw new FailedToDecodeException(ex);
+                }
+
+            } finally {
+                if (LOG.isDebugEnabled()) {
+                    unlog(this);
+                }
+            }
+        }
+
+        @Override
+        protected boolean checksStream() {
+            return false;
+        }
+    };
+
+    public static FieldType<Encodable[]> ENCODABLE_ARRAY = new FieldType<Encodable[]>((byte) next++, Encodable[].class, Indenting.INDENT_AND_OUTDENT) {
+        @Override
+        protected void doWrite(final DataOutputExtended output, final Encodable[] values) throws IOException {
+            try {
+                final DataOutputStream outputStream = output.getDataOutputStream();
+                outputStream.writeInt(values.length);
+                if (LOG.isDebugEnabled()) {
+                    log(this, new StringBuilder().append("length: ").append(values.length));
+                }
+                for (final Encodable encodable : values) {
+                    // using FieldType to write out takes care of null handling
+                    FieldType.ENCODABLE.write(output, encodable);
+                }
+            } finally {
+                if (LOG.isDebugEnabled()) {
+                    unlog(this);
+                }
+            }
+        }
+
+        @SuppressWarnings("unchecked")
+        @Override
+        protected <Q> Q[] doReadArray(final DataInputExtended input, final Class<Q> elementType) throws IOException {
+            try {
+                final DataInputStream inputStream = input.getDataInputStream();
+                final int length = inputStream.readInt();
+                if (LOG.isDebugEnabled()) {
+                    log(this, new StringBuilder().append("length: ").append(length));
+                }
+
+                final Q[] values = (Q[]) Array.newInstance(elementType, length);
+                for (int i = 0; i < values.length; i++) {
+                    // using FieldType to read in takes care of null handling
+                    values[i] = (Q) FieldType.ENCODABLE.read(input);
+                }
+                return values;
+            } finally {
+                if (LOG.isDebugEnabled()) {
+                    unlog(this);
+                }
+            }
+        }
+
+        @Override
+        protected boolean checksStream() {
+            return false;
+        }
+    };
+
+    public static FieldType<Serializable> SERIALIZABLE = new FieldType<Serializable>((byte) next++, Serializable.class, Indenting.INDENT_ONLY) {
+        @Override
+        protected void doWrite(final DataOutputExtended output, final Serializable value) throws IOException {
+            try {
+                if (LOG.isDebugEnabled()) {
+                    log(this, new StringBuilder().append("[SERIALIZABLE]"));
+                }
+
+                // write out as blob of bytes
+                final ObjectOutputStream oos = new ObjectOutputStream(output.getDataOutputStream());
+                oos.writeObject(value);
+                oos.flush();
+            } finally {
+                if (LOG.isDebugEnabled()) {
+                    unlog(this);
+                }
+            }
+        }
+
+        @Override
+        protected Serializable doRead(final DataInputExtended input) throws IOException {
+            try {
+                if (LOG.isDebugEnabled()) {
+                    log(this, new StringBuilder().append("[SERIALIZABLE]"));
+                }
+
+                // read in a blob of bytes
+                final ObjectInputStream ois = new ObjectInputStream(input.getDataInputStream());
+                try {
+                    return (Serializable) ois.readObject();
+                } catch (final ClassNotFoundException ex) {
+                    throw new FailedToDeserializeException(ex);
+                }
+            } finally {
+                if (LOG.isDebugEnabled()) {
+                    unlog(this);
+                }
+            }
+        }
+
+        @Override
+        protected boolean checksStream() {
+            return false;
+        }
+    };
+
+    public static FieldType<Serializable[]> SERIALIZABLE_ARRAY = new FieldType<Serializable[]>((byte) next++, Serializable[].class, Indenting.INDENT_AND_OUTDENT) {
+        @Override
+        protected void doWrite(final DataOutputExtended output, final Serializable[] values) throws IOException {
+            try {
+                final DataOutputStream outputStream = output.getDataOutputStream();
+                outputStream.writeInt(values.length);
+                if (LOG.isDebugEnabled()) {
+                    log(this, new StringBuilder().append("length: ").append(values.length));
+                }
+
+                for (final Serializable value : values) {
+                    // using FieldType to write out takes care of null handling
+                    FieldType.SERIALIZABLE.write(output, value);
+                }
+            } finally {
+                if (LOG.isDebugEnabled()) {
+                    unlog(this);
+                }
+            }
+        }
+
+        @Override
+        @SuppressWarnings("unchecked")
+        protected <Q> Q[] doReadArray(final DataInputExtended input, final Class<Q> elementType) throws IOException {
+            try {
+                final DataInputStream inputStream = input.getDataInputStream();
+                final int length = inputStream.readInt();
+                if (LOG.isDebugEnabled()) {
+                    log(this, new StringBuilder().append("length: ").append(length));
+                }
+
+                final Q[] values = (Q[]) Array.newInstance(elementType, length);
+                for (int i = 0; i < values.length; i++) {
+                    // using FieldType to read in takes care of null handling
+                    values[i] = (Q) FieldType.SERIALIZABLE.read(input);
+                }
+                return values;
+            } finally {
+                if (LOG.isDebugEnabled()) {
+                    unlog(this);
+                }
+            }
+        }
+
+        @Override
+        protected boolean checksStream() {
+            return false;
+        }
+    };
+
+    public static FieldType<?> get(final byte idx) {
+        return cache.get(idx);
+    }
+
+    private final byte idx;
+    private final Class<T> cls;
+    private final Indenting indenting;
+
+    private FieldType(final byte idx, final Class<T> cls, final Indenting indenting) {
+        this.idx = idx;
+        this.cls = cls;
+        this.indenting = indenting;
+        cache.put(idx, this);
+    }
+
+    public byte getIdx() {
+        return idx;
+    }
+
+    public Class<T> getCls() {
+        return cls;
+    }
+
+    /**
+     * Whether this implementation checks ordering in the stream.
+     * 
+     * <p>
+     * Broadly, the type safe ones do, the {@link Encodable} and
+     * {@link Serializable} ones do not.
+     */
+    protected boolean checksStream() {
+        return true;
+    }
+
+    public final T read(final DataInputExtended input) throws IOException {
+        final DataInputStream inputStream = input.getDataInputStream();
+        final byte fieldTypeIdxAndNullability = inputStream.readByte();
+
+        final boolean isNull = fieldTypeIdxAndNullability >= NULL_BIT;
+        final byte fieldTypeIdx = (byte) (fieldTypeIdxAndNullability - (isNull ? NULL_BIT : 0));
+        try {
+            final FieldType<?> fieldType = FieldType.get(fieldTypeIdx);
+            if (fieldType == null || (fieldType.checksStream() && fieldType != this)) {
+                throw new IllegalStateException("Mismatch in stream: expected " + this + " but got " + fieldType + " (" + fieldTypeIdx + ")");
+            }
+
+            if (isNull && LOG.isDebugEnabled()) {
+                // only log if reading a null; otherwise actual value read
+                // logged later
+                log(this, new StringBuilder().append("(null)"));
+            }
+
+            if (isNull) {
+                return null;
+            } else {
+                return doRead(input);
+            }
+        } finally {
+            if (isNull && LOG.isDebugEnabled()) {
+                // only unlog if reading a null
+                unlog(this);
+            }
+        }
+    }
+
+    public final <Q> Q[] readArray(final DataInputExtended input, final Class<Q> elementType) throws IOException {
+        final DataInputStream inputStream = input.getDataInputStream();
+        final byte fieldTypeIdxAndNullability = inputStream.readByte();
+
+        final boolean isNull = fieldTypeIdxAndNullability >= NULL_BIT;
+        final byte fieldTypeIdx = (byte) (fieldTypeIdxAndNullability - (isNull ? NULL_BIT : 0));
+        try {
+            final FieldType<?> fieldType = FieldType.get(fieldTypeIdx);
+            if (fieldType.checksStream() && fieldType != this) {
+                throw new IllegalStateException("Mismatch in stream: expected " + this + " but got " + fieldType);
+            }
+
+            if (isNull && LOG.isDebugEnabled()) {
+                // only log if reading a null; otherwise actual value read
+                // logged later
+                log(this, new StringBuilder().append("(null)"));
+            }
+
+            if (isNull) {
+                return null;
+            } else {
+                return doReadArray(input, elementType);
+            }
+
+        } finally {
+            if (isNull && LOG.isDebugEnabled()) {
+                // only unlog if reading a null
+                unlog(this);
+            }
+        }
+
+    }
+
+    public final void write(final DataOutputExtended output, final T value) throws IOException {
+        byte fieldTypeIdxAndNullability = getIdx();
+        final boolean isNull = value == null;
+        if (isNull) {
+            // set high order bit
+            fieldTypeIdxAndNullability += NULL_BIT;
+        }
+        try {
+
+            final DataOutputStream outputStream = output.getDataOutputStream();
+
+            outputStream.write(fieldTypeIdxAndNullability);
+            if (isNull && LOG.isDebugEnabled()) {
+                // only log if writing a null; otherwise actual value logged
+                // later
+                log(this, new StringBuilder().append("(null)"));
+            }
+
+            if (!isNull) {
+                doWrite(output, value);
+            }
+        } finally {
+            if (isNull && LOG.isDebugEnabled()) {
+                // only unlog if writing a null
+                unlog(this);
+            }
+        }
+    }
+
+    protected T doRead(final DataInputExtended input) throws IOException {
+        throw new UnsupportedOperationException("not supported for this field type");
+    }
+
+    protected <Q> Q[] doReadArray(final DataInputExtended input, final Class<Q> elementType) throws IOException {
+        throw new UnsupportedOperationException("not supported for this field type");
+    }
+
+    protected abstract void doWrite(DataOutputExtended output, T value) throws IOException;
+
+    private boolean isIndentingAndOutdenting() {
+        return indenting == Indenting.INDENT_AND_OUTDENT;
+    }
+
+    // ///////////////////////////////////////////////////////
+    // debugging
+    // ///////////////////////////////////////////////////////
+
+    private static ThreadLocal<int[]> debugIndent = new ThreadLocal<int[]>();
+
+    private static void log(final FieldType<?> fieldType, final StringBuilder buf) {
+        buf.insert(0, ": ");
+        buf.insert(0, fieldType);
+        if (fieldType.isIndentingAndOutdenting()) {
+            buf.insert(0, "> ");
+        }
+        buf.insert(0, spaces(currentDebugLevel()));
+        incrementDebugLevel();
+        LOG.debug(buf.toString());
+    }
+
+    private static void unlog(final FieldType<?> fieldType) {
+        unlog(fieldType, new StringBuilder());
+    }
+
+    private static void unlog(final FieldType<?> fieldType, final StringBuilder buf) {
+        if (fieldType.isIndentingAndOutdenting()) {
+            buf.insert(0, "< ");
+        }
+        decrementDebugLevel();
+        if (fieldType.isIndentingAndOutdenting()) {
+            buf.insert(0, spaces(currentDebugLevel()));
+            LOG.debug(buf.toString());
+        }
+    }
+
+    private static String spaces(final int num) {
+        return LOG_INDENT.substring(0, num);
+    }
+
+    private static int currentDebugLevel() {
+        return debugIndent()[0];
+    }
+
+    private static void incrementDebugLevel() {
+        final int[] indentLevel = debugIndent();
+        indentLevel[0] += 2;
+    }
+
+    private static void decrementDebugLevel() {
+        final int[] indentLevel = debugIndent();
+        indentLevel[0] -= 2;
+    }
+
+    private static int[] debugIndent() {
+        int[] indentLevel = debugIndent.get();
+        if (indentLevel == null) {
+            indentLevel = new int[1];
+            debugIndent.set(indentLevel);
+        }
+        return indentLevel;
+    }
+
+    // ///////////////////////////////////////////////////////
+    // toString
+    // ///////////////////////////////////////////////////////
+
+    @Override
+    public String toString() {
+        return getCls().getSimpleName();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/e4735c72/framework/core/metamodel/src/main/java/org/apache/isis/core/commons/encoding/HexUtils.java
----------------------------------------------------------------------
diff --git a/framework/core/metamodel/src/main/java/org/apache/isis/core/commons/encoding/HexUtils.java b/framework/core/metamodel/src/main/java/org/apache/isis/core/commons/encoding/HexUtils.java
new file mode 100644
index 0000000..de068dd
--- /dev/null
+++ b/framework/core/metamodel/src/main/java/org/apache/isis/core/commons/encoding/HexUtils.java
@@ -0,0 +1,63 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.isis.core.commons.encoding;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+
+import org.apache.commons.codec.DecoderException;
+import org.apache.commons.codec.binary.Hex;
+
+import org.apache.isis.core.commons.exceptions.IsisException;
+
+public final class HexUtils {
+    
+    private HexUtils() {
+    }
+
+    public static String encoded(final Object object) {
+        final ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        final DataOutputStreamExtended outputImpl = new DataOutputStreamExtended(baos);
+        try {
+            outputImpl.writeEncodable(object);
+            final byte[] byteArray = baos.toByteArray();
+            return new String(Hex.encodeHex(byteArray));
+        } catch (final IOException e) {
+            throw new IsisException("Failed to write object", e);
+        }
+    }
+
+    public static <T> T decoded(final String hexEncoded, Class<T> cls) {
+        final char[] chars = hexEncoded.toCharArray();
+        byte[] bytes;
+        try {
+            bytes = Hex.decodeHex(chars);
+            final ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
+            final DataInputStreamExtended inputImpl = new DataInputStreamExtended(bais);
+            return inputImpl.readEncodable(cls);
+        } catch (final IOException ex) {
+            throw new IsisException("Failed to read object", ex);
+        } catch (final DecoderException ex) {
+            throw new IsisException("Failed to hex decode object", ex);
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/e4735c72/framework/core/metamodel/src/main/java/org/apache/isis/core/commons/encoding/encoding.ucd
----------------------------------------------------------------------
diff --git a/framework/core/metamodel/src/main/java/org/apache/isis/core/commons/encoding/encoding.ucd b/framework/core/metamodel/src/main/java/org/apache/isis/core/commons/encoding/encoding.ucd
new file mode 100644
index 0000000..a9bfb18
--- /dev/null
+++ b/framework/core/metamodel/src/main/java/org/apache/isis/core/commons/encoding/encoding.ucd
@@ -0,0 +1,166 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<editmodel:ClassDiagramEditModel xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:editmodel="editmodel.xmi" xmlns:options="options.xmi" name="encoding" size="1283,724" id="org.apache.isis.core.commons.encoding" metadata="uml2-1.0" initialized="true" zoom="0.5" tag="1000" key="32303037303533312D31303030206F72672E6170616368652E697369732E636F72652E636F6D6D6F6E732F64616E">
+  <children xsi:type="editmodel:InterfaceEditModel" name="Encodable" location="15,544" size="109,81" id="org.apache.isis.core.commons.encoding/Encodable" runTimeClassModel="encode(Lorg.apache.isis.core.commons.encoding.DataOutputExtended;)">
+    <children xsi:type="editmodel:CompartmentEditModel" size="0,0"/>
+    <children xsi:type="editmodel:CompartmentEditModel" size="66,18">
+      <children xsi:type="editmodel:MethodEditModel" name="encode" id="org.apache.isis.core.commons.encoding/Encodable#encode(Lorg.apache.isis.core.commons.encoding.DataOutputExtended;)"/>
+    </children>
+    <children xsi:type="editmodel:CompartmentEditModel" size="0,0"/>
+    <classifierPreferences xsi:type="editmodel:UMLClassDiagramClassifierPreference" showStereotype="true" attributeSorter="Natural" methodSorter="Natural" innerClassSorter="Natural" showPublicAttributes="true" showPackageAttributes="true" showStaticAttributes="true" showPublicMethods="true" showPackageMethods="true" showStaticMethods="true" showPublicInnerClasses="true" showPackageInnerClasses="true" showStaticInnerClasses="true" packageIndication="3" showAttributeProperty="true"/>
+  </children>
+  <children xsi:type="editmodel:ClassEditModel" name="FieldType" location="989,14" size="274,643" id="org.apache.isis.core.commons.encoding/FieldType" runTimeClassModel="uNSIGNED_BYTE,sHORT_ARRAY,lONG_ARRAY,write(Lorg.apache.isis.core.commons.encoding.DataOutputExtended;LT;),eNCODABLE_ARRAY,toString(),fLOAT_ARRAY,getIdx(),sTRING,eNCODABLE,sERIALIZABLE_ARRAY,bYTE,sERIALIZABLE,dOUBLE,read(Lorg.apache.isis.core.commons.encoding.DataInputExtended;),dOUBLE_ARRAY,bOOLEAN_ARRAY,cls,idx,cHAR,org.apache.isis.core.commons.encoding.FieldType.Indenting,readArray(Lorg.apache.isis.core.commons.encoding.DataInputExtended;Ljava.lang.Class;),bOOLEAN,iNTEGER_ARRAY,uNSIGNED_SHORT,bYTE_ARRAY,get(B),getCls(),sTRING_ARRAY,fLOAT,sHORT,iNTEGER,lONG,cHAR_ARRAY">
+    <children xsi:type="editmodel:CompartmentEditModel" size="251,468">
+      <children xsi:type="editmodel:AttributeEditModel" name="bOOLEAN" id="org.apache.isis.core.commons.encoding/FieldType#bOOLEAN"/>
+      <children xsi:type="editmodel:AttributeEditModel" name="bOOLEAN_ARRAY" id="org.apache.isis.core.commons.encoding/FieldType#bOOLEAN_ARRAY"/>
+      <children xsi:type="editmodel:AttributeEditModel" name="bYTE" id="org.apache.isis.core.commons.encoding/FieldType#bYTE"/>
+      <children xsi:type="editmodel:AttributeEditModel" name="bYTE_ARRAY" id="org.apache.isis.core.commons.encoding/FieldType#bYTE_ARRAY"/>
+      <children xsi:type="editmodel:AttributeEditModel" name="sHORT" id="org.apache.isis.core.commons.encoding/FieldType#sHORT"/>
+      <children xsi:type="editmodel:AttributeEditModel" name="sHORT_ARRAY" id="org.apache.isis.core.commons.encoding/FieldType#sHORT_ARRAY"/>
+      <children xsi:type="editmodel:AttributeEditModel" name="iNTEGER" id="org.apache.isis.core.commons.encoding/FieldType#iNTEGER"/>
+      <children xsi:type="editmodel:AttributeEditModel" name="uNSIGNED_BYTE" id="org.apache.isis.core.commons.encoding/FieldType#uNSIGNED_BYTE"/>
+      <children xsi:type="editmodel:AttributeEditModel" name="uNSIGNED_SHORT" id="org.apache.isis.core.commons.encoding/FieldType#uNSIGNED_SHORT"/>
+      <children xsi:type="editmodel:AttributeEditModel" name="iNTEGER_ARRAY" id="org.apache.isis.core.commons.encoding/FieldType#iNTEGER_ARRAY"/>
+      <children xsi:type="editmodel:AttributeEditModel" name="lONG" id="org.apache.isis.core.commons.encoding/FieldType#lONG"/>
+      <children xsi:type="editmodel:AttributeEditModel" name="lONG_ARRAY" id="org.apache.isis.core.commons.encoding/FieldType#lONG_ARRAY"/>
+      <children xsi:type="editmodel:AttributeEditModel" name="cHAR" id="org.apache.isis.core.commons.encoding/FieldType#cHAR"/>
+      <children xsi:type="editmodel:AttributeEditModel" name="cHAR_ARRAY" id="org.apache.isis.core.commons.encoding/FieldType#cHAR_ARRAY"/>
+      <children xsi:type="editmodel:AttributeEditModel" name="fLOAT" id="org.apache.isis.core.commons.encoding/FieldType#fLOAT"/>
+      <children xsi:type="editmodel:AttributeEditModel" name="fLOAT_ARRAY" id="org.apache.isis.core.commons.encoding/FieldType#fLOAT_ARRAY"/>
+      <children xsi:type="editmodel:AttributeEditModel" name="dOUBLE" id="org.apache.isis.core.commons.encoding/FieldType#dOUBLE"/>
+      <children xsi:type="editmodel:AttributeEditModel" name="dOUBLE_ARRAY" id="org.apache.isis.core.commons.encoding/FieldType#dOUBLE_ARRAY"/>
+      <children xsi:type="editmodel:AttributeEditModel" name="sTRING" id="org.apache.isis.core.commons.encoding/FieldType#sTRING"/>
+      <children xsi:type="editmodel:AttributeEditModel" name="sTRING_ARRAY" id="org.apache.isis.core.commons.encoding/FieldType#sTRING_ARRAY"/>
+      <children xsi:type="editmodel:AttributeEditModel" name="eNCODABLE" id="org.apache.isis.core.commons.encoding/FieldType#eNCODABLE"/>
+      <children xsi:type="editmodel:AttributeEditModel" name="eNCODABLE_ARRAY" id="org.apache.isis.core.commons.encoding/FieldType#eNCODABLE_ARRAY"/>
+      <children xsi:type="editmodel:AttributeEditModel" name="sERIALIZABLE" id="org.apache.isis.core.commons.encoding/FieldType#sERIALIZABLE"/>
+      <children xsi:type="editmodel:AttributeEditModel" name="sERIALIZABLE_ARRAY" id="org.apache.isis.core.commons.encoding/FieldType#sERIALIZABLE_ARRAY"/>
+      <children xsi:type="editmodel:AttributeEditModel" name="idx" id="org.apache.isis.core.commons.encoding/FieldType#idx"/>
+      <children xsi:type="editmodel:AttributeEditModel" name="cls" id="org.apache.isis.core.commons.encoding/FieldType#cls"/>
+    </children>
+    <children xsi:type="editmodel:CompartmentEditModel" size="103,126">
+      <children xsi:type="editmodel:MethodEditModel" name="get" id="org.apache.isis.core.commons.encoding/FieldType#get(B)"/>
+      <children xsi:type="editmodel:MethodEditModel" name="getIdx" id="org.apache.isis.core.commons.encoding/FieldType#getIdx()"/>
+      <children xsi:type="editmodel:MethodEditModel" name="getCls" id="org.apache.isis.core.commons.encoding/FieldType#getCls()"/>
+      <children xsi:type="editmodel:MethodEditModel" name="readArray" id="org.apache.isis.core.commons.encoding/FieldType#readArray(Lorg.apache.isis.core.commons.encoding.DataInputExtended;Ljava.lang.Class;)"/>
+      <children xsi:type="editmodel:MethodEditModel" name="read" id="org.apache.isis.core.commons.encoding/FieldType#read(Lorg.apache.isis.core.commons.encoding.DataInputExtended;)"/>
+      <children xsi:type="editmodel:MethodEditModel" name="write" id="org.apache.isis.core.commons.encoding/FieldType#write(Lorg.apache.isis.core.commons.encoding.DataOutputExtended;LT;)"/>
+      <children xsi:type="editmodel:MethodEditModel" name="toString" id="org.apache.isis.core.commons.encoding/FieldType#toString()"/>
+    </children>
+    <children xsi:type="editmodel:CompartmentEditModel" size="0,0"/>
+    <classifierPreferences xsi:type="editmodel:UMLClassDiagramClassifierPreference" showStereotype="true" attributeSorter="Natural" methodSorter="Natural" innerClassSorter="Natural" showPublicAttributes="true" showPackageAttributes="true" showStaticAttributes="true" showPublicMethods="true" showPackageMethods="true" showStaticMethods="true" showPublicInnerClasses="true" showPackageInnerClasses="true" showStaticInnerClasses="true" packageIndication="3" showAttributeProperty="true"/>
+  </children>
+  <children xsi:type="editmodel:InterfaceEditModel" targetConnections="//@children.5/@sourceConnections.0" name="DataInputExtended" location="676,13" size="163,315" id="org.apache.isis.core.commons.encoding/DataInputExtended" runTimeClassModel="readFloats(),readBytes(),readSerializable(Ljava.lang.Class;),readUTFs(),readEncodable(Ljava.lang.Class;),readChars(),readDoubles(),readEncodables(Ljava.lang.Class;),readInts(),readBooleans(),readShorts(),readSerializables(Ljava.lang.Class;),getDataInputStream(),readLongs()">
+    <children xsi:type="editmodel:CompartmentEditModel" size="0,0"/>
+    <children xsi:type="editmodel:CompartmentEditModel" size="134,252">
+      <children xsi:type="editmodel:MethodEditModel" name="getDataInputStream" id="org.apache.isis.core.commons.encoding/DataInputExtended#getDataInputStream()"/>
+      <children xsi:type="editmodel:MethodEditModel" name="readBooleans" id="org.apache.isis.core.commons.encoding/DataInputExtended#readBooleans()"/>
+      <children xsi:type="editmodel:MethodEditModel" name="readBytes" id="org.apache.isis.core.commons.encoding/DataInputExtended#readBytes()"/>
+      <children xsi:type="editmodel:MethodEditModel" name="readChars" id="org.apache.isis.core.commons.encoding/DataInputExtended#readChars()"/>
+      <children xsi:type="editmodel:MethodEditModel" name="readDoubles" id="org.apache.isis.core.commons.encoding/DataInputExtended#readDoubles()"/>
+      <children xsi:type="editmodel:MethodEditModel" name="readEncodable" id="org.apache.isis.core.commons.encoding/DataInputExtended#readEncodable(Ljava.lang.Class;)"/>
+      <children xsi:type="editmodel:MethodEditModel" name="readEncodables" id="org.apache.isis.core.commons.encoding/DataInputExtended#readEncodables(Ljava.lang.Class;)"/>
+      <children xsi:type="editmodel:MethodEditModel" name="readFloats" id="org.apache.isis.core.commons.encoding/DataInputExtended#readFloats()"/>
+      <children xsi:type="editmodel:MethodEditModel" name="readInts" id="org.apache.isis.core.commons.encoding/DataInputExtended#readInts()"/>
+      <children xsi:type="editmodel:MethodEditModel" name="readLongs" id="org.apache.isis.core.commons.encoding/DataInputExtended#readLongs()"/>
+      <children xsi:type="editmodel:MethodEditModel" name="readSerializable" id="org.apache.isis.core.commons.encoding/DataInputExtended#readSerializable(Ljava.lang.Class;)"/>
+      <children xsi:type="editmodel:MethodEditModel" name="readSerializables" id="org.apache.isis.core.commons.encoding/DataInputExtended#readSerializables(Ljava.lang.Class;)"/>
+      <children xsi:type="editmodel:MethodEditModel" name="readShorts" id="org.apache.isis.core.commons.encoding/DataInputExtended#readShorts()"/>
+      <children xsi:type="editmodel:MethodEditModel" name="readUTFs" id="org.apache.isis.core.commons.encoding/DataInputExtended#readUTFs()"/>
+    </children>
+    <children xsi:type="editmodel:CompartmentEditModel" size="0,0"/>
+    <classifierPreferences xsi:type="editmodel:UMLClassDiagramClassifierPreference" showStereotype="true" attributeSorter="Natural" methodSorter="Natural" innerClassSorter="Natural" showPublicAttributes="true" showPackageAttributes="true" showStaticAttributes="true" showPublicMethods="true" showPackageMethods="true" showStaticMethods="true" showPublicInnerClasses="true" showPackageInnerClasses="true" showStaticInnerClasses="true" packageIndication="3" showAttributeProperty="true"/>
+  </children>
+  <children xsi:type="editmodel:ClassEditModel" targetConnections="//@children.4/@sourceConnections.0" name="DataInputExtendedDecorator" location="757,388" size="225,29" id="org.apache.isis.core.commons.encoding/DataInputExtendedDecorator" runTimeClassModel="">
+    <children xsi:type="editmodel:CompartmentEditModel" size="0,0"/>
+    <children xsi:type="editmodel:CompartmentEditModel" size="0,0"/>
+    <children xsi:type="editmodel:CompartmentEditModel" size="0,0"/>
+    <sourceConnections xsi:type="editmodel:GeneralizationEditModel" autoLocated="true" id="org.apache.isis.core.commons.encoding/DataInputExtended&lt;-org.apache.isis.core.commons.encoding/DataInputExtendedDecorator" source="//@children.3" target="//@children.5/@sourceConnections.0" targetEnd="//@children.3/@sourceConnections.0/@children.1" sourceEnd="//@children.3/@sourceConnections.0/@children.0" connectionRouterKind="GeneralizationManhattan">
+      <children xsi:type="editmodel:AssociationEndEditModel" location="112,0" anchorKind="FixedAtEdge" attachSource="true"/>
+      <children xsi:type="editmodel:AssociationEndEditModel"/>
+    </sourceConnections>
+    <classifierPreferences xsi:type="editmodel:UMLClassDiagramClassifierPreference" showStereotype="true" attributeSorter="Natural" methodSorter="Natural" innerClassSorter="Natural" showPublicAttributes="true" showPackageAttributes="true" showStaticAttributes="true" showPackageMethods="true" showStaticMethods="true" showPublicInnerClasses="true" showPackageInnerClasses="true" showStaticInnerClasses="true" packageIndication="3" showAttributeProperty="true"/>
+  </children>
+  <children xsi:type="editmodel:ClassEditModel" name="DebugDataInputExtended" location="768,448" size="204,29" id="org.apache.isis.core.commons.encoding/DebugDataInputExtended" runTimeClassModel="">
+    <children xsi:type="editmodel:CompartmentEditModel" size="0,0"/>
+    <children xsi:type="editmodel:CompartmentEditModel" size="0,0"/>
+    <children xsi:type="editmodel:CompartmentEditModel" size="0,0"/>
+    <sourceConnections xsi:type="editmodel:GeneralizationEditModel" autoLocated="true" id="org.apache.isis.core.commons.encoding/DataInputExtendedDecorator&lt;-org.apache.isis.core.commons.encoding/DebugDataInputExtended" source="//@children.4" target="//@children.3" targetEnd="//@children.4/@sourceConnections.0/@children.1" sourceEnd="//@children.4/@sourceConnections.0/@children.0" connectionRouterKind="Manual">
+      <children xsi:type="editmodel:AssociationEndEditModel" location="101,0" attachSource="true"/>
+      <children xsi:type="editmodel:AssociationEndEditModel" location="112,29"/>
+    </sourceConnections>
+    <classifierPreferences xsi:type="editmodel:UMLClassDiagramClassifierPreference" showStereotype="true" attributeSorter="Natural" methodSorter="Natural" innerClassSorter="Natural" showPublicAttributes="true" showPackageAttributes="true" showStaticAttributes="true" showPackageMethods="true" showStaticMethods="true" showPublicInnerClasses="true" showPackageInnerClasses="true" showStaticInnerClasses="true" packageIndication="3" showAttributeProperty="true"/>
+  </children>
+  <children xsi:type="editmodel:ClassEditModel" name="DataInputStreamExtended" location="510,388" size="209,57" id="org.apache.isis.core.commons.encoding/DataInputStreamExtended" runTimeClassModel="dataInputStream">
+    <children xsi:type="editmodel:CompartmentEditModel" size="182,18">
+      <children xsi:type="editmodel:AttributeEditModel" name="dataInputStream" id="org.apache.isis.core.commons.encoding/DataInputStreamExtended#dataInputStream"/>
+    </children>
+    <children xsi:type="editmodel:CompartmentEditModel" size="0,0"/>
+    <children xsi:type="editmodel:CompartmentEditModel" size="0,0"/>
+    <sourceConnections xsi:type="editmodel:GeneralizationEditModel" targetConnections="//@children.3/@sourceConnections.0" autoLocated="true" id="org.apache.isis.core.commons.encoding/DataInputExtended&lt;-org.apache.isis.core.commons.encoding/DataInputStreamExtended" source="//@children.5" target="//@children.2" targetEnd="//@children.5/@sourceConnections.0/@children.1" sourceEnd="//@children.5/@sourceConnections.0/@children.0" connectionRouterKind="GeneralizationManhattan">
+      <children xsi:type="editmodel:AssociationEndEditModel" location="104,0" anchorKind="FixedAtEdge" attachSource="true"/>
+      <children xsi:type="editmodel:AssociationEndEditModel" location="81,315" anchorKind="FixedAtEdge"/>
+    </sourceConnections>
+    <classifierPreferences xsi:type="editmodel:UMLClassDiagramClassifierPreference" showStereotype="true" attributeSorter="Natural" methodSorter="Natural" innerClassSorter="Natural" showPublicAttributes="true" showPackageAttributes="true" showStaticAttributes="true" showPackageMethods="true" showStaticMethods="true" showPublicInnerClasses="true" showPackageInnerClasses="true" showStaticInnerClasses="true" packageIndication="3" showAttributeProperty="true"/>
+  </children>
+  <children xsi:type="editmodel:ClassEditModel" name="DataOutputStreamExtended" location="15,435" size="223,57" id="org.apache.isis.core.commons.encoding/DataOutputStreamExtended" runTimeClassModel="dataOutputStream">
+    <children xsi:type="editmodel:CompartmentEditModel" size="200,18">
+      <children xsi:type="editmodel:AttributeEditModel" name="dataOutputStream" id="org.apache.isis.core.commons.encoding/DataOutputStreamExtended#dataOutputStream"/>
+    </children>
+    <children xsi:type="editmodel:CompartmentEditModel" size="0,0"/>
+    <children xsi:type="editmodel:CompartmentEditModel" size="0,0"/>
+    <sourceConnections xsi:type="editmodel:GeneralizationEditModel" id="org.apache.isis.core.commons.encoding/DataOutputExtended&lt;-org.apache.isis.core.commons.encoding/DataOutputStreamExtended" source="//@children.6" target="//@children.9" targetEnd="//@children.6/@sourceConnections.0/@children.1" sourceEnd="//@children.6/@sourceConnections.0/@children.0" connectionRouterKind="Manhattan">
+      <children xsi:type="editmodel:AssociationEndEditModel" location="125,-1" anchorKind="FixedAtEdge" attachSource="true"/>
+      <children xsi:type="editmodel:AssociationEndEditModel" location="86,350"/>
+    </sourceConnections>
+    <classifierPreferences xsi:type="editmodel:UMLClassDiagramClassifierPreference" showStereotype="true" attributeSorter="Natural" methodSorter="Natural" innerClassSorter="Natural" showPublicAttributes="true" showPackageAttributes="true" showStaticAttributes="true" showPackageMethods="true" showStaticMethods="true" showPublicInnerClasses="true" showPackageInnerClasses="true" showStaticInnerClasses="true" packageIndication="3" showAttributeProperty="true"/>
+  </children>
+  <children xsi:type="editmodel:ClassEditModel" name="DebugDataOutputExtended" location="281,499" size="214,29" id="org.apache.isis.core.commons.encoding/DebugDataOutputExtended" runTimeClassModel="">
+    <children xsi:type="editmodel:CompartmentEditModel" size="0,0"/>
+    <children xsi:type="editmodel:CompartmentEditModel" size="0,0"/>
+    <children xsi:type="editmodel:CompartmentEditModel" size="0,0"/>
+    <sourceConnections xsi:type="editmodel:GeneralizationEditModel" autoLocated="true" id="org.apache.isis.core.commons.encoding/DataOutputExtendedDecorator&lt;-org.apache.isis.core.commons.encoding/DebugDataOutputExtended" source="//@children.7" target="//@children.8" targetEnd="//@children.7/@sourceConnections.0/@children.1" sourceEnd="//@children.7/@sourceConnections.0/@children.0" connectionRouterKind="Manual">
+      <children xsi:type="editmodel:AssociationEndEditModel" location="106,0" attachSource="true"/>
+      <children xsi:type="editmodel:AssociationEndEditModel" location="127,29"/>
+    </sourceConnections>
+    <classifierPreferences xsi:type="editmodel:UMLClassDiagramClassifierPreference" showStereotype="true" attributeSorter="Natural" methodSorter="Natural" innerClassSorter="Natural" showPublicAttributes="true" showPackageAttributes="true" showStaticAttributes="true" showPackageMethods="true" showStaticMethods="true" showPublicInnerClasses="true" showPackageInnerClasses="true" showStaticInnerClasses="true" packageIndication="3" showAttributeProperty="true"/>
+  </children>
+  <children xsi:type="editmodel:ClassEditModel" targetConnections="//@children.7/@sourceConnections.0" name="DataOutputExtendedDecorator" location="260,435" size="235,29" id="org.apache.isis.core.commons.encoding/DataOutputExtendedDecorator" runTimeClassModel="">
+    <children xsi:type="editmodel:CompartmentEditModel" size="0,0"/>
+    <children xsi:type="editmodel:CompartmentEditModel" size="0,0"/>
+    <children xsi:type="editmodel:CompartmentEditModel" size="0,0"/>
+    <sourceConnections xsi:type="editmodel:GeneralizationEditModel" id="org.apache.isis.core.commons.encoding/DataOutputExtended&lt;-org.apache.isis.core.commons.encoding/DataOutputExtendedDecorator" source="//@children.8" target="//@children.9" targetEnd="//@children.8/@sourceConnections.0/@children.1" sourceEnd="//@children.8/@sourceConnections.0/@children.0" connectionRouterKind="Manhattan">
+      <children xsi:type="editmodel:AssociationEndEditModel" location="117,0" anchorKind="FixedAtEdge" attachSource="true"/>
+      <children xsi:type="editmodel:AssociationEndEditModel" location="86,351" anchorKind="FixedAtEdge"/>
+    </sourceConnections>
+    <classifierPreferences xsi:type="editmodel:UMLClassDiagramClassifierPreference" showStereotype="true" attributeSorter="Natural" methodSorter="Natural" innerClassSorter="Natural" showPublicAttributes="true" showPackageAttributes="true" showStaticAttributes="true" showPackageMethods="true" showStaticMethods="true" showPublicInnerClasses="true" showPackageInnerClasses="true" showStaticInnerClasses="true" packageIndication="3" showAttributeProperty="true"/>
+  </children>
+  <children xsi:type="editmodel:InterfaceEditModel" targetConnections="//@children.8/@sourceConnections.0 //@children.6/@sourceConnections.0" name="DataOutputExtended" location="150,14" size="173,351" id="org.apache.isis.core.commons.encoding/DataOutputExtended" runTimeClassModel="writeByte(I),writeBooleans([Z),writeEncodables([Ljava.lang.Object;),getDataOutputStream(),writeUTFs([Ljava.lang.String;),writeSerializables([Ljava.lang.Object;),writeEncodable(Ljava.lang.Object;),writeShorts([S),writeInts([I),writeLongs([J),writeChars([C),writeSerializable(Ljava.lang.Object;),writeBytes([B),writeFloats([F),write(I),writeDoubles([D)">
+    <children xsi:type="editmodel:CompartmentEditModel" size="0,0"/>
+    <children xsi:type="editmodel:CompartmentEditModel" size="133,288">
+      <children xsi:type="editmodel:MethodEditModel" name="getDataOutputStream" id="org.apache.isis.core.commons.encoding/DataOutputExtended#getDataOutputStream()"/>
+      <children xsi:type="editmodel:MethodEditModel" name="write" id="org.apache.isis.core.commons.encoding/DataOutputExtended#write(I)"/>
+      <children xsi:type="editmodel:MethodEditModel" name="writeBooleans" id="org.apache.isis.core.commons.encoding/DataOutputExtended#writeBooleans([Z)"/>
+      <children xsi:type="editmodel:MethodEditModel" name="writeByte" id="org.apache.isis.core.commons.encoding/DataOutputExtended#writeByte(I)"/>
+      <children xsi:type="editmodel:MethodEditModel" name="writeBytes" id="org.apache.isis.core.commons.encoding/DataOutputExtended#writeBytes([B)"/>
+      <children xsi:type="editmodel:MethodEditModel" name="writeChars" id="org.apache.isis.core.commons.encoding/DataOutputExtended#writeChars([C)"/>
+      <children xsi:type="editmodel:MethodEditModel" name="writeDoubles" id="org.apache.isis.core.commons.encoding/DataOutputExtended#writeDoubles([D)"/>
+      <children xsi:type="editmodel:MethodEditModel" name="writeEncodable" id="org.apache.isis.core.commons.encoding/DataOutputExtended#writeEncodable(Ljava.lang.Object;)"/>
+      <children xsi:type="editmodel:MethodEditModel" name="writeEncodables" id="org.apache.isis.core.commons.encoding/DataOutputExtended#writeEncodables([Ljava.lang.Object;)"/>
+      <children xsi:type="editmodel:MethodEditModel" name="writeFloats" id="org.apache.isis.core.commons.encoding/DataOutputExtended#writeFloats([F)"/>
+      <children xsi:type="editmodel:MethodEditModel" name="writeInts" id="org.apache.isis.core.commons.encoding/DataOutputExtended#writeInts([I)"/>
+      <children xsi:type="editmodel:MethodEditModel" name="writeLongs" id="org.apache.isis.core.commons.encoding/DataOutputExtended#writeLongs([J)"/>
+      <children xsi:type="editmodel:MethodEditModel" name="writeSerializable" id="org.apache.isis.core.commons.encoding/DataOutputExtended#writeSerializable(Ljava.lang.Object;)"/>
+      <children xsi:type="editmodel:MethodEditModel" name="writeSerializables" id="org.apache.isis.core.commons.encoding/DataOutputExtended#writeSerializables([Ljava.lang.Object;)"/>
+      <children xsi:type="editmodel:MethodEditModel" name="writeShorts" id="org.apache.isis.core.commons.encoding/DataOutputExtended#writeShorts([S)"/>
+      <children xsi:type="editmodel:MethodEditModel" name="writeUTFs" id="org.apache.isis.core.commons.encoding/DataOutputExtended#writeUTFs([Ljava.lang.String;)"/>
+    </children>
+    <children xsi:type="editmodel:CompartmentEditModel" size="0,0"/>
+    <classifierPreferences xsi:type="editmodel:UMLClassDiagramClassifierPreference" showStereotype="true" attributeSorter="Natural" methodSorter="Natural" innerClassSorter="Natural" showPublicAttributes="true" showPackageAttributes="true" showStaticAttributes="true" showPublicMethods="true" showPackageMethods="true" showStaticMethods="true" showPublicInnerClasses="true" showPackageInnerClasses="true" showStaticInnerClasses="true" packageIndication="3" showAttributeProperty="true"/>
+  </children>
+  <diagramOptions xsi:type="options:ClassDiagramOptions" level="-1" showScope="InPackage" properties="wireOptions=3;Product=eUML2"/>
+  <boardSetting snapToGeometry="true" gridEnabled="true" gridSpacing="15,15" gridOrigin="0,0" rulerUnit="pixel" gridVisibility="false">
+    <leftRuler/>
+    <topRuler/>
+  </boardSetting>
+  <classDiagramPreferences xsi:type="editmodel:UMLClassDiagramPreference" showPopupBars="true" showConnectionHandles="true" attributeSorter="Natural" methodSorter="Natural" showClassStereotype="true" showPackageStereotype="true" showDependencyStereotype="true" showInterfaceStereotype="true" innerClassSorter="Natural" showPublicAttributes="true" showPackageAttributes="true" showStaticAttributes="true" showPublicMethods="true" showPackageMethods="true" showStaticMethods="true" showPublicInnerClasses="true" showPackageInnerClasses="true" showStaticInnerClasses="true" packageIndication="3" showAttributeProperty="true"/>
+</editmodel:ClassDiagramEditModel>

http://git-wip-us.apache.org/repos/asf/isis/blob/e4735c72/framework/core/metamodel/src/main/java/org/apache/isis/core/commons/encoding/package-info.java
----------------------------------------------------------------------
diff --git a/framework/core/metamodel/src/main/java/org/apache/isis/core/commons/encoding/package-info.java b/framework/core/metamodel/src/main/java/org/apache/isis/core/commons/encoding/package-info.java
new file mode 100644
index 0000000..4bab80b
--- /dev/null
+++ b/framework/core/metamodel/src/main/java/org/apache/isis/core/commons/encoding/package-info.java
@@ -0,0 +1,30 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+/**
+ * The {@link org.apache.isis.core.commons.ensure.Ensure} and {@link org.junit.Assert}
+ * classes provide the ability to specify assertions about state,
+ * throwing an exception ("fail early") if the assertion fails.
+ * 
+ * <p>
+ * The {@link org.apache.isis.core.commons.ensure.Ensure} class
+ * uses {@link org.hamcrest.Matcher Hamcrest matcher}s and is
+ * more powerful so generally to be preferred.
+ */
+package org.apache.isis.core.commons.encoding;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/isis/blob/e4735c72/framework/core/metamodel/src/main/java/org/apache/isis/core/commons/ensure/Assert.java
----------------------------------------------------------------------
diff --git a/framework/core/metamodel/src/main/java/org/apache/isis/core/commons/ensure/Assert.java b/framework/core/metamodel/src/main/java/org/apache/isis/core/commons/ensure/Assert.java
new file mode 100644
index 0000000..b0e0e86
--- /dev/null
+++ b/framework/core/metamodel/src/main/java/org/apache/isis/core/commons/ensure/Assert.java
@@ -0,0 +1,92 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.isis.core.commons.ensure;
+
+public final class Assert {
+
+    public static void assertEquals(final Object expected, final Object actual) {
+        assertEquals("", expected, actual);
+    }
+
+    public static void assertEquals(final String message, final int expected, final int value) {
+        if (expected != value) {
+            throw new IsisAssertException(message + " expected " + expected + "; but was " + value);
+        }
+    }
+
+    public static void assertEquals(final String message, final Object expected, final Object actual) {
+        assertTrue(message + ": expected " + expected + " but was " + actual, (expected == null && actual == null) || (expected != null && expected.equals(actual)));
+    }
+
+    public static void assertFalse(final boolean flag) {
+        assertFalse("expected false", flag);
+    }
+
+    public static void assertFalse(final String message, final boolean flag) {
+        assertTrue(message, !flag);
+    }
+
+    public static void assertFalse(final String message, final Object target, final boolean flag) {
+        assertTrue(message, target, !flag);
+    }
+
+    public static void assertNotNull(final Object object) {
+        assertNotNull("", object);
+    }
+
+    public static void assertNotNull(final String message, final Object object) {
+        assertTrue("unexpected null: " + message, object != null);
+    }
+
+    public static void assertNotNull(final String message, final Object target, final Object object) {
+        assertTrue(message, target, object != null);
+    }
+
+    public static void assertNull(final Object object) {
+        assertTrue("unexpected reference; should be null", object == null);
+    }
+
+    public static void assertNull(final String message, final Object object) {
+        assertTrue(message, object == null);
+    }
+
+    public static void assertSame(final Object expected, final Object actual) {
+        assertSame("", expected, actual);
+    }
+
+    public static void assertSame(final String message, final Object expected, final Object actual) {
+        assertTrue(message + ": expected " + expected + " but was " + actual, expected == actual);
+    }
+
+    public static void assertTrue(final boolean flag) {
+        assertTrue("expected true", flag);
+    }
+
+    public static void assertTrue(final String message, final boolean flag) {
+        assertTrue(message, null, flag);
+    }
+
+    public static void assertTrue(final String message, final Object target, final boolean flag) {
+        if (!flag) {
+            throw new IsisAssertException(message + (target == null ? "" : (": " + target)));
+        }
+    }
+
+}