Establishing the interface connections, we face a chicken-egg-problem:
To establish a connection, a predecessors/successors pull interface is
assigned to the current's stage push interface.
However, propagating stages (in auto-detection mode) can only create
their pull interfaces if the corresponding, opposite-side push interface
is present already (because that's the mechanism to determine the supported
propagation directions).
Hence, we need to resolve this by performing two sweeps:
- initialization, assuming both propagation directions should be supported,
thus generating both pull interfaces, i.e. providing the egg
- stripping down the interfaces to the actual context
This context is provided by two stages pushing from both ends
into a (potentially long) sequence of propagating stages (tbd).
Contributions of this PR:
- PropagatingEitherWay: explicitly distinguish AUTO from BOTHWAYS interface
AUTO: auto-derive interface from provided push interfaces
BOTHWAYS: explicitly require both directions
- SerialContainer: (better, but not yet perfect) validation of connectivity
- ParallelContainer: determine interface from what children offer
- store "failure" solutions to facilitate debugging
- Introspection assigns solution IDs as soon as they are created in a stage
Thus, solution IDs represent their creation order.
In contrast, the order of publishing (in StageStatistics) should
represent the cost order.
- Storing failures is disabled if Introspection is not available.