public void notifyUser(NotificationMetaData notifMetaData, String senderId, String componentId)
     throws AttachmentException {
   SilverTrace.info("attachment", "AttachmentBmImpl.notifyUser()", "root.MSG_GEN_EXIT_METHOD");
   try {
     SilverTrace.info(
         "attachment",
         "AttachmentBmImpl.notifyUser()",
         "root.MSG_GEN_EXIT_METHOD",
         " senderId = " + senderId + " componentId = " + componentId);
     if (notifMetaData.getSender() == null || notifMetaData.getSender().length() == 0) {
       notifMetaData.setSender(senderId);
     }
     NotificationSender notifSender = new NotificationSender(componentId);
     notifSender.notifyUser(notifMetaData);
   } catch (NotificationManagerException e) {
     throw new AttachmentException(
         "AttachmentBmImpl.notifyUser()",
         SilverpeasRuntimeException.ERROR,
         "attachment.MSG_ATTACHMENT_NOT_EXIST",
         e);
   }
 }
  public String addEntry(
      TodoDetail todo, boolean notifyAttendees, String txtTitle, String txtMessage) {
    SilverTrace.info("calendar", "TodoBackboneAcess.addEntry()", "root.MSG_GEN_ENTER_METHOD");
    NotificationSender notifSender = new NotificationSender(todo.getComponentId());
    try {
      ToDoHeader header = todoDetailToHeader(todo);
      SilverTrace.info(
          "calendar", "TodoBackboneAcess.addEntry()", "root.MSG_GEN_ENTER_METHOD", "apres header");
      String id = getCalendarBm().addToDo(header);
      SilverTrace.info(
          "calendar", "TodoBackboneAcess.addEntry()", "root.MSG_GEN_ENTER_METHOD", "id=" + id);

      if (todo.getAttendees() != null) {
        Collection<UserRecipient> selectedUsers = new ArrayList<UserRecipient>();
        for (Attendee attendee : todo.getAttendees()) {
          getCalendarBm().addToDoAttendee(id, attendee);
          if (notifyAttendees && (!todo.getDelegatorId().equals(attendee.getUserId()))) {
            selectedUsers.add(new UserRecipient(attendee.getUserId()));
          }
        }
        if (!selectedUsers.isEmpty()) {
          NotificationMetaData notifMetaData =
              new NotificationMetaData(NotificationParameters.NORMAL, txtTitle, txtMessage);
          notifMetaData.setSender(todo.getDelegatorId());
          notifMetaData.setUserRecipients(selectedUsers);
          notifSender.notifyUser(notifMetaData);
        }
      }
      return id;
    } catch (Exception e) {
      SilverTrace.error(
          "calendar",
          "TodoBackboneAcess.addEntry()",
          "calendar.MSG_ADD_ENTRY_FAILED",
          "value return id= null",
          e);
      return null;
    }
  }
  /**
   * Notify user that an action has been done
   *
   * @throws WorkflowException
   */
  @Override
  public void notifyActor(Task task, User sender, User user, String text) throws WorkflowException {
    String componentId = task.getProcessInstance().getModelId();
    List<String> userIds = new ArrayList<String>();
    if (user != null) {
      userIds.add(user.getUserId());
    } else if (StringUtil.isDefined(task.getGroupId())) {
      List<User> usersInGroup = task.getProcessInstance().getUsersInGroup(task.getGroupId());
      for (User userInGroup : usersInGroup) {
        userIds.add(userInGroup.getUserId());
      }
    } else {
      String role = task.getUserRoleName();
      List<User> usersInRole = task.getProcessInstance().getUsersInRole(role);
      for (User userInRole : usersInRole) {
        userIds.add(userInRole.getUserId());
      }
    }

    NotificationSender notifSender = notificationSenders.get(componentId);
    if (notifSender == null) {
      notifSender = new NotificationSender(componentId);
      notificationSenders.put(componentId, notifSender);
    }

    for (String userId : userIds) {
      try {
        String title = task.getProcessInstance().getTitle(task.getUserRoleName(), "");

        DataRecord data = task.getProcessInstance().getAllDataRecord(task.getUserRoleName(), "");
        text = DataRecordUtil.applySubstitution(text, data, "");

        NotificationMetaData notifMetaData =
            new NotificationMetaData(NotificationParameters.NORMAL, title, text);
        if (sender != null) {
          notifMetaData.setSender(sender.getUserId());
        } else {
          notifMetaData.setSender(userId);
        }
        notifMetaData.addUserRecipient(new UserRecipient(userId));
        String link =
            "/RprocessManager/"
                + componentId
                + "/searchResult?Type=ProcessInstance&Id="
                + task.getProcessInstance().getInstanceId()
                + "&role="
                + task.getUserRoleName();
        notifMetaData.setLink(link);
        notifSender.notifyUser(notifMetaData);
      } catch (WorkflowException e) {
        SilverTrace.warn(
            "workflowEngine",
            "TaskManagerImpl.notifyUser()",
            "workflowEngine.EX_ERR_NOTIFY",
            "user = "******"workflowEngine",
            "TaskManagerImpl.notifyUser()",
            "workflowEngine.EX_ERR_NOTIFY",
            "user = " + userId,
            e);
      }
    }
  }