class NextObjectiveCodec extends JsonCodec<NextObjective> {

    @Override
    public ObjectNode encode(NextObjective nextObjective, CodecContext context) {

        checkNotNull(nextObjective, NOT_NULL_MESSAGE);

        final JsonCodec<TrafficTreatment> trafficTreatmentCodec = context.codec(TrafficTreatment.class);
        final JsonCodec<TrafficSelector> trafficSelectorCodec = context.codec(TrafficSelector.class);

        // encode common properties
        ObjectiveCodecHelper och = new ObjectiveCodecHelper();
        ObjectNode result = och.encode(nextObjective, context);

        // encode id
        result.put(ID, nextObjective.id());

        // encode type
        result.put(TYPE, nextObjective.type().toString());

        // encode operation
        result.put(OPERATION, nextObjective.op().toString());

        // encode treatments
        ArrayNode treatments = context.mapper().createArrayNode();
        nextObjective.next().forEach(t -> {
            ObjectNode treatmentJson = trafficTreatmentCodec.encode(t, context);
            treatments.add(treatmentJson);
        });
        result.set(TREATMENTS, treatments);

        // encode meta
        if (nextObjective.meta() != null) {
            ObjectNode trafficSelectorNode = trafficSelectorCodec.encode(nextObjective.meta(), context);
            result.set(META, trafficSelectorNode);
        }

        return result;
    }

}