'Recursive helper function for concretize().
This concretizes everything bottom-up.  As things are
concretized, they\'re added to the presets, and ancestors
will prefer the settings of their children.'

def _concretize_helper(self, presets=None, visited=None):

    if (presets is None):
        presets = {}
    if (visited is None):
        visited = set()
    if (self.name in visited):
        return False
    changed = False
    for name in sorted(self._dependencies.keys()):
        changed |= self._dependencies[name].spec._concretize_helper(presets, visited)
    if (self.name in presets):
        changed |= self.constrain(presets[self.name])
    else:
        if (not self.virtual):
            changed |= any((spack.concretizer.concretize_architecture(self), spack.concretizer.concretize_compiler(self), spack.concretizer.concretize_compiler_flags(self), spack.concretizer.concretize_version(self), spack.concretizer.concretize_variants(self)))
        presets[self.name] = self
    visited.add(self.name)
    return changed
