/** * Does a diff of two values. * * @return a {@link StateDiff}, a {@link ListDiff}, {@link #NOP}, or an actual value (including * {@code null}) */ public static Serializable diff(Object a, Object b) { if (equalsLoose(a, b)) { return NOP; } if (a instanceof Object[] && b instanceof Object[]) { return diff((Object[]) a, (Object[]) b); } if (a instanceof List && b instanceof List) { @SuppressWarnings("unchecked") List<Object> la = (List<Object>) a; @SuppressWarnings("unchecked") List<Object> lb = (List<Object>) b; return (Serializable) diff(la, lb); } if (a instanceof State && b instanceof State) { StateDiff diff = diff((State) a, (State) b); return diff.isEmpty() ? NOP : diff; } return (Serializable) b; }