<specification xmlns="http://jboss.com/products/weld/tck/audit"
               xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
               xsi:schemaLocation="http://jboss.com/products/weld/tck/audit"
               name="JSR-349:Bean Validation" version="1.1.0" id="beanvalidation">

    <section id="2" title="Constraint Definition"/>
    <section id="2.1" title="Constraint Annotation">
        <assertion id="a" testable="false">
            <text>An annotation is considered a constraint definition if its retention policy
                contains RUNTIME and if the annotation itself is annotated with
                javax.validation.Constraint
            </text>
        </assertion>
        <assertion id="b" testable="false">
            <text>Constraint annotations can target any of the following ElementTypes: FIELD,
                METHOD, TYPE, ANNOTATION_TYPE
            </text>
        </assertion>
        <assertion id="c">
            <text>If a constraint definition is not valid, a ConstraintDefinitionException is raised
                either at validation time or when the metadata is requested
            </text>
        </assertion>
        <assertion id="d">
            <text>Applying a constraint annotation to an incompatible type will raise a
                UnexpectedTypeException
            </text>
        </assertion>
    </section>

    <section id="2.1.1" title="Constraint definition properties">
        <assertion id="a">
            <text>A constraint definition may have attributes that are specified at the time the
                constraint is applied to a JavaBean.
            </text>
        </assertion>
        <assertion id="b">
            <text>Annotation elements starting with valid are not allowed</text>
        </assertion>
        <assertion id="c">
            <text>Every constraint annotation must define a message element of type String</text>
        </assertion>
        <assertion id="d">
            <text>Every constraint annotation must define a groups element that specifies which
                processing groups the constraint definition is associated with.
            </text>
        </assertion>
        <assertion id="e">
            <text>The default value for the groups element must be an empty array.</text>
        </assertion>
        <assertion id="f">
            <text>If no group is specified when declaring the constraint on an element, the Default
                group is considered declared.
            </text>
        </assertion>
        <assertion id="g" implied="true">
            <text>The type of the groups parameter is Class&lt;?&gt;[].</text>
        </assertion>

        <assertion id="h">
            <text>Every constraint annotation must define a payload element that specifies which
                payload the constraint declaration is associated with.
            </text>
        </assertion>
        <assertion id="i">
            <text>The default value for the payload parameter must be an empty array.</text>
        </assertion>
        <assertion id="j">
            <text>Each attachable payload extends Payload.</text>
        </assertion>
    </section>

    <section id="2.2" title="Applying multiple constraints of the same type">
        <assertion id="a">
            <text>The bean validation provider treats regular annotations (annotations not annotated
                by @Constraint) whose value element has a return type of an array of constraint
                annotations in a special way. Each element in the value array are processed by the
                Bean Validation implementation as regular constraint annotations.
            </text>
        </assertion>
    </section>
    <section id="2.3" title="Constraint composition">
        <assertion id="a">
            <text>Each constraint annotation hosted on a constraint annotation is applied to the
                target element and this recursively
            </text>
        </assertion>
        <assertion id="b">
            <text>Note that the main annotation and its constraint validation implementation is also
                applied
            </text>
        </assertion>
        <assertion id="c">
            <text>By default, each failing constraint generates an error report</text>
        </assertion>
        <assertion id="d">
            <text>Groups from the main constraint annotation are inherited by the composing
                annotations
            </text>
        </assertion>
        <assertion id="e">
            <text>Any groups definition on a composing annotation is ignored</text>
        </assertion>
        <assertion id="f">
            <text>The property type a composed constraint is placed on must be compatible with all
                constraints (composing and composed)
            </text>
        </assertion>
        <assertion id="g">
            <text>If a composed constraint is marked as @ReportAsSingleViolation, and if any of its
                composing constraint reports one or more violations, all reports from composing
                constraints are ignored and the error report corresponding to the composed
                constraint is generated
            </text>
        </assertion>
        <assertion id="h">
            <text>Composing annotations can define the value of message and custom attributes
                (excluding groups) but these are fixed in the composed constraint definition
            </text>
        </assertion>
        <assertion id="i">
            <text>It is possible to override attributes and messages defined on a composing
                annotation. An attribute from the main annotation is used to override one or more
                attributes of the composing annotations. Such an attribute is annotated with the
                @OverridesAttribute annotation or its multivalued equivalent
                @OverridesAttribute.List
            </text>
        </assertion>
        <assertion id="j">
            <text>The types of the overridden and overriding attributes must be identical</text>
        </assertion>
        <assertion id="k">
            <text>A composing constraint can itself be a composed constraint. In this case,
                attribute values are overridden recursively according to the described rules
            </text>
        </assertion>
        <assertion id="l">
            <text>If a constraint is used more than once as a composing constraint, the multi value
                constraints model as described in Section 2.2 is used
            </text>
        </assertion>
        <assertion id="m">
            <text>To select the appropriate composing constraint targeted, OverridesAttrib-
                ute.constraintIndex is used. It represents the constraint index in the value
                array
            </text>
        </assertion>
        <assertion id="n">
            <text>If index is undefined, the single constraint declaration is targeted</text>
        </assertion>
        <assertion id="o">
            <text>If the composition is invalid (infinite composition, wrong attribute overriding, a
                single attribute mapped to more than one source attribute etc), a
                ConstraintDefinitionException is raised either at validation time or when the
                metadata is requested
            </text>
        </assertion>
        <assertion id="p">
            <text>Any payload definition on a composing annotation is ignored</text>
        </assertion>
    </section>
    <section id="2.4" title="Constraint validation implementation">
        <assertion id="a">
            <text>A constraint validation implementation performs the validation of a given
                constraint annotation for a given type
            </text>
        </assertion>
        <assertion id="b">
            <text>The implementation classes are specified by the validatedBy element of the
                @Constraint annotation that decorates the constraint definition
            </text>
        </assertion>
        <assertion id="c" testable="false">
            <text>The constraint validation implementation implements the ConstraintValidator
                interface
            </text>
        </assertion>
        <assertion id="d" testable="false">
            <text>T must resolve in a non parameterized type or generic parameters of T must be
                unbounded wildcard types
            </text>
        </assertion>
        <assertion id="e">
            <text>The initialize method is called by the Bean validation provider prior to any use
                of the constraint implementation.
            </text>
        </assertion>
        <assertion id="f">
            <text>The isValid method is evaluated by the Bean Validation provider each time a given
                value is validated
            </text>
        </assertion>
        <assertion id="g" testable="false">
            <text>It returns false if the value is not valid, true otherwise</text>
        </assertion>
        <assertion id="h" testable="false">
            <text>isValid implementations must be thread-safe</text>
        </assertion>
        <assertion id="i">
            <text>If the property is of an unanticipated type, an UnexpectedTypeException is
                raised
            </text>
        </assertion>
        <assertion id="j">
            <text>If an exception occurs either in the initialize or isValid method, the runtime
                exception is wrapped into a ValidationException by the Bean Validation engine
            </text>
        </assertion>
        <assertion id="k" testable="false">
            <text>The constraint validation implementation is not allowed to change the state of the
                value passed to isValid.
            </text>
        </assertion>
        <assertion id="l">
            <text>By default, each invalid constraint leads to the generation of one error object
                represented by a ConstraintViolation object. This object is build from the default
                error message as defined by the constraint declaration and the context in which the
                constraint declaration is placed on (bean, property, attribute)
            </text>
        </assertion>
        <assertion id="m">
            <text>The ConstraintValidatorContext methods let the constraint implementation disable
                the default error object generation and create one or more custom ones
            </text>
        </assertion>
        <assertion id="n">
            <text>The non-interpolated message passed as a parameter is used to build the
                ConstraintViolation object (the message interpolation operation is applied to
                it)
            </text>
        </assertion>
        <assertion id="o">
            <text>By default, the propertyPath exposed on the ConstraintViolation represents the
                path to the bean or property hosting the constraint
            </text>
        </assertion>
        <assertion id="q">
            <text>You can point an error to a subpath of this default path by using the error
                builder fluent API.
            </text>
        </assertion>
        <assertion id="r">
            <text>If disableDefaultError is called, no custom error is added (using the error
                builder) and if the constraint is not valid, a ValidationException is raised.
            </text>
        </assertion>
    </section>
    <section id="2.5" title="The ConstraintValidatorFactory">
        <assertion id="a">
            <text>The default ConstraintValidatorFactory provided by the Bean Validation provider
                implementation uses the public constraint no-arg constructor
            </text>
        </assertion>
        <assertion id="b">
            <text>If an exception occurs in the factory while retrieving the ConstraintValidator
                instance, the runtime exception is wrapped in a ValidationException
            </text>
        </assertion>
        <assertion id="c">
            <text>If the instance returned by the factory is null, a ValidationException is
                raised
            </text>
        </assertion>
    </section>

    <section id="3" title="Constraint declaration and validation process"/>
    <section id="3.1" title="Requirements on classes to be validated">
        <assertion id="a">
            <text>Properties to be validated must follow the method signature conventions for
                JavaBeans read properties, as defined by the JavaBeans specification
            </text>
        </assertion>
        <assertion id="b" testable="false">
            <!-- The spec is not clear about whether validation of static fields/properties should just be ignored or an
                            exception should be thrown. -->
            <text>Static fields and static methods are excluded from validation</text>
        </assertion>
        <assertion id="c">
            <text>Constraints can be applied to interfaces and superclasses</text>
        </assertion>
        <assertion id="d">
            <text>The target of an annotation definition can be a field, property, or type, provided
                that the constraint definition supports the specified target and the constraint
                supports the declared type of the target.
            </text>
        </assertion>
    </section>
    <section id="3.1.1" title="Object validation">
        <assertion id="a">
            <text>Constraint declarations can be applied to a class or an interface</text>
        </assertion>
    </section>
    <section id="3.1.2" title="Field and property validation">
        <assertion id="a">
            <text>Constraint declarations can be applied on both fields and properties for the same
                object type
            </text>
        </assertion>
        <assertion id="b">
            <text>The same constraint should however not be duplicated between a field and its
                associated property (the constraint validation would be applied twice)
            </text>
        </assertion>
        <assertion id="c">
            <text>When a field is annotated with a constraint declaration, field access strategy is
                used to access the state validated by such constraint
            </text>
        </assertion>
        <assertion id="d">
            <text>When a property is annotated with a constraint declaration, property access
                strategy is used to access the state validated by such constraint
            </text>
        </assertion>
        <assertion id="e">
            <text>The fields or methods visibility are not constrained</text>
        </assertion>
        <assertion id="f" testable="false">
            <text>Constraints on non getter methods are not supported</text>
        </assertion>
    </section>
    <section id="3.1.3" title="Graph validation">
        <assertion id="a">
            <text>Consider the situation where bean X contains a field of type Y. By annotating
                field Y with the @Valid annotation, the Validator will validate Y (and its
                properties) when X is validated.
            </text>
        </assertion>
        <assertion id="b">
            <text>The exact type Z of the value contained in the field declared of type Y
                (subclass, implementation) is determined at runtime. The constraint definitions of Z
                are used
            </text>
        </assertion>
        <assertion id="c">
            <text>Array of objects is supported by @Valid. The content of the array is
                validated.
            </text>
        </assertion>
        <assertion id="d">
            <text>java.util.Collection is supported by @Valid. The content of the collection is
                validated.
            </text>
        </assertion>
        <assertion id="e">
            <text>java.util.Set is supported by @Valid. The content of the Set is validated.</text>
        </assertion>
        <assertion id="f">
            <text>java.util.List is supported by @Valid. The content of the list is
                validated.
            </text>
        </assertion>
        <assertion id="g">
            <text>java.util.Map is supported by @Valid</text>
        </assertion>
        <assertion id="h">
            <text>java.lang.Iterable is supported by @Valid. The elements of the iterable are
                validated
            </text>
        </assertion>
        <assertion id="i">
            <text>For Map, the value of each entry is validated (the key is not validated)</text>
        </assertion>
        <assertion id="j">
            <text>Like regular references, the type of the collection, array or Iterable element is
                determined at runtime and the constraint definitions for this particular type are
                used
            </text>
        </assertion>
        <assertion id="k">
            <text>The @Valid annotation is applied recursively</text>
        </assertion>
    </section>
    <section id="3.3" title="Inheritance">
        <assertion id="a">
            <text>A constraint declaration can be placed on an interface</text>
        </assertion>
        <assertion id="b">
            <text>For a given class, constraint declarations held on superclasses as well as
                interfaces are evaluated by the Bean Validation provider
            </text>
        </assertion>
    </section>
    <section id="3.4" title="Group and group sequence">
        <assertion id="a">
            <text>If no group is explicitly declared, a constraint belongs to the Default
                group
            </text>
        </assertion>
        <assertion id="b">
            <text>Groups are represented by interfaces</text>
        </assertion>
        <assertion id="c">
            <text>A constraint can belong to one or more groups</text>
        </assertion>
        <assertion id="d">
            <text>During the validation call, one or more groups are validated. All the constraints
                belonging to this set of group is evaluated on the object graph
            </text>
        </assertion>
    </section>
    <section id="3.4.1" title="Group inheritance">
        <assertion id="a">
            <text>A group can inherit one or more groups by using interface inheritance</text>
        </assertion>
        <assertion id="b">
            <text>For a given interface Z, constraints marked as belonging to the group Z (ie where
                the annotation groups property contains the interface Z) or any of the super
                interfaces of Z (inherited groups) are considered part of the group Z
            </text>
        </assertion>
    </section>

    <section id="3.4.2" title="Group sequence ">
        <assertion id="a" testable="false">
            <text>By default, constraints are evaluated in no particular order and this regardless
                of which groups they belong to
            </text>
        </assertion>
        <assertion id="b">
            <text>Each group in a group sequence must be processed sequentially in the order defined
                by @GroupSequence.value when the group defined as a sequence is requested
            </text>
        </assertion>
        <assertion id="c">
            <text>Note that a group member of a sequence can itself be composed of several groups
                via inheritance or sequence definition. In this case, each composed group must
                respect the sequence order as well.
            </text>
        </assertion>
        <assertion id="d">
            <text>If one of the groups processed in the sequence generates one or more constraint
                violation, the groups following in the sequence must not be processed
            </text>
        </assertion>
        <assertion id="e">
            <text>Groups defining a sequence and groups composing a sequence must not be involved in
                a cyclic dependency either directly or indirectly, either through cascaded sequence
                definition or group inheritance
            </text>
        </assertion>
        <assertion id="f">
            <text>If a group containing such a circularity is evaluated, a GroupDefinitionException
                is raised.
            </text>
        </assertion>
        <assertion id="g" testable="false">
            <text>Groups defining a sequence should not directly inherit other groups. In other
                words, the interface hosting the group sequence should not have any super
                interface.
            </text>
        </assertion>
        <assertion id="h" testable="false">
            <text>Groups defining a sequence should not be used directly in constraint
                declarations
            </text>
        </assertion>
        <assertion id="i">
            <text>To define a group as a sequence, the interface must be annotated with the
                @GroupSequence annotation
            </text>
        </assertion>
        <assertion id="j">
            <text>A given constraint can belong to two groups ordered by a sequence. In this case,
                the constraint is evaluated as part of the first group and ignored in the subsequent
                group(s)
            </text>
        </assertion>
    </section>
    <section id="3.4.3" title="Redefining the Default group for a class">
        <assertion id="a">
            <text>To redefine Default for a class, place a @GroupSequence annotation on the class.
                this sequence expresses the sequence of groups that does substitute Default for this
                class.
            </text>
        </assertion>
        <assertion id="b" testable="false">
            <text>Constraints hosted on a class A and belonging to the Default group (by default or
                explicitly) implicitly belong to the group A
            </text>
        </assertion>
        <assertion id="c">
            <text>A sequence defined on a class A (ie. redefining the Default groups for the class)
                must contain the group A
            </text>
        </assertion>
        <assertion id="d">
            <text>If a @GroupSequence redefining the Default group for a class A does not contain
                the group A, a GroupDefinitionException is raised when the class is validated or
                when its metadata is requested
            </text>
        </assertion>
    </section>
    <section id="3.4.4" title="Implicit grouping">
        <assertion id="a">
            <text>Every constraint hosted on an interface Z and part of the Default group
                (implicitly or explicitly) belongs to the group Z
            </text>
        </assertion>
    </section>
    <section id="3.4.5" title="Formal group definitions">
        <assertion id="a">
            <text>If a class does have a @GroupSequence annotation, the group Default contains every
                constraint belonging to every group declared by the @GroupSequence
                annotation.
            </text>
        </assertion>
        <assertion id="b">
            <text>If class X has no @GroupSequence annotation, the group Default contains every
                constraint in the group X and if X has a direct superclass Y, every constraint in
                the group Default of Y this rule
            </text>
        </assertion>
    </section>
    <section id="3.5" title="Validation routine">
        <assertion id="a" testable="false">
            <text>For a given group to validate, the validation routine applied on a given bean
                instance is expected to execute the constraint validations in no particular
                order
            </text>
        </assertion>
        <assertion id="b">
            <text>Note that this implies that a given validation constraint will not be processed
                more than once per validation
            </text>
        </assertion>
        <assertion id="c" testable="false">
            <text>Unless ordered by group sequences, groups can be validated in no particular
                order
            </text>
        </assertion>
    </section>
    <section id="3.5.1" title="Object graph validation ">
        <assertion id="a">
            <text>The @Valid annotation on a given association (i.e. object reference or collection,
                array, Iterable of objects), dictates the Bean Validator implementation to apply
                recursively the bean validation routine on (each of) the associated object(s)
            </text>
        </assertion>
        <assertion id="b">
            <text>This mechanism is recursive</text>
        </assertion>
        <assertion id="c">
            <text>Null references are ignored</text>
        </assertion>
        <assertion id="d">
            <text>To prevent infinite loops, the Bean Validation implementation must ignore the
                cascading operation if the associated object instance has already been validated in
                the current navigation path (starting from the root object)
            </text>
        </assertion>
        <assertion id="e">
            <text>@Valid is an orthogonal concept to the notion of group. If two groups are in
                sequence, the first group must pass for all associated objects before the second
                group is evaluated.
            </text>
        </assertion>
    </section>
    <section id="3.5.2" title="Traversable property">
        <assertion id="a">
            <text>isReachable is called for every property about to be accessed either for
                validation or for cascading
            </text>
        </assertion>
        <assertion id="b">
            <text>isCascadable is called for every property about to be cascaded (ie. marked as
                @Valid)
            </text>
        </assertion>
        <assertion id="c">
            <text>isCascadable for a given property is only called if isReachable returns true. In
                other words, isReachable is always called before isCascadable for a given
                property
            </text>
        </assertion>
        <assertion id="d">
            <text>The Bean Validation provider must not access the state of a property, nor validate
                its constraints if the property is not traversable. A property is traversable if
                TraversableResolver returns true for this property
            </text>
        </assertion>
        <assertion id="e">
            <text>If an exception occurs when the TraversableResolver is called, the exception is
                wrapped into a ValidationException
            </text>
        </assertion>
        <assertion id="f" testable="false">
            <text>If Java Persistence is available in the runtime environment, a property is
                considered reachable if Java Persistence considers the property as loaded
            </text>
        </assertion>
        <assertion id="g" testable="false">
            <text>If Java Persistence is not available in the runtime environment, all properties
                are considered reachable
            </text>
        </assertion>
        <assertion id="h" testable="false">
            <text>If Java Persistence is not available in the runtime environment, all properties
                are considered cascadable
            </text>
        </assertion>
    </section>
    <section id="3.5.3" title="ConstraintValidator resolution algorithm">
        <assertion id="a">
            <text>If the constraint declaration is hosted on a class or an interface, the targeted
                type is the class or the interface
            </text>
        </assertion>
        <assertion id="b">
            <text>If the constraint is hosted on a class attribute, the type of the attribute is the
                targeted type
            </text>
        </assertion>
        <assertion id="c">
            <text>If the constraint is hosted on a getter, the return type of the getter is the
                targeted type
            </text>
        </assertion>
        <assertion id="d">
            <text>the ConstraintValidator chosen to validate a declared type T is the one where the
                type supported by the ConstraintValidator is a supertype of T and where there is no
                other ConstraintValidator whose supported type is a supertype of T and not a
                supertype of the chosen ConstraintValidator supported type
            </text>
        </assertion>
        <assertion id="e">
            <text>If no ConstraintValidator compliant with T is found amongst the
                ConstraintValidators listed by the constraint A, a UnexpectedTypeException is
                raised
            </text>
        </assertion>
        <assertion id="f">
            <text>If more than one maximally specific ConstraintValidator is found, a
                UnexpectedTypeException is raised
            </text>
        </assertion>
    </section>

    <section id="4" title="Validation APIs"/>
    <section id="4.1" title="Validator API ">
        <assertion id="a" testable="false">
            <text>Validator implementations are thread-safe</text>
        </assertion>
    </section>
    <section id="4.1.1" title="Validation methods">
        <assertion id="a">
            <text>validate(T object, Class... groups) is used to validate a given object</text>
        </assertion>
        <assertion id="b">
            <text>An IllegalArgumentException is thrown when validateProperty is called and object
                is null or null is passed to the varargs groups.
            </text>
        </assertion>
        <assertion id="c">
            <text>A Set containing all ConstraintViolation objects representing the failing
                constraints is returned, an empty Set is returned otherwise
            </text>
        </assertion>
        <assertion id="d">
            <text>validateProperty(T object, String propertyName, Class... groups) validates a given
                field or property of an object
            </text>
        </assertion>
        <assertion id="e">
            <text>An IllegalArgumentException is thrown when validateProperty is called and object
                is null or propertyName is null empty or invalid or null is passed to the varargs
                groups.
            </text>
        </assertion>
        <assertion id="f">
            <text>The property name in validateProperty is the JavaBeans property name (as defined
                by the JavaBeans Introspector class)
            </text>
        </assertion>
        <assertion id="g">
            <text>@Valid is not honored by a call to validateProperty.</text>
        </assertion>
        <assertion id="h">
            <text>validateValue(Class beanType, String propertyName, Object value, Class... groups)
                validates the property referenced by propertyName present on beanType or any of its
                superclasses, if the property value were value.
            </text>
        </assertion>
        <assertion id="i">
            <text>An IllegalArgumentException is thrown when validateValue is called and object is
                null or propertyName is null empty or invalid or null is passed to the varargs
                groups.
            </text>
        </assertion>
        <assertion id="j">
            <text>@Valid is not honored by validateValue.</text>
        </assertion>
        <assertion id="k">
            <text>If some unrecoverable failure happens during validation, a ValidationException is
                raised.
            </text>
        </assertion>
    </section>
    <section id="4.1.2" title="groups">
        <assertion id="a">
            <text>All constraints belonging to the targeted group are applied during the validation
                routine.
            </text>
        </assertion>
        <assertion id="b">
            <text>If no group is passed, the Default group is assumed</text>
        </assertion>
        <assertion id="c" testable="false">
            <text>When more than one group is evaluated and passed to the various validate methods,
                order is not constrained
            </text>
        </assertion>
    </section>
    <section id="4.2" title="ConstraintViolation">
        <assertion id="a">
            <text>The getMessage method returns the interpolated (localized) message for the failing
                constraint
            </text>
        </assertion>
        <assertion id="b">
            <text>The getMessageTemplate method returns the non-interpolated error message</text>
        </assertion>
        <assertion id="c">
            <text>The getRootBean method returns the root object being validated that led to the
                failing constraint
            </text>
        </assertion>
        <assertion id="d">
            <text>The getInvalidValue method returns the value (field, property or validated object)
                being passed to isValid
            </text>
        </assertion>
        <assertion id="e">
            <text>getConstraintDescriptor provides access to the failing constraint metadata</text>
        </assertion>
        <assertion id="f">
            <text>getPropertyPath returns the Path object representing the navigation path from the
                root object to the failing object
            </text>
        </assertion>
        <assertion id="g">
            <text>If the failing object is the root object, the property path consists of a single
                Node with name set to null.
            </text>
        </assertion>
        <assertion id="h">
            <text>If failing object is traversed, a Node object whose name equals the name of the
                association property (field name or Java Bean property name) is added to Path.
            </text>
        </assertion>
        <assertion id="i">
            <text>If the traversed association is a List or an array, the added Node object contains
                the index value in getIndex.
            </text>
        </assertion>
        <assertion id="j">
            <text>If the association is a Map, the added Node object (representing a given map
                entry) contains the key value in getKey
            </text>
        </assertion>
        <assertion id="k">
            <text>For all Iterable or Map, the added Node object added is marked as inIterable
                (isInIterable)
            </text>
        </assertion>
        <assertion id="l">
            <text>For a property level constraint (field and getter) a Node object is added to Path
                whose name equals the name of the property.
            </text>
        </assertion>
        <assertion id="m">
            <text>For a class level constraint a Node object is added to Path whose name is null
            </text>
        </assertion>
        <assertion id="n" testable="false">
            <text>Bean Validation implementations should ensure that a ConstraintViolation
                implementation is Serializable provided that the root bean, the leaf bean, the
                invalid value and keys in the Path object are Serializable objects.
            </text>
        </assertion>

    </section>
    <section id="4.3.1" title="Default message interpolation">
        <assertion id="a">
            <text>A conforming implementation includes a default message interpolator</text>
        </assertion>
        <assertion id="b">
            <text>Each constraint defines a message descriptor via its message property</text>
        </assertion>
        <assertion id="c">
            <text>Every constraint definition shall define a default message descriptor for that
                constraint.
            </text>
        </assertion>
        <assertion id="d">
            <text>Messages can be overridden at declaration time in constraints by setting the
                property on the constraint.
            </text>
        </assertion>
        <assertion id="e">
            <text>The message descriptor is a string literal and may contain one or more message
                parameters. Message parameters are string literals enclosed in braces
            </text>
        </assertion>
        <assertion id="f">
            <text>\{ is considered as the literal { instead of being considered as the beginning of
                a message parameter
            </text>
        </assertion>
        <assertion id="g">
            <text>\} is considered as the literal } instead of being considered as the end of a
                message parameter
            </text>
        </assertion>
        <assertion id="h">
            <text>\\ is considered as the literal \ instead of being considered as the escaping
                character
            </text>
        </assertion>
    </section>
    <section id="4.3.1.1" title="Default message interpolation algorithm">
        <assertion id="a">
            <text>Message parameters are extracted from the message string and used as keys to
                search the ResourceBundle named ValidationMessages (step1)
            </text>
        </assertion>
        <assertion id="b">
            <text>Step 1 is applied recursively until no replacement is performed</text>
        </assertion>
        <assertion id="c">
            <text>Message parameters are extracted from the message string and used as keys to
                search the Bean Validation provider's built-in ResourceBundle using the defined
                locale. If a property is found, the message parameter is replaced with the property
                value in the message string (step 2)
            </text>
        </assertion>
        <assertion id="e" testable="false">
            <!-- in order to test one would have to make assumptions about the provider specific resource bundle -->
            <text>Contrary to step 1, step 2 is not processed recursively</text>
        </assertion>
        <assertion id="f" testable="false">
            <!-- in order to test one would have to make assumptions about the provider specific resource bundle -->
            <text>If step 2 triggers a replacement, then step 1 is applied again</text>
        </assertion>
        <assertion id="g">
            <text>As last step message parameters are extracted from the message string. Those
                matching the name of an attribute of the constraint declaration are replaced by the
                value of that attribute.
            </text>
        </assertion>
        <assertion id="h">
            <text>If the locale is passed to the interpolator method interpolate(String,
                CosntraintDescriptor, Object, Locale), this Locale instance is used
            </text>
        </assertion>
        <assertion id="i">
            <text>If the locale is not specified, the default Locale as provided by
                Locale.getDefault() is used.
            </text>
        </assertion>
    </section>
    <section id="4.3.2" title="Custom message interpolation">
        <assertion id="a" testable="false">
            <text>A message interpolator implementation shall be thread-safe</text>
        </assertion>
        <assertion id="b">
            <text>It is possible to override the MessageInterpolator implementation for a given
                Validator instance by invoking
                ValidatorFactory.usingContext().messageInterpolator(messageInterpolator).getValidator()
            </text>
        </assertion>
    </section>
    <section id="4.4" title="Bootstrapping">
        <assertion id="a">
            <text>A bootstrap implementation must be able to bootstrap any Bean Validation provider
                implementation
            </text>
        </assertion>
    </section>
    <section id="4.4.1" title="Examples">
        <assertion id="a" testable="false">
            <text>The ValidatorFactory object is thread-safe</text>
        </assertion>
    </section>
    <section id="4.4.2" title="ValidatorFactory">
        <assertion id="a">
            <text>The MessageInterpolator or the TraversableResolver passed to the ValidatorContext
                are used instead of the ValidatorFactory's MessageInterpolator or
                TraversableResolver instances
            </text>
        </assertion>
        <assertion id="b">
            <text>getMessageInterpolator() returns the MessageInterpolator instance configured
                during the initialization of the ValidatorFactory
            </text>
        </assertion>
    </section>
    <section id="4.4.3" title="Configuration">
        <assertion id="a">
            <text>A Bean Validation provider must define a sub interface of Configuration uniquely
                identifying the provider.
            </text>
        </assertion>
        <assertion id="b" testable="false">
            <text>Streams represented in the XML configuration and opened by the Configuration
                implementation must be closed by the Configuration implementation after the
                ValidatorFactory creation (or if an exception occurs)
            </text>
        </assertion>
        <assertion id="c" testable="false">
            <text>If no ValidationProviderResolver instance has been specified, the default
                ValidationProviderResolver is used
            </text>
        </assertion>
    </section>
    <section id="4.4.4.1" title="ValidationProviderResolver">
        <assertion id="a">
            <text>ValidationProviderResolver returns the list of Bean Validation providers available
                at runtime and more specifically a ValidationProvider instance for each provider
                available in the context
            </text>
        </assertion>
        <assertion id="b" testable="false">
            <text>Implementations must be thread-safe</text>
        </assertion>
        <assertion id="c">
            <text>Bean Validation providers must supply a service provider configuration file by
                creating a text file javax.validation.spi.ValidationProvider and placing it in the
                META-INF/services directory of one of its jar files
            </text>
        </assertion>
    </section>
    <section id="4.4.4.2" title="ValidationProvider">
        <assertion id="a">
            <text>A client can request a specific Bean Validation provider by using
                Validation.byProvider() or by defining the provider in the XML configuration
                file
            </text>
        </assertion>
        <assertion id="b">
            <text>The provider discovery mechanism retrieve all available providers using
                ValidationProviderResolver.getValidationProviders() and returns the first
                ValidationProvider matching the requested provider
            </text>
        </assertion>
        <assertion id="c">
            <text>When the default Bean Validation provider is requested, the first
                ValidationProvider returned by the ValidationProviderResolver strategy is
                returned
            </text>
        </assertion>
        <assertion id="d">
            <text>Every Bean Validation provider must provide a ValidationProvider implementation
                containing a public no-arg constructor
            </text>
        </assertion>
        <assertion id="e">
            <text>If a problem occurs while building the ValidatorFactory, a ValidationException is
                raised
            </text>
        </assertion>
    </section>
    <section id="4.4.5" title="Validation">
        <assertion id="a">
            <text>Validation.buildDefaultValidatorFactory(), is considered to be the default
                ValidatorFactory and is equivalent to the ValidatorFactory returned by
                Validation.byDefaultProvider().configure().buildValidatorFactory()
            </text>
        </assertion>
        <assertion id="b">
            <text>ValidationProvider.createGenericConfiguration(BootstrapState state) is the second
                bootstrapping entry point and let the client provide a custom
                ValidationProviderResolution instance
            </text>
        </assertion>
        <assertion id="c">
            <text>ValidationProvider.createGenericConfiguration(BootstrapState state) is the third
                bootstrapping entry point and let the client define the specific Bean Validation
                provider requested as well as a custom ValidationProviderResolver implementation if
                needed
            </text>
        </assertion>
        <assertion id="d">
            <text>The Validation implementation provided by the Bean Validation provider must not
                contain any non private attribute or method aside from the three public static
                bootstrap methods
            </text>
        </assertion>
        <assertion id="e">
            <text>The bootstrap implementation must ensure it can bootstrap third party
                providers
            </text>
        </assertion>
        <assertion id="f">
            <text>When building the Configuration object, if the ValidationProviderResolver fails or
                if the expected provider is not found, a ValidationException is raised
            </text>
        </assertion>
    </section>
    <section id="4.4.6" title="XML Configuration">
        <assertion id="a">
            <text>Unless explicitly ignored Configuration takes into account the configuration
                available in META-INF/validation.xml
            </text>
        </assertion>
        <assertion id="b" implied="true">
            <text>META-INF/validation.xml will be ignored if Configuration.ignoreXMLConfiguration()
                is called.
            </text>
        </assertion>
        <assertion id="c">
            <text>This configuration file is optional.</text>
        </assertion>
        <assertion id="d" testable="false">
            <text>If more than one META-INF/validation.xml file is found in the classpath, a
                ValidationException is raised.
            </text>
        </assertion>
        <assertion id="e">
            <text>Unless stated otherwise, XML based configuration settings are overridden by values
                explicitly set via the Configuration API
            </text>
        </assertion>
        <assertion id="f">
            <text>default-provider represents the class name of the provider specific Configuration
                sub-interface. If defined, the provider suitable for this interface is used
            </text>
        </assertion>
        <assertion id="g">
            <text>message-interpolator represents the fully qualified class name of the
                MessageInterpolator implementation. When defined in XML, the implementation must
                have a public no-arg constructor.
            </text>
        </assertion>
        <assertion id="h">
            <text>traversable-resolver represents the fully qualified class name of the
                TraversableResolver implementation. When defined in XML, the implementation must
                have a public no-arg constructor.
            </text>
        </assertion>
        <assertion id="i">
            <text>constraint-validator-factory represents the fully qualified class name of the
                ConstraintValidatorFactory implementation. When defined in XML, the implementation
                must have a public no-arg constructor.
            </text>
        </assertion>
        <assertion id="j">
            <text>message-interpolator, traversable-resolver and constraint-validator-factory are
                optional.
            </text>
        </assertion>
        <assertion id="k">
            <text>constraint-mapping represents the resource path of an XML mapping file</text>
        </assertion>
        <assertion id="l">
            <text>More than one constraint-mapping element can be present</text>
        </assertion>
        <assertion id="m">
            <text>Mappings provided via Configuration.addMapping(InputStream) are added to the list
                of mappings described via constraint-mapping
            </text>
        </assertion>
        <assertion id="n" testable="false">
            <text>The namespace javax.validation for properties is reserved for use by this
                specification
            </text>
        </assertion>
        <assertion id="o" testable="false">
            <text>Properties defined via Configuration.addProperty(String, String) are added to the
                properties defined via property
            </text>
        </assertion>
        <assertion id="p" testable="false">
            <text>If a property with the same name are defined in both XML and via the programmatic
                API, the value provided via programmatic API has priority
            </text>
        </assertion>
        <assertion id="q">
            <text>If a public no-arg constructor is missing, a ValidationException is raised during
                the Configuration.buildValidatorFactory() call
            </text>
        </assertion>
    </section>
    <section id="4.4.7" title="Usage">
        <assertion id="a" testable="false">
            <text>ValidatorFactory is a thread-safe object that should be built once per deployment
                unit
            </text>
        </assertion>
        <assertion id="b" testable="false">
            <text>Validator is thread-safe too and should be considered a lightweight object</text>
        </assertion>
    </section>

    <section id="5" title="Constraint metadata request APIs"/>
    <section id="5.1" title="Validator">
        <assertion id="a">
            <text>If a constraint definition or declaration hosted by the requested class (or any of
                it's superclasses and interfaces according to the constraint propagation rules) is
                invalid, a ValidationException is raised
            </text>
        </assertion>
        <assertion id="b">
            <text>Validator.getConstraintsForClass returns a BeanDescriptor object describing the
                bean level constraints and providing access to the property level constraints
                metadata.
            </text>
        </assertion>
        <assertion id="c">
            <text>Validator.getConstraintsForClass throws an IllegalArgumentException if the clazz
                parameter is null
            </text>
        </assertion>
    </section>
    <section id="5.2" title="PropertyDescriptor">
        <assertion id="a">
            <text>getElementClass returns either the object type for a class, or the returned type
                for a property
            </text>
        </assertion>
        <assertion id="b">
            <text>getConstraintDescriptors returns all the ConstraintDescriptors hosted on the given
                element in the class hierarchy, each ConstraintDescriptor describing one of the
                constraints declared on the given element.
            </text>
        </assertion>
        <assertion id="c">
            <text>hasConstraints returns true if the given element (class, field or property) in the
                class hierarchy holds at least one constraint declaration.
            </text>
        </assertion>
        <assertion id="d">
            <text>unorderedAndMatchingGroups restricts to the ConstraintDescriptors matching the set
                of groups passed as parameters and present on the element. Order is not respected
                but group inheritance and inheritance via sequence (including the Default group
                overriding at the class level) are honored.
            </text>
        </assertion>
        <assertion id="e">
            <text>declaredOn lets you restrict the list of element types constraints are hosted
                on.
            </text>
        </assertion>
        <assertion id="f">
            <text>lookingAt lets you restrict which constraints are considered. Either constraints
                belonging to the element but hosted on the class represented by BeanDescritptor
                (Scope.LOCAL_ELEMENT), or constraints belonging to the element but hosted anywhere
                in the class hierarchy (Scope.HIERARCHY).
            </text>
        </assertion>
    </section>
    <section id="5.3" title="BeanDescriptor">
        <assertion id="a">
            <text>isBeanConstrained returns true if the given class (and superclasses and
                interfaces) host at least one validation declaration (either constraint or @Valid
                annotation)
            </text>
        </assertion>
        <assertion id="b">
            <text>getConstraintsForProperty returns a PropertyDescriptor object describing the
                property level constraints (See Section 3.1.2). The property is uniquely identified
                by its name as per the JavaBeans convention: field level and getter level
                constraints of the given name are all returned
            </text>
        </assertion>
        <assertion id="c">
            <text>getConstraintsForProperty throws an IllegalArgumentException if the propertyName
                parameter is null
            </text>
        </assertion>
    </section>
    <section id="5.4" title="PropertyDescriptor">
        <assertion id="a">
            <text>The isCascaded method returns true if the property is marked with @Valid</text>
        </assertion>
        <assertion id="b">
            <text>getPropertyName returns the property name</text>
        </assertion>
    </section>
    <section id="5.5" title="ConstraintDescriptor">
        <assertion id="a">
            <text>If ConstraintDescriptor represents a composing annotation (see Section 2.3), the
                returned annotation must reflect parameter overriding
            </text>
        </assertion>
        <assertion id="b">
            <text>getAttributes returns a map containing the annotation attribute names as a key,
                and the annotation attribute values as a value
            </text>
        </assertion>
        <assertion id="c">
            <text>If ConstraintDescriptor represents a composing annotation (see Section 2.3), the
                returned Map must reflect attribute overriding
            </text>
        </assertion>
        <assertion id="d">
            <text>getGroups returns the groups the constraint is supposed to be applied upon</text>
        </assertion>
        <assertion id="e">
            <text>If no group is set on the constraint declaration, the Default group is
                returned
            </text>
        </assertion>
        <assertion id="f">
            <text>The groups of a composing constraint are the groups of the composed
                constraint
            </text>
        </assertion>
        <assertion id="g">
            <text>getPayload returns the payloads the constraint hosts or an empty set if
                none
            </text>
        </assertion>
        <assertion id="h">
            <text>Likewise, payload from the main constraint annotation is inherited by the
                composing annotations.
            </text>
        </assertion>
        <assertion id="i">
            <text>Any payload definition on a composing annotation is ignored</text>
        </assertion>
        <assertion id="k">
            <text>isReportAsSingleViolation() returns true if the constraint is annotated with
                @ReportAsSingleViolation
            </text>
        </assertion>
        <assertion id="l">
            <text>getComposingConstraints return a set of composing ConstraintDescriptors where each
                descriptor describes a composing constraint.
            </text>
        </assertion>
    </section>

    <section id="6" title="Built-in Constraint definitions">
        <assertion id="a">
            <text>Each Bean Validation provider must recognize built-in constraint annotations as
                valid constraint definitions and provide compliant constraint implementations for
                each
            </text>
        </assertion>
        <assertion id="b">
            <text>The built-in constraint validation implementation is having a lower priority than
                an XML mapping definition
            </text>
        </assertion>
        <assertion id="c">
            <text>@Null constraint</text>
        </assertion>
        <assertion id="d">
            <text>@NotNull constraint</text>
        </assertion>
        <assertion id="e">
            <text>@AssertTrue constraint</text>
        </assertion>
        <assertion id="f">
            <text>@AssertFalse constraint</text>
        </assertion>
        <assertion id="g">
            <text>@Min constraint</text>
        </assertion>
        <assertion id="h">
            <text>@Max constraint</text>
        </assertion>
        <assertion id="i">
            <text>@DecimalMin constraint</text>
        </assertion>
        <assertion id="j">
            <text>@DecimalMax constraint</text>
        </assertion>
        <assertion id="k">
            <text>@Size constraint</text>
        </assertion>
        <assertion id="l">
            <text>@Digits constraint</text>
        </assertion>
        <assertion id="m">
            <text>@Past constraint</text>
        </assertion>
        <assertion id="n">
            <text>@Future constraint</text>
        </assertion>
        <assertion id="o">
            <text>@Pattern constraint</text>
        </assertion>
    </section>

    <section id="7" title="XML deployment descriptor">
        <assertion id="a" testable="true">
            <text>If the xml configuration file does not validate against the given xsd files a
                ValidationException is raised.
            </text>
        </assertion>
    </section>
    <section id="7.1" title="Constraint definition and declaration">
        <assertion id="a">
            <text>Specifically when exploring metadata, the Bean Validation provider must ensure
                that an annotation instance corresponding to the XML declaration is provided via
                ConstraintDescriptor.getAnnnotation()
            </text>
        </assertion>
        <assertion id="b">
            <text>A given class must not be described more than once amongst all the XML mapping
                descriptors
            </text>
        </assertion>
        <assertion id="c">
            <text>A given field or getter must not be described more than once on a given class
                description
            </text>
        </assertion>
        <assertion id="d">
            <text>A given constraint definition must not be overridden more than once amongst all
                the XML mapping descriptors
            </text>
        </assertion>
        <assertion id="e">
            <text>If any of these rule is violated in a given validation deployment, a
                ValidationException is raised during the creation of the ValidatorFactory
            </text>
        </assertion>
    </section>
    <section id="7.1.1" title="Constraint declaration in XML">
        <assertion id="a">
            <text>If default-package is set, all unqualified class names (including annotations) are
                considered part of the package described by default-package.
            </text>
        </assertion>
        <assertion id="b">
            <text>A given JavaBean is described by the bean element.</text>
        </assertion>
        <assertion id="c">
            <text>The name of the class in the bean node is mandatory</text>
        </assertion>
        <assertion id="d">
            <text>By default, all constraint declarations expressed via annotation are ignored for
                classes described in XML
            </text>
        </assertion>
        <assertion id="e">
            <text>You can force Bean Validation to consider both annotations and XML constraint
                declarations by using ignore-annotation="false" on bean
            </text>
        </assertion>
        <assertion id="f">
            <text>If the name of the class does refer to a class not present in in the classpath, a
                ValidationException is raised
            </text>
        </assertion>
    </section>
    <section id="7.1.1.1" title="Class-level overriding">
        <assertion id="a">
            <text>If ignore-annotations is declared, Bean Validation must honor the explicit value
                for this element
            </text>
        </assertion>
        <assertion id="b">
            <text>If not declared, the default value defined in the encapsulating bean element is
                considered
            </text>
        </assertion>
        <assertion id="c">
            <text>When ignore-annotations is true, class-level Bean Validation annotations are
                ignored for this class
            </text>
        </assertion>
        <assertion id="d">
            <text>When ignore-annotations is false, constraints declared in XML and constraints
                declared in annotations are added and form the list of class-level declared
                constraints
            </text>
        </assertion>
        <assertion id="e">
            <text>@GroupSequence is considered unless group-sequence element is explicitly
                used
            </text>
        </assertion>
    </section>
    <section id="7.1.1.2" title="Field-level overriding">
        <assertion id="a">
            <text>If ignore-annotations is declared, Bean Validation must honor the explicit value
                for this element
            </text>
        </assertion>
        <assertion id="b">
            <text>If not declared, the default value defined in the encapsulating bean element is
                considered
            </text>
        </assertion>
        <assertion id="c">
            <text>When ignore-annotations is true, field-level Bean Validation annotations on the
                targeted field are ignored
            </text>
        </assertion>
        <assertion id="d">
            <text>When ignore-annotations is false, constraints declared in XML and constraints
                declared in annotations are added and form the list of field-level declared
                constraints
            </text>
        </assertion>
        <assertion id="e">
            <text>The only way to disable cascading on a field marked as @Valid is to use
                ignore-annotations=true
            </text>
        </assertion>
        <assertion id="f">
            <text>If the name of the field does not correspond to a field in the given bean a
                ValidationException is raised
            </text>
        </assertion>
    </section>
    <section id="7.1.1.3" title="Property-level overriding">
        <assertion id="a">
            <text>The name attribute correspond to the name of the property considered as defined in
                Section 3.1.2. If ignore-annotations is declared, Bean Validation must honor the
                explicit value for this element
            </text>
        </assertion>
        <assertion id="b">
            <text>If not declared, the default value defined in the encapsulating bean element is
                considered
            </text>
        </assertion>
        <assertion id="c">
            <text>When ignore-annotations is true, property-level Bean Validation annotations on the
                targeted property are ignored (including the @Valid)
            </text>
        </assertion>
        <assertion id="d">
            <text>When ignore-annotations is false, constraints declared in XML and constraints
                declared in annotations are added and form the list of property-level declared
                constraints.
            </text>
        </assertion>
        <assertion id="e">
            <text>The only way to disable cascading on a property marked as @Valid is to use
                ignore-annotations=true
            </text>
        </assertion>
        <assertion id="f">
            <text>If the name of the property does not correspond to a property in the given bean a
                ValidationException is raised
            </text>
        </assertion>
    </section>
    <section id="7.1.1.4" title="Constraint declaration">
        <assertion id="a">
            <text>The name attribute is mandatory and represents the name of the element in the
                constraint declaration
            </text>
        </assertion>
        <assertion id="b">
            <text>"message" or "groups" are not permitted names, use the message or groups elements
                instead. Otherwise a ValidationException is raised
            </text>
        </assertion>
        <assertion id="c">
            <text>If the element represents a primitive type, a class or an enum, the string
                representation of its value is placed in the element itself
            </text>
        </assertion>
        <assertion id="d">
            <text>If the element represents a primitive type array, a class array or an enum array,
                the string representation of each value is placed in a element placed under the
                element itself
            </text>
        </assertion>
        <assertion id="e">
            <text>If the element represents an annotation, the annotation element is used to
                represent the annotation and placed under element
            </text>
        </assertion>
        <assertion id="f">
            <text>If the element represents an array of annotations, one or more annotation elements
                are placed under element
            </text>
        </assertion>
        <assertion id="g">
            <text>Elements with default values in the annotation definition do not have to be
                represented in XML: the default value will be used in this case
            </text>
        </assertion>
        <assertion id="h">
            <text>If an XML constraint declaration is missing mandatory elements, or if it contains
                elements not part of the constraint definition, a ValidationException is
                raised
            </text>
        </assertion>
    </section>
    <section id="7.1.2" title="Overriding constraint definitions in XML">
        <assertion id="a">
            <text>A constraint definition is represented by a constraint-definition element</text>
        </assertion>
        <assertion id="b">
            <text>If include-existing-validator is set to false, ConstraintValidator defined on the
                constraint annotation are ignored
            </text>
        </assertion>
        <assertion id="c">
            <text>If set to true, the list of ConstraintValidators described in XML are concatenated
                to the list of ConstraintValidator described on the annotation to form a new array
                of ConstraintValidator evaluated
            </text>
        </assertion>
        <assertion id="d">
            <text>Annotation based ConstraintValidator come before XML based ConstraintValidator in
                the array
            </text>
        </assertion>
        <assertion id="e">
            <text>The validator list is returned by
                ConstraintDescriptor.getConstraintValidatorClasses()
            </text>
        </assertion>
    </section>
    <section id="8" title="Exception model">
        <assertion id="a">
            <text>Every (runtime) exception raised either at initialization time or execution time
                by any of the extension interfaces (ConstraintValidator, ConstraintValidatorFactory,
                MessageInterpolator, TraversableResolver, ValidationProviderResolver) is wrapped in
                a ValidationException
            </text>
        </assertion>
    </section>
    <section id="8.2" title="ConstraintDefinitionException">
        <assertion id="a">
            <text>If a constraint definition does not respect the Bean Validation rules or is
                inconsistent, a ConstraintDefinitionException is raised.
            </text>
        </assertion>
    </section>
    <section id="8.3" title="ConstraintDeclarationException and UnexpectedTypeException">
        <assertion id="a" testable="false">
            <text>When a constraint declaration is illegal, ConstraintDeclarationException is
                raised
            </text>
        </assertion>
        <assertion id="b">
            <text>When the return type of a property cannot be processed for a given constraint, an
                UnexpectedTypeException is raised
            </text>
        </assertion>
    </section>
    <section id="8.4" title="GroupDefinitionException">
        <assertion id="a">
            <text>When a group definition is illegal, GroupDefinitionException is raised</text>
        </assertion>
    </section>
</specification>
