docs: private static void addFieldToJsonObject(Method getter, Object o,
                                               String fieldName, JsonObjectBuilder j) {
          try {
              Object fieldValue = getter.invoke(o);
  
              if (fieldValue == null) {
              } else if (fieldValue instanceof String) {
                  j.add(fieldName, (String) fieldValue);
              } else if (fieldValue instanceof Boolean) {
                  j.add(fieldName, (Boolean) fieldValue);
              } else if (fieldValue instanceof BigInteger) {
                  j.add(fieldName, (BigInteger) fieldValue);
              } else if (fieldValue instanceof java.math.BigDecimal) {
                  j.add(fieldName, (BigDecimal) fieldValue);
              } else if (fieldValue instanceof Double) {
                  j.add(fieldName, (Double) fieldValue);
              } else if (fieldValue instanceof Integer) {
                  j.add(fieldName, (Integer) fieldValue);
              } else if (fieldValue instanceof Long) {
                  j.add(fieldName, (Long) fieldValue);
              } else if (fieldValue instanceof Short) {
                  j.add(fieldName, (Short) fieldValue);
              } else if (fieldValue instanceof Byte) {
                  j.add(fieldName, (Byte) fieldValue);
  
              } else if (fieldValue instanceof Enum) {
                  try {
                      // enums need careful handling.. look for get/set Value to use.
                      Method getValueForEnumMethod = fieldValue.getClass().getMethod("getValue");
                      Object valueFromGetValueMethod = getValueForEnumMethod.invoke(fieldValue);
                      j.add(fieldName, valueFromGetValueMethod.toString());
                  } catch (NoSuchMethodException e) {
                      // else fallback to toString
                      j.add(fieldName, fieldValue.toString());
                  }
              } else if (fieldValue instanceof Collection
                         || fieldValue.getClass().getName().startsWith(DATA_MODEL_PACKAGE)) {
                  JSONArtrifactPair fieldObjects = findFieldsToSerialize(fieldValue);
                  j.add(fieldName, fieldObjects.mainObject);
                  if (fieldObjects.incompatibleFieldsObject != null && !fieldObjects.incompatibleFieldsObject.isEmpty()) {
                      // As per the contract on the HasBreakingChanges interface store incompatible fields in a second object
                      j.add(fieldName + "2", fieldObjects.incompatibleFieldsObject);
                  }
              } else if (fieldValue instanceof Calendar) {
                  Date date = ((Calendar) fieldValue).getTime();
                  j.add(fieldName, getDateFormat().format(date));
              } else if (fieldValue instanceof Date) {
                  j.add(fieldName, getDateFormat().format((Date) fieldValue));
              } else if (fieldValue instanceof Locale) {
                  //note that Locale toString is a bit fiddly to round trip, but it's the best we have for now.
                  String localeString = ((Locale) fieldValue).toString();
                  j.add(fieldName, localeString);
              } else {
                  throw new IllegalStateException("Data Model Error: Unknown data model entity "
                                                  + getter.getName() + " of type " + fieldValue.getClass().getName() + " on "
                                                  + o.getClass().getName());
              }
  
          } catch (IllegalAccessException e) {
              throw new IllegalStateException("Data Model Error: unable to invoke getter "
                                              + getter.getName() + " on "
                                              + o.getClass().getName(), e);
          } catch (IllegalArgumentException e) {
              throw new IllegalStateException("Data Model Error: unable to invoke getter "
                                              + getter.getName() + " on "
                                              + o.getClass().getName(), e);
          } catch (InvocationTargetException e) {
              throw new IllegalStateException("Data Model Error: unable to invoke getter "
                                              + getter.getName() + " on "
                                              + o.getClass().getName(), e);
          } catch (JsonException e) {
              // Shouldn't happen unless field name is null or the value cannot be converted
              throw new IllegalStateException("Data Model Error: unable to invoke getter "
                                              + getter.getName() + " on "
                                              + o.getClass().getName(), e);
          }
      }