/**
   * Gets the update actions for all specified referencing components.
   *
   * @param user user
   * @param actions actions
   * @param visitedServices services
   * @param referencingComponents components
   */
  private void getUpdateActionsForReferencingComponents(
      final NiFiUser user,
      final Collection<Action> actions,
      final Collection<String> visitedServices,
      final Set<ConfiguredComponent> referencingComponents) {
    // consider each component updates
    for (final ConfiguredComponent component : referencingComponents) {
      if (component instanceof ProcessorNode) {
        final ProcessorNode processor = ((ProcessorNode) component);

        // create the processor details
        FlowChangeExtensionDetails processorDetails = new FlowChangeExtensionDetails();
        processorDetails.setType(processor.getProcessor().getClass().getSimpleName());

        // create a processor action
        FlowChangeAction processorAction = new FlowChangeAction();
        processorAction.setUserIdentity(user.getDn());
        processorAction.setUserName(user.getUserName());
        processorAction.setTimestamp(new Date());
        processorAction.setSourceId(processor.getIdentifier());
        processorAction.setSourceName(processor.getName());
        processorAction.setSourceType(Component.Processor);
        processorAction.setComponentDetails(processorDetails);
        processorAction.setOperation(
            ScheduledState.RUNNING.equals(processor.getScheduledState())
                ? Operation.Start
                : Operation.Stop);
        actions.add(processorAction);
      } else if (component instanceof ReportingTask) {
        final ReportingTaskNode reportingTask = ((ReportingTaskNode) component);

        // create the reporting task details
        FlowChangeExtensionDetails processorDetails = new FlowChangeExtensionDetails();
        processorDetails.setType(reportingTask.getReportingTask().getClass().getSimpleName());

        // create a reporting task action
        FlowChangeAction reportingTaskAction = new FlowChangeAction();
        reportingTaskAction.setUserIdentity(user.getDn());
        reportingTaskAction.setUserName(user.getUserName());
        reportingTaskAction.setTimestamp(new Date());
        reportingTaskAction.setSourceId(reportingTask.getIdentifier());
        reportingTaskAction.setSourceName(reportingTask.getName());
        reportingTaskAction.setSourceType(Component.ReportingTask);
        reportingTaskAction.setComponentDetails(processorDetails);
        reportingTaskAction.setOperation(
            ScheduledState.RUNNING.equals(reportingTask.getScheduledState())
                ? Operation.Start
                : Operation.Stop);
        actions.add(reportingTaskAction);
      } else if (component instanceof ControllerServiceNode) {
        final ControllerServiceNode controllerService = ((ControllerServiceNode) component);

        // create the controller service details
        FlowChangeExtensionDetails serviceDetails = new FlowChangeExtensionDetails();
        serviceDetails.setType(
            controllerService.getControllerServiceImplementation().getClass().getSimpleName());

        // create a controller service action
        FlowChangeAction serviceAction = new FlowChangeAction();
        serviceAction.setUserIdentity(user.getDn());
        serviceAction.setUserName(user.getUserName());
        serviceAction.setTimestamp(new Date());
        serviceAction.setSourceId(controllerService.getIdentifier());
        serviceAction.setSourceName(controllerService.getName());
        serviceAction.setSourceType(Component.ControllerService);
        serviceAction.setComponentDetails(serviceDetails);
        serviceAction.setOperation(
            isDisabled(controllerService) ? Operation.Disable : Operation.Enable);
        actions.add(serviceAction);

        // need to consider components referencing this controller service (transitive)
        if (!visitedServices.contains(controllerService.getIdentifier())) {
          getUpdateActionsForReferencingComponents(
              user,
              actions,
              visitedServices,
              controllerService.getReferences().getReferencingComponents());
        }
      }
    }
  }