/**
  * Excludes the current object being edited from the collection if:
  *
  * <ul>
  *   <li>excludeWithDefaultValues is {@code true}
  *   <li>it has default values; and
  *   <li>excluding the object won't invalidate the collection's minimum cardinality
  * </ul>
  *
  * <p>This is so that incomplete objects that contain no user-entered data can be excluded from
  * commits.
  *
  * @return {@code true} if an incomplete object was excluded; otherwise {@code false}
  */
 private boolean excludeObjectWithDefaultValues() {
   IMObjectEditor editor = getCurrentEditor();
   boolean excluded = false;
   if (excludeDefaultValueObject && editor != null) {
     CollectionPropertyEditor collection = getCollectionPropertyEditor();
     IMObject object = editor.getObject();
     List<IMObject> list = collection.getObjects();
     if (hasDefaultValues(editor)) {
       // NOTE: object not in the collection until added, but its editor will still be registered
       boolean inList = list.contains(object);
       int inListSize =
           inList ? list.size() : list.size() + 1; // size of the collection with the obj present
       // only exclude if excluding it doesn't invalidate cardinality constraints
       if (inListSize - 1 >= collection.getMinCardinality()) {
         collection.remove(object);
         excluded = true;
       } else if (inListSize - 1 < collection.getMinCardinality()) {
         if (!inList) {
           // add it if its required to get closer to min cardinality
           addEdited(editor);
         }
       } else {
         // can exclude
         excluded = true;
       }
     } else {
       // user has changed the object, so ensure it is added
       addEdited(editor);
     }
   }
   return excluded;
 }
 /**
  * Returns the set of acts being edited, including that of the {@link #getCurrentEditor()}.
  *
  * @return the set of acts being edited
  */
 public List<Act> getCurrentActs() {
   Set<Act> result = new LinkedHashSet<>(getActs());
   IMObjectEditor current = getCurrentEditor();
   if (current != null) {
     result.add((Act) current.getObject());
   }
   return new ArrayList<>(result);
 }
 /** Invoked when the current editor is modified. */
 @Override
 protected void onCurrentEditorModified() {
   IMObjectEditor editor = getCurrentEditor();
   if (editor != null) {
     // flag the editor as modified before delegating to super, otherwise it may be needlessly
     // unmapped from the
     // collection by excludeObjectWithDefaultValues()
     Act object = (Act) editor.getObject();
     setModified(object, true);
   }
   super.onCurrentEditorModified();
 }
 /**
  * Determines if an object associated with an editor contains default values.
  *
  * <p>This only applies to new objects. These are considered to have default values if they
  * haven't been modified since the editor was created (the editor typically initialises default
  * values within its constructor).
  *
  * @param editor the editor
  * @return {@code true} if the object has default values
  */
 private boolean hasDefaultValues(IMObjectEditor editor) {
   boolean result = false;
   IMObject object = editor.getObject();
   if (object.isNew()) {
     Boolean changed = modified.get(object.getObjectReference());
     if (changed != null && !changed) {
       result = true;
     }
   }
   return result;
 }