Prototype: RecipeDraft retains copies of name/ingredient/step data; snapshot returns Draft with fresh nested lists. Empty content and duplicate items are valid; no name validation.

Final: addUser requires nonempty ID and only read/write permissions; validate before duplicate check, copy permissions. add requires nonempty current unique name and write permission; returns recipe1,recipe2,... only on success. update appends even identical content and returns Integer version; missing/no permission/name conflict returns null. get requires read; null version selects latest, invalid version returns null. history returns detached revisions in order or empty for denied/missing. rollback requires write and appends selected content if its historical name is available; preserve all versions. byIngredient requires read, matches current exact membership once per recipe, sorts ingredient-list size/name/ID. Empty lists/items and duplicates preserve order; empty names raise before permission checks.

The complete public API is in Exercise.java. All domain classes are public static nested classes of Exercise; construct them as new Exercise.ClassName(...). Do not implement a solution in the test runner. Each instance owns independent state. Unless explicitly allowed, null inputs are outside the domain. Failed operations leave state unchanged; validation happens before mutation.

Drag or use the arrow keys to resize. Home collapses the question; End collapses the editor. Enter or double-click resets the split.
Loading editor…
No results yet.

Complete the starter code, then run the checks.
Results and errors will appear here.

Java runs on this device with CheerpJ 4.3.