@@ -0,0 +1,2984 @@
+package seedu.address.model.person;%0A%0Aimport java.util.Collection;%0Aimport java.util.Iterator;%0A%0Aimport javafx.collections.FXCollections;%0Aimport javafx.collections.ObservableList;%0Aimport seedu.address.commons.exceptions.DuplicateDataException;%0Aimport seedu.address.commons.util.CollectionUtil;%0A%0A/**%0A * A list of tasks that enforces uniqueness between its elements and does not allow nulls.%0A *%0A * Supports a minimal set of list operations.%0A *%0A * @see Task#equals(Object)%0A * @see CollectionUtil#elementsAreUnique(Collection)%0A */%0Apublic class UniqueTaskList implements Iterable%3CTask%3E %7B%0A%0A    /**%0A     * Signals that an operation would have violated the 'no duplicates' property of the list.%0A     */%0A    public static class DuplicateTaskException extends DuplicateDataException %7B%0A        protected DuplicateTaskException() %7B%0A            super(%22Operation would result in duplicate tasks%22);%0A        %7D%0A    %7D%0A%0A    /**%0A     * Signals that an operation targeting a specified person in the list would fail because%0A     * there is no such matching person in the list.%0A     */%0A    public static class TaskNotFoundException extends Exception %7B%7D%0A%0A    private final ObservableList%3CTask%3E internalList = FXCollections.observableArrayList();%0A%0A    /**%0A     * Constructs empty TaskList.%0A     */%0A    public UniqueTaskList() %7B%7D%0A%0A    /**%0A     * Returns true if the list contains an equivalent task as the given argument.%0A     */%0A    public boolean contains(ReadOnlyTask toCheck) %7B%0A        assert toCheck != null;%0A        return internalList.contains(toCheck);%0A    %7D%0A%0A    /**%0A     * Adds a task to the list.%0A     *%0A     * @throws DuplicateTaskException if the task to add is a duplicate of an existing task in the list.%0A     */%0A    public void add(Task toAdd) throws DuplicateTaskException %7B%0A        assert toAdd != null;%0A        if (contains(toAdd)) %7B%0A            throw new DuplicateTaskException();%0A        %7D%0A        internalList.add(toAdd);%0A    %7D%0A%0A    /**%0A     * Removes the equivalent task from the list.%0A     *%0A     * @throws TaskNotFoundException if no such task could be found in the list.%0A     */%0A    public boolean remove(ReadOnlyTask toRemove) throws TaskNotFoundException %7B%0A        assert toRemove != null;%0A        final boolean taskFoundAndDeleted = internalList.remove(toRemove);%0A        if (!taskFoundAndDeleted) %7B%0A            throw new TaskNotFoundException();%0A        %7D%0A        return taskFoundAndDeleted;%0A    %7D%0A%0A    public ObservableList%3CTask%3E getInternalList() %7B%0A        return internalList;%0A    %7D%0A%0A    @Override%0A    public Iterator%3CTask%3E iterator() %7B%0A        return internalList.iterator();%0A    %7D%0A%0A    @Override%0A    public boolean equals(Object other) %7B%0A        return other == this // short circuit if same object%0A                %7C%7C (other instanceof UniqueTaskList // instanceof handles nulls%0A                && this.internalList.equals(%0A                ((UniqueTaskList) other).internalList));%0A    %7D%0A%0A    @Override%0A    public int hashCode() %7B%0A        return internalList.hashCode();%0A    %7D%0A%7D%0A

add uniqueTaskList