class MapMarshaller<K, V> implements BytesReader<Map<K, V>>, BytesWriter<Map<K, V>>,
        StatefulCopyable<MapMarshaller<K, V>> {

    // Config fields
    private BytesReader<K> keyReader;
    private BytesWriter<? super K> keyWriter;
    private BytesReader<V> valueReader;
    private BytesWriter<? super V> valueWriter;

    // Cache fields
    private transient Deque<K> orderedKeys;
    private transient Deque<V> orderedValues;

    /**
     * Constructs a {@code MapMarshaller} with the given map keys' and values' serializers.
     *
     * @param keyReader   map keys' reader
     * @param keyWriter   map keys' writer
     * @param valueReader map values' reader
     * @param valueWriter map values' writer
     */
    public MapMarshaller(
            BytesReader<K> keyReader, BytesWriter<? super K> keyWriter,
            BytesReader<V> valueReader, BytesWriter<? super V> valueWriter) {
        this.keyReader = keyReader;
        this.keyWriter = keyWriter;
        this.valueReader = valueReader;
        this.valueWriter = valueWriter;
        initTransients();
    }

    private void initTransients() {
        orderedKeys = new ArrayDeque<>();
        orderedValues = new ArrayDeque<>();
    }

    @NotNull
    @Override
    public Map<K, V> read(Bytes in, @Nullable Map<K, V> using) {<FILL_FUNCTION_BODY>}

    @Override
    public void write(Bytes out, @NotNull Map<K, V> toWrite) {
        out.writeInt(toWrite.size());
        toWrite.forEach((k, v) -> {
            keyWriter.write(out, k);
            valueWriter.write(out, v);
        });
    }

    @Override
    public MapMarshaller<K, V> copy() {
        return new MapMarshaller<>(copyIfNeeded(keyReader), copyIfNeeded(keyWriter),
                copyIfNeeded(valueReader), copyIfNeeded(valueWriter));
    }

    @Override
    public void readMarshallable(@NotNull WireIn wireIn) {
        keyReader = wireIn.read(() -> "keyReader").typedMarshallable();
        keyWriter = wireIn.read(() -> "keyWriter").typedMarshallable();
        valueReader = wireIn.read(() -> "valueReader").typedMarshallable();
        valueWriter = wireIn.read(() -> "valueWriter").typedMarshallable();
        initTransients();
    }

    @Override
    public void writeMarshallable(@NotNull WireOut wireOut) {
        wireOut.write(() -> "keyReader").typedMarshallable(keyReader);
        wireOut.write(() -> "keyWriter").typedMarshallable(keyWriter);
        wireOut.write(() -> "valueReader").typedMarshallable(valueReader);
        wireOut.write(() -> "valueWriter").typedMarshallable(valueWriter);
    }
}

        int size = in.readInt();
        if (using == null) {
            using = new HashMap<>(((int) (size / 0.75)));
            for (int i = 0; i < size; i++) {
                using.put(keyReader.read(in, null), valueReader.read(in, null));
            }
        } else {
            using.forEach((k, v) -> {
                orderedKeys.add(k);
                orderedValues.add(v);
            });
            using.clear();
            for (int i = 0; i < size; i++) {
                using.put(keyReader.read(in, orderedKeys.pollFirst()),
                        valueReader.read(in, orderedValues.pollFirst()));
            }
            orderedKeys.clear(); // for GC, avoid zombie object links
            orderedValues.clear();
        }
        return using;
    
<no_super_class>