public PhaseNameProvider addPhase(Phase phase) {
        NameProvider nameProvider = nameProviders.get(phase.getName());
        if (nameProvider instanceof ComponentNameProvider) {
            throw new ConflictingNodeTypeException("Cannot add phase '" + phase.getName() + "' as it is already provided by " + nameProvider);
        }
        PhaseNameProvider phaseNameProvider;
        if(nameProvider == null) {
            phaseNameProvider = new PhaseNameProvider(phase.getName(), priority++);
        } else {
            phaseNameProvider = (PhaseNameProvider) nameProvider;
        }
        nameProviders.put(phase.getName(), phaseNameProvider);
        for(String before : phase.before()) {
            phaseNameProvider.before(getPhaseNameProvider(before));
        }
        for(String after : phase.after()) {
            getPhaseNameProvider(after).before(phaseNameProvider);
        }

        return phaseNameProvider;
    }
Given a set of phases and a set of components,
a ordered list of components satisfying the dependencies is given if possible.
<p>
The phase list implicitly defines the ordering:
    {@literal if i  < j : p_i before p_j  where i,j are valid indexes of the phrase list p.}
<p>
If multiple components provide the same name, ALL the components providing
the same name must be placed earlier/later than an entity depending on
that name.
<p>
A warning will be logged if multiple components of different types provides the
same name. A component can not provide the same name as a phase.

@author Tony Vaagenes
container-core/src/main/java/com/yahoo/component/chain/dependencies/ordering/ChainBuilder.java