class PatchUtils {

  public enum Format {
    YAML,
    JSON
  }

  private PatchUtils() {
  }

  public static String withoutRuntimeState(Object object, Format format, boolean omitStatus,
      KubernetesSerialization serialization) {
    Function<Object, String> mapper = format == Format.JSON ? serialization::asJson : serialization::asYaml;
    return mapper.apply(withoutRuntimeState(object, omitStatus, serialization));
  }

  static JsonNode withoutRuntimeState(Object object, boolean omitStatus, KubernetesSerialization serialization) {<FILL_FUNCTION_BODY>}

  private static void removeEmptyArrays(ObjectNode raw) {
    List<String> toRemove = new ArrayList<>();
    for (Iterator<String> names = raw.fieldNames(); names.hasNext();) {
      String name = names.next();
      JsonNode node = raw.get(name);
      if (node.isArray() && node.size() == 0) {
        toRemove.add(name);
      }
      if (node.isObject()) {
        removeEmptyArrays((ObjectNode) node);
      }
    }
    raw.remove(toRemove);
  }

  public static String jsonDiff(Object current, Object updated, boolean omitStatus, KubernetesSerialization serialization) {
    return serialization
        .asJson(JsonDiff.asJson(withoutRuntimeState(current, omitStatus, serialization),
            withoutRuntimeState(updated, omitStatus, serialization)));
  }

}

    ObjectNode raw = serialization.convertValue(object, ObjectNode.class);

    // it makes the diffs more compact to not have empty arrays
    removeEmptyArrays(raw);

    Optional.ofNullable(raw.get("metadata")).filter(ObjectNode.class::isInstance).map(ObjectNode.class::cast).ifPresent(m -> {
      m.remove("creationTimestamp");
      m.remove("deletionTimestamp");
      m.remove("generation");
      m.remove("selfLink");
      m.remove("uid");
    });
    if (omitStatus) {
      raw.remove("status");
    }
    return raw;
  
<no_super_class>