static RoutableFactory createCreateVisitorMessageFactory() {
        return ProtobufCodecBuilder
                .of(CreateVisitorMessage.class, DocapiVisiting.CreateVisitorRequest.class)
                .encoder((apiMsg) -> {
                    var builder = DocapiVisiting.CreateVisitorRequest.newBuilder()
                            .setBucketSpace(toProtoBucketSpace(apiMsg.getBucketSpace()))
                            .setVisitorLibraryName(apiMsg.getLibraryName())
                            .setInstanceId(apiMsg.getInstanceId())
                            .setControlDestination(apiMsg.getControlDestination())
                            .setDataDestination(apiMsg.getDataDestination())
                            .setSelection(toProtoDocumentSelection(apiMsg.getDocumentSelection()))
                            .setFieldSet(toProtoFieldSet(apiMsg.getFieldSet()))
                            .setMaxPendingReplyCount(apiMsg.getMaxPendingReplyCount())
                            .setFromTimestamp(apiMsg.getFromTimestamp())
                            .setToTimestamp(apiMsg.getToTimestamp())
                            .setVisitTombstones(apiMsg.getVisitRemoves())
                            .setVisitInconsistentBuckets(apiMsg.getVisitInconsistentBuckets())
                            .setMaxBucketsPerVisitor(apiMsg.getMaxBucketsPerVisitor());
                    for (var id : apiMsg.getBuckets()) {
                        builder.addBuckets(toProtoBucketId(id));
                    }
                    for (var entry : apiMsg.getParameters().entrySet()) {
                        builder.addParameters(toProtoVisitorParameter(entry.getKey(), entry.getValue()));
                    }
                    return builder.build();
                })
                .decoder(DocapiVisiting.CreateVisitorRequest.parser(), (protoMsg) -> {
                    var msg = new CreateVisitorMessage();
                    msg.setBucketSpace(fromProtoBucketSpace(protoMsg.getBucketSpace()));
                    msg.setLibraryName(protoMsg.getVisitorLibraryName());
                    msg.setInstanceId(protoMsg.getInstanceId());
                    msg.setControlDestination(protoMsg.getControlDestination());
                    msg.setDataDestination(protoMsg.getDataDestination());
                    msg.setDocumentSelection(fromProtoDocumentSelection(protoMsg.getSelection()));
                    msg.setFieldSet(fromProtoFieldSet(protoMsg.getFieldSet()));
                    msg.setMaxPendingReplyCount(protoMsg.getMaxPendingReplyCount());
                    msg.setFromTimestamp(protoMsg.getFromTimestamp());
                    msg.setToTimestamp(protoMsg.getToTimestamp());
                    msg.setVisitRemoves(protoMsg.getVisitTombstones());
                    msg.setVisitInconsistentBuckets(protoMsg.getVisitInconsistentBuckets());
                    msg.setMaxBucketsPerVisitor(protoMsg.getMaxBucketsPerVisitor());
                    for (var protoId : protoMsg.getBucketsList()) {
                        msg.getBuckets().add(fromProtoBucketId(protoId));
                    }
                    for (var protoParam : protoMsg.getParametersList()) {
                        msg.getParameters().put(protoParam.getKey(), protoParam.getValue().toByteArray());
                    }
                    return msg;
                })
                .build();
    }
Implementation of MessageBus message request/response serialization built around Protocol Buffers.
documentapi/src/main/java/com/yahoo/documentapi/messagebus/protocol/RoutableFactories80.java