class FlowRuleCodec extends JsonCodec<FlowRule> {

    @Override
    public ObjectNode encode(FlowRule flowRule, CodecContext context) {
        checkNotNull(flowRule, "Flow rule cannot be null");

        CoreService service = context.getService(CoreService.class);
        ApplicationId appId = service.getAppId(flowRule.appId());
        String strAppId = (appId == null) ? "<none>" : appId.name();

        final ObjectNode result = context.mapper().createObjectNode()
                .put("id", Long.toString(flowRule.id().value()))
                .put("tableId", flowRule.tableId())
                .put("appId", strAppId)
                .put("priority", flowRule.priority())
                .put("timeout", flowRule.timeout())
                .put("isPermanent", flowRule.isPermanent())
                .put("deviceId", flowRule.deviceId().toString());

        if (flowRule.treatment() != null) {
            final JsonCodec<TrafficTreatment> treatmentCodec =
                    context.codec(TrafficTreatment.class);
            result.set("treatment", treatmentCodec.encode(flowRule.treatment(), context));
        }

        if (flowRule.selector() != null) {
            final JsonCodec<TrafficSelector> selectorCodec =
                    context.codec(TrafficSelector.class);
            result.set("selector", selectorCodec.encode(flowRule.selector(), context));
        }

        return result;
    }

}