---
features:
  - Implemented a new framework for MuranoPL contracts. Now, instead of several
    independent implementations of the same yaql methods (string(), class()
    etc.) all implementations of the same method are combined into single
    class. Therefore, we now have a class per contract method. This also simplifies
    development of new contracts. Each such class can provide methods for
    data transformation (default contract usage), validation that is used
    to decide if the method can be considered an extension method for the
    value, and json schema generation method that was moved from the schema
    generator script.
  - Previously, when a class overrode a property from its parent
    class the value was stored separately for both of them, transformed
    by each of the contracts. Thus each class saw the value of its contract.
    In absolute majority of the cases, the observed value was the same. However,
    if the contracts were compatible on the provided value (say int() and
    string() contracts on the value "123") they were different. This is
    considered to be a bad pattern.
    Now, the value is stored only once per object and transformed by the
    contract defined in the actual object type. All base contracts are used
    to validate the transformed object thus this pattern will not work
    anymore.
  - The value that is stored in the object's properties is obtained by
    executing special "finalize" contract implementation which by default
    returns the input value unmodified. Because validation happens on
    the transformed value before it gets finalized it is possible for
    transformation to return a value that will pass the validation though
    the final value won't. This is used to relax the template() contract
    limitation that prevented child class from excluding additional properties
    from the template.
  - The ``string()`` contract no longer converts everything to string values.
    Now it only converts scalar values to strings.
    Previous behavior allowed ``string()`` property to
    accept lists and convert them to their Python string representation which
    is clearly not what developers expected.
  - Due to refactoring, contracts work a little bit faster because there is
    no more need to generate yaql function definition for each contract method
    on each call.
