public void keywordTab_doSave(Object panel) {
    log.trace("ENTER");
    long startDate;
    try {
      startDate =
          InternationalisationUtils.parseDate(InternationalisationUtils.getDefaultStartDate())
              .getTime();
    } catch (ParseException e) {
      log.debug("We never should get this", e);
      log.trace("EXIT");
      return;
    }

    // Get the KeywordAction details
    String replyText = keywordSimple_getAutoReply(panel);
    Group joinGroup = keywordSimple_getJoin();
    Group leaveGroup = keywordSimple_getLeave();

    // Get the keyword attached to the selected item.  If the "Add Keyword" option is selected,
    // there will be no keyword attached to it.
    Keyword keyword = null;
    Object selectedKeywordItem = ui.getSelectedItem(keywordListComponent);
    if (selectedKeywordItem != null) keyword = ui.getKeyword(selectedKeywordItem);

    if (keyword == null) {
      // Adding keyword as well as actions
      String newkeyword = ui.getText(ui.find(panel, COMPONENT_TF_KEYWORD));
      try {
        keyword = new Keyword(newkeyword, "");
        this.keywordDao.saveKeyword(keyword);
      } catch (DuplicateKeyException e) {
        ui.alert(InternationalisationUtils.getI18nString(MESSAGE_KEYWORD_EXISTS));
        log.trace("EXIT");
        return;
      }
      keywordTab_doClear(panel);
    } else {
      // Editing an existent keyword.  This keyword may already have actions applied to it, so
      // we need to check for actions and update them as appropriate.
      KeywordAction replyAction =
          this.keywordActionDao.getAction(keyword, KeywordAction.Type.REPLY);
      if (replyAction != null) {
        if (replyText == null) {
          // The reply action has been removed
          keywordActionDao.deleteKeywordAction(replyAction);
        } else {
          replyAction.setReplyText(replyText);
          this.keywordActionDao.updateKeywordAction(replyAction);
          // We set null to don't add it in the end
          replyText = null;
        }
      }

      KeywordAction joinAction = this.keywordActionDao.getAction(keyword, KeywordAction.Type.JOIN);
      if (joinAction != null) {
        if (joinGroup == null) {
          // Previous join action has been removed, so delete it.
          keywordActionDao.deleteKeywordAction(joinAction);
        } else {
          // Group to join has been updated
          joinAction.setGroup(joinGroup);
          this.keywordActionDao.updateKeywordAction(joinAction);
          // Join Group has been handled, so unset it.
          joinGroup = null;
        }
      }

      KeywordAction leaveAction =
          this.keywordActionDao.getAction(keyword, KeywordAction.Type.LEAVE);
      if (leaveAction != null) {
        if (leaveGroup == null) {
          keywordActionDao.deleteKeywordAction(leaveAction);
        } else {
          leaveAction.setGroup(leaveGroup);
          this.keywordActionDao.updateKeywordAction(leaveAction);
          // We set null to don't add it in the end
          leaveGroup = null;
        }
      }
    }

    // Handle creation of new KeywordActions if required
    if (replyText != null) {
      KeywordAction action =
          KeywordAction.createReplyAction(keyword, replyText, startDate, DEFAULT_END_DATE);
      keywordActionDao.saveKeywordAction(action);
    }
    if (joinGroup != null) {
      KeywordAction action =
          KeywordAction.createGroupJoinAction(keyword, joinGroup, startDate, DEFAULT_END_DATE);
      keywordActionDao.saveKeywordAction(action);
    }
    if (leaveGroup != null) {
      KeywordAction action =
          KeywordAction.createGroupLeaveAction(keyword, leaveGroup, startDate, DEFAULT_END_DATE);
      keywordActionDao.saveKeywordAction(action);
    }

    // Refresh the UI
    updateKeywordList();
    ui.infoMessage(InternationalisationUtils.getI18nString(MESSAGE_KEYWORD_SAVED));
    log.trace("EXIT");
  }