docs: @Override
      public boolean validateEventsAndOutcomes(String handlerName, List<Map<String, Object>> configuredEvents) {
  
          if (configuredEvents.isEmpty()) {
              if (tc.isDebugEnabled()) {
                  Tr.debug(tc, "configuredEvents is empty, returning true as all events are valid");
              }
              return true;
          }
          if (tc.isDebugEnabled()) {
              Tr.debug(tc, "configuredEvents: " + configuredEvents.toString());
          }
          if (tc.isDebugEnabled()) {
              Tr.debug(tc, "size of configuredEvents: " + configuredEvents.size());
          }
  
          for (Map<String, Object> events : configuredEvents) {
  
              if (events.isEmpty()) {
                  if (tc.isDebugEnabled()) {
                      Tr.debug(tc, "no events or outcomes specified, all events and outcomes are honoured");
                  }
                  return true;
              } else {
                  boolean isFoundEventName = false;
                  String foundEventName = null;
                  boolean isFoundOutcome = false;
                  String foundOutcome = null;
                  for (Entry<String, Object> entry : events.entrySet()) {
                      if (tc.isDebugEnabled()) {
                          Tr.debug(tc, "entry: " + entry.toString());
                      }
  
                      // if the event is a custom one, we cannot validate, so return true:  buyer beware
                      if (entry.getKey().equals(AuditConstants.CUSTOM) && entry.getValue().equals(Boolean.TRUE)) {
                          return true;
                      } else {
                          if (entry.getKey().equals(AuditConstants.EVENT_NAME)) {
                              isFoundEventName = true;
                              foundEventName = (String) entry.getValue();
                              if (!validateEventName((String) entry.getValue())) {
                                  String eventsList = "";
                                  for (String temp : AuditConstants.validEventNamesList) {
                                      eventsList = eventsList.concat(temp).concat(" ");
                                  }
                                  Tr.error(tc, INCORRECT_AUDIT_EVENT_CONFIGURATION, new Object[] { foundEventName, handlerName, eventsList });
                                  return false;
                              }
                          } else if (entry.getKey().equals(AuditConstants.OUTCOME)) {
                              isFoundOutcome = true;
                              foundOutcome = (String) entry.getValue();
                              if (!validateOutcomeName((String) entry.getValue())) {
                                  String outcomesList = "";
                                  for (String temp : AuditConstants.validOutcomesList) {
                                      outcomesList = outcomesList.concat(temp).concat(" ");
                                  }
                                  Tr.error(tc, INCORRECT_AUDIT_OUTCOME_CONFIGURATION, new Object[] { foundOutcome, handlerName, outcomesList });
                                  return false;
                              }
                          }
                      }
                  }
                  if (!isFoundEventName && isFoundOutcome) {
                      String eventsList = "";
                      for (String temp : AuditConstants.validEventNamesList) {
                          eventsList = eventsList.concat(temp).concat(" ");
                      }
                      Tr.error(tc, "INCORRECT_AUDIT_CONFIGURATION_OUTCOME_SPECIFIED_MISSING_EVENTNAME",
                               new Object[] { foundOutcome, handlerName, eventsList });
                      return false;
                  }
              }
          }
          return true;
      }