Expand all composite properties in the set so that all components
        are explicitly expressed.

def expand_composites (properties):
    """ Expand all composite properties in the set so that all components
        are explicitly expressed.
    """
    if __debug__:
        from .property import Property
        assert is_iterable_typed(properties, Property)
    explicit_features = set(p.feature for p in properties)

    result = []

    # now expand composite features
    for p in properties:
        expanded = expand_composite(p)

        for x in expanded:
            if not x in result:
                f = x.feature

                if f.free:
                    result.append (x)
                elif not x in properties:  # x is the result of expansion
                    if not f in explicit_features:  # not explicitly-specified
                        if any(r.feature == f for r in result):
                            raise FeatureConflict(
                                "expansions of composite features result in "
                                "conflicting values for '%s'\nvalues: '%s'\none contributing composite property was '%s'" %
                                (f.name, [r.value for r in result if r.feature == f] + [x.value], p))
                        else:
                            result.append (x)
                elif any(r.feature == f for r in result):
                    raise FeatureConflict ("explicitly-specified values of non-free feature '%s' conflict\n"
                    "existing values: '%s'\nvalue from expanding '%s': '%s'" % (f,
                    [r.value for r in result if r.feature == f], p, x.value))
                else:
                    result.append (x)

    return result