code: @Action(
              semantics = SemanticsOf.IDEMPOTENT,
              invokeOn = InvokeOn.OBJECT_AND_COLLECTION
      )
      public ExcelModuleDemoToDoItem apply() {
          ExcelModuleDemoToDoItem item = getToDoItem();
          if(item == null) {
              // description must be unique, so check
              item = toDoItems.findByDescription(getDescription());
              if(item != null) {
                  getContainer().warnUser("Item already exists with description '" + getDescription() + "'");
              } else {
                  // create new item
                  // (since this is just a demo, haven't bothered to validate new values)
                  item = toDoItems.newToDo(getDescription(), getCategory(), getSubcategory(), getDueBy(), getCost());
                  item.setNotes(getNotes());
                  item.setOwnedBy(getOwnedBy());
                  item.setComplete(isComplete());
              }
          } else {
              // copy over new values
              // (since this is just a demo, haven't bothered to validate new values)
              item.setDescription(getDescription());
              item.setCategory(getCategory());
              item.setSubcategory(getSubcategory());
              item.setDueBy(getDueBy());
              item.setCost(getCost());
              item.setNotes(getNotes());
              item.setOwnedBy(getOwnedBy());
              item.setComplete(isComplete());
          }
          return actionInvocationContext.getInvokedOn().isCollection()? null: item;
      }
docs: //////////////////////////////////////