@Override
  public byte[] toBinary() {
    int byteBufferLength = 20 + (2 * orderedSfcIndexToTierId.size());
    final List<byte[]> orderedSfcBinaries = new ArrayList<byte[]>(orderedSfcs.length);
    final List<byte[]> dimensionBinaries = new ArrayList<byte[]>(baseDefinitions.length);
    for (final SpaceFillingCurve sfc : orderedSfcs) {
      final byte[] sfcBinary = PersistenceUtils.toBinary(sfc);
      byteBufferLength += (4 + sfcBinary.length);
      orderedSfcBinaries.add(sfcBinary);
    }
    for (final NumericDimensionDefinition dimension : baseDefinitions) {
      final byte[] dimensionBinary = PersistenceUtils.toBinary(dimension);
      byteBufferLength += (4 + dimensionBinary.length);
      dimensionBinaries.add(dimensionBinary);
    }
    final ByteBuffer buf = ByteBuffer.allocate(byteBufferLength);
    buf.putInt(orderedSfcs.length);
    buf.putInt(baseDefinitions.length);
    buf.putInt(orderedSfcIndexToTierId.size());
    buf.putLong(maxEstimatedDuplicateIds);
    for (final byte[] sfcBinary : orderedSfcBinaries) {
      buf.putInt(sfcBinary.length);
      buf.put(sfcBinary);
    }
    for (final byte[] dimensionBinary : dimensionBinaries) {
      buf.putInt(dimensionBinary.length);
      buf.put(dimensionBinary);
    }
    for (final Entry<Integer, Byte> entry : orderedSfcIndexToTierId.entrySet()) {
      buf.put(entry.getKey().byteValue());
      buf.put(entry.getValue());
    }

    return buf.array();
  }
 @Override
 public Set<ByteArrayId> getNaturalSplits() {
   final Set<ByteArrayId> retVal = new HashSet<ByteArrayId>(orderedSfcIndexToTierId.size());
   for (final Byte tier : orderedSfcIndexToTierId.values()) {
     retVal.add(new ByteArrayId(new byte[] {tier}));
   }
   return retVal;
 }