{"action":"created","comment":{"url":"https://api.github.com/repos/nus-cs2103-AY1617S1/addressbook-level4/pulls/comments/86090252","pull_request_review_id":6765228,"id":86090252,"diff_hunk":"@@ -0,0 +1,727 @@\n+# A0139923X\n+###### /java/seedu/todoList/commons/util/StringUtil.java\n+``` java\n+    public static boolean isUnsignedInteger(String s){\n+        return s != null && s.matches(\"^\\\\d+$\");\n+    }\n+    \n+    /**\n+     * Returns true if s represents an unsigned string e.g. A, AB, ABC, ... <br>\n+     *   Will return false for null, empty string, numbers, \" ABC \" (untrimmed) \"A B\" (contains whitespace).\n+     * @param s Should be trimmed.\n+     */\n+```\n+###### /java/seedu/todoList/commons/util/StringUtil.java\n+``` java\n+    public static boolean isUnsignedString(String s){\n+        return s != null && s.matches(\"^[a-zA-Z]+$\");\n+    }\n+    \n+```\n+###### /java/seedu/todoList/commons/util/StringUtil.java\n+``` java\n+    public static boolean isUnsignedDate(String s){\n+        return s != null && s.matches(\"^(\\\\d{2}-\\\\d{2}-\\\\d{4})$\");\n+    }\n+}\n+```\n+###### /java/seedu/todoList/logic/parser/Parser.java\n+``` java\n+    private static final Pattern task_DATA_ARGS_FORMAT = // '/' forward slashes are reserved for delimiter prefixes\n+            Pattern.compile(\"(?<name>.+)\" \n+                    + \" from/(?<date>[^/]+)\" \n+                    + \"( to/(?<endDate>[^/]+))?\"\n+                    + \" p/(?<priority>[^/]+)\");\n+    \n+```\n+###### /java/seedu/todoList/logic/parser/Parser.java\n+``` java\n+    private static final Pattern event_DATA_ARGS_FORMAT = // '/' forward slashes are reserved for delimiter prefixes\n+            Pattern.compile(\"(?<name>.+)\" \n+                    + \" from/(?<date>[^/]+)\" \n+                    + \"( to/(?<endDate>[^/]+))?\"\n+                    + \" at/(?<startTime>[^/]+)\"\n+                    + \" to/(?<endTime>[^/]+)\");\n+    \n+```\n+###### /java/seedu/todoList/logic/parser/Parser.java\n+``` java\n+    private static final Pattern deadline_DATA_ARGS_FORMAT = // '/' forward slashes are reserved for delimiter prefixes\n+            Pattern.compile(\"(?<name>.+)\" \n+                    + \" on/(?<date>[^/]+)\" \n+                    + \" at/(?<endTime>[^/]+)\");\n+\n+    /*\n+     * Edit Command, task,event,deadline pattern\n+     */\n+```\n+###### /java/seedu/todoList/logic/parser/Parser.java\n+``` java\n+    private static final Pattern task_EDIT_ARGS_FORMAT = // '/' forward slashes are reserved for delimiter prefixes\n+            Pattern.compile(\"(?<dataType>.+)\" \n+                    + \" (?<targetIndex>.+)\" \n+                    + \" name/(?<name>.+)\" \n+                    + \" from/(?<date>[^/]+)\"\n+                    + \"( to/(?<endDate>[^/]+))?\"\n+                    + \" p/(?<priority>[^/]+)\");\n+    \n+```\n+###### /java/seedu/todoList/logic/parser/Parser.java\n+``` java\n+    private static final Pattern event_EDIT_ARGS_FORMAT = // '/' forward slashes are reserved for delimiter prefixes\n+            Pattern.compile(\"(?<dataType>.+)\" \n+                    + \" (?<targetIndex>.+)\" \n+                    + \" name/(?<name>.+)\" \n+                    + \" from/(?<date>[^/]+)\"\n+                    + \"( to/(?<endDate>[^/]+))?\"\n+                    + \" at/(?<startTime>[^/]+)\" \n+                    + \" to/(?<endTime>[^/]+)\");\n+\n+```\n+###### /java/seedu/todoList/logic/parser/Parser.java\n+``` java\n+    private static final Pattern deadline_EDIT_ARGS_FORMAT = // '/' forward slashes are reserved for delimiter prefixes\n+            Pattern.compile(\"(?<dataType>.+)\" \n+                    + \" (?<targetIndex>.+)\" \n+                    + \" name/(?<name>.+)\" \n+                    + \" on/(?<date>[^/]+)\"\n+                    + \" at/(?<endTime>[^/]+)\");\n+    \n+    private static final Pattern name_ARGS_FORMAT = Pattern.compile(\"n/(?<name>.+)\");\n+    private static final Pattern priority_ARGS_FORMAT = Pattern.compile(\"p/(?<priority>.+)\");\n+    private static final Pattern date_ARGS_FORMAT = Pattern.compile(\"d/(?<date>.+)\");\n+    private static final Pattern endDate_ARGS_FORMAT = Pattern.compile(\"nd/(?<endDate>.+)\");\n+    private static final Pattern startTime_ARGS_FORMAT = Pattern.compile(\"s/(?<startTime>.+)\");\n+    private static final Pattern endTime_ARGS_FORMAT = Pattern.compile(\"e/(?<endTime>.+)\");\n+\n+    public Parser() {\n+    }\n+\n+    /**\n+     * Parses user input into command for execution.\n+     *\n+     * @param userInput\n+     *            full user input string\n+     * @return the command based on the user input\n+     */\n+    public Command parseCommand(String userInput) {  \t\n+\n+    \tfinal Matcher matcher = BASIC_COMMAND_FORMAT.matcher(userInput.trim());\n+        if (!matcher.matches()) {\n+            return new IncorrectCommand(String.format(MESSAGE_INVALID_COMMAND_FORMAT, HelpCommand.MESSAGE_USAGE));\n+        }\n+        \n+        final String commandWord = matcher.group(\"commandWord\");\n+        final String arguments = matcher.group(\"arguments\");\n+        switch (commandWord) {\n+\n+        case AddCommand.COMMAND_WORD:\n+            return prepareAdd(arguments);\n+\n+        case DeleteCommand.COMMAND_WORD:\n+            return prepareDelete(arguments);\n+\n+        case EditCommand.COMMAND_WORD:\n+            return prepareEdit(arguments);\n+            \n+        case DoneCommand.COMMAND_WORD:\n+        \treturn prepareDone(arguments);\n+        \t\n+        case UndoneCommand.COMMAND_WORD:\n+            return prepareUndone(arguments);\n+            \n+        case ClearCommand.COMMAND_WORD:\n+            return new ClearCommand(arguments);\n+\n+        case FindCommand.COMMAND_WORD:\n+            return prepareFind(arguments);\n+\n+        case ListCommand.COMMAND_WORD:\n+            return new ListCommand(arguments);\n+\n+        case ExitCommand.COMMAND_WORD:\n+            return new ExitCommand();\n+\n+        case HelpCommand.COMMAND_WORD:\n+            return new HelpCommand();\n+\n+        case StorageCommand.COMMAND_WORD:\n+            return new StorageCommand(arguments);\n+            \n+        case UndoCommand.COMMAND_WORD:\n+            return new UndoCommand();\n+            \n+        default:\n+            return new IncorrectCommand(MESSAGE_UNKNOWN_COMMAND);\n+        }\n+    }\n+\n+    /**\n+     * Parses arguments in the context of the add task command.\n+     *\n+     * @param args\n+     *            full command args string\n+     * @return the prepared command\n+     */\n+```\n+###### /java/seedu/todoList/logic/parser/Parser.java\n+``` java\n+    private Command prepareAdd(String args) {\n+        final Matcher matcher_task = task_DATA_ARGS_FORMAT.matcher(args.trim());\n+        final Matcher matcher_event = event_DATA_ARGS_FORMAT.matcher(args.trim());\n+        final Matcher matcher_deadline = deadline_DATA_ARGS_FORMAT.matcher(args.trim());\n+        // Validate arg string format\n+        /*\n+         * Check if input matches task, event or deadline\n+         */\n+        \n+        if (matcher_task.matches()) {\n+            try {\n+                return new AddCommand(\n+                        matcher_task.group(\"name\").trim(), \n+                        matcher_task.group(\"date\").trim(),\n+                        isInputPresent(matcher_task.group(\"endDate\")),\n+                        matcher_task.group(\"priority\").trim()\n+                        );\n+            } catch (IllegalValueException ive) {\n+                return new IncorrectCommand(ive.getMessage());\n+            }\n+        } else if (matcher_event.matches()) {\n+            try {\n+                return new AddCommand(\n+                        matcher_event.group(\"name\").trim(), \n+                        matcher_event.group(\"date\").trim(),\n+                        isInputPresent(matcher_event.group(\"endDate\")).trim(),\n+                        matcher_event.group(\"startTime\").trim(), \n+                        matcher_event.group(\"endTime\").trim()\n+                        );\n+            } catch (IllegalValueException ive) {\n+                return new IncorrectCommand(ive.getMessage());\n+            }\n+        } else if (matcher_deadline.matches()) {\n+            try {\n+                return new AddCommand(\n+                        matcher_deadline.group(\"name\").trim(), \n+                        matcher_deadline.group(\"date\").trim(),\n+                        matcher_deadline.group(\"endTime\").trim()\n+                        );\n+            } catch (IllegalValueException ive) {\n+                return new IncorrectCommand(ive.getMessage());\n+            }\n+        } else {\n+            return new IncorrectCommand(String.format(MESSAGE_INVALID_COMMAND_FORMAT, AddCommand.MESSAGE_USAGE));\n+        }\n+\n+    }\n+\n+    /**\n+     * Parses arguments in the context of the delete task command.\n+     *\n+     * @param args\n+     *            full command args string\n+     * @return the prepared command\n+     */\n+    private Command prepareDelete(String args) {\n+        Optional<String> dataType = parseDataType(args);\n+        Optional<Integer> index = parseIndex(args);\n+        if (!dataType.isPresent() || !((dataType.get().equals(\"todo\")) || (dataType.get().equals(\"event\"))\n+                || (dataType.get().equals(\"deadline\"))) || !index.isPresent()) {\n+            return new IncorrectCommand(String.format(MESSAGE_INVALID_COMMAND_FORMAT, DeleteCommand.MESSAGE_USAGE));\n+        }\n+\n+        return new DeleteCommand(dataType.get(), index.get());\n+    }\n+    \n+    /**\n+     * Parses arguments in the context of the done task command.\n+     *\n+     * @param args\n+     *            full command args string\n+     * @return the prepared command\n+     */\n+```\n+###### /java/seedu/todoList/logic/parser/Parser.java\n+``` java\n+    private Command prepareUndone(String args) {\n+        Optional<String> dataType = parseDataType(args);\n+        Optional<Integer> index = parseIndex(args);\n+        if (!dataType.isPresent() || !((dataType.get().equals(\"todo\")) || (dataType.get().equals(\"event\"))\n+                || (dataType.get().equals(\"deadline\"))) || !index.isPresent()) {\n+            return new IncorrectCommand(String.format(MESSAGE_INVALID_COMMAND_FORMAT, UndoneCommand.MESSAGE_USAGE));\n+        }\n+\n+        return new UndoneCommand(dataType.get(), index.get());\n+    }\n+\n+    /**\n+     * Returns the specified index in the {@code command} IF a positive unsigned\n+     * integer is given as the index. Returns an {@code Optional.empty()}\n+     * otherwise.\n+     */\n+    private Optional<Integer> parseIndex(String command) {\n+        final Matcher matcher = task_DELETE_ARGS_FORMAT.matcher(command.trim());\n+        if (!matcher.matches()) {\n+            return Optional.empty();\n+        }\n+\n+        String index = matcher.group(\"targetIndex\").trim();\n+        if (!StringUtil.isUnsignedInteger(index)) {\n+            return Optional.empty();\n+        }\n+        return Optional.of(Integer.parseInt(index));\n+\n+    }\n+\n+    /**\n+     * Returns the specified dataType in the {@code command} Returns an\n+     * {@code Optional.empty()} otherwise.\n+     */\n+```\n+###### /java/seedu/todoList/logic/parser/Parser.java\n+``` java\n+    private Optional<String> parseDataType(String command) {\n+        final Matcher matcher = task_DELETE_ARGS_FORMAT.matcher(command.trim());\n+        if (!matcher.matches()) {\n+            return Optional.empty();\n+        }\n+\n+        String dataType = matcher.group(\"dataType\");\n+        if (!StringUtil.isUnsignedString(dataType)) {\n+            return Optional.empty();\n+        }\n+        return Optional.of(dataType);\n+    }\n+\n+    /**\n+     * Parses arguments in the context of the find task command.\n+     *\n+     * @param args\n+     *            full command args string\n+     * @return the prepared command\n+     */\n+    private Command prepareFind(String args) {\n+        final Matcher matcher_keywords = KEYWORDS_ARGS_FORMAT.matcher(args.trim());\n+        Optional<String> dataType = parseDataType(args);\n+        if (!dataType.isPresent()) {\n+            return new IncorrectCommand(String.format(MESSAGE_INVALID_COMMAND_FORMAT, FindCommand.MESSAGE_USAGE));\n+        }\n+\n+        // keywords delimited by whitespace\n+        final String[] keywords = matcher_keywords.group(\"keywords\").split(\"\\\\s+\");\n+        final Set<String> keywordSet = new HashSet<>(Arrays.asList(keywords));\n+\n+        return new FindCommand(keywordSet, dataType.get());\n+    }\n+    \n+```\n+###### /java/seedu/todoList/logic/parser/Parser.java\n+``` java\n+    private Command prepareEdit(String args) {\n+        final Matcher matcher_task = task_EDIT_ARGS_FORMAT.matcher(args.trim());\n+        final Matcher matcher_event = event_EDIT_ARGS_FORMAT.matcher(args.trim());\n+        final Matcher matcher_deadline = deadline_EDIT_ARGS_FORMAT.matcher(args.trim());\n+\n+        final Matcher matcher_name = name_ARGS_FORMAT.matcher(args.trim());\n+        final Matcher matcher_priority = priority_ARGS_FORMAT.matcher(args.trim());\n+        final Matcher matcher_date = date_ARGS_FORMAT.matcher(args.trim());\n+        final Matcher matcher_st = startTime_ARGS_FORMAT.matcher(args.trim());\n+        final Matcher matcher_et = endTime_ARGS_FORMAT.matcher(args.trim());\n+        \n+        Optional<String> dataType = parseDataType(args);\n+        \n+        if (!dataType.isPresent()) {\n+            return new IncorrectCommand(String.format(MESSAGE_INVALID_COMMAND_FORMAT, EditCommand.MESSAGE_USAGE));\n+        }\n+        \n+        // check user input to edit todolist\n+        if (dataType.get().equals(\"todo\")) {\n+            if (matcher_task.matches()) {\n+                try {\n+                    return new EditCommand(\n+                            matcher_task.group(\"name\").trim(), \n+                            matcher_task.group(\"date\").trim(),\n+                            isInputPresent(matcher_task.group(\"endDate\")).trim(),\n+                            matcher_task.group(\"priority\").trim(),\n+                            Integer.parseInt(matcher_task.group(\"targetIndex\")), \n+                            dataType.get().trim()\n+                            );\n+                } catch (IllegalValueException ive) {\n+                    return new IncorrectCommand(ive.getMessage());\n+                }\n+            } else if (matcher_event.matches()) {\n+                try {\n+                    return new EditCommand(\n+                            matcher_event.group(\"name\").trim(), \n+                            matcher_event.group(\"date\").trim(),\n+                            isInputPresent(matcher_event.group(\"endDate\")).trim(),\n+                            matcher_event.group(\"startTime\").trim(), \n+                            matcher_event.group(\"endTime\").trim(),\n+                            Integer.parseInt(matcher_event.group(\"targetIndex\")), \n+                            dataType.get().trim()\n+                            );\n+                } catch (IllegalValueException ive) {\n+                    return new IncorrectCommand(ive.getMessage());\n+                }\n+            } else if (matcher_deadline.matches()) {\n+                try {\n+                    return new EditCommand(\n+                            matcher_deadline.group(\"name\").trim(), \n+                            matcher_deadline.group(\"date\").trim(),\n+                            matcher_deadline.group(\"endTime\").trim(), \n+                            Integer.parseInt(matcher_deadline.group(\"targetIndex\")),\n+                            dataType.get().trim()\n+                            );\n+                } catch (IllegalValueException ive) {\n+                    return new IncorrectCommand(ive.getMessage());\n+                }\n+            } else {\n+                return new IncorrectCommand(String.format(MESSAGE_INVALID_COMMAND_FORMAT, EditCommand.MESSAGE_USAGE));\n+            }\n+        \n+        // check user input to edit eventlist\n+        } else if (dataType.get().equals(\"event\")) {\n+            if (matcher_task.matches()) {\n+                try {\n+                    return new EditCommand(\n+                            matcher_task.group(\"name\").trim(), \n+                            matcher_task.group(\"date\").trim(),\n+                            isInputPresent(matcher_task.group(\"endDate\")).trim(),\n+                            matcher_task.group(\"priority\").trim(),\n+                            Integer.parseInt(matcher_task.group(\"targetIndex\")), \n+                            dataType.get().trim()\n+                            );\n+                } catch (IllegalValueException ive) {\n+                    return new IncorrectCommand(ive.getMessage());\n+                }\n+            } else if (matcher_event.matches()) {\n+                try {\n+                    return new EditCommand(\n+                            matcher_event.group(\"name\").trim(), \n+                            matcher_event.group(\"date\").trim(),\n+                            isInputPresent(matcher_event.group(\"endDate\")).trim(),\n+                            matcher_event.group(\"startTime\").trim(), \n+                            matcher_event.group(\"endTime\").trim(),\n+                            Integer.parseInt(matcher_event.group(\"targetIndex\")), \n+                            dataType.get().trim()\n+                            );\n+                } catch (IllegalValueException ive) {\n+                    return new IncorrectCommand(ive.getMessage());\n+                }\n+            } else if (matcher_deadline.matches()) {\n+                try {\n+                    return new EditCommand(\n+                            matcher_deadline.group(\"name\").trim(), \n+                            matcher_deadline.group(\"date\").trim(),\n+                            matcher_deadline.group(\"endTime\").trim(), \n+                            Integer.parseInt(matcher_deadline.group(\"targetIndex\")),\n+                            dataType.get().trim()\n+                            );\n+                } catch (IllegalValueException ive) {\n+                    return new IncorrectCommand(ive.getMessage());\n+                }\n+            } else {\n+                return new IncorrectCommand(String.format(MESSAGE_INVALID_COMMAND_FORMAT, EditCommand.MESSAGE_USAGE));\n+            }\n+        \n+        // check user input to edit deadlinelist\n+        } else if (dataType.get().equals(\"deadline\")) {\n+            if (matcher_task.matches()) {\n+                try {\n+                    return new EditCommand(\n+                            matcher_task.group(\"name\").trim(), \n+                            matcher_task.group(\"date\").trim(),\n+                            isInputPresent(matcher_task.group(\"endDate\")).trim(),\n+                            matcher_task.group(\"priority\").trim(),\n+                            Integer.parseInt(matcher_task.group(\"targetIndex\")), \n+                            dataType.get().trim()\n+                            );\n+                } catch (IllegalValueException ive) {\n+                    return new IncorrectCommand(ive.getMessage());\n+                }\n+            } else if (matcher_event.matches()) {\n+                try {\n+                    return new EditCommand(\n+                            matcher_event.group(\"name\").trim(), \n+                            matcher_event.group(\"date\").trim(),\n+                            isInputPresent(matcher_event.group(\"endDate\")).trim(),\n+                            matcher_event.group(\"startTime\").trim(), \n+                            matcher_event.group(\"endTime\").trim(),\n+                            Integer.parseInt(matcher_event.group(\"targetIndex\")), \n+                            dataType.get().trim()\n+                            );\n+                } catch (IllegalValueException ive) {\n+                    return new IncorrectCommand(ive.getMessage());\n+                }\n+            } else if (matcher_deadline.matches()) {\n+                try {\n+                    return new EditCommand(\n+                            matcher_deadline.group(\"name\").trim(), \n+                            matcher_deadline.group(\"date\").trim(),\n+                            matcher_deadline.group(\"endTime\").trim(), \n+                            Integer.parseInt(matcher_deadline.group(\"targetIndex\")),\n+                            dataType.get().trim()\n+                            );\n+                } catch (IllegalValueException ive) {\n+                    return new IncorrectCommand(ive.getMessage());\n+                }\n+            } else {\n+                return new IncorrectCommand(String.format(MESSAGE_INVALID_COMMAND_FORMAT, EditCommand.MESSAGE_USAGE));\n+            }\n+        } else {\n+            return new IncorrectCommand(String.format(MESSAGE_INVALID_COMMAND_FORMAT, EditCommand.MESSAGE_USAGE));\n+        }\n+    }\n+    \n+    /*\n+     *  Check whether the attribute is set\n+     */\n+```\n+###### /java/seedu/todoList/logic/parser/Parser.java\n+``` java\n+    private String isInputPresent(String input){\n+        return input == null ? \"No End Date\" : input;\n+    }\n+}\n+```\n+###### /java/seedu/todoList/model/ModelManager.java\n+``` java\n+    public synchronized void editTask(ReadOnlyTask target, String dataType, Task task) throws IllegalValueException, TaskNotFoundException {\n+    \t\n+        /*\n+         *  Scenario: User wants to edit todo to change to event or deadline\n+         *  User enters edit todo 1 n/test d/01-01-2016 e/1000\n+         *  This will remove index 1 of todolist and add into deadlinelist\n+         *  \n+         *  During edit process, example: edit todo 1 with parameters of deadline\n+         *  todolist will remove the task index 1 and deadlinelist will add the edited task\n+         */\n+    \tif(task instanceof Todo) {\n+    \t    if(dataType.equals(\"todo\")){\n+                todoList.addTask(task);\n+                todoList.removeTask(target);\n+            }else if(dataType.equals(\"event\")){\n+                todoList.addTask(task);\n+                eventList.removeTask(target);\n+            }else if(dataType.equals(\"deadline\")){\n+                todoList.addTask(task);\n+                deadlineList.removeTask(target);\n+            }\n+    \t\tupdateFilteredTodoListToShowAll();\n+    \t\tindicateTodoListChanged();\n+    \t}\n+    \telse if(task instanceof Event) {\n+    \t    if(dataType.equals(\"todo\")){\n+                eventList.addTask(task);\n+                todoList.removeTask(target);\n+            }else if(dataType.equals(\"event\")){\n+                eventList.addTask(task);\n+                eventList.removeTask(target);\n+            }else if(dataType.equals(\"deadline\")){\n+                eventList.addTask(task);\n+                deadlineList.removeTask(target);\n+            }\n+    \t\tupdateFilteredEventListToShowAll();\n+    \t\tindicateEventListChanged();\n+    \t}\n+    \telse if(task instanceof Deadline) {\n+    \t    if(dataType.equals(\"todo\")){\n+    \t        deadlineList.addTask(task);\n+    \t        todoList.removeTask(target);\n+    \t    }else if(dataType.equals(\"event\")){\n+    \t        deadlineList.addTask(task);\n+                eventList.removeTask(target);\n+    \t    }else if(dataType.equals(\"deadline\")){\n+    \t        deadlineList.addTask(task);\n+                deadlineList.removeTask(target);\n+    \t    }\n+    \t\tupdateFilteredDeadlineListToShowAll();\n+    \t\tindicateDeadlineListChanged();\n+    \t}\n+    \t\n+    \tundoer.prepareUndoEdit(target, dataType, task);\n+    }\n+\n+```\n+###### /java/seedu/todoList/model/ModelManager.java\n+``` java\n+    public synchronized void undoneTask(ReadOnlyTask target, String dataType) throws TaskNotFoundException {\n+        switch(dataType) {\n+            case \"todo\":\n+                todoList.undoneTask(target);\n+                indicateTodoListChanged();\n+            case \"event\":\n+                eventList.undoneTask(target);\n+                indicateEventListChanged();\n+            case \"deadline\":\n+                deadlineList.undoneTask(target);\n+                indicateDeadlineListChanged();\n+        }\n+    }\n+    \n+    @Override\n+    public synchronized void deleteTask(ReadOnlyTask target, String dataType) throws TaskNotFoundException {\n+    \tswitch(dataType) {\n+    \t\tcase \"todo\":\n+    \t\t\ttodoList.removeTask(target);\n+    \t\t\tindicateTodoListChanged();\n+    \t\t\tundoer.prepareUndoDelete(target);\n+    \t\tcase \"event\":\n+    \t\t\teventList.removeTask(target);\n+    \t\t\tindicateEventListChanged();\n+    \t\t\tundoer.prepareUndoDelete(target);\n+    \t\tcase \"deadline\":\n+    \t\t\tdeadlineList.removeTask(target);\n+    \t\t\tindicateDeadlineListChanged();\n+    \t\t\tundoer.prepareUndoDelete(target);\n+    \t}\n+    }\n+\n+    @Override\n+    public synchronized void addTask(Task task) throws IllegalValueException, UniqueTaskList.DuplicatetaskException {\n+    \tif(task instanceof Todo) {\n+    \t\ttodoList.addTask(task);\n+    \t\tupdateFilteredTodoListToShowAll();\n+    \t\tindicateTodoListChanged();\n+    \t\tundoer.prepareUndoAdd(task, \"todo\");\n+    \t}\n+    \telse if(task instanceof Event) {","path":"collated/main/A0139923X.md","position":587,"original_position":587,"commit_id":"76a22dbb5c2f330022c34e5c24f4cdabe69a80c7","original_commit_id":"75e4f27156a44ffea7b46ec4ea31b4686a37b452","user":{"login":"jsfr0st","id":21191313,"avatar_url":"https://avatars.githubusercontent.com/u/21191313?v=3","gravatar_id":"","url":"https://api.github.com/users/jsfr0st","html_url":"https://github.com/jsfr0st","followers_url":"https://api.github.com/users/jsfr0st/followers","following_url":"https://api.github.com/users/jsfr0st/following{/other_user}","gists_url":"https://api.github.com/users/jsfr0st/gists{/gist_id}","starred_url":"https://api.github.com/users/jsfr0st/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jsfr0st/subscriptions","organizations_url":"https://api.github.com/users/jsfr0st/orgs","repos_url":"https://api.github.com/users/jsfr0st/repos","events_url":"https://api.github.com/users/jsfr0st/events{/privacy}","received_events_url":"https://api.github.com/users/jsfr0st/received_events","type":"User","site_admin":false},"body":"done","created_at":"2016-11-02T08:20:25Z","updated_at":"2016-11-02T08:20:25Z","html_url":"https://github.com/nus-cs2103-AY1617S1/addressbook-level4/pull/156#discussion_r86090252","pull_request_url":"https://api.github.com/repos/nus-cs2103-AY1617S1/addressbook-level4/pulls/156","_links":{"self":{"href":"https://api.github.com/repos/nus-cs2103-AY1617S1/addressbook-level4/pulls/comments/86090252"},"html":{"href":"https://github.com/nus-cs2103-AY1617S1/addressbook-level4/pull/156#discussion_r86090252"},"pull_request":{"href":"https://api.github.com/repos/nus-cs2103-AY1617S1/addressbook-level4/pulls/156"}}},"pull_request":{"url":"https://api.github.com/repos/nus-cs2103-AY1617S1/addressbook-level4/pulls/156","id":89527667,"html_url":"https://github.com/nus-cs2103-AY1617S1/addressbook-level4/pull/156","diff_url":"https://github.com/nus-cs2103-AY1617S1/addressbook-level4/pull/156.diff","patch_url":"https://github.com/nus-cs2103-AY1617S1/addressbook-level4/pull/156.patch","issue_url":"https://api.github.com/repos/nus-cs2103-AY1617S1/addressbook-level4/issues/156","number":156,"state":"open","locked":false,"title":"[T8][T14-C1]","user":{"login":"Leook0209","id":18088357,"avatar_url":"https://avatars.githubusercontent.com/u/18088357?v=3","gravatar_id":"","url":"https://api.github.com/users/Leook0209","html_url":"https://github.com/Leook0209","followers_url":"https://api.github.com/users/Leook0209/followers","following_url":"https://api.github.com/users/Leook0209/following{/other_user}","gists_url":"https://api.github.com/users/Leook0209/gists{/gist_id}","starred_url":"https://api.github.com/users/Leook0209/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Leook0209/subscriptions","organizations_url":"https://api.github.com/users/Leook0209/orgs","repos_url":"https://api.github.com/users/Leook0209/repos","events_url":"https://api.github.com/users/Leook0209/events{/privacy}","received_events_url":"https://api.github.com/users/Leook0209/received_events","type":"User","site_admin":false},"body":"Ready for Review\n","created_at":"2016-10-16T14:43:28Z","updated_at":"2016-11-02T08:20:25Z","closed_at":null,"merged_at":null,"merge_commit_sha":null,"assignee":{"login":"okkhoy","id":1023494,"avatar_url":"https://avatars.githubusercontent.com/u/1023494?v=3","gravatar_id":"","url":"https://api.github.com/users/okkhoy","html_url":"https://github.com/okkhoy","followers_url":"https://api.github.com/users/okkhoy/followers","following_url":"https://api.github.com/users/okkhoy/following{/other_user}","gists_url":"https://api.github.com/users/okkhoy/gists{/gist_id}","starred_url":"https://api.github.com/users/okkhoy/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/okkhoy/subscriptions","organizations_url":"https://api.github.com/users/okkhoy/orgs","repos_url":"https://api.github.com/users/okkhoy/repos","events_url":"https://api.github.com/users/okkhoy/events{/privacy}","received_events_url":"https://api.github.com/users/okkhoy/received_events","type":"User","site_admin":false},"assignees":[{"login":"okkhoy","id":1023494,"avatar_url":"https://avatars.githubusercontent.com/u/1023494?v=3","gravatar_id":"","url":"https://api.github.com/users/okkhoy","html_url":"https://github.com/okkhoy","followers_url":"https://api.github.com/users/okkhoy/followers","following_url":"https://api.github.com/users/okkhoy/following{/other_user}","gists_url":"https://api.github.com/users/okkhoy/gists{/gist_id}","starred_url":"https://api.github.com/users/okkhoy/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/okkhoy/subscriptions","organizations_url":"https://api.github.com/users/okkhoy/orgs","repos_url":"https://api.github.com/users/okkhoy/repos","events_url":"https://api.github.com/users/okkhoy/events{/privacy}","received_events_url":"https://api.github.com/users/okkhoy/received_events","type":"User","site_admin":false}],"milestone":null,"commits_url":"https://api.github.com/repos/nus-cs2103-AY1617S1/addressbook-level4/pulls/156/commits","review_comments_url":"https://api.github.com/repos/nus-cs2103-AY1617S1/addressbook-level4/pulls/156/comments","review_comment_url":"https://api.github.com/repos/nus-cs2103-AY1617S1/addressbook-level4/pulls/comments{/number}","comments_url":"https://api.github.com/repos/nus-cs2103-AY1617S1/addressbook-level4/issues/156/comments","statuses_url":"https://api.github.com/repos/nus-cs2103-AY1617S1/addressbook-level4/statuses/76a22dbb5c2f330022c34e5c24f4cdabe69a80c7","head":{"label":"CS2103AUG2016-T14-C1:master","ref":"master","sha":"76a22dbb5c2f330022c34e5c24f4cdabe69a80c7","user":{"login":"CS2103AUG2016-T14-C1","id":22429544,"avatar_url":"https://avatars.githubusercontent.com/u/22429544?v=3","gravatar_id":"","url":"https://api.github.com/users/CS2103AUG2016-T14-C1","html_url":"https://github.com/CS2103AUG2016-T14-C1","followers_url":"https://api.github.com/users/CS2103AUG2016-T14-C1/followers","following_url":"https://api.github.com/users/CS2103AUG2016-T14-C1/following{/other_user}","gists_url":"https://api.github.com/users/CS2103AUG2016-T14-C1/gists{/gist_id}","starred_url":"https://api.github.com/users/CS2103AUG2016-T14-C1/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/CS2103AUG2016-T14-C1/subscriptions","organizations_url":"https://api.github.com/users/CS2103AUG2016-T14-C1/orgs","repos_url":"https://api.github.com/users/CS2103AUG2016-T14-C1/repos","events_url":"https://api.github.com/users/CS2103AUG2016-T14-C1/events{/privacy}","received_events_url":"https://api.github.com/users/CS2103AUG2016-T14-C1/received_events","type":"Organization","site_admin":false},"repo":{"id":69800864,"name":"main","full_name":"CS2103AUG2016-T14-C1/main","owner":{"login":"CS2103AUG2016-T14-C1","id":22429544,"avatar_url":"https://avatars.githubusercontent.com/u/22429544?v=3","gravatar_id":"","url":"https://api.github.com/users/CS2103AUG2016-T14-C1","html_url":"https://github.com/CS2103AUG2016-T14-C1","followers_url":"https://api.github.com/users/CS2103AUG2016-T14-C1/followers","following_url":"https://api.github.com/users/CS2103AUG2016-T14-C1/following{/other_user}","gists_url":"https://api.github.com/users/CS2103AUG2016-T14-C1/gists{/gist_id}","starred_url":"https://api.github.com/users/CS2103AUG2016-T14-C1/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/CS2103AUG2016-T14-C1/subscriptions","organizations_url":"https://api.github.com/users/CS2103AUG2016-T14-C1/orgs","repos_url":"https://api.github.com/users/CS2103AUG2016-T14-C1/repos","events_url":"https://api.github.com/users/CS2103AUG2016-T14-C1/events{/privacy}","received_events_url":"https://api.github.com/users/CS2103AUG2016-T14-C1/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/CS2103AUG2016-T14-C1/main","description":"Address Book sample application (Level 4)","fork":true,"url":"https://api.github.com/repos/CS2103AUG2016-T14-C1/main","forks_url":"https://api.github.com/repos/CS2103AUG2016-T14-C1/main/forks","keys_url":"https://api.github.com/repos/CS2103AUG2016-T14-C1/main/keys{/key_id}","collaborators_url":"https://api.github.com/repos/CS2103AUG2016-T14-C1/main/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/CS2103AUG2016-T14-C1/main/teams","hooks_url":"https://api.github.com/repos/CS2103AUG2016-T14-C1/main/hooks","issue_events_url":"https://api.github.com/repos/CS2103AUG2016-T14-C1/main/issues/events{/number}","events_url":"https://api.github.com/repos/CS2103AUG2016-T14-C1/main/events","assignees_url":"https://api.github.com/repos/CS2103AUG2016-T14-C1/main/assignees{/user}","branches_url":"https://api.github.com/repos/CS2103AUG2016-T14-C1/main/branches{/branch}","tags_url":"https://api.github.com/repos/CS2103AUG2016-T14-C1/main/tags","blobs_url":"https://api.github.com/repos/CS2103AUG2016-T14-C1/main/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/CS2103AUG2016-T14-C1/main/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/CS2103AUG2016-T14-C1/main/git/refs{/sha}","trees_url":"https://api.github.com/repos/CS2103AUG2016-T14-C1/main/git/trees{/sha}","statuses_url":"https://api.github.com/repos/CS2103AUG2016-T14-C1/main/statuses/{sha}","languages_url":"https://api.github.com/repos/CS2103AUG2016-T14-C1/main/languages","stargazers_url":"https://api.github.com/repos/CS2103AUG2016-T14-C1/main/stargazers","contributors_url":"https://api.github.com/repos/CS2103AUG2016-T14-C1/main/contributors","subscribers_url":"https://api.github.com/repos/CS2103AUG2016-T14-C1/main/subscribers","subscription_url":"https://api.github.com/repos/CS2103AUG2016-T14-C1/main/subscription","commits_url":"https://api.github.com/repos/CS2103AUG2016-T14-C1/main/commits{/sha}","git_commits_url":"https://api.github.com/repos/CS2103AUG2016-T14-C1/main/git/commits{/sha}","comments_url":"https://api.github.com/repos/CS2103AUG2016-T14-C1/main/comments{/number}","issue_comment_url":"https://api.github.com/repos/CS2103AUG2016-T14-C1/main/issues/comments{/number}","contents_url":"https://api.github.com/repos/CS2103AUG2016-T14-C1/main/contents/{+path}","compare_url":"https://api.github.com/repos/CS2103AUG2016-T14-C1/main/compare/{base}...{head}","merges_url":"https://api.github.com/repos/CS2103AUG2016-T14-C1/main/merges","archive_url":"https://api.github.com/repos/CS2103AUG2016-T14-C1/main/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/CS2103AUG2016-T14-C1/main/downloads","issues_url":"https://api.github.com/repos/CS2103AUG2016-T14-C1/main/issues{/number}","pulls_url":"https://api.github.com/repos/CS2103AUG2016-T14-C1/main/pulls{/number}","milestones_url":"https://api.github.com/repos/CS2103AUG2016-T14-C1/main/milestones{/number}","notifications_url":"https://api.github.com/repos/CS2103AUG2016-T14-C1/main/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/CS2103AUG2016-T14-C1/main/labels{/name}","releases_url":"https://api.github.com/repos/CS2103AUG2016-T14-C1/main/releases{/id}","deployments_url":"https://api.github.com/repos/CS2103AUG2016-T14-C1/main/deployments","created_at":"2016-10-02T14:13:16Z","updated_at":"2016-10-22T07:50:12Z","pushed_at":"2016-11-02T08:11:29Z","git_url":"git://github.com/CS2103AUG2016-T14-C1/main.git","ssh_url":"git@github.com:CS2103AUG2016-T14-C1/main.git","clone_url":"https://github.com/CS2103AUG2016-T14-C1/main.git","svn_url":"https://github.com/CS2103AUG2016-T14-C1/main","homepage":null,"size":10308,"stargazers_count":1,"watchers_count":1,"language":"Java","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":8,"forks":0,"open_issues":8,"watchers":1,"default_branch":"master"}},"base":{"label":"nus-cs2103-AY1617S1:master","ref":"master","sha":"b3dd6334a0a4abb1353e08a238880dbde5cab94f","user":{"login":"nus-cs2103-AY1617S1","id":20475842,"avatar_url":"https://avatars.githubusercontent.com/u/20475842?v=3","gravatar_id":"","url":"https://api.github.com/users/nus-cs2103-AY1617S1","html_url":"https://github.com/nus-cs2103-AY1617S1","followers_url":"https://api.github.com/users/nus-cs2103-AY1617S1/followers","following_url":"https://api.github.com/users/nus-cs2103-AY1617S1/following{/other_user}","gists_url":"https://api.github.com/users/nus-cs2103-AY1617S1/gists{/gist_id}","starred_url":"https://api.github.com/users/nus-cs2103-AY1617S1/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/nus-cs2103-AY1617S1/subscriptions","organizations_url":"https://api.github.com/users/nus-cs2103-AY1617S1/orgs","repos_url":"https://api.github.com/users/nus-cs2103-AY1617S1/repos","events_url":"https://api.github.com/users/nus-cs2103-AY1617S1/events{/privacy}","received_events_url":"https://api.github.com/users/nus-cs2103-AY1617S1/received_events","type":"Organization","site_admin":false},"repo":{"id":69563984,"name":"addressbook-level4","full_name":"nus-cs2103-AY1617S1/addressbook-level4","owner":{"login":"nus-cs2103-AY1617S1","id":20475842,"avatar_url":"https://avatars.githubusercontent.com/u/20475842?v=3","gravatar_id":"","url":"https://api.github.com/users/nus-cs2103-AY1617S1","html_url":"https://github.com/nus-cs2103-AY1617S1","followers_url":"https://api.github.com/users/nus-cs2103-AY1617S1/followers","following_url":"https://api.github.com/users/nus-cs2103-AY1617S1/following{/other_user}","gists_url":"https://api.github.com/users/nus-cs2103-AY1617S1/gists{/gist_id}","starred_url":"https://api.github.com/users/nus-cs2103-AY1617S1/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/nus-cs2103-AY1617S1/subscriptions","organizations_url":"https://api.github.com/users/nus-cs2103-AY1617S1/orgs","repos_url":"https://api.github.com/users/nus-cs2103-AY1617S1/repos","events_url":"https://api.github.com/users/nus-cs2103-AY1617S1/events{/privacy}","received_events_url":"https://api.github.com/users/nus-cs2103-AY1617S1/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/nus-cs2103-AY1617S1/addressbook-level4","description":"Address Book sample application (Level 4)","fork":true,"url":"https://api.github.com/repos/nus-cs2103-AY1617S1/addressbook-level4","forks_url":"https://api.github.com/repos/nus-cs2103-AY1617S1/addressbook-level4/forks","keys_url":"https://api.github.com/repos/nus-cs2103-AY1617S1/addressbook-level4/keys{/key_id}","collaborators_url":"https://api.github.com/repos/nus-cs2103-AY1617S1/addressbook-level4/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/nus-cs2103-AY1617S1/addressbook-level4/teams","hooks_url":"https://api.github.com/repos/nus-cs2103-AY1617S1/addressbook-level4/hooks","issue_events_url":"https://api.github.com/repos/nus-cs2103-AY1617S1/addressbook-level4/issues/events{/number}","events_url":"https://api.github.com/repos/nus-cs2103-AY1617S1/addressbook-level4/events","assignees_url":"https://api.github.com/repos/nus-cs2103-AY1617S1/addressbook-level4/assignees{/user}","branches_url":"https://api.github.com/repos/nus-cs2103-AY1617S1/addressbook-level4/branches{/branch}","tags_url":"https://api.github.com/repos/nus-cs2103-AY1617S1/addressbook-level4/tags","blobs_url":"https://api.github.com/repos/nus-cs2103-AY1617S1/addressbook-level4/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/nus-cs2103-AY1617S1/addressbook-level4/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/nus-cs2103-AY1617S1/addressbook-level4/git/refs{/sha}","trees_url":"https://api.github.com/repos/nus-cs2103-AY1617S1/addressbook-level4/git/trees{/sha}","statuses_url":"https://api.github.com/repos/nus-cs2103-AY1617S1/addressbook-level4/statuses/{sha}","languages_url":"https://api.github.com/repos/nus-cs2103-AY1617S1/addressbook-level4/languages","stargazers_url":"https://api.github.com/repos/nus-cs2103-AY1617S1/addressbook-level4/stargazers","contributors_url":"https://api.github.com/repos/nus-cs2103-AY1617S1/addressbook-level4/contributors","subscribers_url":"https://api.github.com/repos/nus-cs2103-AY1617S1/addressbook-level4/subscribers","subscription_url":"https://api.github.com/repos/nus-cs2103-AY1617S1/addressbook-level4/subscription","commits_url":"https://api.github.com/repos/nus-cs2103-AY1617S1/addressbook-level4/commits{/sha}","git_commits_url":"https://api.github.com/repos/nus-cs2103-AY1617S1/addressbook-level4/git/commits{/sha}","comments_url":"https://api.github.com/repos/nus-cs2103-AY1617S1/addressbook-level4/comments{/number}","issue_comment_url":"https://api.github.com/repos/nus-cs2103-AY1617S1/addressbook-level4/issues/comments{/number}","contents_url":"https://api.github.com/repos/nus-cs2103-AY1617S1/addressbook-level4/contents/{+path}","compare_url":"https://api.github.com/repos/nus-cs2103-AY1617S1/addressbook-level4/compare/{base}...{head}","merges_url":"https://api.github.com/repos/nus-cs2103-AY1617S1/addressbook-level4/merges","archive_url":"https://api.github.com/repos/nus-cs2103-AY1617S1/addressbook-level4/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/nus-cs2103-AY1617S1/addressbook-level4/downloads","issues_url":"https://api.github.com/repos/nus-cs2103-AY1617S1/addressbook-level4/issues{/number}","pulls_url":"https://api.github.com/repos/nus-cs2103-AY1617S1/addressbook-level4/pulls{/number}","milestones_url":"https://api.github.com/repos/nus-cs2103-AY1617S1/addressbook-level4/milestones{/number}","notifications_url":"https://api.github.com/repos/nus-cs2103-AY1617S1/addressbook-level4/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/nus-cs2103-AY1617S1/addressbook-level4/labels{/name}","releases_url":"https://api.github.com/repos/nus-cs2103-AY1617S1/addressbook-level4/releases{/id}","deployments_url":"https://api.github.com/repos/nus-cs2103-AY1617S1/addressbook-level4/deployments","created_at":"2016-09-29T12:08:54Z","updated_at":"2016-10-10T14:55:25Z","pushed_at":"2016-11-02T08:16:53Z","git_url":"git://github.com/nus-cs2103-AY1617S1/addressbook-level4.git","ssh_url":"git@github.com:nus-cs2103-AY1617S1/addressbook-level4.git","clone_url":"https://github.com/nus-cs2103-AY1617S1/addressbook-level4.git","svn_url":"https://github.com/nus-cs2103-AY1617S1/addressbook-level4","homepage":null,"size":240285,"stargazers_count":3,"watchers_count":3,"language":"Java","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":118,"mirror_url":null,"open_issues_count":53,"forks":118,"open_issues":53,"watchers":3,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/nus-cs2103-AY1617S1/addressbook-level4/pulls/156"},"html":{"href":"https://github.com/nus-cs2103-AY1617S1/addressbook-level4/pull/156"},"issue":{"href":"https://api.github.com/repos/nus-cs2103-AY1617S1/addressbook-level4/issues/156"},"comments":{"href":"https://api.github.com/repos/nus-cs2103-AY1617S1/addressbook-level4/issues/156/comments"},"review_comments":{"href":"https://api.github.com/repos/nus-cs2103-AY1617S1/addressbook-level4/pulls/156/comments"},"review_comment":{"href":"https://api.github.com/repos/nus-cs2103-AY1617S1/addressbook-level4/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/nus-cs2103-AY1617S1/addressbook-level4/pulls/156/commits"},"statuses":{"href":"https://api.github.com/repos/nus-cs2103-AY1617S1/addressbook-level4/statuses/76a22dbb5c2f330022c34e5c24f4cdabe69a80c7"}}}}
{"actor":{"display_login":"jsfr0st"}}