+public abstract class Message<T extends WritableIdentifier, C extends Message<T, C>>
+ implements Immutable, Serializable {
+ /**
+ * Externalizable proxy for use with {@link Message} subclasses.
+ *
+ * @param <T> Target identifier type
+ * @param <C> Message class
+ */
+ protected interface SerialForm<T extends WritableIdentifier, C extends Message<T, C>> extends Externalizable {
+
+ @NonNull C message();
+
+ void setMessage(@NonNull C message);
+
+ @Override
+ default void writeExternal(final ObjectOutput out) throws IOException {
+ final var message = message();
+ message.getTarget().writeTo(out);
+ WritableObjects.writeLong(out, message.getSequence());
+ writeExternal(out, message);
+ }
+
+ void writeExternal(@NonNull ObjectOutput out, @NonNull C msg) throws IOException;
+
+ @Override
+ default void readExternal(final ObjectInput in) throws IOException, ClassNotFoundException {
+ final var target = verifyNotNull(readTarget(in));
+ final var sequence = WritableObjects.readLong(in);
+ setMessage(verifyNotNull(readExternal(in, target, sequence)));
+ }
+
+ @NonNull C readExternal(@NonNull ObjectInput in, @NonNull T target, long sequence)
+ throws IOException, ClassNotFoundException;
+
+ Object readResolve();
+
+ @NonNull T readTarget(@NonNull DataInput in) throws IOException;
+ }
+
+ @java.io.Serial