@Override
 public void writeData(final @NonNull OutputChannel channel, final @NonNull Datum datum) {
   if (!(channel instanceof BdbOutputChannel))
     throw new IllegalArgumentException("Not a BDB channel");
   final BdbOutputChannel bdbChannel = (BdbOutputChannel) channel;
   if (!(datum instanceof ContextualStringDatum))
     throw new IllegalArgumentException("Not an string datum");
   final ContextualStringDatum stringDatum = (ContextualStringDatum) datum;
   try {
     bdbChannel.writeDatumType(datum.getType());
     bdbChannel.dos.writeBoolean(stringDatum.unique);
     bdbChannel.writeNodeId(stringDatum.contextNodeId);
     bdbChannel.dos.writeUTF(stringDatum.value);
   } catch (final IOException e) {
     throw new FoobarError("Unable to save string data", e);
   }
 }
 @Override
 public void writeKey(final @NonNull OutputChannel channel, final @NonNull Datum datum) {
   if (!(channel instanceof BdbOutputChannel))
     throw new IllegalArgumentException("Not a BDB channel");
   final BdbOutputChannel bdbChannel = (BdbOutputChannel) channel;
   if (!(datum instanceof ContextualStringDatum))
     throw new IllegalArgumentException("Not an string datum");
   final ContextualStringDatum stringDatum = (ContextualStringDatum) datum;
   try {
     bdbChannel.writeDatumType(datum.getType());
     bdbChannel.dos.writeBoolean(stringDatum.unique);
     bdbChannel.writeNodeId(stringDatum.contextNodeId);
     // for the key we don't need to record the length because 1) it would
     // mess up the ordering and 2) we don't need to read it back
     final char[] chars = stringDatum.value.toCharArray();
     for (final char c : chars) bdbChannel.dos.writeChar(c);
   } catch (final IOException e) {
     throw new FoobarError("Unable to save string key", e);
   }
 }