class DriverCodec extends JsonCodec<Driver> {

    @Override
    public ObjectNode encode(Driver driver, CodecContext context) {
        checkNotNull(driver, "Driver cannot be null");

        ObjectNode result = context.mapper().createObjectNode()
                .put(NAME, driver.name())
                .put(MANUFACTURER, driver.manufacturer())
                .put(HW_VERSION, driver.hwVersion())
                .put(SW_VERSION, driver.swVersion());

        if (driver.parent() != null) {
            result.put(PARENT, driver.parent().name());
        }

        ArrayNode behaviours = context.mapper().createArrayNode();
        driver.behaviours().forEach(behaviour -> {
            ObjectNode entry = context.mapper().createObjectNode()
                    .put(BEHAVIORS_NAME, behaviour.getCanonicalName())
                    .put(BEHAVIORS_IMPLEMENTATION_NAME,
                            driver.implementation(behaviour).getCanonicalName());

            behaviours.add(entry);
        });
        result.set(BEHAVIOURS, behaviours);

        ArrayNode properties = context.mapper().createArrayNode();
        driver.properties().forEach((name, value) -> {
            ObjectNode entry = context.mapper().createObjectNode()
                    .put("name", name)
                    .put("value", value);

            properties.add(entry);
        });
        result.set(PROPERTIES, properties);

        return result;
    }

}