Refines 'properties' by overriding any non-free properties
        for which a different value is specified in 'requirements'.
        Conditional requirements are just added without modification.
        Returns the resulting list of properties.

def refine (properties, requirements):
    """ Refines 'properties' by overriding any non-free properties
        for which a different value is specified in 'requirements'.
        Conditional requirements are just added without modification.
        Returns the resulting list of properties.
    """
    assert is_iterable_typed(properties, Property)
    assert is_iterable_typed(requirements, Property)
    # The result has no duplicates, so we store it in a set
    result = set()

    # Records all requirements.
    required = {}

    # All the elements of requirements should be present in the result
    # Record them so that we can handle 'properties'.
    for r in requirements:
        # Don't consider conditional requirements.
        if not r.condition:
            required[r.feature] = r

    for p in properties:
        # Skip conditional properties
        if p.condition:
            result.add(p)
        # No processing for free properties
        elif p.feature.free:
            result.add(p)
        else:
            if p.feature in required:
                result.add(required[p.feature])
            else:
                result.add(p)

    return sequence.unique(list(result) + requirements)