private IDataIterator[] createDataProviderIterators() {
      if (context.getErrorInfoCollector().hasErrors()) {
        return null;
      }

      MethodInfo dataVariableMultiplicationsMethod = context.getCurrentFeature().getDataVariableMultiplicationsMethod();
      Iterator<DataVariableMultiplication> dataVariableMultiplications;
      DataVariableMultiplication nextDataVariableMultiplication;
      if (dataVariableMultiplicationsMethod != null) {
        try {
          dataVariableMultiplications = Arrays.stream(((DataVariableMultiplication[]) invokeRaw(null, dataVariableMultiplicationsMethod))).iterator();
          nextDataVariableMultiplication = dataVariableMultiplications.next();
        } catch (Throwable t) {
          supervisor.error(context.getErrorInfoCollector(), new ErrorInfo(dataVariableMultiplicationsMethod, t, getErrorContext()));
          return null;
        }
      } else {
        dataVariableMultiplications = emptyIterator();
        nextDataVariableMultiplication = null;
      }

      List<DataProviderInfo> dataProviderInfos = context.getCurrentFeature().getDataProviders();
      IDataIterator[] dataIterators = new IDataIterator[dataProviders.length];
      for (int dataProviderIndex = 0, dataVariableNameIndex = 0; dataProviderIndex < dataProviders.length; dataProviderIndex++, dataVariableNameIndex++) {
        String nextDataVariableName = dataVariableNames.get(dataVariableNameIndex);
        if ((nextDataVariableMultiplication != null)
          && (nextDataVariableMultiplication.getDataVariables()[0].equals(nextDataVariableName))) {

          // a cross multiplication starts
          dataIterators[dataProviderIndex] = createDataProviderMultiplier(nextDataVariableMultiplication, dataProviderIndex);
          // skip processed providers and variables
          int remainingVariables = nextDataVariableMultiplication.getDataVariables().length;
          dataVariableNameIndex += remainingVariables - 1;
          while (remainingVariables > 0) {
            remainingVariables -= dataProviderInfos.get(dataProviderIndex).getDataVariables().size();
            dataProviderIndex++;
          }
          dataProviderIndex--;
          Assert.that(remainingVariables == 0);
          // wait for next cross multiplication
          nextDataVariableMultiplication = dataVariableMultiplications.hasNext() ? dataVariableMultiplications.next() : null;
        } else {
          // not a cross multiplication, just use a data provider iterator
          DataProviderInfo dataProviderInfo = dataProviderInfos.get(dataProviderIndex);
          dataIterators[dataProviderIndex] = new DataProviderIterator(
            supervisor, context, nextDataVariableName,
            dataProviderInfo, dataProviders[dataProviderIndex]);
          dataVariableNameIndex += dataProviderInfo.getDataVariables().size() - 1;
        }
      }
      return dataIterators;
    }
A fallback iterator that returns a single empty iteration.
<p>
This is used when a feature has no data provider method and iteration behavior is forcefully enabled.

@since 2.3
spock-core/src/main/java/org/spockframework/runtime/DataIteratorFactory.java