class MeterCodec extends JsonCodec<Meter> {

    @Override
    public ObjectNode encode(Meter meter, CodecContext context) {
        checkNotNull(meter, "Meter cannot be null");
        ObjectNode result = context.mapper().createObjectNode()
                .put(ID, meter.id().toString())
                .put(LIFE, meter.life())
                .put(PACKETS, meter.packetsSeen())
                .put(BYTES, meter.bytesSeen())
                .put(REFERENCE_COUNT, meter.referenceCount())
                .put(UNIT, meter.unit().toString())
                .put(BURST, meter.isBurst())
                .put(DEVICE_ID, meter.deviceId().toString());

        if (meter.appId() != null) {
            result.put(APP_ID, meter.appId().toString());
        }

        if (meter.state() != null) {
            result.put(STATE, meter.state().toString());
        }

        ArrayNode bands = context.mapper().createArrayNode();
        meter.bands().forEach(band -> {
            ObjectNode bandJson = context.codec(Band.class).encode(band, context);
            bands.add(bandJson);
        });
        result.set(BANDS, bands);
        return result;
    }

}