class SplitState extends AbstractState implements FlowHolder {

	private final Collection<Flow> flows;

	private final SplitState parentSplit;

	private TaskExecutor taskExecutor = new SyncTaskExecutor();

	private final FlowExecutionAggregator aggregator = new MaxValueFlowExecutionAggregator();

	/**
	 * @param flows collection of {@link Flow} instances.
	 * @param name the name of the state.
	 */
	public SplitState(Collection<Flow> flows, String name) {
		this(flows, name, null);
	}

	/**
	 * @param flows collection of {@link Flow} instances.
	 * @param name the name of the state.
	 * @param parentSplit the parent {@link SplitState}.
	 */
	public SplitState(Collection<Flow> flows, String name, @Nullable SplitState parentSplit) {
		super(name);
		this.flows = flows;
		this.parentSplit = parentSplit;
	}

	/**
	 * Public setter for the taskExecutor.
	 * @param taskExecutor the taskExecutor to set
	 */
	public void setTaskExecutor(TaskExecutor taskExecutor) {
		this.taskExecutor = taskExecutor;
	}

	/**
	 * @return the flows
	 */
	@Override
	public Collection<Flow> getFlows() {
		return flows;
	}

	/**
	 * Execute the flows in parallel by passing them to the {@link TaskExecutor} and wait
	 * for all of them to finish before proceeding.
	 *
	 * @see State#handle(FlowExecutor)
	 */
	@Override
	public FlowExecutionStatus handle(final FlowExecutor executor) throws Exception {<FILL_FUNCTION_BODY>}

	protected FlowExecutionStatus doAggregation(Collection<FlowExecution> results, FlowExecutor executor) {
		return aggregator.aggregate(results);
	}

	@Override
	public boolean isEndState() {
		return false;
	}

}


		// TODO: collect the last StepExecution from the flows as well, so they
		// can be abandoned if necessary
		Collection<Future<FlowExecution>> tasks = new ArrayList<>();

		for (final Flow flow : flows) {

			final FutureTask<FlowExecution> task = new FutureTask<>(() -> flow.start(executor));

			tasks.add(task);

			try {
				taskExecutor.execute(task);
			}
			catch (TaskRejectedException e) {
				throw new FlowExecutionException("TaskExecutor rejected task for flow=" + flow.getName());
			}

		}

		FlowExecutionStatus parentSplitStatus = parentSplit == null ? null : parentSplit.handle(executor);

		Collection<FlowExecution> results = new ArrayList<>();

		// Could use a CompletionService here?
		for (Future<FlowExecution> task : tasks) {
			try {
				results.add(task.get());
			}
			catch (ExecutionException e) {
				// Unwrap the expected exceptions
				Throwable cause = e.getCause();
				if (cause instanceof Exception) {
					throw (Exception) cause;
				}
				else {
					throw e;
				}
			}
		}

		FlowExecutionStatus flowExecutionStatus = doAggregation(results, executor);
		if (parentSplitStatus != null) {
			return Collections.max(Arrays.asList(flowExecutionStatus, parentSplitStatus));
		}
		return flowExecutionStatus;
	
<methods>public void <init>(java.lang.String) ,public java.lang.String getName() ,public abstract org.springframework.batch.core.job.flow.FlowExecutionStatus handle(org.springframework.batch.core.job.flow.FlowExecutor) throws java.lang.Exception,public java.lang.String toString() <variables>private final non-sealed java.lang.String name