/**
  * Matches the contents of a mod ODU singal Id instruction.
  *
  * @param instructionJson JSON instruction to match
  * @param description Description object used for recording errors
  * @return true if contents matches, false otherwise
  */
 private boolean matchModOduSingalIdInstruction(
     JsonNode instructionJson, Description description) {
   ModOduSignalIdInstruction instructionToMatch = (ModOduSignalIdInstruction) instruction;
   String jsonSubType = instructionJson.get("subtype").textValue();
   if (!instructionToMatch.subtype().name().equals(jsonSubType)) {
     description.appendText("subtype was " + jsonSubType);
     return false;
   }
   String jsonType = instructionJson.get("type").textValue();
   if (!instructionToMatch.type().name().equals(jsonType)) {
     description.appendText("type was " + jsonType);
     return false;
   }
   final JsonNode jsonOduSignal = instructionJson.get("oduSignalId");
   int jsonTpn = jsonOduSignal.get("tributaryPortNumber").intValue();
   int jsonTsLen = jsonOduSignal.get("tributarySlotLength").intValue();
   byte[] tributaryBitMap =
       HexString.fromHexString(jsonOduSignal.get("tributarySlotBitmap").asText());
   OduSignalId jsonOduSignalId = OduSignalId.oduSignalId(jsonTpn, jsonTsLen, tributaryBitMap);
   if (!instructionToMatch.oduSignalId().equals(jsonOduSignalId)) {
     description.appendText("oduSignalId was " + instructionToMatch);
     return false;
   }
   return true;
 }
    @Override
    public Criterion decodeCriterion(ObjectNode json) {
      JsonNode oduSignalId =
          nullIsIllegal(
              json.get(CriterionCodec.ODU_SIGNAL_ID),
              CriterionCodec.TRIBUTARY_PORT_NUMBER + MISSING_MEMBER_MESSAGE);

      int tributaryPortNumber =
          nullIsIllegal(
                  oduSignalId.get(CriterionCodec.TRIBUTARY_PORT_NUMBER),
                  CriterionCodec.TRIBUTARY_PORT_NUMBER + MISSING_MEMBER_MESSAGE)
              .asInt();
      int tributarySlotLen =
          nullIsIllegal(
                  oduSignalId.get(CriterionCodec.TRIBUTARY_SLOT_LEN),
                  CriterionCodec.TRIBUTARY_SLOT_LEN + MISSING_MEMBER_MESSAGE)
              .asInt();
      byte[] tributarySlotBitmap =
          HexString.fromHexString(
              nullIsIllegal(
                      oduSignalId.get(CriterionCodec.TRIBUTARY_SLOT_BITMAP),
                      CriterionCodec.TRIBUTARY_SLOT_BITMAP + MISSING_MEMBER_MESSAGE)
                  .asText());

      return Criteria.matchOduSignalId(
          OduSignalId.oduSignalId(tributaryPortNumber, tributarySlotLen, tributarySlotBitmap));
    }