code: def create (raw_properties = []):
      
      assert (is_iterable_typed(raw_properties, property.Property)
              or is_iterable_typed(raw_properties, basestring))
      # FIXME: propagate to callers.
      if len(raw_properties) > 0 and isinstance(raw_properties[0], property.Property):
          x = raw_properties
      else:
          x = [property.create_from_string(ps) for ps in raw_properties]
  
      # These two lines of code are optimized to the current state
      # of the Property class. Since this function acts as the caching
      # frontend to the PropertySet class modifying these two lines
      # could have a severe performance penalty. Be careful.
      # It would be faster to sort by p.id, but some projects may rely
      # on the fact that the properties are ordered alphabetically. So,
      # we maintain alphabetical sorting so as to maintain backward compatibility.
      x = sorted(set(x), key=lambda p: (p.feature.name, p.value, p.condition))
      key = tuple(p.id for p in x)
  
      if key not in __cache:
          __cache [key] = PropertySet(x)
  
      return __cache [key]
docs: Creates a new 'PropertySet' instance for the given raw properties,
          or returns an already existing one.