/**
  * Add {@link FlowPropertyDefinition}s from the flowPropertyDefinitionProviders as a flow for each
  * property.
  *
  * <p>Only the properties that have {@link FlowPropertyDefinition#getPropertyUsage()}.{@link
  * PropertyUsage#isOutputedProperty()} != false get their own flow. This makes it safe to list
  * properties that are expected on input without having a flow created for those input only
  * properties.
  *
  * @param flowPropertyDefinitionProviders
  */
 public void add(FlowPropertyDefinitionProvider... flowPropertyDefinitionProviders) {
   for (FlowPropertyDefinitionProvider flowPropertyDefinitionProvider :
       flowPropertyDefinitionProviders) {
     List<String> outputFlowPropertyDefinitionNames =
         flowPropertyDefinitionProvider.getOutputFlowPropertyDefinitionNames();
     FlowConfigurationException.valid(
         isNotEmpty(outputFlowPropertyDefinitionNames),
         flowPropertyDefinitionProvider.getClass(),
         " has no output properties defined.");
     for (String flowPropertyName : outputFlowPropertyDefinitionNames) {
       // TODO : should we apply expectations: readonly?
       this.add(flowPropertyName, flowPropertyDefinitionProvider, null);
     }
   }
 }