@Test
  public void testExecuteCommand() throws ParseException {
    String userInput = null;

    HashMap<String, Object> expected = null;
    HashMap<String, Object> actual = null;
    ArrayList<String> errorList = new ArrayList<String>();
    ArrayList<String> successList = new ArrayList<String>();
    ArrayList<String> warningList = new ArrayList<String>();
    ArrayList<String> helpList = new ArrayList<String>();
    ArrayList<String> paramList = new ArrayList<String>();
    ArrayList<Task> taskList = new ArrayList<Task>();

    Task task1 = null;
    Task task2 = null;
    Task task3 = null;
    Task task4 = null;
    Task task5 = null;
    Task task6 = null;

    Date startTime = null;
    Date endTime = null;
    // Test display
    userInput = "display";

    errorList = new ArrayList<String>();
    errorList.add(ERROR_EMPTY_TASKLIST);

    expected =
        buildExpectedHashmap(successList, warningList, helpList, paramList, errorList, taskList);

    TaskHandler.executeCommand(userInput);
    actual = stripJson(context.getDataModel());
    assertTrue(isSameObjHash(expected, actual));
    context.clearAllMessages();
    clearArrayLists(successList, warningList, helpList, paramList, errorList, taskList);

    // Test for misspelling
    userInput = "dsplay";

    errorList = new ArrayList<String>();
    errorList.add(ERROR_INVALID_COMMAND);

    helpList = new ArrayList<String>();
    helpList.add(HELP_ADD_TASK);

    expected =
        buildExpectedHashmap(successList, warningList, helpList, paramList, errorList, taskList);

    TaskHandler.executeCommand(userInput);
    actual = stripJson(context.getDataModel());
    assertTrue(isSameObjHash(expected, actual));
    context.clearAllMessages();
    clearArrayLists(successList, warningList, helpList, paramList, errorList, taskList);

    // Test for add floating task
    userInput = "add do \"sth1\"";
    task1 = new Task(1, "sth1", null, null);

    successList = new ArrayList<String>();
    successList.add(MESSAGE_ADD_TASK);
    taskList.add(task1);

    expected =
        buildExpectedHashmap(successList, warningList, helpList, paramList, errorList, taskList);

    TaskHandler.executeCommand(userInput);
    actual = stripJson(context.getDataModel());
    assertTrue(isSameObjHash(expected, actual));
    context.clearAllMessages();
    clearArrayLists(successList, warningList, helpList, paramList, errorList, taskList);

    // Test for add event task
    userInput = "add on 12/10/15 from 1200 to 1240 do \"sth2\"";
    try {
      startTime = df.parse("12/10/15 1200");
      endTime = df.parse("12/10/15 1240");

    } catch (ParseException e) {
      e.printStackTrace();
    }
    task2 = new Task(2, "sth2", startTime, endTime, null);

    successList = new ArrayList<String>();
    successList.add(MESSAGE_ADD_TASK);
    taskList = new ArrayList<Task>();
    taskList.add(task2);

    expected =
        buildExpectedHashmap(successList, warningList, helpList, paramList, errorList, taskList);

    TaskHandler.executeCommand(userInput);
    actual = stripJson(context.getDataModel());
    assertTrue(isSameObjHash(expected, actual));
    context.clearAllMessages();
    clearArrayLists(successList, warningList, helpList, paramList, errorList, taskList);

    // Test for add event task with different start and end dates
    userInput = "add do \"sth3\" from 12/10/15 1200 to 14/10/15 1340";
    try {
      startTime = df.parse("12/10/15 1200");
      endTime = df.parse("14/10/15 1340");

    } catch (ParseException e) {
      e.printStackTrace();
    }
    task3 = new Task(3, "sth3", startTime, endTime, null);

    successList = new ArrayList<String>();
    successList.add(MESSAGE_ADD_TASK);
    errorList = new ArrayList<String>();
    errorList.add(ERROR_START_BEFORE_END);
    taskList = new ArrayList<Task>();
    taskList.add(task3);

    expected =
        buildExpectedHashmap(successList, warningList, helpList, paramList, errorList, taskList);

    TaskHandler.executeCommand(userInput);
    actual = stripJson(context.getDataModel());
    assertTrue(isSameObjHash(expected, actual));
    context.clearAllMessages();
    clearArrayLists(successList, warningList, helpList, paramList, errorList, taskList);

    // Test for add event task with unspecified end time
    userInput = "add do \"sth4\" on 12/10/15 from 1200";
    try {
      startTime = df.parse("12/10/15 1200");
      endTime = df.parse("12/10/15 1300");

    } catch (ParseException e) {
      e.printStackTrace();
    }
    task4 = new Task(4, "sth4", startTime, endTime, null);

    successList = new ArrayList<String>();
    successList.add(MESSAGE_ADD_TASK);
    taskList = new ArrayList<Task>();
    taskList.add(task4);

    expected =
        buildExpectedHashmap(successList, warningList, helpList, paramList, errorList, taskList);

    TaskHandler.executeCommand(userInput);
    actual = stripJson(context.getDataModel());
    assertTrue(isSameObjHash(expected, actual));
    context.clearAllMessages();
    clearArrayLists(successList, warningList, helpList, paramList, errorList, taskList);

    // Test for add event task with unspecified start time
    userInput = "add do \"sth5\" on 12/10/15 to 1240";
    try {
      startTime = df.parse("12/10/15 1100");
      endTime = df.parse("12/10/15 1240");

    } catch (ParseException e) {
      e.printStackTrace();
    }
    task5 = new Task(5, "sth5", startTime, endTime, null);

    successList = new ArrayList<String>();
    successList.add(MESSAGE_ADD_TASK);
    taskList = new ArrayList<Task>();
    taskList.add(task5);

    expected =
        buildExpectedHashmap(successList, warningList, helpList, paramList, errorList, taskList);

    TaskHandler.executeCommand(userInput);
    actual = stripJson(context.getDataModel());
    assertTrue(isSameObjHash(expected, actual));
    context.clearAllMessages();
    clearArrayLists(successList, warningList, helpList, paramList, errorList, taskList);

    // Test for add deadline task
    userInput = "add do \"sth6\" by 12/10/15 2359";
    try {
      df.parse("12/10/15 2359");

    } catch (ParseException e) {
      e.printStackTrace();
    }
    task6 = new Task(6, "sth6", startTime, endTime, null);

    successList = new ArrayList<String>();
    successList.add(MESSAGE_ADD_TASK);
    taskList = new ArrayList<Task>();
    taskList.add(task6);

    expected =
        buildExpectedHashmap(successList, warningList, helpList, paramList, errorList, taskList);

    TaskHandler.executeCommand(userInput);
    actual = stripJson(context.getDataModel());
    assertTrue(isSameObjHash(expected, actual));
    context.clearAllMessages();
    clearArrayLists(successList, warningList, helpList, paramList, errorList, taskList);

    // Test for edit desc only
    userInput = "edit 1 do \"nothing-5\"";

    task1 = new Task(1, "nothing-5", null, null);
    taskList.add(task1);
    successList = new ArrayList<String>();
    successList.add(String.format(MESSAGE_EDIT_TASK, 1));

    expected =
        buildExpectedHashmap(successList, warningList, helpList, paramList, errorList, taskList);

    TaskHandler.executeCommand(userInput);
    actual = stripJson(context.getDataModel());
    assertTrue(isSameObjHash(expected, actual));
    context.clearAllMessages();
    clearArrayLists(successList, warningList, helpList, paramList, errorList, taskList);

    // Test for edit floating to event (set startDate, startTime, endDate and endTime
    userInput = "edit 2 on 12/10/15 from 1200 to 1400";

    try {
      startTime = df.parse("12/10/15 1200");
      endTime = df.parse("12/10/15 1400");

    } catch (ParseException e) {
      e.printStackTrace();
    }
    task2 = new Task(2, "sth2", startTime, endTime, null);
    taskList.add(task2);
    successList = new ArrayList<String>();
    successList.add(String.format(MESSAGE_EDIT_TASK, 2));

    expected =
        buildExpectedHashmap(successList, warningList, helpList, paramList, errorList, taskList);

    TaskHandler.executeCommand(userInput);
    actual = stripJson(context.getDataModel());
    assertTrue(isSameObjHash(expected, actual));
    context.clearAllMessages();
    clearArrayLists(successList, warningList, helpList, paramList, errorList, taskList);

    // Test for edit floating task startDate only
    userInput = "edit 5 from 10/15/15";
    try {
      startTime = df.parse("10/15/15 0000");
      endTime = task5.getEndDateTime();

    } catch (ParseException e) {
      e.printStackTrace();
    }
    task5 = new Task(5, "sth5", startTime, endTime, null);
    taskList.add(task5);
    successList = new ArrayList<String>();
    successList.add(String.format(MESSAGE_EDIT_TASK, 5));

    expected =
        buildExpectedHashmap(successList, warningList, helpList, paramList, errorList, taskList);

    TaskHandler.executeCommand(userInput);
    actual = stripJson(context.getDataModel());
    assertTrue(isSameObjHash(expected, actual));
    context.clearAllMessages();
    clearArrayLists(successList, warningList, helpList, paramList, errorList, taskList);

    // Test for edit floating task startDate and startTime
    userInput = "edit 5 from 10/15/15 2115";
    try {
      startTime = df.parse("10/15/15 2115");
      endTime = task5.getEndDateTime();

    } catch (ParseException e) {
      e.printStackTrace();
    }
    task5 = new Task(5, "sth5", startTime, endTime, null);
    taskList.add(task5);
    successList = new ArrayList<String>();
    successList.add(String.format(MESSAGE_EDIT_TASK, 5));

    expected =
        buildExpectedHashmap(successList, warningList, helpList, paramList, errorList, taskList);

    TaskHandler.executeCommand(userInput);
    actual = stripJson(context.getDataModel());
    assertTrue(isSameObjHash(expected, actual));
    context.clearAllMessages();
    clearArrayLists(successList, warningList, helpList, paramList, errorList, taskList);

    // Test for edit task startDate, startTime and endTime
    userInput = "edit 5 on 10/25/15 from 1130 to 1409";
    try {
      startTime = df.parse("10/25/15 1130");
      endTime = df.parse("10/25/15 1409");

    } catch (ParseException e) {
      e.printStackTrace();
    }
    task5 = new Task(5, "sth5", startTime, endTime, null);
    taskList.add(task5);
    successList = new ArrayList<String>();
    successList.add(String.format(MESSAGE_EDIT_TASK, 5));

    expected =
        buildExpectedHashmap(successList, warningList, helpList, paramList, errorList, taskList);

    TaskHandler.executeCommand(userInput);
    actual = stripJson(context.getDataModel());
    assertTrue(isSameObjHash(expected, actual));
    context.clearAllMessages();
    clearArrayLists(successList, warningList, helpList, paramList, errorList, taskList);

    // Test for edit task endDate and endTime
    userInput = "edit 5 to 10/27/15 2220";
    try {
      startTime = task5.getStartDateTime();
      endTime = df.parse("10/27/15 2220");

    } catch (ParseException e) {
      e.printStackTrace();
    }
    task5 = new Task(5, "sth5", startTime, endTime, null);
    taskList.add(task5);
    successList = new ArrayList<String>();
    successList.add(String.format(MESSAGE_EDIT_TASK, 5));

    expected =
        buildExpectedHashmap(successList, warningList, helpList, paramList, errorList, taskList);

    TaskHandler.executeCommand(userInput);
    actual = stripJson(context.getDataModel());
    assertTrue(isSameObjHash(expected, actual));
    context.clearAllMessages();
    clearArrayLists(successList, warningList, helpList, paramList, errorList, taskList);

    // Test for edit task endDate only
    userInput = "edit 5 to 12/24/15";
    try {
      startTime = task5.getStartDateTime();
      endTime = df.parse("12/24/15 2220");

    } catch (ParseException e) {
      e.printStackTrace();
    }
    task5 = new Task(5, "sth5", startTime, endTime, null);
    taskList.add(task5);
    successList = new ArrayList<String>();
    successList.add(String.format(MESSAGE_EDIT_TASK, 5));

    expected =
        buildExpectedHashmap(successList, warningList, helpList, paramList, errorList, taskList);

    TaskHandler.executeCommand(userInput);
    actual = stripJson(context.getDataModel());
    assertTrue(isSameObjHash(expected, actual));
    context.clearAllMessages();
    clearArrayLists(successList, warningList, helpList, paramList, errorList, taskList);

    // Test for edit task startDate and endDate only
    userInput = "edit 5 on 12/25/15";
    try {
      startTime = df.parse("10/25/15 1130");
      endTime = df.parse("12/24/15 2220");

    } catch (ParseException e) {
      e.printStackTrace();
    }
    task5 = new Task(5, "sth5", startTime, endTime, null);
    taskList.add(task5);
    successList = new ArrayList<String>();
    successList.add(String.format(MESSAGE_EDIT_TASK, 5));

    expected =
        buildExpectedHashmap(successList, warningList, helpList, paramList, errorList, taskList);

    TaskHandler.executeCommand(userInput);
    actual = stripJson(context.getDataModel());
    assertFalse(isSameObjHash(expected, actual)); // @A0118772 endtime should not change!
    context.clearAllMessages();
    clearArrayLists(successList, warningList, helpList, paramList, errorList, taskList);

    // Test for edit task startDate and startTime only
    userInput = "edit 5 on 09/25/15 from 1000";
    try {
      startTime = df.parse("09/25/15 1000");
      endTime = df.parse("12/24/15 2220");

    } catch (ParseException e) {
      e.printStackTrace();
    }
    task5 = new Task(5, "sth5", startTime, endTime, null);
    taskList.add(task5);
    successList = new ArrayList<String>();
    successList.add(String.format(MESSAGE_EDIT_TASK, 5));

    expected =
        buildExpectedHashmap(successList, warningList, helpList, paramList, errorList, taskList);

    TaskHandler.executeCommand(userInput);
    actual = stripJson(context.getDataModel());
    assertTrue(isSameObjHash(expected, actual));
    context.clearAllMessages();
    clearArrayLists(successList, warningList, helpList, paramList, errorList, taskList);

    // Test for edit task endDate and endTime only
    userInput = "edit 5 on 10/25/15 to 0030";
    try {
      startTime = df.parse("09/25/15 1000");
      endTime = df.parse("10/25/15 0030");

    } catch (ParseException e) {
      e.printStackTrace();
    }
    task5 = new Task(5, "sth5", startTime, endTime, null);
    taskList.add(task5);
    successList = new ArrayList<String>();
    successList.add(String.format(MESSAGE_EDIT_TASK, 5));

    expected =
        buildExpectedHashmap(successList, warningList, helpList, paramList, errorList, taskList);

    TaskHandler.executeCommand(userInput);
    actual = stripJson(context.getDataModel());
    assertTrue(isSameObjHash(expected, actual));
    context.clearAllMessages();
    clearArrayLists(successList, warningList, helpList, paramList, errorList, taskList);

    // Test for edit task venue
    userInput = "edit 5 at \"do from on to at by\"";

    startTime = task5.getStartDateTime();
    endTime = task5.getEndDateTime();

    task5 = new Task(5, "do from on to at by", startTime, endTime, null);
    taskList.add(task5);
    successList = new ArrayList<String>();
    successList.add(String.format(MESSAGE_EDIT_TASK, 5));

    expected =
        buildExpectedHashmap(successList, warningList, helpList, paramList, errorList, taskList);

    TaskHandler.executeCommand(userInput);
    actual = stripJson(context.getDataModel());
    assertTrue(isSameObjHash(expected, actual));
    context.clearAllMessages();
    clearArrayLists(successList, warningList, helpList, paramList, errorList, taskList);

    // Test for delete task
    userInput = "delete 2";

    taskList.add(task2);
    successList = new ArrayList<String>();
    successList.add(String.format(MESSAGE_DELETE_TASK, 2));

    expected =
        buildExpectedHashmap(successList, warningList, helpList, paramList, errorList, taskList);

    TaskHandler.executeCommand(userInput);
    actual = stripJson(context.getDataModel());
    assertTrue(isSameObjHash(expected, actual));
    context.clearAllMessages();
    clearArrayLists(successList, warningList, helpList, paramList, errorList, taskList);
  }