code: @Override
    public void alertOnFailedUpdate(final Executor executor, List<ExecutableFlow> flows,
        final ExecutorManagerException updateException) {
  
      flows = flows.stream()
          .filter(flow -> flow.getExecutionOptions() != null)
          .filter(flow -> CollectionUtils.isNotEmpty(flow.getExecutionOptions().getFailureEmails()))
          .collect(Collectors.toList());
  
      // group by mail creator in case some flows use different creators
      final ImmutableListMultimap<String, ExecutableFlow> creatorsToFlows = Multimaps
          .index(flows, flow -> flow.getExecutionOptions().getMailCreator());
  
      for (final String mailCreatorName : creatorsToFlows.keySet()) {
  
        final ImmutableList<ExecutableFlow> creatorFlows = creatorsToFlows.get(mailCreatorName);
        final MailCreator mailCreator = getMailCreator(mailCreatorName);
  
        // group by recipients in case some flows have different failure email addresses
        final ImmutableListMultimap<List<String>, ExecutableFlow> emailsToFlows = Multimaps
            .index(creatorFlows, flow -> flow.getExecutionOptions().getFailureEmails());
  
        for (final List<String> emailList : emailsToFlows.keySet()) {
          sendFailedUpdateEmail(executor, updateException, mailCreator, emailsToFlows.get(emailList));
        }
      }
    }
docs: Sends as many emails as there are unique combinations of:
  
  [mail creator] x [failure email address list]
  
  Executions with the same combo are grouped into a single message.