All Downloads are FREE. Search and download functionalities are using the official Maven repository.

prise.cdi-tck-web-impl.4.1.0.Alpha5.source-code.tck-audit-cdi.xml Maven / Gradle / Ivy

There is a newer version: 4.1.0.Beta1
Show newest version
<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 /Users/pmuir/workspace/jboss-test-audit/api/src/main/resources/tck-audit.xsd"
               name="Jakarta Contexts and Dependency Injection 3.0" id="cdi" version="3.0" generateSectionIds="true">

    <section id="architecture" title="Architecture" level="1"/>

    <section id="concepts" title="Concepts" level="1">

        <assertion id="a">
            <text>A bean comprises of a (nonempty) set of bean types.</text>
        </assertion>

        <assertion id="b">
            <text>A bean comprises of a (nonempty) set of qualifiers.</text>
        </assertion>

        <assertion id="c">
            <text>A bean comprises of a scope.</text>
        </assertion>

        <assertion id="e">
            <text>A bean comprises of an optional bean name.</text>
        </assertion>

        <assertion id="f">
            <text>A bean comprises of a set of interceptor bindings.</text>
            <note>This may only be tested indirectly</note>
        </assertion>

        <assertion id="g">
            <text>A bean comprises of a bean implementation.</text>
        </assertion>

        <assertion id="h" testable="false">
            <text>A bean may or may not be an alternative.</text>
        </assertion>
    </section>

    <section id="capabilities" title="Functionality provided by the container to the bean" level="2">
    </section>

    <section id="bean_types" title="Bean types" level="2">

        <assertion id="a">
            <text>A bean may have multiple bean types.</text>
        </assertion>

        <assertion id="l">
            <text>All beans have the bean type |java.lang.Object|.</text>
        </assertion>

    </section>

    <section id="legal_bean_types" title="Legal bean types" level="3">
        <assertion id="a">
            <text>A bean type may be an interface.</text>
        </assertion>

        <assertion id="b">
            <text>A bean type may be a concrete class.</text>
        </assertion>

        <assertion id="c">
            <text>A bean type may be an abstract class.</text>
        </assertion>

        <assertion id="d">
            <text>A bean type may be declared final.</text>
        </assertion>

        <assertion id="e">
            <text>A bean type may have final methods.</text>
        </assertion>

        <assertion id="f">
            <text>A bean type may be a parameterized type with actual type parameters.</text>
        </assertion>

        <assertion id="g">
            <text>A bean type may be a parameterized type with type variables.</text>
        </assertion>

        <assertion id="i">
            <text>A bean type may be an array type. Two array types are considered identical only if the element type is identical.</text>
        </assertion>

        <assertion id="j">
            <text>A bean type may be a primitive type. Primitive types are considered to be identical to their corresponding wrapper types in |java.lang|.
            </text>
        </assertion>

        <assertion id="k">
            <text>A bean type may be a raw type.</text>
        </assertion>

        <assertion id="la">
            <text>A type variable is not a legal bean type.</text>
        </assertion>

        <assertion id="lb">
            <text>A parameterized type that contains a wildcard type parameter is not a legal bean type.</text>
        </assertion>

        <group>
            <text>An array type whose component type is not a legal bean type.</text>
            <assertion id="lc">
                <text>An array type whose component type is a type variable is not a legal bean type.</text>
            </assertion>
            <assertion id="ld">
                <text>An array type whose component type is a parameterized type that contains a wildcard type parameter is not a legal bean type.</text>
            </assertion>
        </group>

    </section>

    <section id="restricting_bean_types" title="Restricting the bean types of a bean" level="3">
        <group>
            <text>The bean types of a bean may be restricted by annotating the bean class or producer method or field with the annotation
                |@jakarta.enterprise.inject.Typed|. When a |@Typed| annotation is explicitly specified, only the types whose classes are explicitly listed using
                the |value| member, together with |java.lang.Object| are bean types of the bean.
            </text>
            <assertion id="a">
                <text>Check managed bean</text>
            </assertion>
            <assertion id="c">
                <text>Check producer method</text>
            </assertion>
            <assertion id="d">
                <text>Check producer field</text>
            </assertion>
            <assertion id="e">
                <text>Check generic managed bean</text>
            </assertion>
            <assertion id="g">
                <text>Check generic producer method</text>
            </assertion>
            <assertion id="h">
                <text>Check generic producer field</text>
            </assertion>
        </group>

        <group>
            <text>If a bean class or producer method or field specifies a |@Typed| annotation, and the |value| member specifies a class which does not
                correspond to a type in the unrestricted set of bean types of a bean, the container automatically detects the problem and treats it as a
                definition error.
            </text>
            <assertion id="j">
                <text>Check managed bean</text>
            </assertion>
            <assertion id="l">
                <text>Check producer method</text>
            </assertion>
            <assertion id="m">
                <text>Check producer field</text>
            </assertion>
        </group>
    </section>

    <section id="typecasting_between_bean_types" title="Typecasting between bean types" level="3">
        <assertion id="a">
            <text>A client of a bean may typecast its contextual reference to a bean to any bean type of the bean which is a Java interface. However, the client
                may not in general typecast its contextual reference to an arbitrary concrete bean type of the bean.
            </text>
        </assertion>
    </section>

    <section id="qualifiers" title="Qualifiers" level="2">

    </section>

    <section id="builtin_qualifiers" title="Built-in qualifier types" level="3">

        <assertion id="aa">
            <text>Every bean has the built-in qualifier |@Any|, even if it does not explicitly declare this qualifier, ~except for the special |@New| qualified
                beans defined in Section 3.14, "@New qualified beans"~.
            </text>
            <note>@New qualified beans cannot be checked since @New beans aren't required to be available via programmatic lookup</note>
        </assertion>

        <assertion id="ab">
            <text>If a bean does not explicitly declare a qualifier other than |@Named| or |@Any|, the bean has exactly one additional qualifier, of type
                |@Default|. This
                is called the default qualifier.
            </text>
        </assertion>

        <assertion id="b">
            <text>The default qualifier is also assumed for any injection point that does not explicitly declare a qualifier.</text>
        </assertion>
    </section>

    <section id="defining_qualifier_types" title="Defining new qualifier types" level="3">
        <assertion id="aa" testable="false">
            <text>A qualifier type is a Java annotation defined as |@Target({METHOD, FIELD, PARAMETER, TYPE})|~ and |@Retention(RUNTIME)|~.</text>
            <note>Non-runtime retention annotations are discarded by the compiler</note>
        </assertion>

        <assertion id="ba">
            <text>A qualifier type may be declared by specifying the |@jakarta.inject.Qualifier| meta-annotation.</text>
        </assertion>

        <assertion id="d" testable="false">
            <text>A qualifier type may define annotation members.</text>
            <note>This is true by default in the JLS</note>
        </assertion>
    </section>

    <section id="declaring_bean_qualifiers" title="Declaring the qualifiers of a bean" level="3">
        <group>
            <text>The qualifiers of a bean are declared by annotating the bean class or producer method or field with the qualifier types.</text>

            <assertion id="a">
                <text>Test by annotating a bean class.</text>
            </assertion>

            <assertion id="b">
                <text>Test by annotating a producer method.</text>
            </assertion>

            <assertion id="c">
                <text>Test by annotating a producer field.</text>
            </assertion>
        </group>

        <assertion id="d">
            <text>Any bean may declare multiple qualifier types.</text>
        </assertion>
    </section>

    <section id="injected_field_qualifiers" title="Specifying qualifiers of an injected field" level="3">
        <assertion id="a">
            <text>Qualifier types may be applied to injected fields (see Section 3.8, "Injected fields") to determine the bean that is injected, according to
                the rules of typesafe resolution defined in Section 5.3, "Typesafe resolution".
            </text>
        </assertion>

        <assertion id="b">
            <text>A bean may only be injected to an injection point if it has all the qualifiers of the injection point.</text>
        </assertion>
    </section>

    <section id="method_constructor_parameter_qualifiers" title="Specifying qualifiers of a method or constructor parameter" level="3">
        <group>
            <text>Qualifier types may be applied to parameters of producer methods, initializer methods, disposer methods, observer methods or bean constructors
                (see Chapter 3, Bean implementation) to determine the bean instance that is passed when the method is called by the container.
            </text>

            <assertion id="a">
                <text>Test producer method.</text>
            </assertion>

            <assertion id="b">
                <text>Test initializer method.</text>
            </assertion>

            <assertion id="c">
                <text>Test disposer method.</text>
            </assertion>

            <assertion id="ca">
                <text>Test observer method.</text>
            </assertion>

            <assertion id="d">
                <text>Test bean constructor.</text>
            </assertion>
        </group>
    </section>

    <section id="repeating_qualifiers" title="Repeating qualifiers" level="3">
        <assertion id="a">
            <text>A repeated qualifier behaves just as any other qualifier does</text>
        </assertion>
    </section>

    <section id="scopes" title="Scopes" level="2">
        <assertion id="a">
            <text>All beans have a scope.</text>
        </assertion>

        <assertion id="b" testable="false">
            <text>A scope type is represented by an annotation type.</text>
            <note>This is a statement of intent</note>
        </assertion>

        <assertion id="c">
            <text>The set of scope types is extensible.</text>
        </assertion>
    </section>

    <section id="builtin_scopes" title="Built-in scope types" level="3">

        <group>

            <text>There are five standard scope types defined by this specification, all defined in the package |jakarta.enterprise.context|.</text>

            <assertion id="a">
                <text>The container must provide an implementation of the @RequestScoped, @ApplicationScoped and @SessionScoped annotations defined in Section
                    6.7, “Context management for built-in scopes”.
                </text>
            </assertion>

            <assertion id="ba">
                <text>The |@ConversationScoped| annotation represents the conversation scope defined in Section 6.7.4, "Conversation context lifecycle".</text>
            </assertion>

            <assertion id="ca">
                <text>The |@Dependent| pseudo-scope is for dependent objects, as defined in Section 6.4, "Dependent pseudo-scope"</text>
            </assertion>

            <assertion id="e" testable="false">
                <text>If an interceptor or decorator has any scope other than |@Dependent|, non-portable behavior results.</text>
            </assertion>

        </group>

    </section>

    <section id="defining_new_scope_type" title="Defining new scope types" level="3">
        <assertion id="aa">
            <text>A scope type is a Java annotation defined as |@Target({TYPE, METHOD, FIELD})|~ and |@Retention(RUNTIME)|~.</text>
        </assertion>

        <assertion id="ab" testable="false">
            <text>A scope type is a Java annotation defined as ~|@Target({TYPE, METHOD, FIELD})| and ~|@Retention(RUNTIME)|.</text>
            <note>Non-runtime retention annotations are discarded by the compiler</note>
        </assertion>

        <assertion id="ac" testable="false">
            <text>A scope type must not have any attributes. If a scope type has attributes non-portable behavior results.</text>
        </assertion>

        <assertion id="ba">
            <text>All scope types must specify the |@jakarta.inject.Scope| or |@jakarta.enterprise.context.NormalScope| meta-annotation.</text>
        </assertion>

    </section>

    <section id="declaring_bean_scope" title="Declaring the bean scope" level="3">
        <assertion id="a">
            <text>The scope of a bean is defined by annotating the bean class or producer method or field with a scope type.</text>
        </assertion>

        <group>
            <text>A bean class or producer method or field may specify at most one scope type annotation. If a bean class or producer method or field specifies
                multiple scope type annotations, the container automatically detects the problem and treats it as a definition error.
            </text>
            <assertion id="ba">
                <text>Test with a bean class.</text>
            </assertion>
            <assertion id="bb">
                <text>Test with a producer method.</text>
            </assertion>
            <assertion id="bc">
                <text>Test with a producer field.</text>
            </assertion>
        </group>

        <assertion id="c">
            <text>A scope type may be specified using a stereotype annotation, as defined in Section 2.7.2, "Declaring the stereotypes for a bean"</text>
        </assertion>
    </section>

    <section id="default_scope" title="Default scope" level="3">
        <assertion id="aa">
            <text>When no scope is explicitly declared by annotating the bean class or producer method or field the scope of a bean is defaulted.</text>
        </assertion>

        <assertion id="b">
            <text>If the bean does not declare any stereotype with a declared default scope, the default scope for the bean is |@Dependent|.</text>
        </assertion>

        <assertion id="c">
            <text>If all stereotypes declared by the bean that have some declared default scope have the same default scope, then that scope is the default
                scope for the bean.
            </text>
        </assertion>

        <assertion id="da">
            <text>If there are two different stereotypes declared by the bean that declare different default scopes, then there is no default scope and the bean
                must explicitly declare a scope. If it does not explicitly declare a scope, the container automatically
                detects the problem and treats it as a definition error.
            </text>
        </assertion>

        <assertion id="e">
            <text>If a bean explicitly declares a scope, any default scopes declared by stereotypes are ignored.</text>
        </assertion>
    </section>

    <section id="default_bean_discovery" title="Default bean discovery mode" level="2">

        <group>
            <text>If the bean discovery mode is annotated then:</text>
            <assertion id="a">
                <text>bean classes that don’t have bean defining annotation (as defined in Section 2.5.1, “Bean defining annotations”) are not discovered</text>
            </assertion>
            <assertion id="b">
                <text>producer methods (as defined in Section 3.3, “Producer methods”) whose bean class does not have a bean defining annotation are not
                    discovered
                </text>
            </assertion>
            <assertion id="c">
                <text>producer fields (as defined in Section 3.4, “Producer fields”) whose bean class does not have a bean defining annotation are not
                    discovered
                </text>
            </assertion>
            <assertion id="d">
                <text>disposer methods (as defined in Section 3.5, “Disposer methods”) whose bean class does not have a bean defining annotation are not
                    discovered
                </text>
            </assertion>
            <assertion id="e">
                <text>observer methods (as defined in Section 10.4.2, “Declaring an observer method”) whose bean class does not have a bean defining annotation
                    are not discovered
                </text>
            </assertion>
        </group>

    </section>

    <section id="bean_defining_annotations" title="Bean defining annotations" level="3">

        <assertion id="a" testable="false">
            <text>A bean class may have a bean defining annotation, allowing it to be placed anywhere in an application, as defined in Section 12.1. A bean
                class with a bean defining annotation is said to be an implicit bean.
            </text>
            <note>This is a statement of intent</note>
        </assertion>

        <group>
            <text>The set of bean defining annotations contains:</text>
            <assertion id="ba">
                <text>@ApplicationScoped, @SessionScoped, @ConversationScoped and @RequestScoped annotations</text>
            </assertion>
            <assertion id="bb">
                <text>all other normal scope types</text>
            </assertion>
            <assertion id="bc">
                <text>@Interceptor annotation</text>
            </assertion>
            <assertion id="bd">
                <text>@Decorator annotation</text>
            </assertion>
            <assertion id="be">
                <text>all stereotype annotations (i.e. annotations annotated with @Stereotype)</text>
            </assertion>
            <assertion id="bf">
                <text>the @Dependent scope annotation</text>
            </assertion>
        </group>

        <assertion id="ca">
            <text>Note that to ensure compatibility with other JSR-330 implementations, all pseudo-scope annotations except @Dependent are not bean defining
                annotations.
            </text>
        </assertion>
        <assertion id="cb">
            <text>However, a stereotype annotation including a pseudo-scope annotation is a bean defining annotation.</text>
        </assertion>

    </section>

    <section id="names" title="Bean names" level="2">

        <assertion id="a">
            <text>A valid bean name is a period-separated list of valid EL identifiers</text>
        </assertion>
    </section>

    <section id="declaring_bean_name" title="Declaring the bean name" level="3">

        <group>
            <text>To specify the name of a bean, the qualifier |@jakarta.inject.Named| is applied to the bean class or producer method or field.</text>

            <assertion id="a">
                <text>Test with a bean class.</text>
            </assertion>

            <assertion id="b">
                <text>Test with a producer method.</text>
            </assertion>

            <assertion id="c">
                <text>Test with a producer field.</text>
            </assertion>
        </group>

    </section>

    <section id="default_name" title="Default bean names" level="3">

        <group>
            <text>A default name must be assigned by the container when a bean class or producer method or field of a bean declares a |@Named| annotation and no
                bean name is explicitly specified by the |value| member.
            </text>
            <assertion id="a">
                <text>Test with a bean class.</text>
            </assertion>
            <assertion id="b">
                <text>Test with a producer method.</text>
            </assertion>
            <assertion id="c">
                <text>Test with a producer field.</text>
            </assertion>
        </group>

        <assertion id="e">
            <text>A default name must be assigned by the container when a bean declares a stereotype that declares an empty |@Named| annotation, and the bean
                does not explicitly specify an bean name.
            </text>
        </assertion>

        <group>
            <text>If a bean class or producer method or field of a bean declares a |@Named| annotation and no bean name is explicitly specified the value of the
                |value| member is defaulted.
            </text>
            <assertion id="fa">
                <text>Test with a bean class.</text>
            </assertion>
            <assertion id="fb">
                <text>Test with a producer method.</text>
            </assertion>
            <assertion id="fc">
                <text>Test with a producer field.</text>
            </assertion>
        </group>

    </section>

    <section id="beans_with_no_name" title="Beans with no name" level="3">

        <assertion id="a">
            <text>If |@Named| is not declared by the bean, nor by its stereotypes, a bean has no name.</text>
        </assertion>

        <assertion id="b" testable="false">
            <text>If an interceptor or decorator has a name, non-portable behavior results.</text>
        </assertion>
    </section>

    <section id="alternatives" title="Alternatives" level="2">
        <assertion id="a" testable="false">
            <text>An alternative is a bean that must be explicitly selected if it should be available for lookup, injection or EL resolution.</text>
            <note>Tested in section 5.1.1 Declaring selected alternatives.</note>
        </assertion>
    </section>

    <section id="declaring_alternative" title="Declaring an alternative" level="3">

        <group>
            <text>An alternative may be declared by annotating the bean class or producer method or field with the |@Alternative| annotation.</text>

            <assertion id="aa">
                <text>Test with a bean class.</text>
            </assertion>

            <assertion id="ab">
                <text>Test with a producer method.</text>
            </assertion>

            <assertion id="ac">
                <text>Test with a producer field.</text>
            </assertion>
        </group>

        <group>
            <text>An alternative may be declared by annotating a bean, producer method or producer field with a stereotype that declares an |@Alternative|
                annotation.
            </text>

            <assertion id="ba">
                <text>Test with a bean.</text>
            </assertion>

            <assertion id="bb">
                <text>Test with a producer method.</text>
            </assertion>

            <assertion id="bc">
                <text>Test with a producer field.</text>
            </assertion>
        </group>

        <assertion id="c" testable="false">
            <text>If an interceptor or decorator is an alternative, non-portable behavior results.</text>
            <note>Non-portable behavior.</note>
        </assertion>

    </section>

    <section id="stereotypes" title="Stereotypes" level="2">

        <assertion id="a">
            <text>A stereotype may specify that all beans with the stereotype have defaulted bean names.</text>
        </assertion>

        <assertion id="aa">
            <text>A stereotype may specify that all beans with the stereotype are alternatives.</text>
        </assertion>

        <group>
            <text>A bean may declare zero, one or multiple stereotypes.</text>

            <assertion id="b" testable="false">
                <text>A bean may declare zero stereotypes.</text>
                <note>Not testable through API</note>
            </assertion>

            <assertion id="c">
                <text>Test with one stereotype.</text>
            </assertion>

            <assertion id="d">
                <text>Test with multiple stereotypes.</text>
            </assertion>
        </group>

    </section>

    <section id="defining_new_stereotype" title="Defining new stereotypes" level="3">
        <group>
            <text>A beans stereotype is a Java annotation defined as |@Target({TYPE, METHOD, FIELD})|, |@Target(TYPE)|, |@Target(METHOD)|, |@Target(FIELD)| or
                |@Target({METHOD, FIELD})| and |@Retention(RUNTIME)|.
            </text>

            <assertion id="aa" testable="false">
                <text>Test |@Target({TYPE, METHOD, FIELD})|.</text>
            </assertion>

            <assertion id="ab" testable="false">
                <text>Test |@Target(TYPE)|.</text>
            </assertion>

            <assertion id="ac" testable="false">
                <text>Test |@Target(FIELD)|.</text>
            </assertion>

            <assertion id="ad" testable="false">
                <text>Test |@Target({METHOD, FIELD})|.</text>
            </assertion>

            <assertion id="ae" testable="false">
                <text>|@Retention(RUNTIME)| - untestable.</text>
                <note>Non-runtime retention annotations are discarded by the compiler</note>
            </assertion>
        </group>

        <assertion id="b">
            <text>A stereotype may be declared by specifying the |@jakarta.enterprise.inject.Stereotype| meta-annotation.</text>
        </assertion>
    </section>

    <section id="stereotype_default_scope" title="Declaring the default scope for a stereotype" level="4">

        <group>
            <text>The default scope of a stereotype is defined by annotating the stereotype with a scope type. A stereotype may declare at most one scope. If a
                stereotype declares more than one scope, the container automatically detects the problem and treats it as a definition error.
            </text>

            <assertion id="aa">
                <text>Test with one scope.</text>
            </assertion>

            <assertion id="ab">
                <text>Test that a stereotype with multiple scopes throws an exception.</text>
            </assertion>
        </group>

    </section>

    <section id="specify_stereotype_interceptor_bindings" title="Specifying interceptor bindings for a stereotype" level="4">
        <assertion id="aa">
            <text>The interceptor bindings of a stereotype are defined by annotating the stereotype with the interceptor binding types.</text>
        </assertion>

        <assertion id="a">
            <text>A stereotype may declare zero interceptor bindings.</text>
        </assertion>

        <assertion id="b">
            <text>A stereotype may declare one interceptor bindings.</text>
        </assertion>

        <assertion id="c">
            <text>A stereotype may declare multiple interceptor bindings.</text>
        </assertion>
    </section>

    <section id="named_stereotype" title="Declaring a @Named stereotype" level="4">
        <assertion id="aa">
            <text>A stereotype may declare an empty |@Named| annotation, which specifies that every bean with the stereotype has a defaulted name when a name is
                not explicitly specified by the bean.
            </text>
        </assertion>

        <assertion id="ab">
            <text>A |@Named| qualifier declared by a stereotype is not added to the qualifiers of a bean with the stereotype.</text>
        </assertion>

        <assertion id="ac">
            <text>If a stereotype declares a non-empty |@Named| annotation, the container automatically detects the problem and treats it as a definition
                error.
            </text>
        </assertion>

        <assertion id="b" testable="false">
            <text>A stereotype should not declare any qualifier annotation other than |@Named|. If a stereotype declares any other qualifier annotation,
                non-portable behavior results.
            </text>
            <note>The behavior here is undefined.</note>
        </assertion>

        <assertion id="c" testable="false">
            <text>A stereotype should not be annotated |@Typed|. If a stereotype is annotated |@Typed|, non-portable behavior results.</text>
        </assertion>

    </section>

    <section id="alternative_stereotype" title="Declaring an @Alternative stereotype" level="4">
        <assertion id="a">
            <text>A stereotype may declare an |@Alternative| annotation, which specifies that every bean with the stereotype is an alternative.</text>
        </assertion>
    </section>

    <section id="stereotypes_with_additional_stereotypes" title="Stereotypes with additional stereotypes" level="4">
        <assertion id="a">
            <text>A stereotype may declare other stereotypes.</text>
        </assertion>

        <assertion id="b">
            <text>Stereotype declarations are transitive - a stereotype declared by a second stereotype is inherited by all beans and other stereotypes that
                declare the second stereotype.
            </text>
        </assertion>

        <assertion id="c" testable="false">
            <text>Stereotypes declared |@Target(TYPE)| may not be applied to stereotypes declared |@Target({TYPE, METHOD, FIELD})|, |@Target(METHOD)|,
                |@Target(FIELD)|, |@Target({METHOD, FIELD})|.
            </text>
            <note>No definition of what happens if you do this</note>
        </assertion>

    </section>

    <section id="declaring_stereotypes" title="Declaring the stereotypes for a bean" level="3">
        <group>
            <text>Stereotype annotations may be applied to a bean class or producer method or field.</text>

            <assertion id="a">
                <text>Test with a bean class.</text>
            </assertion>

            <assertion id="b">
                <text>Test with a producer method.</text>
            </assertion>

            <assertion id="c">
                <text>Test with a producer field.</text>
            </assertion>
        </group>

        <assertion id="db">
            <text>The default scope declared by the stereotype may be overridden by the bean.</text>
        </assertion>

        <assertion id="e">
            <text>Multiple stereotypes may be applied to the same bean.</text>
        </assertion>
    </section>

    <section id="builtin_stereotypes" title="Built-in stereotypes" level="3">
        <assertion id="aa" testable="false">
            <text>The built-in stereotype |@jakarta.enterprise.inject.Model| is intended for use with beans that define the model layer of an MVC web application
                architecture such as JSF.
            </text>
            <note>Tested by API signature test</note>
        </assertion>
    </section>

    <section id="exceptions" title="Problems detected automatically by the container" level="2">
        <assertion id="a" testable="false">
            <text>When the application violates a rule defined by this specification, the container automatically detects the problem. There are three kinds of
                problem - definition errors occur when a single bean definition violates the rules of this specification, deployment problems occur when there
                are problems resolving dependencies, or inconsistent specialization, in a particular deployment, and exceptions occur at runtime.
            </text>
            <note>Generalization</note>
        </assertion>

        <assertion id="b">
            <text>Definition errors are developer errors. They may be detected by tooling at development time, and are also detected by the container at
                initialization time. If a definition error exists in a deployment, initialization will be aborted by the container.
            </text>
        </assertion>

        <assertion id="ba">
            <text>If a definition error exists, the container must throw a subclass of |jakarta.enterprise.inject.spi.DefinitionException|.</text>
        </assertion>

        <assertion id="c">
            <text>Deployment problems are detected by the container at initialization time. If a deployment problem exists in a deployment, initialization will
                be aborted by the container.
            </text>
        </assertion>

        <assertion id="ca">
            <text>If a deployment problem occurs, the container must throw a subclass of |jakarta.enterprise.inject.spi.DeploymentException|.</text>
        </assertion>

        <assertion id="d" testable="false">
            <text>The container is permitted to define a non-portable mode, for use at development time, in which some definition errors and deployment problems
                do not cause application initialization to abort.
            </text>
        </assertion>

        <assertion id="e" testable="false">
            <text>Exceptions represent problems that may not be detected until they actually occur at runtime. All exceptions defined by this specification are
                unchecked exceptions. All exceptions defined by this specification may be safely caught and handled by the application.
            </text>
        </assertion>

    </section>

    <section id="priorities" title="Priority ordering" level="2">
    </section>

    <section id="implementation" title="Programming model" level="1">

    </section>

    <section id="managed_beans" title="Managed beans" level="2">

        <assertion id="a">
            <text>If the bean class of a managed bean is annotated with both the |@Interceptor| and |@Decorator| stereotypes, the container automatically
                detects the problem and treats it as a definition error.
            </text>
        </assertion>

        <group>
            <text>If a managed bean has a non-static public field, it must have scope |@Dependent|. If a managed bean with a non-static public field declares
                any scope other than |@Dependent|, the container automatically detects the problem and treats it as a definition error.
            </text>
            <assertion id="fa">
                <text>Check a dependent scoped bean with a public field.</text>
            </assertion>
            <assertion id="fb">
                <text>Check a managed bean with a static public field which declares any scope other than |@Dependent|.</text>
            </assertion>
            <assertion id="fc">
                <text>If a managed bean with a non-static public field declares any scope other than |@Dependent|, the container automatically detects the
                    problem and treats it as a definition error.
                </text>
            </assertion>
        </group>

        <assertion id="g">
            <text>If the managed bean class is a generic type, it must have scope |@Dependent|. If a managed bean with a parameterized bean class declares any
                scope other than |@Dependent|, the container automatically detects the problem and treats it as a definition error.
            </text>
        </assertion>
    </section>

    <section id="what_classes_are_beans" title="Which Java classes are managed beans?" level="3">
        <assertion id="b">
            <text>A Java class is not a managed bean if it is an inner class.</text>
        </assertion>

        <assertion id="ba">
            <text>A Java class that is a static nested class can be a managed bean.</text>
            <note>Implied as the inverse of assertion 3.1.1.b</note>
        </assertion>

        <assertion id="ca">
            <text>A Java class is not a managed bean if it is an abstract class, unless it is annotated |@Decorator|.</text>
        </assertion>

        <assertion id="cb">
            <text>A Java class is not a managed bean if it is an interface, unless it is annotated |@Decorator|.</text>
        </assertion>

        <assertion id="g">
            <text>A Java class is not a managed bean if it implements |jakarta.enterprise.inject.spi.Extension|.</text>
        </assertion>

        <assertion id="h">
            <text>A Java class is not a managed bean if it is annotated |@Vetoed| or placed in a package annotated |@Vetoed|.</text>
        </assertion>

        <assertion id="p">
            <text>A Java class is only a managed bean if it has an appropriate constructor - a constructor with no parameters.</text>
        </assertion>

        <assertion id="q">
            <text>A Java class is only a managed bean if it has an appropriate constructor - a constructor annotated |@Inject|.</text>
        </assertion>

        <assertion id="r" testable="false">
            <text>If packages annotated |@Vetoed| are split across classpath entries, non-portable behavior results. An application can prevent packages being
                split across jars by sealing the package as defined by the Extension Mechanism Architecture.
            </text>
            <note>Non-portable behavior.</note>
        </assertion>

    </section>

    <section id="managed_bean_types" title="Bean types of a managed bean" level="3">

        <assertion id="a">
            <text>The unrestricted set of bean types for a managed bean contains the bean class, every superclass and all interfaces it implements directly or
                indirectly.
            </text>
        </assertion>

        <assertion id="b">
            <text>
                The resulting set of bean types for a managed bean consists only of legal bean types, all other types are
                removed from the set of bean types.
            </text>
        </assertion>
    </section>

    <section id="declaring_managed_bean" title="Declaring a managed bean" level="3">
        <assertion id="a">
            <text>A managed bean with a constructor that takes no parameters does not require any special annotations</text>
        </assertion>

        <assertion id="ab" testable="false">
            <text>If the managed bean does not have a constructor that takes no parameters, it must have a constructor annotated |@Inject|. No additional
                special annotations are required.
            </text>
        </assertion>

        <group>
            <text>A bean class may also specify a scope, name, stereotypes and/or qualifiers.</text>

            <assertion id="ba">
                <text>Test a bean with a scope.</text>
            </assertion>

            <assertion id="bb">
                <text>Test a bean with a name.</text>
            </assertion>

            <assertion id="bd">
                <text>Test a bean with a stereotype.</text>
            </assertion>

            <assertion id="be">
                <text>Test a bean with a qualifier.</text>
            </assertion>
        </group>

        <assertion id="c">
            <text>A managed bean may extend another managed bean.</text>
        </assertion>
    </section>

    <section id="specialize_managed_bean" title="Specializing a managed bean" level="3">
        <group>
            <text>If a bean class of a managed bean X is annotated |@Specializes|, then the bean class of X must directly extend the bean class of another
                managed bean Y. Then X directly specializes Y, as defined in Section 4.3, "Specialization".
            </text>

            <assertion id="aa">
                <text>Test that a specializing bean has all its own qualifiers and the qualifiers of the specialized bean.</text>
            </assertion>

            <assertion id="ab">
                <text>Test that a specializing bean has the name of the specialized bean.</text>
            </assertion>

            <assertion id="ac">
                <text>Test a specialized bean extending a managed bean.</text>
            </assertion>
        </group>

        <group>
            <text>If the bean class of X does not directly extend the bean class of another managed bean, the container automatically detects the problem and
                treats it as a definition error.
            </text>

            <assertion id="da">
                <text>Test a specializing bean extending a non simple bean.</text>
            </assertion>

            <assertion id="db">
                <text>Test a specializing bean extending nothing.</text>
            </assertion>

            <assertion id="dd">
                <text>Test a specializing bean implementing an interface and extending nothing.</text>
            </assertion>
        </group>
    </section>

    <section id="managed_bean_name" title="Default bean name for a managed bean" level="3">
        <assertion id="a">
            <text>The default name for a managed bean is the unqualified class name of the bean class, after converting the first character to lower case</text>
        </assertion>
    </section>

    <section id="producer_method" title="Producer methods" level="2">
        <assertion id="aa">
            <text>A producer method must be a default-access, public, protected or private, non-abstract method of a managed bean class.</text>
        </assertion>

        <assertion id="b">
            <text>A producer method may be static.</text>
        </assertion>

        <assertion id="c">
            <text>A producer method may be non-static.</text>
        </assertion>

        <assertion id="e">
            <text>If a producer method sometimes returns a null value, then the producer method must have scope |@Dependent|.</text>
        </assertion>

        <assertion id="f">
            <text>If a producer method returns a null value at runtime, and the producer method declares scope other than |@Dependent|, an
                |IllegalProductException| is thrown by the container. This restriction allows the container to use a client proxy, as defined in Section 5.4,
                "Client proxies".
            </text>
        </assertion>

        <assertion id="ga">
            <text>If the producer method return type is a parameterized type, it must specify an actual type parameter or type variable for each type
                parameter.
            </text>
        </assertion>

        <assertion id="ha">
            <text>If a producer method return type contains a wildcard type parameter the container automatically detects the problem and treats it as a
                definition error.
            </text>
        </assertion>

        <assertion id="hb">
            <text>If a producer method return type is an array type whose component type contains a wildcard type parameter the container automatically detects
                the problem and treats it as a definition error.
            </text>
        </assertion>

        <assertion id="iaa">
            <text>If the producer method return type is a parameterized type with a type variable, it must have scope |@Dependent|.</text>
        </assertion>

        <assertion id="iab">
            <text>If a producer method with a parameterized return type with a type variable declares any scope other than |@Dependent|, the container
                automatically detects the problem and treats it as a definition error.
            </text>
        </assertion>

        <assertion id="ib">
            <text>If a producer method return type is a type variable the container automatically detects the problem and treats it as a definition error.
            </text>
        </assertion>

        <assertion id="ic">
            <text>If a producer method return type is an array type whose component type is a type variable the container automatically detects the problem and
                treats it as a definition error.
            </text>
        </assertion>

        <assertion id="j">
            <text>The application may call producer methods directly. However, if the application calls a producer method directly, no parameters will be passed
                to the producer method by the container; the returned object is not bound to any context; and its lifecycle is not managed by the container.
            </text>
        </assertion>

        <assertion id="k">
            <text>A bean may declare multiple producer methods.</text>
        </assertion>
    </section>

    <section id="producer_method_types" title="Bean types of a producer method" level="3">
        <assertion id="a">
            <text>If the return type of a producer method is an interface, the unrestricted set of bean types contains the return type, all interfaces it
                extends directly or indirectly and |java.lang.Object|
            </text>
        </assertion>

        <group>
            <text>If a return type of a producer method is primitive or is a Java array type, the unrestricted set of bean types contains exactly two types: the
                method return type and |java.lang.Object|.
            </text>
            <assertion id="ba">
                <text>Check primitive return type</text>
            </assertion>

            <assertion id="bb">
                <text>Check array return type</text>
            </assertion>
        </group>


        <assertion id="c">
            <text>If the return type of a producer method is a class, the unrestricted set of bean types contains the return type, every superclass and all
                interfaces it implements directly or indirectly.
            </text>
        </assertion>

        <assertion id="d">
            <text>The resulting set of bean types for a producer method consists only of legal bean types, all other types
                are removed from the set of bean types.
            </text>
        </assertion>
    </section>

    <section id="declaring_producer_method" title="Declaring a producer method" level="3">
        <assertion id="a">
            <text>A producer method may be declared by annotating a method with the |@jakarta.enterprise.inject.Produces| annotation</text>
        </assertion>

        <assertion id="ba">
            <text>A producer method may specify a scope.</text>
        </assertion>

        <assertion id="bb">
            <text>A producer method may specify a name.</text>
        </assertion>

        <assertion id="bd">
            <text>A producer method may specify stereotypes.</text>
        </assertion>

        <assertion id="be">
            <text>A producer method may specify qualifiers.</text>
        </assertion>

        <group>
            <text>If a producer method is annotated |@Inject|, has a parameter annotated |@Disposes|, or has a parameter annotated |@Observes|, or has a
                parameter annotated |@ObservesAsync|, the container
                automatically detects the problem and treats it as a definition error.
            </text>

            <assertion id="ca">
                <text>Test with a producer method annotated |@Inject|.</text>
            </assertion>

            <assertion id="da">
                <text>Test with a producer method annotated |@Disposes|.</text>
            </assertion>

            <assertion id="ea">
                <text>Test with a producer method annotated |@Observes|.</text>
            </assertion>

            <assertion id="fa">
                <text>Test with a producer method annotated |@ObservesAsync|.</text>
            </assertion>
        </group>

        <assertion id="ga">
            <text>Interceptors ~and decorators~ may not declare producer methods. If an interceptor ~or decorator~ has a method annotated |@Produces|, the
                container automatically detects the problem and treats it as a definition error.
            </text>
        </assertion>

        <assertion id="gb">
            <text>~Interceptors and~ decorators may not declare producer methods. If an ~interceptor or~ decorator has a method annotated |@Produces|, the
                container automatically detects the problem and treats it as a definition error.
            </text>
        </assertion>

        <assertion id="h">
            <text>A producer method may have any number of parameters.</text>
        </assertion>

        <assertion id="i">
            <text>All producer method parameters are injection points.</text>
        </assertion>
    </section>

    <section id="specialize_producer_method" title="Specializing a producer method" level="3">
        <assertion id="aa">
            <text>If a producer method X is annotated |@Specializes|, then it must be non-static and directly override another producer method Y. Then X
                directly specializes Y, as defined in Section 4.3 "Specialization".
            </text>
        </assertion>

        <assertion id="ba">
            <text>If a producer method is static, the container automatically detects the problem and treats it as a definition error.</text>
        </assertion>

        <assertion id="ca">
            <text>If a producer method does not directly override another producer method, the container automatically detects the problem and treats it as a
                definition error.
            </text>
        </assertion>
    </section>

    <section id="producer_method_name" title="Default bean name for a producer method" level="3">
        <group>
            <text>The default name for a producer method is the method name, unless the method follows the JavaBeans property getter naming convention, in which
                case the default name is the JavaBeans property name
            </text>
            <assertion id="a">
                <text>Test default name is the method name.</text>
            </assertion>
            <assertion id="b">
                <text>Test default name is the JavaBeans property name.</text>
            </assertion>
        </group>
    </section>

    <section id="producer_field" title="Producer fields" level="2">
        <assertion id="a">
            <text>A producer field must be a default-access, public, protected or private, field of a managed bean class~</text>
            <note>Just test that a producer field on these works</note>
        </assertion>

        <assertion id="b">
            <text>A producer field may be static.</text>
        </assertion>

        <assertion id="c">
            <text>A producer field may be non-static.</text>
        </assertion>

        <assertion id="d">
            <text>If a producer field sometimes contains a null value when accessed, then the producer field must have scope |@Dependent|</text>
        </assertion>

        <assertion id="e">
            <text>If a producer field contains a null value at runtime, and the producer field declares any other scope, an |IllegalProductException| is thrown
                by the container. This restriction allows the container to use a client proxy, as defined in Section 5.4, "Client proxies"
            </text>
        </assertion>

        <assertion id="fa">
            <text>If the producer field type is a parameterized type, it must specify an _actual type parameter_ or type variable for each type parameter</text>
        </assertion>

        <assertion id="fb">
            <text>If the producer field type is a parameterized type, it must specify an actual type parameter or _type variable_ for each type parameter</text>
        </assertion>

        <assertion id="ga">
            <text>If a producer field type contains a wildcard type parameter the container automatically detects the problem and treats it as a definition
                error.
            </text>
        </assertion>

        <assertion id="gc">
            <text>If a producer field type is an array type whose component type contains a wildcard parameter the container automatically detects the problem
                and treats it as a definition error.
            </text>
        </assertion>

        <assertion id="gb">
            <text>If the producer field type is a parameterized type with a type variable, it must have scope |@Dependent|. If a producer field with a
                parameterized type with a type variable declares any scope other than |@Dependent|, the container automatically detects the problem and treats
                it as a definition error.
            </text>
        </assertion>

        <assertion id="ha">
            <text>If a producer field type is a type variable the container automatically detects the problem and treats it as a definition error.</text>
        </assertion>

        <assertion id="hb">
            <text>If a producer field type is an array type whose component type is a type variable the container automatically detects the problem and treats
                it as a definition error.
            </text>
        </assertion>

        <assertion id="i" testable="false">
            <text>The application may access producer fields directly. However, if the application accesses a producer field directly, the returned object is
                not bound to any context; and its lifecycle is not managed by the container
            </text>
            <note>This is a statement of intent</note>
        </assertion>

        <assertion id="j">
            <text>A bean may declare multiple producer fields</text>
        </assertion>
    </section>

    <section id="producer_field_types" title="Bean types of a producer field" level="3">
        <assertion id="a">
            <text>The bean types of a producer field depend upon the field type. If the field type is an interface, the unrestricted set of bean types contains
                the field type, all interfaces it extends directly or indirectly and |java.lang.Object|.
            </text>
        </assertion>

        <group>
            <text>The bean types of a producer field depend upon the field type. If a field type is primitive or is a Java array type, the unrestricted set of
                bean types contains exactly two types: the field type and |java.lang.Object|.
            </text>
            <assertion id="ba">
                <text>Check primitive type</text>
            </assertion>

            <assertion id="bb">
                <text>Check array type</text>
            </assertion>
        </group>

        <assertion id="c">
            <text>The bean types of a producer field depend upon the field type. If the field type is a class, the unrestricted set of bean types contains the
                field type, every superclass and all interfaces it implements directly or indirectly
            </text>
        </assertion>
        <assertion id="d">
            <text>The resulting set of bean types for a producer field consists only of legal bean types, all other types
                are removed from the set of bean types.
            </text>
        </assertion>
    </section>

    <section id="declaring_producer_field" title="Declaring a producer field" level="3">
        <assertion id="a">
            <text>A producer field may be declared by annotating a field with the |@jakarta.enterprise.inject.Produces| annotation.</text>
        </assertion>

        <assertion id="b">
            <text>A producer field may specify a scope.</text>
        </assertion>

        <assertion id="c">
            <text>A producer field may specify a name.</text>
        </assertion>

        <assertion id="e">
            <text>A producer field may specify stereotypes.</text>
        </assertion>

        <assertion id="f">
            <text>A producer field may specify qualifiers.</text>
        </assertion>

        <assertion id="g">
            <text>If a producer field is annotated |@Inject|, the container automatically detects the problem and treats it as a definition error.</text>
        </assertion>

        <assertion id="ia">
            <text>Interceptors ~and decorators~ may not declare producer fields. If an interceptor ~or decorator~ has a field annotated |@Produces|, the
                container automatically detects the problem and treats it as a definition error.
            </text>
        </assertion>

        <assertion id="ib">
            <text>~Interceptors~ and decorators may not declare producer fields. If ~an interceptor or~ decorator has a field annotated |@Produces|, the
                container automatically detects the problem and treats it as a definition error.
            </text>
        </assertion>
    </section>

    <section id="producer_field_name" title="Default bean name for a producer field" level="3">
        <assertion id="a">
            <text>The default name for a producer field is the field name</text>
        </assertion>
    </section>

    <section id="disposer_method" title="Disposer methods" level="2">

        <assertion id="aa">
            <text>A disposer method must be a default-access, public, protected or private, non-abstract method of a managed bean class.</text>
        </assertion>

        <assertion id="b">
            <text>A disposer method may be static.</text>
        </assertion>

        <assertion id="c">
            <text>A disposer method may be non-static.</text>
        </assertion>

        <assertion id="e">
            <text>A bean may declare multiple disposer methods.</text>
        </assertion>
    </section>

    <section id="disposer_method_disposed_parameter" title="Disposed parameter of a disposer method" level="3">
        <assertion id="a">
            <text>Each disposer method must have exactly one disposed parameter, of the same type as the corresponding producer method return type or producer
                field type.
            </text>
        </assertion>

        <assertion id="ba">
            <text>When searching for disposer methods for a producer method or producer field the container considers the type and qualifiers of the disposed
                parameter. If a producer method or producer field declared by the same bean class is assignable to the disposed parameter, according to the
                rules of typesafe resolution defined in Section 5.2, "Typesafe resolution", the container must call this method when destroying any instance
                returned by that producer method or producer field.
            </text>
        </assertion>

        <assertion id="da">
            <text>A disposer method may resolve to multiple producer methods or producer fields declared by the bean class, in which case the container must
                call it when destroying any instance returned by any of these producer methods or producer fields.
            </text>
        </assertion>
    </section>

    <section id="declaring_disposer_method" title="Declaring a disposer method" level="3">
        <assertion id="a">
            <text>A disposer method may be declared by annotating a parameter |@jakarta.enterprise.inject.Disposes|. That parameter is the disposed parameter
            </text>
        </assertion>

        <assertion id="ba">
            <text>Qualifiers may be declared by annotating the disposed parameter.</text>
        </assertion>

        <assertion id="bb">
            <text>If a method has more than one parameter annotated |@Disposes|, the container automatically detects the problem and treats it as a definition
                error.
            </text>
        </assertion>

        <assertion id="ca">
            <text>If a disposer method is annotated |@Produces|, the container automatically detects the problem and treats it as a definition error.</text>
        </assertion>

        <assertion id="da">
            <text>If a disposer method is annotated |@Inject|, the container automatically detects the problem and treats it as a definition error.</text>
        </assertion>

        <assertion id="ea">
            <text>If a disposer method has a parameter annotated |@Observes|, the container automatically detects the problem and treats it as a definition
                error.
            </text>
        </assertion>

        <assertion id="fa">
            <text>If a disposer method has a parameter annotated |@ObservesAsync|, the container automatically detects the problem and treats it as a definition
                error.
            </text>
        </assertion>

        <assertion id="ga">
            <text>Interceptors ~and decorators~ may not declare disposer methods. If an interceptor ~or decorator~ has a method annotated |@Disposes|, the
                container automatically detects the problem and treats it as a definition error.
            </text>
        </assertion>

        <assertion id="gb">
            <text>~Interceptors and ~decorators may not declare disposer methods. If ~an interceptor or~ decorator has a method annotated |@Disposes|, the
                container automatically detects the problem and treats it as a definition error.
            </text>
        </assertion>

        <assertion id="h">
            <text>In addition to the disposed parameter, a disposer method may declare additional parameters, which may also specify qualifiers. These
                additional parameters are injection points.
            </text>
        </assertion>
    </section>

    <section id="disposer_method_resolution" title="Disposer method resolution" level="3">
        <assertion id="aa">
            <text>A disposer method is bound to a producer method if the producer method is declared by the same bean class as the disposer method, and the
                producer method is assignable to the disposed parameter, according to the rules of typesafe resolution defined in Section 5.2, "Typesafe
                resolution".
            </text>
        </assertion>

        <assertion id="ab">
            <text>A disposer method is bound to a producer field if the producer field is declared by the same bean class as the disposer method, and the
                producer field is assignable to the disposed parameter, according to the rules of typesafe resolution defined in Section 5.2, "Typesafe
                resolution".
            </text>
        </assertion>

        <assertion id="ba">
            <text>If there are multiple disposer methods for a single producer method or producer field, the container automatically detects the problem and
                treats it as a definition error.
            </text>
        </assertion>

        <assertion id="ca">
            <text>If there is no producer method or producer field declared by the bean class that is assignable to the disposed parameter of a disposer method,
                the container automatically detects the problem and treats it as a definition error.
            </text>
        </assertion>
    </section>

    <section id="bean_constructors" title="Bean constructors" level="2">
        <assertion id="a">
            <text>When the container instantiates a bean, it calls the bean constructor. The bean constructor is a default-access, public, protected or private
                constructor of the bean class.
            </text>
        </assertion>
    </section>

    <section id="declaring_bean_constructor" title="Declaring a bean constructor" level="3">
        <group>
            <text>The bean constructor may be identified by annotating the constructor |@Inject|</text>
            <assertion id="aa">
                <text>Test an @Inject constructor is used on a managed bean</text>
            </assertion>
        </group>

        <assertion id="ba">
            <text>If a bean class does not explicitly declare a constructor using |@Inject|, the constructor that accepts no parameters is the bean
                constructor.
            </text>
            <note>Can't check implicit constructor</note>
        </assertion>

        <assertion id="ca">
            <text>If a bean class has more than one constructor annotated |@Inject|, the container automatically detects the problem and treats it as a
                definition error.
            </text>
        </assertion>

        <assertion id="da">
            <text>If a bean constructor has a parameter annotated |@Disposes|, the container automatically detects the problem and treats it as a definition
                error.
            </text>
        </assertion>

        <assertion id="ea">
            <text>If a bean constructor has a parameter annotated |@Observes|, the container automatically detects the problem and treats it as a definition
                error.
            </text>
        </assertion>

        <assertion id="fa">
            <text>If a bean constructor has a parameter annotated |@ObservesAsync|, the container automatically detects the problem and treats it as a
                definition
                error.
            </text>
        </assertion>

        <assertion id="f">
            <text>A bean constructor may have any number of parameters.</text>
        </assertion>

        <assertion id="g">
            <text>All parameters of a bean constructor are injection points.</text>
        </assertion>
    </section>

    <section id="injected_fields" title="Injected fields" level="2">
        <group>
            <text>An injected field is a non-static, non-final field of a bean class or of any other classes supporting injection.</text>

            <assertion id="a">
                <text>Test a bean class.</text>
            </assertion>
        </group>

    </section>

    <section id="declaring_injected_field" title="Declaring an injected field" level="3">
        <assertion id="aa">
            <text>An injected field may be declared by annotating the field |@jakarta.inject.Inject|.</text>
        </assertion>

        <assertion id="b">
            <text>If an injected field is annotated |@Produces|, the container automatically detects the problem and treats it as a definition error.</text>
        </assertion>
    </section>

    <section id="initializer_methods" title="Initializer methods" level="2">
        <group>
            <text>An initializer method is a default-access, public, protected or private, non-abstract, non-static, non-generic method of a bean class or of
                any other classes supporting injection.
            </text>

            <assertion id="a">
                <text>Test a bean-class.</text>
            </assertion>

        </group>

        <assertion id="f">
            <text>Method interceptors are never called when the container calls an initializer method</text>
        </assertion>

        <assertion id="g">
            <text>A bean class may declare multiple (or zero) initializer methods</text>
        </assertion>

        <assertion id="h" testable="false">
            <text>The application may call initializer methods directly, but then no parameters will be passed to the method by the container</text>
            <note>This is a statement of intent</note>
        </assertion>
    </section>

    <section id="declaring_initializer" title="Declaring an initializer method" level="3">
        <assertion id="a">
            <text>An initializer method may be declared by annotating the method |@jakarta.inject.Inject|</text>
        </assertion>

        <assertion id="ab">
            <text>If a generic method of a bean is annotated |@Inject|, the container automatically detects the problem and treats it as a definition error.
            </text>
        </assertion>

        <assertion id="ba">
            <text>If an initializer method is annotated |@Produces|, the container automatically detects the problem and treats it as a definition error.</text>
        </assertion>

        <assertion id="ca">
            <text>If an initializer method has a parameter annotated |@Disposes|, the container automatically detects the problem and treats it as a definition
                error.
            </text>
        </assertion>

        <assertion id="da">
            <text>If an initializer method has a parameter annotated |@Observes|, the container automatically detects the problem and treats it as a definition
                error.
            </text>
        </assertion>

        <assertion id="ea">
            <text>If an initializer method has a parameter annotated |@ObservesAsync|, the container automatically detects the problem and treats it as a
                definition
                error.
            </text>
        </assertion>

        <assertion id="e">
            <text>An initializer method may have any number of parameters.</text>
        </assertion>

        <assertion id="f">
            <text>All initializer method parameters are injection points.</text>
        </assertion>
    </section>

    <section id="injection_point_default_qualifier" title="The default qualifier at injection points" level="2">
        <assertion id="a">
            <text>If an injection point declares no qualifier, the injection point has exactly one qualifier, the default qualifier |@Default|.</text>
        </assertion>
    </section>

    <section id="named_at_injection_point" title="The qualifier @Named at injection points" level="2">
        <assertion id="a">
            <text>If an injected field declares a |@Named| annotation that does not specify the |value| member, the name of the field is assumed.</text>
        </assertion>

        <assertion id="b">
            <text>If any other injection point declares a |@Named| annotation that does not specify the |value| member, the container automatically detects the
                problem and treats it as a definition error.
            </text>
        </assertion>
    </section>

    <section id="new" title="@New qualified beans" level="2">
        <assertion id="d">
            <text>For each managed bean, a second bean exists which has the same bean class.</text>
        </assertion>

        <assertion id="e">
            <text>For each managed bean, a second bean exists which has the same bean types.</text>
        </assertion>

        <assertion id="f">
            <text>For each managed bean, a second bean exists which has the same bean constructor.</text>
        </assertion>

        <assertion id="g">
            <text>For each managed bean, a second bean exists which has the same initializer methods.</text>
        </assertion>

        <assertion id="h">
            <text>For each managed bean, a second bean exists which has the same injected fields.</text>
        </assertion>

        <assertion id="i">
            <text>For each managed bean, a second bean exists which has the same interceptor bindings.</text>
        </assertion>

        <assertion id="p">
            <text>This second bean has scope |@Dependent|.</text>
        </assertion>

        <assertion id="r">
            <text>This second bean has exactly one qualifier: |@jakarta.enterprise.inject.New(X.class)| where |x| is the bean class.</text>
        </assertion>

        <assertion id="s">
            <text>This second bean has no bean name.</text>
        </assertion>

        <assertion id="t">
            <text>This second bean has no stereotypes.</text>
        </assertion>

        <assertion id="u">
            <text>This second bean has no observer methods.</text>
        </assertion>

        <assertion id="v">
            <text>This second bean has no producer methods.</text>
        </assertion>

        <assertion id="w">
            <text>This second bean has no producer fields.</text>
        </assertion>

        <assertion id="x">
            <text>This second bean has no disposer methods.</text>
        </assertion>

        <assertion id="xb">
            <text>This second bean is not an alternative.</text>
        </assertion>

        <assertion id="xc">
            <text>This second bean is enabled, in the sense of Section 5.1.2, "Enabled and disabled beans", if and only if some other enabled bean has an
                injection point with the qualifier |@New(X.class)| where |X| is the bean class.
            </text>
        </assertion>

        <assertion id="xd" testable="false">
            <text>This bean is called the |@New| qualified bean for the class |X|.</text>
        </assertion>

        <group>
            <text>Note that this second bean exists, and may be enabled and available for injection even if the first bean is disabled, as defined by Section
                5.1.2, “Enabled and disabled beans” or if the bean class is deployed outside of a bean deployment archive, as defined in Section 12.1, “Bean
                deployment archives”, and is therefore not discovered during the bean discovery process defined in Chapter 12, Packaging and deployment. The
                container discovers |@New| qualified beans by inspecting injection points of other enabled beans.
            </text>
            <assertion id="ya">
                <text>Check that @New on a field injection point outside the BDA, but in the classpath causes a bean with qualifier @New and the given type to
                    be created
                </text>
            </assertion>
            <assertion id="yc">
                <text>Check that @New on a initializer method injection point outside the BDA, but in the classpath causes a bean with qualifier @New and the
                    given type to be created
                </text>
            </assertion>
            <assertion id="ye">
                <text>Check that @New on a constructor injection point outside the BDA, but in the classpath causes a bean with qualifier @New and the given
                    type to be created
                </text>
            </assertion>
            <assertion id="yg">
                <text>Check that @New on a producer method injection point outside the BDA, but in the classpath causes a bean with qualifier @New and the given
                    type to be created
                </text>
            </assertion>
            <assertion id="yi">
                <text>Check that @New on a observer method injection point outside the BDA, but in the classpath causes a bean with qualifier @New and the given
                    type to be created
                </text>
            </assertion>
            <assertion id="yk">
                <text>Check that @New on a disposer method injection point outside the BDA, but in the classpath causes a bean with qualifier @New and the given
                    type to be created
                </text>
            </assertion>
        </group>

        <assertion id="z">
            <text>When the qualifier |@New| is specified at an injection point and no |value| member is explicitly specified, the container defaults the |value|
                to the declared type of the injection point.
            </text>
        </assertion>
    </section>

    <section id="unproxyable" title="Unproxyable bean types" level="2">

        <group>

            <text>Certain legal bean types cannot be proxied by the container. If an injection point whose declared type cannot be proxied by the container
                resolves to a bean with a normal scope, the container automatically detects the problem and treats it as a deployment problem.
            </text>

            <assertion id="aa">
                <text>Test a class which doesn't have a non-private constructor with no parameters.</text>
            </assertion>

            <assertion id="baa">
                <text>Test a class which is declared final.</text>
            </assertion>

            <assertion id="bba">
                <text>Test a class that has non-static, final method with public visibility.</text>
            </assertion>

            <assertion id="bbb">
                <text>Test a class that has non-static, final method with public visibility declared on a superclass.</text>
            </assertion>

            <assertion id="bca">
                <text>Test with a class that has static final method with public visibility.</text>
                <note>This is not allowed in CDI 1.0.</note>
            </assertion>

            <assertion id="bda">
                <text>Test a class that has final method with private visibility.</text>
                <note>This is not allowed in CDI 1.0.</note>
            </assertion>

            <assertion id="ca">
                <text>Test primitive type.</text>
            </assertion>

            <assertion id="da">
                <text>Test array type.</text>
            </assertion>

        </group>

        <group>
            <text>A bean type must be proxyable if an injection point resolves to a bean:</text>

            <assertion id="ea">
                <text>That has an associated decorator.</text>
            </assertion>

            <assertion id="eb">
                <text>That has a bound interceptor.</text>
            </assertion>

        </group>

    </section>

    <section id="inheritance" title="Inheritance and specialization" level="1">

    </section>

    <section id="type_level_inheritance" title="Inheritance of type-level metadata" level="2">
        <group>
            <text>Suppose a class X is extended directly or indirectly by the bean class of a managed bean Y. If X is annotated with a qualifier type,
                stereotype or interceptor binding type Z then Y inherits the annotation if and only if Z declares the |@Inherited| meta-annotation and neither Y
                nor any intermediate class that is a subclass of X and a superclass of Y declares an annotation of type Z.
            </text>

            <assertion id="aa">
                <text>Test qualifier type for directly extended managed bean annotated |@Inherited| is inherited.</text>
            </assertion>

            <assertion id="aaa">
                <text>Test qualifier type for directly extended managed bean not annotated |@Inherited| is not inherited.</text>
            </assertion>

            <assertion id="ab">
                <text>Test stereotype for directly extended managed bean annotated |@Inherited| is inherited.</text>
            </assertion>

            <assertion id="aba">
                <text>Test stereotype for directly extended managed bean not annotated |@Inherited| is not inherited.</text>
            </assertion>

            <assertion id="ad">
                <text>Test interceptor binding type for directly extended managed bean annotated |@Inherited| is inherited.</text>
            </assertion>

            <assertion id="ada">
                <text>Test interceptor binding type for directly extended managed bean not annotated |@Inherited| is not inherited.</text>
            </assertion>

            <assertion id="ag">
                <text>Test qualifier type for indirectly extended managed bean annotated |@Inherited| is inherited.</text>
            </assertion>

            <assertion id="aga">
                <text>Test qualifier type for indirectly extended managed bean not annotated |@Inherited| is not inherited.</text>
            </assertion>

            <assertion id="ah">
                <text>Test stereotype for indirectly extended managed bean annotated |@Inherited| is inherited.</text>
            </assertion>

            <assertion id="aha">
                <text>Test stereotype for indirectly extended managed bean not annotated |@Inherited| is not inherited.</text>
            </assertion>

            <assertion id="aj">
                <text>Test interceptor binding type for indirectly extended managed bean annotated |@Inherited| is inherited.</text>
            </assertion>

            <assertion id="aja">
                <text>Test interceptor binding type for indirectly extended managed bean not annotated |@Inherited| is not inherited.</text>
            </assertion>

        </group>

        <group>
            <text>Suppose a class X is extended directly or indirectly by the bean class of a managed bean Y. If X is annotated with a scope type Z then Y
                inherits the annotation if and only if Z declares the |@Inherited| meta-annotation and neither Y nor any intermediate class that is a subclass
                of X and a superclass of Y declares a scope type.
            </text>

            <assertion id="ba">
                <text>Test scope type for directly extended managed bean annotated |@Inherited| is inherited.</text>
            </assertion>

            <assertion id="baa">
                <text>Test scope type for directly extended managed bean not annotated |@Inherited| is not inherited.</text>
            </assertion>

            <assertion id="bc">
                <text>Test scope type for indirectly extended managed bean annotated |@Inherited| is inherited.</text>
            </assertion>

            <assertion id="bca">
                <text>Test scope type for indirectly extended managed bean not annotated |@Inherited| is not inherited.</text>
            </assertion>
        </group>

        <assertion id="hhh">
            <text>For class X which is extended _directly_ by the bean class of a _managed_ bean Y, a scope type explicitly declared by X and inherited by Y
                from X takes precedence over default scopes of stereotypes declared or inherited by Y.
            </text>
        </assertion>

        <assertion id="hhi">
            <text>For class X which is extended _indirectly_ by the bean class of a _managed_ bean Y, a scope type explicitly declared by X and inherited by Y
                from X takes precedence over default scopes of stereotypes declared or inherited by Y.
            </text>
        </assertion>

        <assertion id="i" testable="false">
            <text>For annotations defined by the bean specification, all built-in _scope types_ are declared |@Inherited|</text>
            <note>sigtest</note>
        </assertion>

        <assertion id="j" testable="false">
            <text>For annotations defined by the bean specification, all built-in _stereotypes_ are declared |@Inherited|</text>
            <note>sigtest</note>
        </assertion>

        <assertion id="k" testable="false">
            <text>For annotations defined by the bean specification, _no built-in qualifier type is declared |@Inherited|_</text>
            <note>sigtest</note>
        </assertion>

        <assertion id="m" testable="false">
            <text>The |@Named| annotation is not declared |@Inherited| and bean names are not inherited unless specialization is used</text>
            <note>sigtest</note>
        </assertion>

    </section>

    <section id="member_level_inheritance" title="Inheritance of member-level metadata" level="2">

        <group>
            <text>Suppose a class X is extended directly or indirectly by the bean class of a managed bean. If X declares an injected field x then Y inherits
                x.
            </text>

            <assertion id="aa">
                <text>Check managed bean X _directly_ extends managed bean Y</text>
            </assertion>

            <assertion id="ac">
                <text>Check managed bean X _indirectly_ extends managed bean Y</text>
            </assertion>
        </group>

        <group>
            <text>Suppose a class X is extended directly or indirectly by the bean class of a managed bean Y. If X declares an initializer, non-static observer,
                @PostConstruct or @PreDestroy method x() then Y inherits x() if and only if neither Y nor any intermediate class that is a subclass of X and a
                superclass of Y overrides the method x().
            </text>

            <assertion id="baa">
                <text>Check managed bean X _directly_ extends managed bean Y with _|@PostConstruct|_</text>
            </assertion>

            <assertion id="bac">
                <text>Check managed bean X _indirectly_ extends managed bean Y with _|@PostConstruct|_</text>
            </assertion>

            <assertion id="bba">
                <text>Check managed bean X _directly_ extends managed bean Y with _|@PostDestroy|_</text>
            </assertion>

            <assertion id="bbc">
                <text>Check managed bean X _indirectly_ extends managed bean Y with _|@PostDestroy|_</text>
            </assertion>

            <assertion id="dc">
                <text>Check managed bean X _directly_ extends managed bean Y with a _non-static observer method_</text>
            </assertion>

            <assertion id="di">
                <text>Check managed bean X _indirectly_ extends managed bean Y with a _non-static observer method_</text>
            </assertion>

            <assertion id="dm">
                <text>Check managed bean X _directly_ extends managed bean Y with a _initializer method_</text>
            </assertion>

            <assertion id="do">
                <text>Check managed bean X _indirectly_ extends managed bean Y with a _initializer method_</text>
            </assertion>
        </group>

        <group>
            <text>Suppose a class X is extended directly or indirectly by the bean class of a managed bean. If X declares a non-static method x() annotated with
                an interceptor binding type Z then Y inherits the binding if and only if neither Y nor any intermediate class that is a subclass of X and a
                superclass of Y overrides the method x().
            </text>

            <assertion id="ka">
                <text>Check managed bean X _directly_ extends managed bean Y</text>
            </assertion>

            <assertion id="kc">
                <text>Check managed bean X _indirectly_ extends managed bean Y</text>
            </assertion>

        </group>

        <group>
            <text>Suppose a class X is extended directly or indirectly by the bean class of a managed bean Y. If X declares a non-static producer or disposer
                method x() then Y does not inherit this method.
            </text>

            <assertion id="da">
                <text>Check managed bean X _directly_ extends managed bean Y with a _non-static producer method_</text>
            </assertion>

            <assertion id="db">
                <text>Check managed bean X _directly_ extends managed bean Y with a _non-static disposer method_</text>
            </assertion>

            <assertion id="dg">
                <text>Check managed bean X _indirectly_ extends managed bean Y with a _non-static producer method_</text>
            </assertion>

            <assertion id="dh">
                <text>Check managed bean X _indirectly_ extends managed bean Y with a _non-static disposer method_</text>
            </assertion>
        </group>

        <group>
            <text>Suppose a class X is extended directly or indirectly by the bean class of a managed bean or session bean Y. If X declares a non-static
                producer field x then Y does not inherit this field.
            </text>

            <assertion id="ea">
                <text>Check managed bean X _directly_ extends managed bean Y</text>
                <note>We don't test session beans, as they can't have non-static producer fields</note>
            </assertion>

            <assertion id="ec">
                <text>Check managed bean X _indirectly_ extends managed bean Y</text>
                <note>We don't test session beans, as they can't have non-static producer fields</note>
            </assertion>

        </group>

        <group>
            <text>If X is a generic type, and an injection point or observer method declared by X is inherited by Y, and the declared type of the injection
                point, producer method, producer field, disposed para- meter or event parameter contains type variables declared by X, the type of the injection
                point, producer method, producer field, disposed parameter or event parameter inherited in Y is the declared type, after substitution of actual
                type arguments declared by Y or any intermediate class that is a subclass of X and a superclass of Y.
            </text>

            <assertion id="f">
                <text>Check injection point</text>
            </assertion>

            <assertion id="g">
                <text>check observer method</text>
            </assertion>
        </group>

    </section>

    <section id="specialization" title="Specialization" level="2">

        <assertion id="a" testable="false">
            <text>If two beans both support a certain bean type, and share at least one qualifier, then they are both eligible for injection to any injection
                point with that declared type and qualifier.
            </text>
        </assertion>

        <group>
            <text>When an enabled bean specializes a second bean, we can be certain that the second bean is never instantiated or called by the container. Even
                if the second bean defines a producer or observer method, the method will never be called.
            </text>
            <assertion id="ca">
                <text>The second bean is never instantiated.</text>
            </assertion>
            <assertion id="cb">
                <text>Producer method on specialized bean is not called.</text>
            </assertion>
            <assertion id="cc">
                <text>Observer method on specialized bean is not called.</text>
            </assertion>
            <assertion id="cd">
                <text>Producer field on specialized bean is not used.</text>
            </assertion>
        </group>

    </section>

    <section id="direct_and_indirect_specialization" title="Direct and indirect specialization" level="3">
        <assertion id="ia">
            <text>A bean X is said to specialize another bean Y if X directly specializes Y.</text>
        </assertion>

        <assertion id="ib">
            <text>A bean X is said to specialize another bean Y if a bean Z exists, such that X directly specializes Z and Z specializes Y.</text>
        </assertion>

        <assertion id="j">
            <text>A bean X that specializes bean Y will include all qualifiers of Y, together with all qualifiers declared explicitly by X.</text>
        </assertion>

        <assertion id="k">
            <text>A bean X that specializes bean Y will have the same name as Y if Y has a name.</text>
        </assertion>

        <assertion id="l">
            <text>X must have all the bean types of Y. If X does not have some bean type of Y, the container automatically detects the problem and treats it as
                a definition error.
            </text>
        </assertion>

        <group>
            <text>If Y has a bean name and X declares a bean name explicitly the container automatically detects the problem and treats it as a definition
                error.
            </text>
            <assertion id="la">
                <text>Test that a specializing producer method with a name throws a definition exception.</text>
            </assertion>
            <assertion id="lb">
                <text>Test that a specializing managed bean with a name throws a definition exception.</text>
            </assertion>
        </group>

        <assertion id="n" testable="false">
            <text>If an interceptor or decorator is annotated |@Specializes|, non-portable behavior results.</text>
            <note>Defines non-portable behavior</note>
        </assertion>
    </section>

    <section id="injection_and_resolution" title="Dependency injection and lookup" level="1">

        <assertion id="b">
            <text>The container is required to support circularities in the bean dependency graph where at least one bean participating in every circular chain
                of dependencies has a normal scope, as defined in Section 6.3, "Normal scopes and pseudo-scopes".
            </text>
            <note>The RI has unit tests for this atm</note>
        </assertion>

        <assertion id="c" testable="false">
            <text>The container is not required to support circular chains of dependencies where every bean participating in the chain has a pseudo-scope.
            </text>
        </assertion>
    </section>

    <section id="selection" title="Modularity" level="2">
        <group>
            <text>A bean packaged in a certain module is available for injection, lookup and name resolution to classes packaged in some other module if the
                bean class of the bean is required to be accessible to the other module by the class accessibility requirements of the module architecture.
            </text>

            <assertion id="aa">
                <text>Test with injection.</text>
            </assertion>

            <assertion id="ab">
                <text>Test with lookup.</text>
            </assertion>

            <assertion id="ac">
                <text>Test with name resolution.</text>
            </assertion>
        </group>

        <assertion id="d" testable="false">
            <text>An alternative is never available for injection, lookup or name resolution in a module unless the module is a bean archive and the alternative
                is explicitly selected for the bean archive or the application..
            </text>
            <note>If a module/library is not BDA then no injection is possible at all</note>
        </assertion>

        <assertion id="e">
            <text>Nor is an alternative available for injection, lookup or name resolution in every bean deployment archive. An alternative must be explicitly
                selected in every bean deployment archive in which the alternative should be available for injection, lookup and name resolution.
            </text>
        </assertion>
    </section>

    <section id="declaring_selected_alternatives" title="Declaring selected alternatives" level="3">

        <assertion id="a" testable="false">
            <text>This specification defines two methods of selecting alternatives. From Contexts and Dependency Injection 1.1 onwards the |@Priority|
                annotation allows an alternative to be selected for an entire application. Contexts and Dependency Injection 1.0 allowed only for an alternative
                to be selected for a bean archive.
            </text>
            <note>Statement of intent.</note>
        </assertion>

    </section>

    <section id="declaring_selected_alternatives_application" title="Declaring selected alternatives for an application" level="4">

        <group>
            <text>An alternative may be given a priority for the application by placing the |@Priority| annotation on the bean class of a managed bean.</text>
            <assertion id="aa">
                <text>Test |@Priority| on the bean class of a managed bean.</text>
            </assertion>
        </group>

        <group>
            <text>An alternative may be given a priority for the application by placing the |@Priority| annotation on the bean class that declares the producer
                method, field or resource.
            </text>
            <assertion id="ba">
                <text>Test |@Priority| on the bean class of a producer method.</text>
            </assertion>
            <assertion id="bb">
                <text>Test |@Priority| on the bean class of a producer field.</text>
            </assertion>
            <assertion id="bc">
                <text>Test |@Priority| on the resource.</text>
            </assertion>
        </group>

    </section>

    <section id="declaring_selected_alternatives_bean_archive" title="Declaring selected alternatives for a bean archive" level="4">

        <assertion id="a" testable="false">
            <text>An alternative may be explicitly declared using the |&lt;alternatives&gt;| element of the |beans.xml| file of the bean archive. The |&lt;alternative&gt;|
                element contains a list of bean classes and stereotypes.
            </text>
            <note>Statement of intent.</note>
        </assertion>

        <group>
            <text>An alternative is selected for the bean archive if the alternative is a managed bean and the bean class of the bean is listed.</text>
            <assertion id="ba">
                <text>Test selected managed bean.</text>
            </assertion>
        </group>

        <group>
            <text>An alternative is selected for the bean archive if the alternative is a producer method, field or resource, and the bean class that declares
                the method or field is listed.
            </text>
            <assertion id="ca">
                <text>Test selected producer method.</text>
            </assertion>
            <assertion id="cb">
                <text>Test selected producer field.</text>
            </assertion>
            <assertion id="cc">
                <text>Test selected resource.</text>
            </assertion>
        </group>

        <assertion id="d">
            <text>An alternative is selected for the bean archive if any @Alternative stereotype of the alternative is listed.</text>
        </assertion>

        <assertion id="e">
            <text>For each child |&lt;class&gt;| element the container verifies that either a class with the specified name exists and is annotated with
                @Alternative or an @Alternative stereotype, or a class with the specified name exists and declares a field or method annotated with @Produces
                and, at the same time, annotated with @Alternative or an @Alternative stereotype, or an alternative bean whose bean class has the specified name
                exists. Otherwise, the container automatically detects the problem and treats it as a deployment problem.
            </text>
        </assertion>

        <assertion id="f">
            <text>Each child |&lt;stereotype&gt;| element must specify the name of a |@Alternative| stereotype annotation. If there is no annotation with the
                specified name, or the annotation is not a |@Alternative| stereotype, the container automatically detects the problem and treats it as a
                deployment problem.
            </text>
        </assertion>

        <assertion id="g">
            <text>If the same type is listed twice under the |&lt;alternatives&gt;| element, the container automatically detects the problem and treats it as a
                deployment problem.
            </text>
        </assertion>

        <assertion id="h">
            <text>For a custom implementation of the |Bean| interface defined in Section "bean", the container calls |isAlternative()| to determine whether the
                bean is an alternative, and |getBeanClass()| and |getStereotypes()| to determine whether an alternative is selected in a certain bean deployment
                archive.
            </text>
        </assertion>

        <assertion id="i" implied="true">
            <text>An alternative selected only for a specific bean archive is not selected for an application.</text>
        </assertion>

    </section>

    <section id="enablement" title="Enabled and disabled beans" level="3">
        <assertion id="a" testable="false">
            <text>A bean is said to be enabled if it is deployed in a bean deployment archive, and it is not a producer method or field of a disabled bean, and
                it is not specialized by any other enabled bean, as defined in Section 4.3, "Specialization", and either it is not an alternative, or it is not
                an alternative, or it is a selected alternative of at least one bean archive or the application. Otherwise, the bean is said to be disabled.
            </text>
            <note>Tested in section inter_module_injection</note>
        </assertion>
    </section>

    <section id="inconsistent_specialization" title="Inconsistent specialization" level="3">
        <assertion id="a">
            <text>Suppose an enabled bean X specializes a second bean Y. If there is another enabled bean that specializes Y we say that inconsistent
                specialization exists. The container automatically detects inconsistent specialization and treats it as a deployment problem.
            </text>
        </assertion>
    </section>

    <section id="inter_module_injection" title="Inter-module injection" level="3">
        <group>
            <text>A bean is available for injection in a certain module if the bean is not an interceptor or decorator, the bean is enabled, the bean is either
                not an alternative, or the module is a bean archive and the bean is a selected alternative of the bean archive, and the bean class is required
                to be accessible to classes in the module, according to the class accessibility requirements of the module architecture.
            </text>

            <assertion id="a">
                <text>Check a decorator can not be injected</text>
            </assertion>

            <assertion id="b">
                <text>Check an interceptor can not be injected</text>
            </assertion>

            <assertion id="c">
                <text>Check an enabled managed bean can be injected</text>
            </assertion>

            <assertion id="e">
                <text>Check an enabled producer field can be injected</text>
            </assertion>

            <assertion id="f">
                <text>Check an enabled producer method can be injected</text>
            </assertion>

            <assertion id="g">
                <text>Check producer method of a disabled bean is not injectable</text>
            </assertion>

            <assertion id="h">
                <text>Check producer field of a disabled bean is not injectable</text>
            </assertion>

            <assertion id="i">
                <text>Check a disabled managed bean is not injectable</text>
            </assertion>

            <assertion id="l">
                <text>Check a specialized managed bean is not injectable</text>
            </assertion>

            <assertion id="m" testable="false">
                <text>Check a specialized producer field is not injectable</text>
                <note>Specialized producer field is not legal.</note>
            </assertion>

            <assertion id="n">
                <text>Check a specialized producer method is not injectable</text>
            </assertion>

            <assertion id="o">
                <text>Check a selected alternative being managed bean is injected</text>
            </assertion>

        </group>

        <group>
            <text>For a custom implementation of the |Bean| interface defined in Section 11.1, "The Bean interface, the container calls |getBeanClass()| to
                determine the bean class of the bean and |InjectionPoint.getMember()| and then |Member.getDeclaringClass()| to determine the class that declares
                an injection point.
            </text>
            <assertion id="q">
                <text>Check |Bean.getBeanClass()| is used to determine the bean class</text>
                <note>It is not clear from the spec when exactly the method should be called.</note>
            </assertion>

            <assertion id="r">
                <text>Check |InjectionPoint.getMember().getDeclaringClass()| is used to determine the class declaring the injection point</text>
                <note>It is not clear from the spec when exactly the method should be called.</note>
            </assertion>
        </group>
    </section>

    <section id="typesafe_resolution" title="Typesafe resolution" level="2">
    </section>

    <section id="performing_typesafe_resolution" title="Performing typesafe resolution" level="3">

        <group>
            <text>A bean is assignable to a given injection point if the bean has a bean type that matches the required type. For this purpose, primitive types
                are considered to match their corresponding wrapper types in |java.lang| and array types are considered to match only if their element types are
                identical. Parameterized and raw types are considered to match if they are identical or if the bean type is assignable to the required type, as
                defined in Section 5.2.3, "Assignability of raw and parameterized types".
            </text>

            <assertion id="i">
                <text>Test with a primitive type.</text>
            </assertion>

            <assertion id="j">
                <text>Test with an array type.</text>
            </assertion>

            <assertion id="ka">
                <text>Test with a parameterized type.</text>
            </assertion>

            <assertion id="kb">
                <text>Test with a raw type.</text>
            </assertion>

            <assertion id="kc">
                <text>Test with a |@Named| bean.</text>
            </assertion>
        </group>

        <group>
            <text>A bean is assignable to a given injection point if the bean has all the required qualifiers. If no required qualifiers were explicitly
                specified, the container assumes the required qualifier |@Default|. A bean has the required qualifier if it has a qualifier with (a) the same
                type and (b) the same annotation member value for each member which is not annotated |@jakarta.enterprise.util.NonBinding|.
            </text>

            <assertion id="la">
                <text>Test with beans with required qualifiers.</text>
            </assertion>

            <assertion id="lb">
                <text>Test with beans without required qualifiers.</text>
            </assertion>

            <assertion id="lc">
                <text>Test with matching beans with matching qualifier with same type.</text>
            </assertion>

            <assertion id="ld">
                <text>Test with matching beans with matching qualifier with same annotation member value for each member which is not annotated
                    |@jakarta.enterprise.util.NonBinding|.
                </text>
            </assertion>
        </group>

        <assertion id="n">
            <text>A bean is eligible for injection to a certain injection point if it is available for injection in the module that contains the class that
                declares the injection point, and it is assignable to the injection point.
            </text>
        </assertion>

        <group>
            <text>For a custom implementation of the |Bean| interface defined in Section 11.1, "The Bean interface", the container calls |getTypes()| and
                |getQualifiers()| to determine the bean types and qualifiers.
            </text>

            <assertion id="na">
                <text>Test |getTypes()| determines bean types.</text>
            </assertion>

            <assertion id="nb">
                <text>Test |getQualifiers()| determines qualifiers.</text>
            </assertion>
        </group>

    </section>

    <section id="unsatisfied_and_ambig_dependencies" title="Unsatisfied and ambiguous dependencies" level="3">

        <group>
            <text>When an ambiguous dependency exists, the container attempts to resolve the ambiguity. The container eliminates all eligible beans that are not
                alternatives selected for the bean archive or selected for the application, except for producer methods and fields of beans that are
                alternatives.
            </text>
            <assertion id="ca">
                <text>If there is exactly one bean remaining, the container will select this bean, and the ambiguous dependency is called resolvable.</text>
            </assertion>

            <assertion id="cb">
                <text>If all the beans left are alternatives with a priority, then the container will determine the highest priority value, and eliminate all
                    beans, except for producer methods and fields of beans that are alternatives with the highest priority value. If there is exactly one bean
                    remaining, the container will select this bean, and the ambiguous dependency is called resolvable.
                </text>
            </assertion>
        </group>

        <group>
            <text>The container must validate all injection points of all enabled beans, all observer methods and all disposer methods when the application is
                initialized to ensure that there are no unsatisfied or ambiguous dependencies. If an unsatisfied or ambiguous dependency exists, the container
                automatically detects the problem and treats it as a deployment problem.
            </text>
            <assertion id="aa">
                <text>Test unsatisfied dependency for enabled bean.</text>
            </assertion>
            <assertion id="ab">
                <text>Test unsatisfied dependency for observer method.</text>
            </assertion>
            <assertion id="ac">
                <text>Test unsatisfied dependency for disposer method.</text>
            </assertion>
            <assertion id="ae">
                <text>Test ambiguous dependency for enabled bean.</text>
            </assertion>
            <assertion id="af">
                <text>Test ambiguous dependency for observer method.</text>
            </assertion>
            <assertion id="ag">
                <text>Test ambiguous dependency for disposer method.</text>
            </assertion>
        </group>

        <assertion id="b">
            <text>For a custom implementation of the |Bean| interface defined in Section 11.1, "The Bean interface", the container calls |getInjectionPoints()|
                to determine the set of injection points.
            </text>
        </assertion>
    </section>

    <section id="legal_injection_point_types" title="Legal injection point types" level="3">
        <assertion id="a">
            <text>Any legal bean type, as defined in Section 2.2.1, "Legal bean types" may be the required type of an injection point.</text>
        </assertion>

        <assertion id="b">
            <text>The required type of an injection point may contain a wildcard type parameter.</text>
        </assertion>

        <assertion id="c">
            <text>If an injection point type is a type variable, the container automatically detects the problem and treats it as a definition error.</text>
        </assertion>

    </section>

    <section id="assignable_parameters" title="Assignability of raw and parameterized types" level="3">
        <assertion id="a">
            <text>A parameterized bean type is considered assignable to a raw required type if the raw types are identical and all type parameters of the bean
                type are either unbounded type variables or |java.lang.Object|.
            </text>
        </assertion>

        <group>
            <text>A parameterized bean type is considered assignable to a parameterized required type if they have identical raw type and for each parameter:
                the required type parameter and the bean type parameter are actual types with identical raw type, and, if the type is parameterized, the bean
                type parameter is assignable to the required type parameter according to these rules, or the required type parameter is a wildcard, the bean
                type parameter is an actual type and the actual type is assignable to the upper bound, if any, of the wildcard and assignable from the lower
                bound, if any, of the wildcard, or the required type parameter is a wildcard, the bean type parameter is a type
                variable and the upper bound of the type variable is assignable to or assignable from the upper bound, if any, of the wildcard and assignable
                from the lower bound, if any, of the wildcard, or the required type parameter is an actual type, the bean type parameter is a type variable and
                the actual type is as- signable to the upper bound, if any, of the type variable, or the required type parameter and the bean type parameter are
                both type variables and the upper bound of the required type parameter is assignable to the upper bound, if any, of the bean type parameter.
            </text>

            <assertion id="ba">
                <text>Check the required type parameter and the bean type parameter are actual types with identical raw type</text>
            </assertion>

            <assertion id="bb">
                <text>Check the required type parameter and the bean type parameter are actual types with identical raw type for nested type parameters</text>
            </assertion>

            <assertion id="c">
                <text>Check the required type parameter is a wildcard, the bean type parameter is an actual type and the actual type is assignable to the upper
                    bound of the wildcard and assignable from the lower bound of the wildcard
                </text>
            </assertion>

            <assertion id="da">
                <text>Check the required type parameter is a wildcard, the bean type parameter is a type variable and the upper bound of the type variable is
                    _assignable to_ the _upper_ bound of the wildcard
                </text>
            </assertion>

            <assertion id="db">
                <text>Check the required type parameter is a wildcard, the bean type parameter is a type variable and the upper bound of the type variable is
                    _assignable from_ the _upper_ bound of the wildcard
                </text>
            </assertion>

            <assertion id="dc">
                <text>Check the required type parameter is a wildcard, the bean type parameter is a type variable and the upper bound of the type variable is
                    _assignable from_ the _lower_ bound of the wildcard
                </text>
            </assertion>

            <assertion id="e">
                <text>Check the required type parameter is an actual type, the bean type parameter is a type variable and the actual type is assignable to the
                    upper bound of the type variable
                </text>
            </assertion>

            <assertion id="f">
                <text>Check the required type parameter and the bean type parameter are both type variables and the upper bound of the required type parameter
                    is assignable to the upper bound of the bean type parameter.
                </text>
            </assertion>
        </group>

        <assertion id="g">
            <text>A raw bean type is considered assignable to a parameterized required type if the raw types are identical and all type parameters of the
                required type are either unbounded type variables or |java.lang.Object|.
            </text>
        </assertion>

    </section>

    <section id="primitive_types_and_null_values" title="Primitive types and null values" level="3">
        <group>
            <text>If necessary, the container performs boxing or unboxing when it injects a value to a field or parameter of primitive or wrapper type.</text>

            <assertion id="aa">
                <text>Test boxing.</text>
            </assertion>

            <assertion id="ab">
                <text>Test unboxing.</text>
            </assertion>
        </group>

        <assertion id="b">
            <text>If an injection point of primitive type resolves to a producer method or producer field that returns a null value at runtime, the container
                must inject the primitive type's default value as defined by the Java Language Specification.
            </text>
        </assertion>

    </section>

    <section id="qualifier_annotation_members" title="Qualifier annotations with members" level="3">
        <assertion id="a" testable="false">
            <text>Qualifier types may have annotation members.</text>
            <note>A statement of intent</note>
        </assertion>

        <assertion id="b">
            <text>An annotation member may be excluded from consideration using the |@NonBinding| annotation.</text>
        </assertion>

        <assertion id="c" testable="false">
            <text>Array-valued or annotation-valued members of a qualifier type should be annotated |@NonBinding| in a portable application. If an array-valued
                or annotation-valued member of a qualifier is not annotated |@NonBinding|, non-portable behavior results.
            </text>
        </assertion>
    </section>

    <section id="multiple_qualifiers" title="Multiple qualifiers" level="3">
        <assertion id="a">
            <text>A bean class may declare multiple qualifiers.</text>
        </assertion>

        <assertion id="b">
            <text>A producer method may declare multiple qualifiers.</text>
        </assertion>

        <assertion id="c">
            <text>A producer field may declare multiple qualifiers.</text>
        </assertion>

        <assertion id="d">
            <text>A bean must declare all of the qualifiers that are specified at the injection point to be considered a candidate for injection.</text>
        </assertion>
    </section>

    <section id="name_resolution" title="EL name resolution" level="2">
        <assertion id="d">
            <text>An name resolves to a bean if the bean has the given bean name, and the bean is available for injection in the module where the name
                resolution is requested.
            </text>
        </assertion>

        <assertion id="e">
            <text>For a custom implementation of the |Bean| interface defined in Section 11.1, "The Bean interface", the container calls |getName()| to
                determine the bean name.
            </text>
        </assertion>
    </section>

    <section id="ambig_names" title="Ambiguous EL names" level="3">

        <group>
            <text>An ambiguous name exists when a name resolves to multiple beans. When an ambiguous name exists, the container attempts to resolve the
                ambiguity. The container eliminates all eligible beans that are not alternatives selected for the bean archive or selected for the application,
                except for producer methods and fields of beans that are alternatives.
            </text>
            <assertion id="ca">
                <text>If there is exactly one bean remaining, the container will select this bean, and the ambiguous dependency is called resolvable.</text>
            </assertion>
            <assertion id="cb">
                <text>If all the beans left are alternatives with a priority, then the container will determine the highest priority value, and eliminate all
                    beans, except for producer methods and fields of beans that are alternatives with the highest priority value. If there is exactly one bean
                    remaining, the container will select this bean, and the ambiguous dependency is called resolvable.
                </text>
            </assertion>
        </group>

        <group>
            <text>All unresolvable ambiguous names are detected by the container when the application is initialized. Suppose two beans are both available for
                injection in a certain module, and either
            </text>

            <assertion id="da">
                <text>Test two beans have the same bean name and the name is not resolvable.</text>
            </assertion>

            <assertion id="db">
                <text>Test the bean name of one bean is of the form x.y , where y is a valid bean name, and x is the bean name of the other bean.</text>
            </assertion>
        </group>
    </section>

    <section id="client_proxies" title="Client proxies" level="2">
        <assertion id="b">
            <text>A contextual reference to a bean with a normal scope, as defined in Section 6.3, “Normal scopes and pseudo-scopes”, is not a direct reference
                to a contextual instance of the bean (the object returned by |Contextual.create()|). Instead, the contextual reference is a client proxy object.
            </text>
        </assertion>

        <assertion id="a" testable="false">
            <text>Client proxies are never required for a bean whose scope is a pseudo-scope such as |@Dependent|.</text>
        </assertion>

        <assertion id="c" implied="true">
            <text>Client proxies are serializable</text>
            <note>For the statement "Client proxies may be passivated, even when the bean itself may not be. Therefore the container must use a client proxy
                whenever a bean with normal scope is injected into a bean with a passivating scope" to hold true the client proxy must be serializable.
            </note>
        </assertion>

        <assertion id="d">
            <text>The container must guarantee that when any valid injected reference to a bean of normal scope is invoked, the invocation is always processed
                by the current instance of the injected bean.
            </text>
        </assertion>

        <assertion id="e" testable="false">
            <text>Client proxies may be shared between multiple injection points.</text>
        </assertion>
    </section>

    <section id="client_proxy_invocation" title="Client proxy invocation" level="3">
        <assertion id="aa">
            <text>Every time a method of the bean is invoked upon a client proxy, the client proxy must obtain a contextual instance of the bean, as defined in
                Section 6.5.2, "Contextual instance of a bean", and invoke the method upon this instance.
            </text>
        </assertion>

        <assertion id="ab">
            <text>If the scope is not active, as specified in Section 6.5.1, "The active context object for a scope", the client proxy rethrows
                |ContextNotActiveException| or |IllegalStateException|.
            </text>
        </assertion>

        <assertion id="b" testable="false">
            <text>The behavior of all methods declared by |java.lang.Object|, except for |toString()|, is undefined for a client proxy.</text>
        </assertion>

    </section>

    <section id="injection" title="Dependency injection" level="2">
        <assertion id="b">
            <text>The container is required to perform dependency injection whenever it creates a contextual instance of a managed bean.</text>
        </assertion>

        <assertion id="d">
            <text>The container is required to perform dependency injection whenever it instantiates non-contextual instances of managed beans.</text>
        </assertion>

        <assertion id="g">
            <text>The container interacts with instances of beans or objects supporting injection by calling methods and getting and setting the field values.
            </text>
        </assertion>

        <assertion id="h">
            <text>The object injected by the container may not be a direct reference to a contextual instance of the bean. Instead, it is an injectable
                reference, as defined by Section 6.5.5, "Injectable references".
            </text>
        </assertion>
    </section>

    <section id="instantiation" title="Injection using the bean constructor" level="3">
        <group>
            <text>When the container instantiates a managed bean with a constructor annotated |@Inject|, the container calls this constructor, passing an
                injectable reference to each parameter. If there is no constructor annotated |@Inject|, the container calls the constructor with no parameters.
            </text>
            <assertion id="aa">
                <text>Test managed bean with a constructor annotated |@Inject|.</text>
            </assertion>
            <assertion id="ba">
                <text>Test constructor with no parameters is used for a managed bean</text>
            </assertion>
        </group>
    </section>

    <section id="fields_initializer_methods" title="Injection of fields and initializer methods" level="3">
        <group>
            <text>When the container creates a new instance of a managed bean the container must: Initialize the values of all injected fields. The container
                sets the value of each injected field to an injectable reference. Call all initializer methods, passing an injectable reference to each
                parameter.
            </text>
            <assertion id="ac">
                <text>Test managed bean fields injected</text>
            </assertion>
            <assertion id="ad">
                <text>Test managed bean initializer methods called</text>
            </assertion>
        </group>

        <group>
            <text>The container must ensure that: Initializer methods declared by a class X in the type hierarchy of the bean are called after all injected
                fields declared by X or by superclasses of X have been initialized. Any |@PostConstruct| callback declared by a class X in the type hierarchy of
                the bean is called after all initializer methods declared by X or by superclasses of X have been called, after all injected fields declared by X
                or by superclasses of X have been initialized.
            </text>
            <assertion id="bg">
                <text>Test managed bean initializer methods called after injected field of X</text>
            </assertion>
            <assertion id="bh">
                <text>Test managed bean initializer methods called after injected field of superclass of X</text>
            </assertion>
            <assertion id="bk">
                <text>Test managed bean @PostConstruct called after initializer of X</text>
            </assertion>
            <assertion id="bl">
                <text>Test managed bean @PostConstruct called after initializer of superclass of X</text>
            </assertion>
        </group>
    </section>

    <section id="dependent_objects_destruction" title="Destruction of dependent objects" level="3">
        <assertion id="a">
            <text>When the container destroys an instance of a bean, the container destroys all dependent objects, as defined in Section 6.4.2, "Destruction of
                objects with scope @Dependent", after the |@PreDestroy| callback completes.
            </text>
        </assertion>
    </section>

    <section id="producer_or_disposer_methods_invocation" title="Invocation of producer or disposer methods" level="3">
        <assertion id="a">
            <text>When the container calls a producer method, if the method is static, the container must invoke the method.</text>
        </assertion>

        <assertion id="b">
            <text>When the container calls a disposer method, if the method is static, the container must invoke the method.</text>
        </assertion>

        <assertion id="c">
            <text>When the container calls a producer method, if the method is non-static the container must obtain a contextual instance of the bean which
                declares the method, as defined by Section 6.5.2 "Contextual instance of a bean", then invoke the method upon this instance.
            </text>
        </assertion>

        <assertion id="d">
            <text>When the container calls a disposer method, if the method is non-static the container must obtain a contextual instance of the bean which
                declares the method, as defined by Section 6.5.2 "Contextual instance of a bean", then invoke the method upon this instance.
            </text>
        </assertion>

        <assertion id="e">
            <text>The container passes an injectable reference to each injected method parameter.</text>
        </assertion>

        <assertion id="f">
            <text>The container is also responsible for destroying dependent objects created during this invocation, as defined in Section 6.4.2, "Destruction
                of objects with scope @Dependent".
            </text>
            <note></note>
        </assertion>

    </section>

    <section id="producer_fields_access" title="Access to producer field values" level="3">
        <assertion id="a">
            <text>When the container accesses the value of a producer field, if the producer field is static, the container must access the field value.</text>
        </assertion>

        <assertion id="b">
            <text>When the container accesses the value of a producer field, if the producer field is non-static, the container must obtain a contextual
                instance of the bean which declares the producer field, as defined by Section 6.5.2 "Contextual instance of a bean", then access the field value
                of this instance.
            </text>
        </assertion>
    </section>

    <section id="observers_method_invocation" title="Invocation of observer methods" level="3">
        <assertion id="a">
            <text>When the container calls an observer method (defined in Section 10.4 "Observer methods"), if the observer method is static, the container must
                invoke the method.
            </text>
        </assertion>

        <assertion id="baa">
            <text>When the container calls an observer method (defined in Section 10.4 "Observer methods"), if the observer method is non-static, the container
                must obtain a contextual instance of the bean according to Section 6.5.2 "Contextual instance of a bean". If this observer method is a
                conditional observer method, obtain the contextual instance that already exists, only if the scope of the bean that declares the observer method
                is currently active, without creating a new contextual instance. Finally, the container must invoke the observer method on the resulting
                instance, if any, as a business method invocation, as defined in Section 7.2 "Container invocations and interception".
            </text>
        </assertion>

        <assertion id="c">
            <text>The container must pass the event object to the event parameter and an injectable instance to each injected method parameter.</text>
        </assertion>

        <assertion id="d">
            <text>The container is also responsible for destroying dependent objects created during this invocation, as defined in Section 6.4.2, "Destruction
                of objects with scope @Dependent".
            </text>
        </assertion>
    </section>

    <section id="injection_point" title="Injection point metadata" level="3">
        <assertion id="aa">
            <text>The |getBean()| method returns the Bean object representing the bean that defines the injection point.</text>
        </assertion>

        <assertion id="aaa">
            <text>If the injection point does not belong to a bean, |getBean()| returns a null value.</text>
        </assertion>

        <assertion id="aab">
            <text>If the injection point represents a dynamically obtained instance, the |getBean()| method should return the |Bean| object representing the
                bean that defines the |Instance| injection point.
            </text>
        </assertion>

        <assertion id="ba">
            <text>The |getType()| method returns the required type of the injection point.</text>
        </assertion>

        <assertion id="baa">
            <text>If the injection point represents a dynamically obtained instance, the |getType()| method returns the required type (as defined by
                |Instance.select()|).
            </text>
        </assertion>

        <assertion id="bc">
            <text>The |getQualifiers()| method returns the required qualifiers of the injection point.</text>
        </assertion>

        <assertion id="bca">
            <text>If the injection point represents a dynamically obtained instance, the |getQualifiers()| method returns required qualifiers of the injection
                point including any additional required qualifers (as defined by |Instance.select()|).
            </text>
        </assertion>

        <assertion id="ca">
            <text>The |getMember()| method returns the |Field| object in the case of field injection.</text>
        </assertion>

        <assertion id="caa">
            <text>If the injection point represents a dynamically obtained instance, the |getMember()| method returns the |Field| object representing the field
                that defines the |Instance| injection point in the case of field injection.
            </text>
        </assertion>

        <assertion id="cb">
            <text>The |getMember()| method returns the |Method| object in the case of method parameter injection.</text>
        </assertion>

        <assertion id="cba">
            <text>If the injection point represents a dynamically obtained instance, the |getMember()| method returns the |Method| object representing the
                method that defines the |Instance| injection point in the case of method parameter injection.
            </text>
        </assertion>

        <assertion id="cc">
            <text>The |getMember()| method returns the |Constructor| object in the case of constructor parameter injection.</text>
        </assertion>

        <assertion id="cca">
            <text>If the injection point represents a dynamically obtained instance, the |getMember()| method returns the |Constructor| object representing the
                constructor that defines the |Instance| injection point in the case of constructor parameter injection.
            </text>
        </assertion>

        <assertion id="daa">
            <text>The |getAnnotated()| method returns an instance of |jakarta.enterprise.inject.spi.AnnotatedField| or
                |jakarta.enterprise.inject.spi.AnnotatedParameter|, depending upon whether the injection point is an injected field or a constructor/method
                parameter.
            </text>
        </assertion>

        <assertion id="dab">
            <text>If the injection point represents a dynamically obtained instance, then the |getAnnotated()| method returns an instance of
                |jakarta.enterprise.inject.spi.AnnotatedField| or |jakarta.enterprise.inject.spi.AnnotatedParameter| representing the |Instance| injection point,
                depending upon whether the injection point is an injected field or a constructor/method parameter.
            </text>
        </assertion>

        <assertion id="dba">
            <text>The |isDelegate()| method returns true if the injection point is a decorator delegate injection point, and false otherwise.</text>
        </assertion>

        <assertion id="dbb">
            <text>If the injection point represents a dynamically obtained instance then |isDelegate()| returns false.</text>
        </assertion>

        <assertion id="dca">
            <text>The |isTransient()| method returns true if the injection point is a transient field, and false otherwise.</text>
        </assertion>

        <assertion id="dcb">
            <text>If the injection point represents a dynamically obtained instance then the |isTransient()| method returns true if the |Instance| injection
                point is a transient field, and false otherwise.
            </text>
        </assertion>

        <assertion id="ea">
            <text>The container must provide a bean with scope |@Dependent|, bean type |InjectionPoint| and qualifier |@Default|, allowing dependent objects, as
                defined in Section 6.4.1, "Dependent objects", to obtain information about the injection point to which they belong.
            </text>
        </assertion>

        <assertion id="eb">
            <text>The built-in implementation must be a passivation capable dependency, as defined in Section 6.6.2, "Passivation capable dependencies".</text>
        </assertion>

        <assertion id="f">
            <text>If a bean that declares any scope other than |@Dependent| has an injection point of type |InjectionPoint| and qualifier |@Default|, the
                container automatically detects the problem and treats it as a definition error.
            </text>
        </assertion>

        <assertion id="g">
            <text>If a disposer method has an injection point of type |InjectionPoint| and qualifier |@Default|, the container automatically detects the
                problem and treats it as a definition error.
            </text>
        </assertion>

        <assertion id="h">
            <text>If a class supporting injection that is not a bean has an injection point of type |InjectionPoint| and qualifier |@Default|, the container
                automatically detects the problem and treats it as a definition error.
            </text>
        </assertion>

    </section>

    <section id="bean_metadata" title="Bean metadata" level="3">

        <group>
            <text>The container must provide beans allowing a bean instance to obtain a |Bean|, |Interceptor| or |Decorator| instance containing its metadata.
            </text>
            <assertion id="a">
                <text>Bean with scope |@Dependent|, qualifier |@Default| and type |Bean| can be injected into any bean instance.</text>
            </assertion>
            <assertion id="b">
                <text>Bean with scope |@Dependent|, qualifier |@Default| and type |Interceptor| can be injected into any interceptor instance.</text>
            </assertion>
            <assertion id="c">
                <text>Bean with scope |@Dependent|, qualifier |@Default| and type |Decorator| which can be injected into any decorator instance.</text>
            </assertion>
        </group>

        <group>
            <text>Additionally, the container must provide beans allowing interceptors and decorators to obtain information about the beans they intercept and
                decorate.
            </text>
            <assertion id="d">
                <text>Bean with scope |@Dependent|, qualifier |@Intercepted| and type |Bean| which can be injected into any interceptor instance.</text>
            </assertion>
            <assertion id="e">
                <text>Bean with scope |@Dependent|, qualifier |@Decorated| and type |Bean| can be injected into any decorator instance.</text>
            </assertion>
        </group>

        <assertion id="f">
            <text>These beans are passivation capable dependencies, as defined in Section 6.6.2, "Passivation capable dependencies".</text>
        </assertion>

        <assertion id="h">
            <text>If an |Interceptor| instance is injected into a bean instance other than an interceptor instance, the container automatically detects the
                problem and treats it as a definition error.
            </text>
        </assertion>

        <assertion id="i">
            <text>If a |Decorator| instance is injected into a bean instance other than a decorator instance, the container automatically detects the problem
                and treats it as a definition error.
            </text>
        </assertion>

        <assertion id="r">
            <text>If a |Bean| instance with qualifier |@Intercepted| is injected into a bean instance other than an interceptor instance, the container
                automatically detects the problem and treats it as a definition error.
            </text>
        </assertion>

        <assertion id="s">
            <text>If a |Bean| instance with qualifier |@Decorated| is injected into a bean instance other than an interceptor instance, the container
                automatically detects the problem and treats it as a definition error.
            </text>
        </assertion>

        <group>
            <text>The injection of bean metadata is restricted.</text>
            <assertion id="j">
                <text>If the injection point is a field, an initializer method parameter or a bean constructor, with qualifier |@Default| and type parameter of
                    the injected |Bean| is not the same as the type declaring the injection point, the container automatically detects the problem and treats it
                    as a definition error.
                </text>
            </assertion>
            <assertion id="k">
                <text>If the injection point is a field, an initializer method parameter or a bean constructor, with qualifier |@Default| and type parameter of
                    the injected |Interceptor| is not the same as the type declaring the injection point, the container automatically detects the problem and
                    treats it as a definition error.
                </text>
            </assertion>
            <assertion id="l">
                <text>If the injection point is a field, an initializer method parameter or a bean constructor, with qualifier |@Default| and type parameter of
                    the injected |Decorator| is not the same as the type declaring the injection point, the container automatically detects the problem and
                    treats it as a definition error.
                </text>
            </assertion>
            <assertion id="m">
                <text>If the injection point is a field, an initializer method parameter or a bean constructor of an interceptor, with qualifier |@Intercepted|
                    and the type parameter of the injected |Bean| is not an unbounded wildcard, the container automatically detects the problem and treats it as
                    a definition error.
                </text>
            </assertion>
            <assertion id="n">
                <text>If he injection point is a field, an initializer method parameter or a bean constructor of a decorator, with qualifier |@Decorated| and
                    the type parameter of the injected |Bean| is not the same as the delegate type, the container automatically detects the problem and treats
                    it as a definition error.
                </text>
            </assertion>
            <assertion id="o">
                <text>If the injection point is a producer method parameter and the type parameter of the injected |Bean| is not the same as the producer method
                    return type, the container automatically detects the problem and treats it as a definition error.
                </text>
            </assertion>
            <assertion id="p">
                <text>If the injection point is a disposer method parameter then no Bean instance can be injected, the container automatically detects the
                    problem and treats it as a definition error.
                </text>
            </assertion>
        </group>

    </section>

    <section id="programmatic_lookup" title="Programmatic lookup" level="2">
        <assertion id="aa">
            <text>An instance of the |jakarta.enterprise.inject.Instance| interface may be injected.</text>
        </assertion>

        <assertion id="ba">
            <text>The method |jakarta.enterprise.inject.Instance.get()| returns a contextual reference.</text>
        </assertion>

        <assertion id="ca">
            <text>Any combination of qualifiers may be specified at the injection point.</text>
        </assertion>

        <assertion id="da">
            <text>The |@Any| qualifier may be used to allow the application to specify qualifiers dynamically.</text>
        </assertion>

        <assertion id="e">
            <text>The |@New| qualifier may be used, allowing the application to obtain a |@New| qualified bean, as defined in Section 3.12, "@New qualified
                beans".
            </text>
        </assertion>
    </section>

    <section id="dynamic_lookup" title="The Instance interface" level="3">
        <assertion id="aa">
            <text>The |Instance| interface provides a method for obtaining instances of beans with a specified combination of required type and qualifiers, and
                inherits the ability to iterate beans with that combination of required type and qualifiers from |java.lang.Iterable|.
            </text>
        </assertion>

        <assertion id="ab">
            <text>For an injected |Instance|, the required type is the type parameter specified at the injection point, and the required qualifiers are the
                qualifiers specified at the injection point.
            </text>
        </assertion>

        <assertion id="ba">
            <text>The |select()| method returns a child |Instance| for a given required type and additional required qualifiers. If no required type is given,
                the required type is the same as the parent.
            </text>
        </assertion>

        <assertion id="bb" testable="false">
            <text>Rules specified at "The default qualifier at injection points" are applied before performing typesafe resolution.</text>
        </assertion>

        <assertion id="c">
            <text>If an injection point of raw type |Instance| is defined, the container automatically detects the problem and treats it as a definition
                error.
            </text>
        </assertion>

        <assertion id="da">
            <text>If two instances of the same non repeating qualifier type are passed to |select()|, an |IllegalArgumentException| is thrown.</text>
        </assertion>

        <assertion id="e">
            <text>If an instance of an annotation that is not a qualifier type is passed to |select()|, an |IllegalArgumentException| is thrown.</text>
        </assertion>

        <assertion id="fa">
            <text>The |get()| method must identify a bean that has the required type and required qualifiers and is eligible for injection into the class into
                which the parent |Instance| was injected, according to the rules of typesafe resolution, as defined in Section 5.2, "Typesafe resolution",
                resolving ambiguities according to Section 5.2.1, "Unsatisfied and ambiguous dependencies".
            </text>
        </assertion>

        <assertion id="fba">
            <text>If typesafe resolution results in an unsatisfied dependency, throw an |UnsatisfiedResolutionException|.</text>
        </assertion>

        <assertion id="fbb">
            <text>If typesafe resolution results in an unresolvable ambiguous dependency, throw an |AmbiguousResolutionException|.</text>
        </assertion>

        <assertion id="fc">
            <text>Otherwise, obtain a contextual reference for the bean and the required type, as defined in Section 6.5.3, "Contextual reference for a bean".
            </text>
        </assertion>

        <assertion id="ia">
            <text>The |iterator()| method must identify the set of beans that have the required type and required qualifiers and are eligible for injection into
                the class into which the parent |Instance| was injected, according to the rules of typesafe resolution, as defined in Section 5.2, "Typesafe
                resolution".
            </text>
        </assertion>

        <assertion id="ib">
            <text>The |iterator()| method must return an |Iterator|, that iterates over the set of contextual references for the resulting beans and required
                type, as defined in Section 6.5.3, "Contextual reference for a bean".
            </text>
        </assertion>

        <assertion id="ja">
            <text>
                The |stream()| method must identify the set of beans that have the required type and required qualifiers and are eligible for
                injection into the class into which the parent |Instance| was injected, according to the rules of
                typesafe resolution, as defined in Section 5.2.1, "Performing typesafe resolution", resolving ambiguities according
                to Section 5.2.2 "Unsatisfied and ambiguous dependencies".
            </text>
        </assertion>

        <assertion id="jb">
            <text>
                The |stream()| method must return a |Stream|, that can stream over the set of contextual references for the resulting beans and
                required type, as defined in Section 6.5.3, "Contextual reference for a bean".
            </text>
        </assertion>

        <group>
            <text>The methods |isUnsatisfied()|, |isAmbiguous()| and |isResolvable()| must:</text>

            <assertion id="la">
                <text>
                    Identify the set of beans that have the required type and required qualifiers and are eligible for
                    injection into the class into which the parent Instance was injected, according to the rules of
                    typesafe resolution, as defined in Performing typesafe resolution, resolving ambiguities according
                    to Unsatisfied and ambiguous dependencies.
                </text>
            </assertion>

            <assertion id="l">
                <text>The method |isUnsatisfied()| returns true if there is no bean found, or false otherwise.</text>
            </assertion>

            <assertion id="m">
                <text>The method |isAmbiguous()| returns true if there is more than one bean found, or false otherwise.</text>
            </assertion>

            <assertion id="ma">
                <text>The method |isResolvable()| returns true if there is exactly one bean found, or false otherwise.</text>
            </assertion>
        </group>

        <group>
            <text>The method |destroy()| instructs the container to destroy the instance. The bean instance passed to |destroy()| should be a dependent scoped
                bean instance, or a client proxy for a normal scoped bean. Applications are encouraged to always call |destroy()| when they no longer require an
                instance obtained from |Instance|.
            </text>
            <assertion id="n">
                <text>Test dependent scoped bean instance passed to |destroy()|.</text>
            </assertion>
            <assertion id="o">
                <text>Test client proxy passed to |destroy()|.</text>
            </assertion>
            <assertion id="p" implied="true">
                <text>Test |UnsupportedOperationException| is thrown when if the active context object for the scope type of the bean does not support
                    destroying bean instances.
                </text>
            </assertion>
        </group>

    </section>

    <section id="builtin_instance" title="The built-in Instance" level="3">
        <assertion id="a" testable="false">
            <text>The container must provide a built-in bean that is eligible for injection to any injection point with required type Instance &lt;X&gt; or
                Provider&lt;&gt;, for any
                legal bean type X.
            </text>
        </assertion>

        <assertion id="b" testable="false">
            <text>The container must provide a built-in bean that has any qualifiers.</text>
        </assertion>

        <assertion id="d">
            <text>The container must provide a built-in bean with scope @Dependent.</text>
        </assertion>

        <assertion id="e">
            <text>The container must provide a built-in bean with no bean name.</text>
        </assertion>

        <assertion id="f">
            <text>The container must provide a built-in bean with an implementation provided automatically by the container.</text>
        </assertion>

        <assertion id="g">
            <text>The built-in implementation must be a passivation capable dependency, as defined in Section 6.6.2, "Passivation capable dependencies".</text>
        </assertion>
    </section>

    <section id="annotationliteral_typeliteral" title="Using AnnotationLiteral and TypeLiteral" level="3">
        <assertion id="a" implied="true">
            <text>Test |jakarta.enterprise.util.AnnotationLiteral| when using |Instance.select()| to specify qualifiers.</text>
        </assertion>

        <assertion id="b" implied="true">
            <text>Test |jakarta.enterprise.util.TypeLiteral| when specifying a parameterized type with actual type parameters when calling |Instance.select()|.
            </text>
        </assertion>
    </section>

    <section id="built_in_annotation_literals" title="Built-in annotation literals" level="3">

    </section>

    <section id="contexts" title="Scopes and contexts" level="1">

    </section>

    <section id="contextual" title="The Contextual interface" level="2">
        <assertion id="aa">
            <text>If an exception occurs while creating an instance, the exception is rethrown by the |create()| method. If the exception is a checked
                exception, it must be wrapped and rethrown as an (unchecked) |CreationException|.
            </text>
        </assertion>

        <assertion id="ab">
            <text>If an exception occurs while destroying an instance, the exception must be caught by the |destroy()| method.</text>
        </assertion>

        <assertion id="ac" testable="false">
            <text>If the application invokes a contextual instance after it has been destroyed, the behavior is undefined.</text>
            <note>A statement about container specific behavior which is not spec defined</note>
        </assertion>

        <assertion id="a" testable="false">
            <text>The container and portable extensions may define implementations of the |Contextual| interface that do not extend |Bean|, but it is not
                recommended that applications directly implement |Contextual|.
            </text>
            <note>Advice only</note>
        </assertion>
    </section>

    <section id="creational_context" title="The CreationalContext interface" level="3">
        <assertion id="ca" testable="false">
            <text>The interface |jakarta.enterprise.context.spi.CreationalContext| provides operations that are used by the |Contextual| implementation during
                instance creation and destruction.
            </text>
            <note>introductory text</note>
        </assertion>

        <assertion id="d">
            <text>|push()| registers an incompletely initialized contextual instance with the container. A contextual instance is considered incompletely
                initialized until it is returned by the |create()| method.
            </text>
        </assertion>

        <assertion id="e">
            <text>|release()| destroys all dependent objects, as defined in Section 6.4.1, "Dependent objects", of the instance which is being destroyed, by
                passing each dependent object to the |destroy()| method of its |Contextual| object.
            </text>
        </assertion>

        <assertion id="f" testable="false">
            <text>The implementation of |Contextual| is not required to call |push()|. However, for certain bean scopes, invocation of |push()| between
                instantiation and injection helps the container minimize the use of client proxy objects (which would otherwise be required to allow circular
                dependencies).
            </text>
        </assertion>

        <assertion id="g">
            <text>If |Contextual.create()| calls |push()|, it must also return the instance passed to |push()|.</text>
        </assertion>

        <assertion id="h" testable="false">
            <text>|Contextual.create()| should use the given |CreationalContext| when obtaining contextual references to inject, as defined in Section 6.5.3,
                "Contextual reference for a bean", in order to ensure that any dependent objects are associated with the contextual instance that is being
                created.
            </text>
            <note>Advice</note>
        </assertion>

        <assertion id="i" testable="false">
            <text>|Contextual.destroy()| should call |release()| to allow the container to destroy dependent objects of the contextual instance.</text>
            <note>Advice</note>
        </assertion>
    </section>

    <section id="context" title="The Context interface" level="2">
        <assertion id="aa" testable="false">
            <text>The |jakarta.enterprise.context.spi.Context| interface provides an operation for obtaining contextual instances with a particular scope of any
                contextual type.
            </text>
            <note>Introductory text</note>
        </assertion>

        <assertion id="ab">
            <text>The method |getScope()| returns the scope type of the context object.</text>
        </assertion>

        <assertion id="ha">
            <text>When a context object is active the |isActive()| method returns |true|. Otherwise, we say that the context object is inactive and the
                |isActive()| method returns false.
            </text>
        </assertion>

        <assertion id="j">
            <text>The |Context.get()| method may either return an existing instance of the given contextual type, ~or if no |CreationalContext| is given, return
                a null value, or if a |CreationalContext| is given, create a new instance of the given contextual type by calling |Contextual.create()| and
                return the new instance~.
            </text>
        </assertion>

        <assertion id="k">
            <text>The |Context.get()| method may either ~return an existing instance of the given contextual type~, or if no |CreationalContext| is given,
                return a null value, ~or if a |CreationalContext| is given, create a new instance of the given contextual type by calling |Contextual.create()|
                and return the new instance~.
            </text>
        </assertion>

        <assertion id="l">
            <text>The |Context.get()| method may either ~return an existing instance of the given contextual type, or if no |CreationalContext| is given, return
                a null value~, or if a |CreationalContext| is given, create a new instance of the given contextual type by calling |Contextual.create()| and
                return the new instance.
            </text>
        </assertion>

        <assertion id="m">
            <text>If the context object is inactive, the |get()| method must throw a |ContextNotActiveException|.</text>
        </assertion>

        <assertion id="na">
            <text>The |get()| method may not return a null value _unless no |CreationalContext| is given_, or |Contextual.create()| returns a null value.</text>
        </assertion>

        <assertion id="nb">
            <text>The |get()| method may not return a null value unless no |CreationalContext| is given, or _|Contextual.create()| returns a null value_.</text>
        </assertion>

        <assertion id="o">
            <text>The |get()| method may not create a new instance of the given contextual type unless a |CreationalContext| is given.</text>
        </assertion>

        <assertion id="s">
            <text>When the container calls |get()| for a context that is associated with a passivating scope it must ensure that the given instance of
                |Contextual| and the instance of |CreationalContext|, if given, are serializable.
            </text>
        </assertion>

        <assertion id="t">
            <text>The |destroy()| method destroys an existing contextual instance, removing it from the context instance.</text>
            <note>The AlterableContext interface was introduced in Contexts and Dependency Injection for Jakarta EE 1.1 to allow bean instances to be destroyed by
                the application.
            </note>
        </assertion>

        <assertion id="p">
            <text>The context object is responsible for destroying any contextual instance it creates by passing the instance to the |destroy()| method of the
                |Contextual| object representing the contextual type.
            </text>
        </assertion>

        <assertion id="q">
            <text>A destroyed instance must not subsequently be returned by the |get()| method.</text>
        </assertion>

        <assertion id="r">
            <text>The context object must pass the same instance of |CreationalContext| to |Contextual.destroy()| that it passed to |Contextual.create()| when
                it created the instance.
            </text>
        </assertion>
    </section>

    <section id="normal_scope" title="Normal scopes and pseudo-scopes" level="2">
        <assertion id="a" testable="false">
            <text>There may be no more than one mapped instance of a context object per contextual type per thread</text>
            <note>Not testable through API</note>
        </assertion>

        <assertion id="b" testable="false">
            <text>A context may be associated with one or more threads</text>
            <note>A statement of intent</note>
        </assertion>

        <assertion id="c">
            <text>The |get()| operation of the |Context| object for an active normal scope returns the current instance of the given contextual type.</text>
        </assertion>

        <assertion id="d">
            <text>When a context is destroyed, all mapped instances belonging to that context are destroyed by passing them to the |Contextual.destroy()|
                method.
            </text>
        </assertion>

        <assertion id="e">
            <text>Contexts with normal scopes must obey the following rule: Suppose beans A, B and Z all have normal scopes. Suppose A has an injection point x,
                and B has an injection point y. Suppose further that both x and y resolve to bean Z according to the typesafe resolution algorithm. If a is the
                current instance of A, and b is the current instance of B, then both a.x and b.y refer to the same instance of Z. This instance is the current
                instance of Z.
            </text>
        </assertion>

        <assertion id="ea" testable="false">
            <text>All normal scopes must be explicitly declared |@NormalScope|, to indicate to the container that a client proxy is required.</text>
            <note>A statement of intent</note>
        </assertion>

        <assertion id="fa" testable="false">
            <text>All pseudo-scopes must be explicitly declared |@Scope|, to indicate to the container that no client proxy is required.</text>
            <note>A statement of intent</note>
        </assertion>

        <assertion id="g" testable="false">
            <text>All scopes defined by this specification, except for the |@Dependent| pseudo-scope, are normal scopes</text>
            <note>A statement of intent</note>
        </assertion>
    </section>

    <section id="dependent_context" title="Dependent pseudo-scope" level="2">
        <assertion id="a">
            <text>When a bean is declared to have |@Dependent| scope, no injected instance of the bean is ever shared between multiple injection points.</text>
        </assertion>

        <assertion id="b">
            <text>When a bean is declared to have |@Dependent| scope, any instance of the bean injected into an object that is being created by the container is
                bound to the lifecycle of the newly created object.
            </text>
        </assertion>

        <group>
            <text>When a bean is declared to have |@Dependent| scope, any instance of the bean that receives a producer method, producer field, disposer method
                or observer method invocation exists to service that invocation only
            </text>

            <assertion id="da">
                <text>Test with a producer method.</text>
            </assertion>

            <assertion id="db">
                <text>Test with a producer field.</text>
            </assertion>

            <assertion id="dc">
                <text>Test with a disposer method.</text>
            </assertion>

            <assertion id="dd">
                <text>Test with an observer method.</text>
            </assertion>
        </group>

        <assertion id="dg">
            <text>When a bean is declared to have |@Dependent| scope, any instance of the bean injected into method parameters of a disposer method or observer
                method exists to service the method invocation only (except for observer methods of container lifecycle events).
            </text>
        </assertion>

        <assertion id="e">
            <text>Every invocation of the |get()| operation of the |Context| object for the |@Dependent| scope with a |CreationalContext| returns a new instance
                of the given bean.
            </text>
        </assertion>

        <assertion id="f">
            <text>Every invocation of the |get()| operation of the |Context| object for the |@Dependent| scope with no |CreationalContext| returns a null
                value.
            </text>
        </assertion>

        <assertion id="g">
            <text>The |@Dependent| scope is always active.</text>
        </assertion>
    </section>

    <section id="dependent_objects" title="Dependent objects" level="3">
        <group>
            <text>Instances of interceptors or decorators with scope |@Dependent| are dependent objects of the bean instance they decorate.</text>
            <assertion id="aa">
                <text>Test with a |@Dependent|-scoped interceptor.</text>
            </assertion>

            <assertion id="ab">
                <text>Test with a |@Dependent|-scoped decorator.</text>
            </assertion>
        </group>

        <group>
            <text>An instance of a bean with scope |@Dependent| injected into a field, bean constructor or initializer method is a dependent object of the bean
                into which it was injected.
            </text>

            <assertion id="ga">
                <text>Test with |@Dependent|-scoped bean injected into field.</text>
            </assertion>

            <assertion id="gb">
                <text>Test with |@Dependent|-scoped bean injected into bean constructor.</text>
            </assertion>

            <assertion id="gc">
                <text>Test with |@Dependent|-scoped bean injected into initializer method.</text>
            </assertion>
        </group>

        <assertion id="h">
            <text>An instance of a bean with scope |@Dependent| injected into a producer method is a dependent object of the producer method bean instance that
                is being produced.
            </text>
        </assertion>

        <assertion id="i">
            <text>An instance of a bean with scope |@Dependent| obtained by direct invocation of an |Instance| is a dependent object of the instance of
                |Instance|.
            </text>
        </assertion>
    </section>

    <section id="dependent_destruction" title="Destruction of objects with scope @Dependent" level="3">

        <group>
            <text>The container must ensure that all dependent objects of a non-contextual instance of a bean are destroyed when the instance is destroyed by
                the container.
            </text>

            <assertion id="aaaa">
                <text>Test with a managed bean.</text>
            </assertion>

        </group>

        <group>
            <text>The container must ensure that all |@Dependent| scoped contextual instances injected into method parameters of a disposer method or observer
                method of any other event are destroyed when the invocation completes.
            </text>
            <assertion id="ccc">
                <text>Check disposer method.</text>
            </assertion>

            <assertion id="ccd">
                <text>Check observer method.</text>
            </assertion>
        </group>

        <group>
            <text>The container must ensure that all |@Dependent| scoped contextual instances injected into method or constructor parameters that are annotated
                with |@TransientReference| are destroyed when the invocation completes.
            </text>
            <assertion id="fa">
                <text>Test producer method parameter.</text>
            </assertion>
            <assertion id="fb">
                <text>Test initializer method parameter.</text>
            </assertion>
            <assertion id="fc">
                <text>Test bean constructor parameter.</text>
            </assertion>
        </group>

        <group>
            <text>The container must ensure that any |@Dependent| scoped contextual instance created to receive a producer method, producer field, disposer
                method or observer method invocation is destroyed when the invocation completes.
            </text>

            <assertion id="ddd">
                <text>Check producer method.</text>
            </assertion>

            <assertion id="dde">
                <text>Check producer field.</text>
            </assertion>

            <assertion id="ddf">
                <text>Check disposer method.</text>
            </assertion>

            <assertion id="ddg">
                <text>Check observer method.</text>
            </assertion>
        </group>

        <assertion id="e" testable="false">
            <text>The container is permitted to destroy any |@Dependent| scoped contextual instance at any time if the instance is no longer referenced by the
                application (excluding weak, soft and phantom references).
            </text>
            <note>In other words this is unspecified</note>
        </assertion>
    </section>

    <section id="contextual_instances_and_references" title="Contextual instances and contextual references" level="2">

    </section>

    <section id="active_context" title="The active context object for a scope" level="3">
        <assertion id="a">
            <text>From time to time, the container must obtain an active context object for a certain scope type. The container must search for an active
                instance of |Context| associated with the scope type. If no active context object exists for the scope type, the container throws a
                |ContextNotActiveException|.
            </text>
        </assertion>

        <assertion id="b">
            <text>If more than one active context object exists for the given scope type, the container must throw an |IllegalStateException|.</text>
        </assertion>
    </section>

    <section id="activating_builtin_contexts" title="Activating Built In Contexts" level="3">
        <assertion id="a" testable="false">
            <text>
                Certain built in contexts support the ability to be activated and deactivated. This allows developers to
                control built-in contexts in ways that they could also manage custom built contexts.
                When activating and deactivating built in contexts, it is important to realize that they can only be
                activated if not already active within a given thread.
            </text>
        </assertion>
    </section>

    <section id="activating_request_context" title="6.5.2.1. Activating a Request Context" level="4">
        <assertion id="a">
            <text>Request contexts can be managed either programmatically or via interceptor.</text>
        </assertion>

        <assertion id="b">
            <text>To programmatically manage request contexts, the container provides a built in bean that is @Dependent
                scoped and of type RequestContextController that allows you to activate and deactivate a request
                context on the current thread. The object should be considered stateful, invoking the same instance on
                different threads may not work properly, non-portable behavior may occur.
            </text>
        </assertion>

        <assertion id="c">
            <text>When the activate() method is called, if the request context is not already active on the current thread
                then it will be activated and the method returns true. Otherwise, the method returns false.
            </text>
        </assertion>

        <group>
            <text>When the deactivate() method is called,</text>
            <assertion id="da">
                <text>if this controller started the request context then the request context is stopped</text>
            </assertion>
            <assertion id="db">
                <text>The method does nothing if this controller did not activate the context and the context is active.</text>
            </assertion>
            <assertion id="dc">
                <text>This method throws a ContextNotActiveException if there is no request context active.</text>
            </assertion>
        </group>

        <assertion id="e">
            <text>If within the same thread the activate() and deactivate() methods are invoked repeatedly, the
                instances between the activations are not the same instances, each request context should be assumed
                to be new.
            </text>
        </assertion>

        <assertion id="f">
            <text>To automatically start a request context via interceptor binding, the container provides an interceptor
                @ActivateRequestContext which will activate a request context if not already active prior to the
                method’s invocation, and deactivate it upon method completion, with the same rules as in
                RequestContextController.
            </text>
        </assertion>

        <assertion id="g">
            <text>When the requestContext is managed via interceptor binding, the interceptor is automatically registered with a priority of PLATFORM_BEFORE +
                100
            </text>
        </assertion>

    </section>

    <section id="contextual_instance" title="Contextual instance of a bean" level="3">
        <assertion id="a">
            <text>From time to time, the container must obtain a contextual instance of a bean. The container must obtain the active context object for the bean
                scope, then obtain an instance of the bean by calling |Context.get()|, passing the |Bean| instance representing the bean and an instance of
                |CreationalContext|.
            </text>
        </assertion>

        <assertion id="b">
            <text>From time to time, the container attempts to obtain a contextual instance of a bean that already exists, without creating a new contextual
                instance. The container must determine if the scope of the bean is active and if it is, obtain the active context object for the bean scope,
                then attempt to obtain an instance of the bean by calling |Context.get()|, passing the |Bean| instance representing the bean without passing any
                instance of |CreationalContext|.
            </text>
        </assertion>

        <assertion id="c" testable="false">
            <text>If the scope is not active, or if |Context.get()| returns a null value, there is no contextual instance that already exists.</text>
            <note>Statement of intent</note>
        </assertion>

        <assertion id="e">
            <text>For a custom implementation of the |Bean| interface defined in Section 11.1, "The Bean interface", the container calls |getScope()| to
                determine the bean scope.
            </text>
        </assertion>
    </section>

    <section id="contextual_reference" title="Contextual reference for a bean" level="3">
        <assertion id="aa">
            <text>Contextual references must be obtained with a given |CreationalContext|, allowing any instance of scope |@Dependent| that is created to be
                later destroyed.
            </text>
        </assertion>

        <assertion id="a">
            <text>If the bean has a normal scope and the given bean type cannot be proxied by the container, as defined in Section 5.4.1, "Unproxyable bean
                types", the container throws an |UnproxyableResolutionException|.
            </text>
        </assertion>

        <assertion id="b">
            <text>If the bean has a normal scope, then the contextual reference for the bean is a client proxy, as defined in Section 5.4, "Client proxies",
                created by the container, that implements the given bean type and all bean types of the bean which are Java interfaces.
            </text>
        </assertion>

        <assertion id="c">
            <text>If the bean has a pseudo-scope, the container must obtain a contextual instance of the bean. If the bean has scope |@Dependent|, the container
                must associate it with the |CreationalContext|.
            </text>
        </assertion>

        <group>
            <text>The container must ensure that every injection point of type |InjectionPoint| and qualifier |@Default| of any dependent object instantiated
                during this process receives an instance of |InjectionPoint| representing the injection point into which the dependent object will be injected,
                or a null value if it is not being injected into any injection point.
            </text>
            <assertion id="da">
                <text>Test an injected dependent object.</text>
            </assertion>
            <assertion id="db">
                <text>Test a non-injected dependent object.</text>
            </assertion>
        </group>
    </section>

    <section id="contextual_reference_validity" title="Contextual reference validity" level="3">
        <assertion id="a">
            <text>Any reference to a bean with a normal scope is valid as long as the application maintains a hard reference to it. However, it may only be
                invoked when the context associated with the normal scope is active. If it is invoked when the context is inactive, a
                |ContextNotActiveException| is thrown by the container.
            </text>
        </assertion>

        <assertion id="b">
            <text>Any reference to a bean with a normal scope is invalid after CDI container shutdown. Maintaining such reference and attempting
                to use it after container shutdown results in an IllegalStateException.
            </text>
        </assertion>

        <assertion id="c" testable="false">
            <text>Any reference to a bean with a pseudo-scope (such as |@Dependent|) is valid until the bean instance to which it refers is destroyed. It may be
                invoked even if the context associated with the pseudo-scope is not active. If the application invokes a method of a reference to an instance
                that has already been destroyed, the behavior is undefined.
            </text>
            <note>Describes unspecified behavior</note>
        </assertion>
    </section>

    <section id="injectable_reference" title="Injectable references" level="3">
        <assertion id="a">
            <text>From time to time, the container must obtain an injectable reference for an injection point. The container must identify a bean according to
                the rules defined in Section 5.2, "Typesafe resolution" and resolving ambiguities according to Section 5.2.1, "Unsatisfied and ambiguous
                dependencies", then obtain a contextual reference for this bean and the type of the injection point according to Section 6.5.3, "Contextual
                reference for a bean".
            </text>
        </assertion>

        <assertion id="b" testable="false">
            <text>For certain combinations of scopes, the container is permitted to optimize the procedure for obtaining an injectable reference for an
                injection point - the container is permitted to directly inject a contextual instance of the bean, as defined in Section 6.5.2, "Contextual
                instance of a bean", and if an incompletely initialized instance of the bean is registered with the current |CreationalContext|, as defined in
                Section 6.1, "The Contextual interface", the container is permitted to directly inject this instance.
            </text>
        </assertion>
    </section>

    <section id="injectable_reference_validity" title="Injectable reference validity" level="3">
        <assertion id="a">
            <text>Injectable references to a bean must respect the rules of contextual reference validity, with the following exceptions - a reference to a bean
                injected into a field, bean constructor or initializer method is only valid until the object into which it was injected is destroyed, a
                reference to a bean injected into a producer method is only valid until the producer method bean instance that is being produced is destroyed,
                and a reference to a bean injected into a disposer method or observer method is only valid until the invocation of the method completes.
            </text>
        </assertion>

        <assertion id="b" testable="false">
            <text>The application should not invoke a method of an invalid injected reference. If the application invokes a method of an invalid injected
                reference, the behavior is undefined.
            </text>
            <note>Behavior is undefined.</note>
        </assertion>
    </section>

    <section id="passivating_scope" title="Passivation and passivating scopes" level="2">
        <assertion id="a" implied="true">
            <text>Test that passivation occurs.</text>
        </assertion>
    </section>

    <section id="passivation_capable" title="Passivation capable beans" level="3">

        <group>
            <text>A managed bean is passivation capable if and only if the bean class is serializable and all interceptors and decorators of the bean are
                passivation capable.
            </text>
            <assertion id="ba">
                <text>Tests with a serializable bean class.</text>
            </assertion>
            <assertion id="bb">
                <text>Tests with a serializable interceptor.</text>
            </assertion>
            <assertion id="bc">
                <text>Tests with a serializable decorator.</text>
            </assertion>
        </group>

        <assertion id="c" testable="false">
            <text>A producer method is passivation capable if and only if it never returns a value which is not passivation capable at runtime.</text>
            <note>Tested in "Validation of passivation capable beans and dependencies" section</note>
        </assertion>

        <assertion id="d" testable="false">
            <text>A producer field is passivation capable if and only if it never refers to a value which is not passivation capable at runtime.</text>
            <note>Tested in "Validation of passivation capable beans and dependencies" section</note>
        </assertion>

        <group>
            <text>A producer method is passivation capable if and only if it never returns a value which is not passivation capable at runtime.</text>

            <assertion id="caa" testable="false">
                <text>Test that a producer method with a primitive return type is passivation capable.</text>
            </assertion>

            <assertion id="ca">
                <text>Test that a producer method with a serializable return type is passivation capable.</text>
            </assertion>
        </group>

        <group>
            <text>A producer field is passivation capable if and only if it never refers to a value which is not passivation capable at runtime.</text>

            <assertion id="daa">
                <text>Test that a producer field with a primitive type is passivation capable.</text>
            </assertion>

            <assertion id="da">
                <text>Test that a producer field with a serializable type is passivation capable.</text>
            </assertion>

        </group>

        <assertion id="ea">
            <text>A custom implementation of Bean is passivation capable if it implements the interface |PassivationCapable|.</text>
        </assertion>

        <assertion id="f">
            <text>An implementation of |Contextual| that is not a bean is passivation capable if it implements both |PassivationCapable| and |Serializable|.
            </text>
        </assertion>

        <assertion id="g" testable="false">
            <text>The |getId()| method of the |PassivationCapable| implementation must return a value that uniquely identifies the instance of |Bean| or
                |Contextual|.
            </text>
            <note>This is a requirement of the implementation</note>
        </assertion>

        <assertion id="h" testable="false">
            <text>The |getId()| ~method of the |PassivationCapable| implementation must return a value that uniquely identifies the instance of |Bean| or
                |Contextual|. It~ is recommended that the string contain the package name of the class that implements |Bean| or |Contextual|.
            </text>
            <note>Recommendation only</note>
        </assertion>
    </section>

    <section id="passivation_capable_injection_points" title="Passivation capable injection points" level="3">

        <assertion id="a">
            <text>An injection point of a bean is passivation capable if the injection point is a transient field.</text>
        </assertion>

        <assertion id="b">
            <text>An injection point of a bean is passivation capable if the injection point is a non-transient field which resolves to a bean that is a
                passivation capable dependency.
            </text>
        </assertion>

        <assertion id="c">
            <text>An injection point of a bean is passivation capable if the injection point is a bean constructor parameter which is annotated with
                |@TransientReference|.
            </text>
        </assertion>

        <assertion id="d">
            <text>An injection point of a bean is passivation capable if the injection point is a bean constructor parameter which resolves to a bean that is a
                passivation capable dependency.
            </text>
        </assertion>

        <assertion id="e">
            <text>An injection point of a bean is passivation capable if the injection point is a method parameter which is annotated with
                |@TransientReference|.
            </text>
        </assertion>

        <assertion id="f">
            <text>An injection point of a bean is passivation capable if the injection point is a method parameter which resolves to a bean that is a
                passivation capable dependency.
            </text>
        </assertion>

    </section>

    <section id="passivation_capable_dependency" title="Passivation capable dependencies" level="3">

        <assertion id="b">
            <text>The container must guarantee that all beans with normal scope are passivation capable dependencies.</text>
        </assertion>

        <assertion id="c">
            <text>The container must guarantee that all passivation capable beans with scope |@Dependent| are passivation capable dependencies.</text>
        </assertion>

        <group>
            <text>The container must guarantee that the built-in beans of type |Instance|, |Event|, |InjectionPoint| and |BeanManager| are passivation capable
                dependencies.
            </text>
            <assertion id="ea">
                <text>Test built-in |Instance|.</text>
            </assertion>
            <assertion id="eb">
                <text>Test built-in |Event|.</text>
            </assertion>
            <assertion id="ec">
                <text>Test built-in |InjectionPoint|.</text>
            </assertion>
            <assertion id="ed">
                <text>Test built-in |BeanManager|.</text>
            </assertion>
        </group>

        <assertion id="fa">
            <text>A custom implementation of |Bean| is a passivation capable dependency if it implements |PassivationCapable|.</text>
        </assertion>
    </section>

    <section id="passivating_scopes" title="Passivating scopes" level="3">
        <group>
            <text>A passivating scope requires that beans with the scope are passivation capable, and implementations of |Contextual| passed to any context
                object for the scope are passivation capable.
            </text>

            <assertion id="a">
                <text>Test that a bean with the scope is passivation capable.</text>
            </assertion>

            <assertion id="b" testable="false">
                <text>Test that an implementation of |Contextual| passed to the context object for the scope is passivation capable.</text>
                <note>This is in essence enforced by the stuff in 6.6.4</note>
            </assertion>
        </group>

        <assertion id="b" testable="false">
            <text>Passivating scopes must be explicitly declared |@NormalScope(passivating=true)|.</text>
            <note>A statement of intent</note>
        </assertion>
    </section>

    <section id="passivation_validation" title="Validation of passivation capable beans and dependencies" level="3">

        <group>
            <text>If a managed bean which declares a passivating scope, or a built-in bean is not passivation capable then the container automatically detects
                the problem and treats it as a deployment problem.
            </text>
            <assertion id="a">
                <text>Test managed bean.</text>
            </assertion>
        </group>

        <group>
            <text>If a managed bean which declares a passivating scope, or a built-in bean has has an injection point that is not passivation capable, then the
                container automatically detects the problem and treats it as a deployment problem.
            </text>
            <assertion id="aa">
                <text>Test non-transient injected field.</text>
            </assertion>
            <assertion id="ab">
                <text>Test transient injected field.</text>
            </assertion>
            <assertion id="ac">
                <text>Test bean constructor parameter which is not annotated with |@TransientReference|.</text>
            </assertion>
            <assertion id="ad">
                <text>Test bean constructor parameter which is annotated with |@TransientReference|.</text>
            </assertion>
            <assertion id="ae">
                <text>Test initializer method parameter which is not annotated with |@TransientReference|.</text>
            </assertion>
            <assertion id="af">
                <text>Test initializer method parameter which is annotated with |@TransientReference|.</text>
            </assertion>
        </group>

        <assertion id="ag" testable="false">
            <text>If a managed bean which declares a passivating scope, or a built-in bean has a non-transient injected field, bean constructor parameter or
                initializer method parameter that resolves to a bean that is not a dependent scoped bean and that is not a passivation capable dependency then
                the container automatically detects the problem and treats it as a deployment problem.
            </text>
            <note>It's not defined which non-dependent bean is not a passivation capable dependency.</note>
        </assertion>

        <group>
            <text>If a managed bean which declares a passivating scope, or a built-in bean has an interceptor or decorator with a non-transient injected field
                that does not resolve to a passivation capable dependency, then the container automatically detects the problem and treats it as a deployment
                problem.
            </text>
            <assertion id="aac">
                <text>Test interceptor with a non-transient injected field that does not resolve to a passivation capable dependency.</text>
            </assertion>
            <assertion id="aaf">
                <text>Test decorator with a non-transient injected field that does not resolve to a passivation capable dependency.</text>
            </assertion>
        </group>

        <assertion id="ca">
            <text>If a producer method declares a passivating scope and has a return type that is declared final and does not implement or extend |Serializable|
                then the container automatically detects the problem and treats it as a deployment problem.
            </text>
        </assertion>

        <assertion id="ea">
            <text>If a producer method declares a passivating scope and doesn't only return |Serializable| types at runtime, then the container must throw an
                |IllegalProductException|.
            </text>
        </assertion>

        <assertion id="d">
            <text>If a producer field declares a passivating scope and has a type that is declared final and does not implement or extend |Serializable| then
                the container automatically detects the problem and treats it as a deployment problem.
            </text>
        </assertion>

        <assertion id="eb">
            <text>If a producer field declares a passivating scope and doesn't only contain |Serializable| values at runtime then the container must throw
                an|IllegalProductException|.
            </text>
        </assertion>

        <group>
            <text>If a producer method or field of scope |@Dependent| returns an unserializable object for injection into an injection point that requires a
                passivation capable dependency, the container must throw an |IllegalProductException|
            </text>

            <assertion id="fab">
                <text>Test for a runtime exception with a producer method.</text>
            </assertion>

            <assertion id="fbb">
                <text>Test for a runtime exception with a producer field.</text>
            </assertion>
        </group>

        <group>
            <text>For a custom implementation of |Bean|, the container calls |getInjectionPoints()| to determine the injection points, and
                |InjectionPoint.isTransient()| to determine whether the injected point is a transient field.
            </text>

            <assertion id="ga">
                <text>Test calling |getInjectionPoints()|.</text>
            </assertion>

            <assertion id="gb">
                <text>Test calling |InjectionPoint.isTransient()|.</text>
            </assertion>
        </group>

        <group>
            <text>If a bean which declares a passivating scope type has a decorator or interceptor which is not a passivation capable dependency, the container
                automatically detects the problem and treats it as a deployment problem.
            </text>
            <assertion id="ha">
                <text>Test a bean with decorator which is not a passivation capable dependency.</text>
            </assertion>
            <assertion id="hc">
                <text>Test a bean with interceptor which is not a passivation capable dependency.</text>
            </assertion>
        </group>

        <assertion id="k" implied="true">
            <text>Passivation capable interceptor with non-passivation capable dependencies is allowed unless it intercepts a bean declaring passivation
                scope.
            </text>
        </assertion>

        <assertion id="l" implied="true">
            <text>Passivation capable decorator with non-passivation capable dependencies is allowed unless it decorates a bean declaring passivation scope.
            </text>
        </assertion>

    </section>

    <section id="builtin_contexts" title="Context management for built-in scopes" level="2">
        <assertion id="a">
            <text>A portable extension may define a custom context object for any or all of the built-in scopes. For
                example, a remoting framework might provide a request context object for the built-in request scope.
            </text>
        </assertion>

        <assertion id="b">
            <text>The context associated with a built-in normal scope propagates across local, synchronous Java method
                calls. The context does not propagate across remote method invocations or to asynchronous processes.
            </text>
        </assertion>

        <group>
            <text>Portable extensions are encouraged to synchronously fire (where X is the scope type associated with the context.):</text>
            <assertion id="ea" testable="false">
                <text>an event with qualifier @Initialized(X.class) when a custom context is initialized, i.e. ready for
                    use,
                </text>
            </assertion>
            <assertion id="eb" testable="false">
                <text>an event with qualifier @BeforeDestroyed(X.class) when a custom context is about to be destroyed,
                    i.e. before the actual destruction,
                </text>
            </assertion>
            <assertion id="ec" testable="false">
                <text>an event with qualifier @Destroyed(X.class) when a custom context is destroyed, i.e. after the actual
                    destruction,
                </text>
            </assertion>
        </group>

    </section>

    <section id="request_context" title="Request context lifecycle" level="3">
        <assertion id="a">
            <text>An event with qualifier |@Initialized(RequestScoped.class)| is synchronously fired when the request
                context is initialized.
            </text>
        </assertion>

        <assertion id="b">
            <text>An event with qualifier |@BeforeDestroyed(RequestScoped.class)| is synchronously
                fired when the request context is about to be destroyed, i.e. before the actual destruction.
            </text>
        </assertion>

        <assertion id="c">
            <text>An event with qualifier |@Destroyed(RequestScoped.class)| is synchronously fired when the request context is
                destroyed, i.e. after the actual destruction.
            </text>
        </assertion>

        <group>
            <text>The request context is active:</text>
            <assertion id="da">
                <text>during notification of an asynchronous observer method</text>
            </assertion>
            <assertion id="db">
                <text>during |@PostConstruct| callback of any bean.</text>
            </assertion>
        </group>

        <group>
            <text>The request context is destroyed:</text>
            <assertion id="ea">
                <text>after the invocation of an asynchronous observer method completes</text>
            </assertion>
            <assertion id="eb">
                <text>after the |@PostConstruct| callback completes, if it did not already exist when the |@PostConstruct| callback occurred</text>
            </assertion>
        </group>

    </section>

    <section id="session_context" title="Session context lifecycle" level="3">
    </section>

    <section id="application_context" title="Application context lifecycle" level="3">
        <assertion id="a">
            <text>An event with qualifier @Initialized(ApplicationScoped.class) is synchronously fired when the
                application context is initialized.
            </text>
        </assertion>

        <assertion id="b">
            <text>An event with qualifier @BeforeDestroyed(ApplicationScoped.class) is
                synchronously fired when the application context is about to be destroyed, i.e. before the actual
                destruction.
            </text>
        </assertion>

        <assertion id="c">
            <text>An event with qualifier @Destroyed(ApplicationScoped.class) is synchronously fired when
                the application context is destroyed, i.e. after the actual destruction.
            </text>
        </assertion>
    </section>

    <section id="conversation_context" title="Conversation context lifecycle" level="3">
    </section>


    <section id="conversation" title="The Conversation interface" level="3">
        <group>
            <text>The container provides a built-in bean with bean type |Conversation|, scope |@RequestScoped|, and qualifier |@Default|, named
                |jakarta.enterprise.context.conversation|.
            </text>
            <assertion id="iaa">
                <text>Test the bean type is correct.</text>
            </assertion>

            <assertion id="ib">
                <text>Test the scope is correct.</text>
            </assertion>

            <assertion id="id">
                <text>Test the qualifier is correct.</text>
            </assertion>

            <assertion id="ie">
                <text>Test the bean name is correct.</text>
            </assertion>
        </group>

        <assertion id="j">
            <text>|begin()| marks the current transient conversation long-running. A conversation identifier may, optionally, be specified. If no conversation
                identifier is specified, an identifier is generated by the container.
            </text>
        </assertion>

        <assertion id="k">
            <text>|end()| marks the current long-running conversation transient.</text>
        </assertion>

        <assertion id="l">
            <text>|getId()| returns the identifier of the current long-running conversation, or a null value if the current conversation is transient.</text>
        </assertion>

        <assertion id="m">
            <text>|getTimeout()| returns the timeout, in milliseconds, of the current conversation.</text>
        </assertion>

        <assertion id="n">
            <text>|setTimeout()| sets the timeout of the current conversation.</text>
        </assertion>

        <assertion id="o">
            <text>|isTransient()| returns |true| if the conversation is marked transient, or |false| if it is marked long-running.</text>
        </assertion>

        <assertion id="p">
            <text>If any method of |Conversation| is called when the conversation scope is not active, a |ContextNotActiveException| is thrown.</text>
        </assertion>

        <assertion id="q">
            <text>If |end()| is called, and the current conversation is marked transient, an |IllegalStateException| is thrown.</text>
        </assertion>

        <assertion id="r">
            <text>If |begin()| is called, and the current conversation is already marked long-running, an |IllegalStateException| is thrown.</text>
        </assertion>

        <assertion id="s">
            <text>If |begin()| is called with an explicit conversation identifier, and a long-running conversation with that identifier already exists, an
                |IllegalArgumentException| is thrown.
            </text>
        </assertion>
    </section>

    <section id="lifecycle" title="Lifecycle of contextual instances" level="1">
    </section>

    <section id="bean_instantiation_restriction" title="Restriction upon bean instantiation" level="2">
    </section>

    <section id="biz_method" title="Container invocations and interception" level="2">

        <assertion id="aa">
            <text>When the application invokes a method of a bean via a contextual reference to the bean, as defined in Section 6.5.3, "Contextual reference for
                a bean", the invocation is treated as a business method invocation.
            </text>
        </assertion>

        <assertion id="ab">
            <text>When the application invokes a method of a bean via a non-contextual reference to the bean, if the instance was created by the container, the
                invocation is treated as a business method invocation.
            </text>
        </assertion>

        <assertion id="ac">
            <text>When the application invokes a method of a bean via a non-contextual reference to the bean, if the instance was enhanced with
                the |InterceptionFactory| interface as defined in `Apply interceptor programmatically`, the invocation is treated as a business method
                invocation.
            </text>
        </assertion>

        <assertion id="ad">
            <text>Invocations of initializer methods by the container are not business method invocations.</text>
        </assertion>

        <group>
            <text>Invocations of producer, disposer and observer methods by the container are business method invocations are are intercepted by method
                interceptors and decorators.
            </text>

            <assertion id="ia">
                <text>Verify producer methods are intercepted</text>
            </assertion>

            <assertion id="ib">
                <text>Verify producer methods are decorated</text>
            </assertion>

            <assertion id="ic">
                <text>Verify disposer methods are intercepted</text>
            </assertion>

            <assertion id="id">
                <text>Verify disposer methods are decorated</text>
            </assertion>

            <assertion id="ie">
                <text>Verify observer methods are intercepted</text>
            </assertion>

            <assertion id="if">
                <text>Verify observer methods are decorated</text>
            </assertion>
        </group>

        <assertion id="j">
            <text>Invocation of lifecycle callbacks by the container are not business method invocations, but are intercepted by interceptors for lifecycle
                callbacks.
            </text>
        </assertion>

        <group>
            <text>Invocations of interceptors and decorator methods during method or lifecycle callback interception are not business method invocations, and
                therefore no recursive interception occurs.
            </text>
            <assertion id="ka">
                <text>Verify decorators callbacks are not intercepted</text>
            </assertion>

            <assertion id="kb">
                <text>Verify decorators callbacks are not decorated</text>
            </assertion>

            <assertion id="kc">
                <text>Verify interceptor callbacks are not intercepted</text>
            </assertion>

            <assertion id="kd">
                <text>Verify interceptor callbacks are not decorated</text>
            </assertion>
        </group>

        <assertion id="m">
            <text>Invocations of methods declared by |java.lang.Object| are not business method invocations.</text>
        </assertion>

        <group>
            <text>If, and only if, the invocation is a business method invocation it passes through method interceptors and decorators.</text>

            <assertion id="a">
                <text>Verify that a managed bean's business methods are intercepted</text>
            </assertion>

            <assertion id="b">
                <text>Verify that a managed bean's business methods are decorated</text>
            </assertion>

        </group>

        <assertion id="g">
            <text>If the invocation is not a business method invocation, it is treated as a normal Java method call and is not intercepted by the container.
            </text>
        </assertion>

    </section>

    <section id="contextual_instance_lifecycle" title="Lifecycle of contextual instances" level="2">

    </section>

    <section id="managed_bean_lifecycle" title="Lifecycle of managed beans" level="3">
        <assertion id="aa">
            <text>When the |create()| method of the |Bean| object that represents a managed bean is called, the container obtains an instance of the bean, as
                defined by the Managed Beans specification, calling the bean constructor as defined by Section 5.5.1, "Injection using the bean constructor",
                and performing dependency injection as defined in Section 5.5.2, "Injection of fields and initializer methods".
            </text>
        </assertion>

        <assertion id="ba">
            <text>When the |destroy()| method is called, the container destroys the instance, as defined by the Managed Beans specification, and any dependent
                objects, as defined in Section 5.5.3, "Destruction of dependent objects".
            </text>
        </assertion>
    </section>

    <section id="producer_method_lifecycle" title="Lifecycle of producer methods" level="3">
        <assertion id="ea">
            <text>When the create() method of a |Bean| object that represents a producer method is called, the container must invoke the producer method as
                defined by Section 5.5.4, "Invocation of producer or disposer methods". The return value of the producer method, after method interception
                completes, is the new contextual instance to be returned by |Bean.create()|.
            </text>
        </assertion>

        <assertion id="k">
            <text>If the producer method returns a null value and the producer method bean has the scope |@Dependent|, the |create()| method returns a null
                value.
            </text>
        </assertion>

        <assertion id="l">
            <text>If the producer method returns a null value, and the scope of the producer method is not |@Dependent|, the |create()| method throws an
                |IllegalProductException|.
            </text>
        </assertion>

        <assertion id="ma">
            <text>When the |destroy()| method is called, and if there is a disposer method for this producer method, the container must invoke the disposer
                method as defined by Section 5.5.4, "Invocation of producer or disposer methods", passing the instance given to |destroy()| to the disposed
                parameter.
            </text>
        </assertion>

        <assertion id="r">
            <text>Finally, the container destroys dependent objects, as defined in Section 5.5.3, "Destruction of dependent objects".</text>
        </assertion>
    </section>

    <section id="producer_field_lifecycle" title="Lifecycle of producer fields" level="3">
        <assertion id="ga">
            <text>When the |create()| method of a |Bean| object that represents a producer field is called, the container must access the producer field as
                defined by Section 5.5.5, "Access to producer field values" to obtain the current value of the field. The value of the producer field is the new
                contextual instance to be returned by |Bean.create()|.
            </text>
        </assertion>

        <assertion id="m">
            <text>If the producer field contains a null value and the producer field bean has the scope |@Dependent|, the |create()| method returns a null
                value.
            </text>
        </assertion>

        <assertion id="n">
            <text>If the producer field contains a null value, and the scope of the producer method is not |@Dependent|, the |create()| method throws an
                |IllegalProductException|.
            </text>
        </assertion>

        <assertion id="o">
            <text>When the |destroy()| method is called, and if there is a disposer method for this producer field, the container must invoke the disposer
                method as defined by Section 5.5.4, "Invocation of producer or disposer methods", passing the instance given to |destroy()| to the disposed
                parameter.
            </text>
        </assertion>
    </section>

    <section id="decorators" title="Decorators" level="1">
        <assertion id="a" testable="false">
            <text>Decorators may be associated with any managed bean that is not itself an interceptor or decorator, with any EJB session bean or with any
                built-in bean other than the built-in bean with type |BeanManager| and qualifier |@Default|.
            </text>
            <note>Tested elsewhere.</note>
        </assertion>

        <assertion id="b">
            <text>Decorators are not applied to the return value of a producer method or the current value of a producer field.</text>
        </assertion>

        <assertion id="c">
            <text>A decorator instance is a dependent object of the object it decorates.</text>
        </assertion>
    </section>

    <section id="decorator_bean" title="Decorator beans" level="2">
        <assertion id="a" testable="false">
            <text>A decorator is a managed bean.</text>
            <note>Statement of intent</note>
        </assertion>

        <assertion id="b">
            <text>The set of decorated types of a decorator includes all bean types of the managed bean which are Java interfaces, except for
                |java.io.Serializable|.
            </text>
        </assertion>

        <assertion id="c">
            <text>The decorator bean class and its superclasses are not decorated types of the decorator.</text>
        </assertion>

        <assertion id="d">
            <text>The decorator class may be abstract.</text>
        </assertion>

        <assertion id="e">
            <text>If the set of decorated types of a decorator is empty, the container automatically detects the problem and treats it as a definition error.
            </text>
        </assertion>

        <assertion id="f">
            <text>If a decorator declares any scope other than @Dependent, the container automatically detects the problem and treats it as a definition
                error.
            </text>
        </assertion>

    </section>

    <section id="decorator_annotation" title="Declaring a decorator" level="3">
        <assertion id="a">
            <text>A decorator is declared by annotating the bean class with the |@jakarta.decorator.Decorator| stereotype.</text>
        </assertion>
    </section>

    <section id="delegate_attribute" title="Decorator delegate injection points" level="3">
        <assertion id="a">
            <text>All decorators have a delegate injection point. A delegate injection point is an injection point of the bean class. The type and qualifiers of
                the injection point are called the delegate type and delegate qualifiers. The decorator applies to beans that are assignable to the delegate
                injection point. The delegate injection point must be be declared by annotating the injection point with the annotation
                |@jakarta.decorator.Delegate|.
            </text>
        </assertion>

        <group>
            <text>A decorator must have exactly one delegate injection point. If a decorator has more than one delegate injection point, or does not have a
                delegate injection point, the container automatically detects the problem and treats it as a definition error.
            </text>

            <assertion id="ca">
                <text>Test with more than one delegate injection point.</text>
            </assertion>

            <assertion id="cb">
                <text>Test a decorator without a delegate injection point.</text>
            </assertion>
        </group>

        <group>
            <text>The delegate injection point must be an injected field, initializer method parameter or bean constructor method parameter. If an injection
                point that is not an injected field, initializer method parameter or bean constructor method parameter is annotated |@Delegate|, the container
                automatically detects the problem and treats it as a definition error.
            </text>

            <assertion id="cc">
                <text>Check an injected field is ok</text>
            </assertion>

            <assertion id="cd">
                <text>Check an initializer method parameter is ok</text>
            </assertion>

            <assertion id="ce">
                <text>Check a bean constructor method parameter is ok</text>
            </assertion>

            <assertion id="cf">
                <text>Check that a producer method parameter is not ok</text>
            </assertion>

        </group>

        <assertion id="cg">
            <text>If a bean class that is not a decorator has an injection point annotated |@Delegate|, the container automatically detects the problem and
                treats it as a definition error.
            </text>
        </assertion>

        <assertion id="f">
            <text>The container must inject a delegate object to the delegate injection point. The delegate object implements the delegate type and delegates
                method invocations to the remaining uninvoked decorators and eventually to the bean. When the container calls a decorator during business method
                interception, the decorator may invoke any method of the delegate object.
            </text>
        </assertion>

        <assertion id="g">
            <text>If a decorator invokes the delegate object at any other time, the invoked method throws an |IllegalStateException|.</text>
        </assertion>

    </section>

    <section id="decorated_types" title="Decorated types of a decorator" level="3">
        <assertion id="a">
            <text>The delegate type of a decorator must implement or extend every decorated type (with exactly the same type parameters). If the delegate type
                does not implement or extend a decorated type of the decorator (or specifies different type parameters), the container automatically detects the
                problem and treats it as a definition error.
            </text>
        </assertion>

        <assertion id="ab">
            <text>If a decorated type is a parameterized type and the delegate type does not have exactly the same type parameters as the decorated type, the
                container automatically detects the problem and treats it as a definition error.
            </text>
        </assertion>

        <assertion id="b">
            <text>A decorator is not required to implement the delegate type.</text>
        </assertion>

        <assertion id="c">
            <text>A decorator may be an abstract Java class, and is not required to implement every method of every decorated type.</text>
        </assertion>

        <assertion id="ca">
            <text>Whenever the decorator does not implement a method of the decorated type, the container will provide an implicit implementation that calls the
                method on the delegate.
            </text>
        </assertion>

        <assertion id="cb">
            <text>If a decorator has abstract methods that are not declared by a decorated type, the container automatically detects the problem and treats it
                as a definition error.
            </text>
        </assertion>

        <assertion id="d">
            <text>The decorator intercepts every method which is declared by a decorated type of the decorator and is implemented by the bean class of the
                decorator.
            </text>
        </assertion>
    </section>

    <section id="enabled_decorators" title="Decorator enablement and ordering" level="2">

        <assertion id="a" testable="false">
            <text>This specification defines two methods of enabling and ordering decorators. From Contexts and Dependency Injection 1.1 onwards the |@Priority|
                annotation allows a decorator to be enabled and ordered for an entire application. Contexts and Dependency Injection 1.0 allowed only for a
                decorator to be enabled and ordered for a bean archive.
            </text>
            <note>Statement of intent</note>
        </assertion>

        <assertion id="b">
            <text>Decorators are called after interceptors.</text>
        </assertion>

        <assertion id="c">
            <text>Decorators enabled using @Priority are called before decorators enabled using |beans.xml|.</text>
        </assertion>

        <assertion id="d">
            <text>If a decorator is enabled for the application and for the bean archive, then the enablement from the
                bean archive is ignored by the container. The decorator will only be executed once based on the
                @Priority annotation’s invocation chain.
            </text>
        </assertion>
    </section>

    <section id="enabled_decorators_priority" title="Decorator enablement and ordering for an application" level="3">

        <assertion id="a">
            <text>A decorator may be enabled for the entire application by applying the |@Priority| annotation, along with a priority value, on the decorator
                class.
            </text>
        </assertion>

        <assertion id="b">
            <text>Decorators with the smaller priority values are called first.</text>
        </assertion>

        <assertion id="c" testable="false">
            <text>The order of more than one decorator with the same priority is undefined.</text>
            <note>Undefined behaviour.</note>
        </assertion>

        <assertion id="d" testable="false">
            <text>The priority value ranges defined in the Java Interceptors specification section 5.5 should be used when defining decorator priorities.</text>
            <note>No explicit requirement.</note>
        </assertion>

    </section>

    <section id="enabled_decorators_bean_archive" title="Decorator enablement and ordering for a bean archive" level="3">

        <assertion id="a">
            <text>A decorator may be explicitly enabled by listing its bean class under the |&lt;decorators&gt;| element of the beans.xml file of the bean
                archive.
            </text>
        </assertion>

        <assertion id="b">
            <text>The order of the decorator declarations determines the decorator ordering. Decorators which occur earlier in the list are called first.</text>
        </assertion>

        <group>
            <text>Each child |&lt;class&gt;| element must specify the name of a decorator bean class. If there is no class with the specified name, or if the
                class with the specified name is not a decorator bean class, the container automatically detects the problem and treats it as a deployment
                problem.
            </text>
            <assertion id="ca">
                <text>Test with a nonexistent class name.</text>
            </assertion>
            <assertion id="cb">
                <text>Test with a non-decorator class.</text>
            </assertion>
        </group>

        <assertion id="d">
            <text>If the same class is listed twice under the |&lt;decorators&gt;| element, the container automatically detects the problem and treats it as a
                deployment problem.
            </text>
        </assertion>

    </section>

    <section id="decorator_resolution" title="Decorator resolution" level="2">
        <assertion id="aa">
            <text>The process of matching decorators to a certain bean is called decorator resolution. A decorator is bound to a bean if the bean is assignable
                to the delegate injection point according to the rules defined in Section 5.2, "Typesafe resolution", and the decorator is enabled in the bean
                archive containing the bean.
            </text>
        </assertion>

        <assertion id="ab">
            <text>If a decorator matches a managed bean, and the managed bean class is declared final, the container automatically detects the problem and
                treats it as a deployment problem.
            </text>
        </assertion>

        <assertion id="ac">
            <text>If a decorator matches a managed bean with a non-static, non-private, final method, and the decorator also implements that method, the
                container automatically detects the problem and treats it as a deployment problem.
            </text>
        </assertion>

        <assertion id="b">
            <text>For a custom implementation of the |Decorator| interface defined in Section 11.1.1, "The Decorator interface", the container calls
                |getDelegateType()|, |getDelegateQualifiers()| and |getDecoratedTypes()| to determine the delegate type and qualifiers and decorated types of
                the decorator.
            </text>
        </assertion>
    </section>

    <section id="delegate_assignable_parameters" title="Assignability of raw and parameterized types for delegate injection points" level="3">
        <group>
            <text>A raw bean type is considered assignable to a parameterized delegate type if the raw types are identical and all type parameters of the
                delegate type are either unbounded type variables or |java.lang.Object|.
            </text>

            <assertion id="aa">
                <text>Check all type parameters are unbounded type variables</text>
            </assertion>

            <assertion id="ab">
                <text>Check all type parameters are Object</text>
            </assertion>

            <assertion id="ac">
                <text>Check mix</text>
            </assertion>
        </group>

        <group>
            <text>A parameterized bean type is considered assignable to a parameterized delegate type if they have identical raw type and for each parameter:
                the delegate type parameter and the bean type parameter are actual types with identical raw type, and, if the type is parameterized, the bean
                type parameter is assignable to the delegate type parameter according to these rules, or the delegate type parameter is a wildcard, the bean
                type parameter is an actual type and the actual type is assignable to the upper bound, if any, of the wildcard and assignable from the lower
                bound, if any, of the wildcard, or the delegate type parameter is a wildcard, the bean type parameter is a type
                variable and the upper bound of the type variable is assignable to the upper bound, if any, of the wildcard and assignable from the lower bound,
                if any, of the wildcard, or the delegate type parameter and the bean type parameter are both type variables and the upper bound of the bean type
                parameter is assignable to the upper bound, if any, of the delegate type parameter, or the delegate type parameter is a type variable, the bean
                type parameter is an actual type, and the actual type is assignable to the upper bound, if any, of the type variable.
            </text>

            <assertion id="c">
                <text>Check both have identical type parameters</text>
            </assertion>

            <assertion id="d">
                <text>Check nested identical type parameters</text>
            </assertion>

            <assertion id="e">
                <text>Check delegate type parameter is a wildcard, the bean type parameter is an actual type and the actual type is assignable to the upper
                    bound of the wildcard and assignable from the lower bound of the wildcard
                </text>
            </assertion>

            <assertion id="f">
                <text>Check delegate type parameter is a wildcard, the bean type parameter is a type variable and the upper bound of the type variable is
                    assignable to the upper bound of the wildcard and assignable from the lower bound of the wildcard
                </text>
            </assertion>

            <assertion id="g">
                <text>Check the delegate type parameter and the bean type parameter are both type variables and the upper bound of the bean type parameter is
                    assignable to the upper bound of the delegate type parameter
                </text>
            </assertion>

            <assertion id="h">
                <text>Check the delegate type parameter is a type variable, the bean type parameter is an actual type, and the actual type is as- signable to
                    the upper bound of the type variable
                </text>
            </assertion>
        </group>


    </section>

    <section id="decorator_invocation" title="Decorator invocation" level="2">

        <group>
            <text>Whenever a business method is invoked on an instance of a bean with decorators, the container intercepts the business method invocation and,
                after processing all interceptors of the method, invokes decorators of the bean. The container searches for the first decorator of the instance
                that implements the method that is being invoked as a business method. If such decorator exists, the container calls the method of the
                decorator.
            </text>
            <assertion id="aa">
                <text>Test decorator of managed bean is called.</text>
            </assertion>
            <assertion id="aca">
                <text>Test injected Event</text>
            </assertion>
            <assertion id="acb">
                <text>Test injected Instance</text>
            </assertion>
            <assertion id="ach">
                <text>Test injected Conversation</text>
            </assertion>
        </group>

        <assertion id="b">
            <text>If no such decorator exists, the container invokes the business method of the intercepted instance.</text>
        </assertion>

        <assertion id="d">
            <text>When any decorator is invoked by the container, it may in turn invoke a method of the delegate. The container intercepts the delegate
                invocation and searches for the first decorator of the instance such that the decorator occurs after the decorator invoking the delegate, and
                the decorator implements the method that is being invoked upon the delegate.
            </text>
        </assertion>

        <assertion id="e">
            <text>If no such decorator exists, the container invokes the business method of the intercepted instance.</text>
        </assertion>

        <assertion id="f">
            <text>Otherwise, the container calls the method of the decorator.</text>
        </assertion>
    </section>

    <section id="interceptors" title="Interceptor bindings" level="1">
    </section>

    <section id="interceptor_bindings" title="Interceptor binding types" level="2">
    </section>

    <section id="stereotype_interceptor_bindings" title="Interceptor bindings for stereotypes" level="3">
        <assertion id="a">
            <text>Interceptor bindings may be applied to a stereotype by annotating the stereotype annotation.</text>
        </assertion>

        <assertion id="b">
            <text>An interceptor binding declared by a stereotype is inherited by any bean that declares that stereotype.</text>
        </assertion>

        <assertion id="c" testable="false">
            <text>If a stereotype declares interceptor bindings, it must be defined as |@Target(TYPE)|.</text>
            <note>Undefined behaviour.</note>
        </assertion>
    </section>

    <section id="declaring_interceptor" title="Declaring the interceptor bindings of an interceptor" level="2">

    </section>

    <section id="binding_interceptor_to_bean" title="Binding an interceptor to a bean" level="2">

        <assertion id="a">
            <text>Interceptor bindings may be used to associate interceptors with any managed bean that is not a decorator.</text>
        </assertion>

        <assertion id="b">
            <text>The set of interceptor bindings for a method are those declared at class level includes those declared on stereotypes. An interceptor binding
                declared on a bean class replaces an interceptor binding of the same type declared by a stereotype that is applied to the bean class.
            </text>
        </assertion>

        <assertion id="c">
            <text>Since CDI 2.0 it is possible to apply interceptors programmatically to the return value of a producer
                method, with the |InterceptionFactory| interface as defined in `Apply interceptor programmatically`.
            </text>
        </assertion>

        <assertion id="d">
            <text>If a managed bean has a class-level or method-level interceptor binding, the managed bean must be a proxyable bean type, as defined in Section
                "unproxyable".
            </text>
        </assertion>

    </section>

    <section id="enabled_interceptors" title="Interceptor enablement and ordering" level="2">

        <assertion id="a" testable="false">
            <text>This specification extends the Java Interceptors specification and defines support for enabling interceptors only for a bean archive, as
                defined by Contexts and Dependency Injection 1.0, and the ability to override the interceptor order using the portable extension SPI, defined in
                Section "atd".
            </text>
            <note>Statement of intent.</note>
        </assertion>

        <assertion id="b">
            <text>An interceptor may be explicitly enabled for a bean archive by listing its class under the |&lt;interceptors&gt;| element of the |beans.xml|
                file of the bean archive.
            </text>
        </assertion>

        <assertion id="c">
            <text>The order of the interceptor declarations determines the interceptor ordering. Interceptors which occur earlier in the list are called
                first.
            </text>
        </assertion>

        <group>
            <text>Each child |&lt;class&gt;| element must specify the name of an interceptor class. If there is no class with the specified name, or if the
                class with the specified name is not an interceptor class, the container automatically detects the problem and treats it as a deployment
                problem.
            </text>
            <assertion id="da">
                <text>Test with a non-existant class.</text>
            </assertion>
            <assertion id="db">
                <text>Test with a class that isn't an interceptor.</text>
            </assertion>
        </group>

        <assertion id="e">
            <text>If the same class is listed twice under the |&lt;interceptors&gt;| element, the container automatically detects the problem and treats it as a
                deployment problem.
            </text>
        </assertion>

        <assertion id="f">
            <text>Interceptors enabled using |@Priority| are called before interceptors enabled using |beans.xml|.</text>
        </assertion>

        <assertion id="g" implied="true">
            <text>Interceptors declared using interceptor bindings are called after interceptors declared using the |Interceptors| annotation (or using the
                corresponding element of a deployment descriptor).
            </text>
            <note>This is defined in the Interceptors 1.2 spec, 5.1 Defining Interceptor Order.</note>
        </assertion>

        <assertion id="h" implied="true">
            <text>Interceptors declared using interceptor bindings are called before any around-invoke, around-timeout, or lifecycle event callback methods
                declared on the target class or any superclass of the target class.
            </text>
            <note>This is defined in the Interceptors 1.2 spec, 5.1 Defining Interceptor Order.</note>
        </assertion>

        <assertion id="i" implied="true">
            <text>By default, a bean archive has no enabled interceptors.</text>
        </assertion>

        <assertion id="j">
            <text>If an interceptor declares any scope other than @Dependent, the container automatically detects the problem and treats it as a definition
                error.
            </text>
        </assertion>

        <assertion id="k">
            <text>If an interceptor is enabled for the application and for the bean archive, then the enablement from the
                bean archive is ignored by the container. The interceptor will only be executed once based on the
                @Priority annotation’s invocation chain.
            </text>
        </assertion>

    </section>

    <section id="interceptor_resolution" title="Interceptor resolution" level="2">

        <assertion id="a" testable="false">
            <text>This specification extends the Java Interceptors specification and defines the effect of applying |@Nonbinding| to an interceptor binding
                member, and how the interceptor bindings of a custom implementation of the |Interceptor| interface are determined.
            </text>
            <note>Statement of intent.</note>
        </assertion>

        <assertion id="b">
            <text>If any interceptor binding has a member annotated |@jakarta.enterprise.util.Nonbinding|, the member is ignored when performing interceptor
                resolution, and the method does not need to have the same annotation member value.
            </text>
        </assertion>

        <group>
            <text>For a custom implementation of the |Interceptor| interface defined in Section "interceptor", the container calls |getInterceptorBindings()| to
                determine the interceptor bindings of the interceptor and |intercepts()| to determine if the interceptor intercepts a given kind of lifecycle
                callback or business method.
            </text>
            <assertion id="ca">
                <text>Check for @PostConstruct</text>
            </assertion>
            <assertion id="cb">
                <text>Check for @PreDestroy</text>
            </assertion>
            <assertion id="cc">
                <text>Check for @PostActivate</text>
            </assertion>
            <assertion id="cd">
                <text>Check for @PrePassivate</text>
            </assertion>
            <assertion id="ce">
                <text>Check for @AroundInvoke</text>
            </assertion>
            <assertion id="cf">
                <text>Check for @AroundTimeout</text>
            </assertion>
        </group>

    </section>

    <section id="events" title="Events" level="1">
    </section>

    <section id="event_types_and_qualifier_types" title="Event types and qualifier types" level="2">

        <assertion id="aa">
            <text>An event object is an instance of a concrete Java class with no unresolvable type variables.</text>
        </assertion>

        <assertion id="c">
            <text>The event types of the event include all superclasses and interfaces of the runtime class of the event object.</text>
        </assertion>

        <assertion id="cb" testable="false">
            <text>An event type may not contain an unresolvable type variable.</text>
        </assertion>

        <assertion id="d">
            <text>An event qualifier type is a Java annotation defined as |@Target({FIELD, PARAMETER})| or |@Target({METHOD, FIELD, PARAMETER, TYPE})|</text>
        </assertion>

        <assertion id="g">
            <text>All event qualifier types must specify the |@jakarta.inject.Qualifier| meta-annotation</text>
        </assertion>

        <assertion id="i">
            <text>Every event has the qualifier |@jakarta.enterprise.inject.Any|, even if it does not explicitly declare this qualifier.</text>
        </assertion>

        <assertion id="j">
            <text>Any Java type may be an observed event type.</text>
        </assertion>
    </section>

    <section id="firing_events" title="Firing events" level="2">
        <assertion id="a">
            <text>Beans fire events via an instance of the |jakarta.enterprise.event.Event| interface, which may be injected.</text>
        </assertion>

        <assertion id="c">
            <text>Any combination of qualifiers may be specified at the injection point.</text>
        </assertion>

        <assertion id="d">
            <text>Or, the |@Any| qualifier may be used, allowing the application to specify qualifiers dynamically.</text>
        </assertion>

    </section>

    <section id="firing_events_synchronously" title="Firing events synchronously" level="3">

        <assertion id="b">
            <text>The method |fire()| accepts an event object.</text>
        </assertion>

        <assertion id="e">
            <text>Event fired with the fire() method is fired synchronously. All the resolved synchronous observers are called in the thread in which fire() was
                called.
            </text>
        </assertion>

        <assertion id="f">
            <text>A synchronous observer notification blocks the calling thread until it completes.</text>
        </assertion>
    </section>

    <section id="firing_events_asynchronously" title="Firing events asynchronously" level="3">

        <assertion id="a">
            <text>Event fired with the fireAsync() method is fired asynchronously. All the resolved asynchronous observers are called in one or more different
                threads.
            </text>
        </assertion>

    </section>

    <section id="event" title="The Event interface" level="3">
        <assertion id="ca">
            <text>The |Event| interface provides a method for firing events with a specified combination of type and qualifiers.</text>
        </assertion>

        <assertion id="cb">
            <text>For an injected |Event|, the specified type is the type parameter specified at the injection point, and the specified qualifiers are the
                qualifiers specified at the injection point.
            </text>
        </assertion>

        <assertion id="eaa">
            <text>The |select()| method returns a child |Event| for a given specified type and additional specified qualifiers. If no specified type is given,
                the specified type is the same as the parent.
            </text>
        </assertion>

        <assertion id="eab">
            <text>If the specified type contains a type variable, an |IllegalArgumentException| is thrown.</text>
        </assertion>

        <assertion id="eba">
            <text>If two instances of the same non repeating qualifier type are passed to |select()|, an |IllegalArgumentException| is thrown.</text>
        </assertion>

        <assertion id="ec">
            <text>If an instance of an annotation that is not a qualifier type is passed to |select()|, an |IllegalArgumentException| is thrown.</text>
        </assertion>

        <assertion id="eda">
            <text>The method |fire()| and |fireAsync()| fire an event with the specified qualifiers and notifies observers, as defined by Section 10.5,
                "Observer notification".
            </text>
        </assertion>

        <assertion id="edb">
            <text>If the container is unable to resolve the parameterized type of the event object, it uses the specified type to infer the parameterized type
                of the event types.
            </text>
        </assertion>

        <assertion id="ee">
            <text>The method fireAsync() may be called with a |NotificationOptions| object to configure the observer
                methods notification, e.g. to specify an |Executor| object to be used for asynchronous delivery.
            </text>
        </assertion>

        <group>
            <text>The following elements are container specific:</text>
            <assertion id="efa" testable="false">
                <text>the default Executor used by the container when fireAsync() is called without specifying an Executor,</text>
            </assertion>
            <assertion id="efb" testable="false">
                <text>the CompletionStage returned by fireAsync methods,</text>
            </assertion>
            <assertion id="efc" testable="false">
                <text>all dependent stages of this initial CompletionStage.</text>
            </assertion>
        </group>

        <assertion id="f">
            <text>If the runtime type of the event object contains an unresolvable type variable, an |IllegalArgumentException| is thrown.</text>
        </assertion>

        <assertion id="g">
            <text>If the runtime type of the event object is assignable to the type of a container lifecycle event, |IllegalArgumentException| is thrown.</text>
        </assertion>
    </section>

    <section id="builtin_event" title="The built-in Event" level="3">
        <assertion id="a">
            <text>The container must provide a built-in bean with |Event&lt;X&gt;| in its set of bean types, for every Java type |x| that does not contain a
                type variable.
            </text>
        </assertion>

        <assertion id="b">
            <text>The container must provide a built-in bean with every event qualifier type in its set of qualifier types.</text>
        </assertion>

        <assertion id="d">
            <text>The container must provide a built-in bean with scope |@Dependent|.</text>
        </assertion>

        <assertion id="e">
            <text>The container must provide a built-in bean with no bean name.</text>
        </assertion>

        <assertion id="f">
            <text>The container must provide a built-in bean with an implementation provided automatically by the container.</text>
        </assertion>

        <assertion id="e">
            <text>If an injection point of raw type |Event| is defined, the container automatically detects the problem and treats it as a definition error.
            </text>
        </assertion>

        <assertion id="g">
            <text>The built-in implementation must be a passivation capable dependency, as defined in Section 6.6.2, "Passivation capable
                dependencies".
            </text>
        </assertion>
    </section>

    <section id="observer_resolution" title="Observer resolution" level="2">
        <assertion id="a" testable="false">
            <text>The process of matching an event to its observer methods is called observer resolution. The container considers event type and qualifiers when
                resolving observers.
            </text>
            <note>Statement of intent</note>
        </assertion>

        <assertion id="b" testable="false">
            <text>Observer resolution usually occurs at runtime.</text>
            <note>Describes non-portable behavior</note>
        </assertion>

        <group>
            <text>An event is delivered to an observer method if the observer method belongs to an enabled bean, an event type is assignable to the observed
                event type, taking type parameters into consideration, the observer method has no event qualifiers or has a subset of the event qualifiers. An
                observer method has an event qualifier if it has an observed event qualifier with (a) the same type and (b) the same annotation member value for
                each member which is not annotated |@jakarta.enterprise.util.Nonbinding|. Also the event is not a container lifecycle event, as defined in Section
                11.5 "Container lifecycle events", or the observer method belongs to an extension.
            </text>
            <assertion id="c">
                <text>Check an event is delivered if the observer method belongs to an enabled bean, an event type is assignable to the observed event type and
                    has a subset of the event qualifiers.
                </text>
            </assertion>
            <assertion id="d">
                <text>Check an event is not delivered if the observer method belongs to an disabled bean.</text>
            </assertion>
            <assertion id="e">
                <text>Check an event is delivered if the observer method if the event is fired synchronously and the observer is defined with @Observes</text>
            </assertion>
            <assertion id="f">
                <text>Check an event is delivered if the observer method if the event is fired asynchronously and the observer is defined with @ObservesAsync .
                </text>
            </assertion>
        </group>

        <assertion id="j">
            <text>If the runtime type of the event object contains an unresolvable type variable, the container must throw an |IllegalArgumentException|.</text>
        </assertion>

        <assertion id="k">
            <text>For a custom implementation of the |ObserverMethod| interface defined in Section 11.1.3, "The ObserverMethod interface", the container must
                call |getObservedType()| and |getObservedQualifiers()| to determine the observed event type and qualifiers.
            </text>
        </assertion>
    </section>

    <section id="observers_assignability" title="Assignability of type variables, raw and parameterized types" level="3">
        <assertion id="a">
            <text>An event type is considered assignable to a type variable if the event type is assignable to the upper bound, if any.</text>
        </assertion>

        <assertion id="b">
            <text>A parameterized event type is considered assignable to a raw observed event type if the raw types are identical.</text>
        </assertion>

        <group>
            <text>A parameterized event type is considered assignable to a parameterized observed event type if they have identical raw type and for each
                parameter the observed event type parameter is an actual type with identical raw type to the event type parameter, and, if the type is
                parameterized, the event type parameter is assignable to the observed event type parameter according to these rules, or the observed event type
                parameter is a wildcard and the event type parameter is assignable to the upper bound, if any, of the wildcard and assignable from the lower
                bound, if any, of the wildcard, or the observed event type parameter is a type variable and the event type parameter is
                assignable to the upper bound, if any, of the type variable.
            </text>
            <assertion id="c">
                <text>Check the event type parameter and the observed event type parameter are actual types with identical raw type.</text>
            </assertion>
            <assertion id="d">
                <text>Check the event type parameter and the observed event type parameter are actual types with identical raw type for nested type
                    parameters.
                </text>
            </assertion>
            <assertion id="e">
                <text>Check the observed event type parameter is a wildcard and the event type parameter is assignable to the upper bound, if any,
                    of the wildcard and assignable from the lower bound, if any, of the wildcard.
                </text>
            </assertion>
            <assertion id="f">
                <text>Check the observed event type parameter is a type variable and the event type parameter is assignable to the upper bound, if
                    any, of the type variable.
                </text>
            </assertion>
        </group>

    </section>

    <section id="event_qualifier_types_with_members" title="Event qualifier types with members" level="3">
        <assertion id="a">
            <text>The qualifier type for an |Event| qualifier may have annotation members.</text>
        </assertion>

        <assertion id="b" testable="false">
            <text>The container uses |equals()| to compare event qualifier type member values.</text>
            <note>Since only primitive types are allowed, the call to equals() cannot be checked</note>
        </assertion>
    </section>

    <section id="multiple_event_qualifiers" title="Multiple event qualifiers" level="3">
        <assertion id="a">
            <text>An event parameter may have multiple qualifiers.</text>
        </assertion>

        <assertion id="b">
            <text>An observer method will only be notified if all the observed event qualifiers are specified when the event is fired.</text>
        </assertion>

    </section>

    <section id="observer_methods" title="Observer methods" level="2">
        <assertion id="aa" testable="false">
            <text>An observer method allows the application to receive and respond to event notifications.</text>
            <note>A general statement.</note>
        </assertion>

        <assertion id="ab">
            <text>An observer method is a non-abstract method of a managed bean class (or of an extension, as defined in Section 11.5, "Container lifecycle
                events").
            </text>
        </assertion>

        <assertion id="c">
            <text>An observer method may be either static or non-static.</text>
        </assertion>

        <assertion id="e">
            <text>There may be arbitrarily many observer methods with the same event parameter type and qualifiers.</text>
        </assertion>

        <assertion id="f">
            <text>A bean (or extension) may declare multiple observer methods.</text>
        </assertion>
    </section>

    <section id="observer_method_event_parameter" title="Event parameter of an observer method" level="3">
        <assertion id="a">
            <text>Each observer method must have exactly one event parameter, of the same type as the event type it observes. When searching for observer
                methods for an event, the container considers the type and qualifiers of the event parameter
            </text>
        </assertion>

        <assertion id="b">
            <text>If the event parameter does not explicitly declare any qualifier, the observer method observes events with no qualifier.</text>
        </assertion>

        <group>
            <text>The event parameter type may contain a type variable or wildcard.</text>
            <assertion id="ca">
                <text>Test with a type variable.</text>
            </assertion>

            <assertion id="cb">
                <text>Test with a wildcard.</text>
            </assertion>
        </group>

        <group>
            <text>The event parameter may be an array type whose component type contains a type variable or a wildcard.</text>
            <assertion id="da">
                <text>Test with a type variable.</text>
            </assertion>

            <assertion id="db">
                <text>Test with a wildcard.</text>
            </assertion>
        </group>

        <assertion id="e">
            <text>Modifications made to the event parameter in an observer method are propagated to following observers.</text>
        </assertion>

    </section>

    <section id="observes" title="Declaring an observer method" level="3">
        <assertion id="a">
            <text>An observer method may be declared by annotating a parameter |@jakarta.enterprise.event.Observes| or |@jakarta.enterprise.event.ObservesAsync| of
                a default-access, public, protected or private method. That parameter is the event parameter. The declared type of the parameter is the observed
                event type.
            </text>
        </assertion>

        <assertion id="ab">
            <text>If @Observes is used the observer method is a synchronous observer method.</text>
        </assertion>

        <assertion id="ac">
            <text>If @ObservesAsync is used the observer method is an asynchronous observer method.</text>
        </assertion>

        <assertion id="b">
            <text>If a method has more than one parameter annotated |@Observes| or |@ObservesAsync|, the container automatically detects the problem and treats
                it as a definition error.
            </text>
        </assertion>

        <assertion id="ba">
            <text>If a method has a parameter annotated |@Observes| and |@ObservesAsync|, the container automatically
                detects the problem and treats it as a definition error.
            </text>
        </assertion>

        <assertion id="c">
            <text>Observed event qualifiers may be declared by annotating the event parameter.</text>
        </assertion>

        <assertion id="d">
            <text>If an observer method is annotated |@Produces| the container automatically detects the problem and treats it as a definition error.</text>
        </assertion>

        <assertion id="e">
            <text>If an observer method is annotated |@Inject| the container automatically detects the problem and treats it as a definition error.</text>
        </assertion>

        <assertion id="f">
            <text>If an observer method has a parameter annotated |@Disposes|, the container automatically detects the problem and treats it as a definition
                error.
            </text>
        </assertion>

        <assertion id="h">
            <text>Interceptors and decorators may not declare observer methods. If an interceptor or decorator has a method with a parameter annotated
                |@Observes| or |@ObservesAsync|, the container automatically detects the problem and treats it as a definition error.
            </text>
        </assertion>

        <assertion id="i">
            <text>In addition to the event parameter, observer methods may declare additional parameters, which may declare qualifiers. These additional
                parameters are injection points.
            </text>
        </assertion>
    </section>

    <section id="event_metadata" title="The EventMetadata interface" level="3">

        <group>
            <text>The interface |jakarta.enterprise.inject.spi.EventMetadata| provides access to metadata about an observed event.</text>
            <assertion id="a">
                <text>|getQualifiers()| returns the set of qualifiers with which the event was fired.</text>
            </assertion>
            <assertion id="b">
                <text>|getInjectionPoint()| returns the |InjectionPoint| from which this event payload was fired, or |null| if it was fired from
                    |BeanManager.fireEvent()|.
                </text>
            </assertion>
            <assertion id="c">
                <text>|getType()| returns the type representing runtime class of the event object with type variables resolved.</text>
            </assertion>
        </group>

        <assertion id="e">
            <text>The container must provide a bean with scope |@Dependent|, bean type |EventMetadata| and qualifier |@Default|, allowing observer methods to
                obtain information about the events they observe.
            </text>
        </assertion>

        <assertion id="f">
            <text>If an injection point of type |EventMetadata| and qualifier |@Default| which is not a parameter of an observer method exists, the container
                automatically detects the problem and treats it as a definition error.
            </text>
        </assertion>

    </section>

    <section id="conditional_observer_methods" title="Conditional observer methods" level="3">
        <assertion id="a">
            <text>A conditional observer method may be declared by specifying |receive=IF_EXISTS|.</text>
        </assertion>

        <assertion id="b">
            <text>Beans with scope |@Dependent| may not have conditional observer methods. If a bean with scope |@Dependent| has an observer method declared
                |receive=IF_EXISTS|, the container automatically detects the problem and treats it as a definition error.
            </text>
        </assertion>

        <assertion id="c">
            <text>The enumeration |jakarta.enterprise.event.Reception| identifies the possible values of |receive|.</text>
        </assertion>
    </section>

    <section id="transactional_observer_methods" title="Transactional observer methods" level="3">
        <assertion id="a">
            <text>Transactional observer methods are observer methods which receive event notifications during the before or after completion phase of the
                transaction in which the event was fired. If no transaction is in progress when the event is fired, they are notified at the same time as other
                observers
            </text>
        </assertion>

        <assertion id="aa">
            <text>If the transaction is in progress, but |jakarta.transaction.Synchronization| callback cannot be registered due to the transaction being already
                marked for rollback or in state where |jakarta.transaction.Synchronization| callbacks cannot be registered, the before completion, after
                completion and after failure observer methods are notified at the same time as other observers, but
                after success observer methods get skipped.
            </text>
        </assertion>

        <assertion id="b">
            <text>A before completion observer method is called during the before completion phase of the transaction</text>
        </assertion>

        <assertion id="c">
            <text>An after completion observer method is called during the after completion phase of the transaction</text>
        </assertion>

        <assertion id="d">
            <text>An after success observer method is called during the after completion phase of the transaction, only when the transaction completes
                successfully
            </text>
        </assertion>

        <assertion id="e">
            <text>An after failure observer method is called during the after completion phase of the transaction, only when the transaction fails</text>
        </assertion>

        <assertion id="f" testable="false">
            <text>The enumeration |jakarta.enterprise.event.TransactionPhase| identifies the kind of transactional observer method.</text>
            <note>Should we just sigtest this?</note>
        </assertion>

        <assertion id="gaa">
            <text>A transactional observer method may be declared by specifying any value other than |IN_PROGRESS| for |during|.</text>
        </assertion>
    </section>

    <section id="observer_notification" title="Observer notification" level="2">

        <assertion id="aa">
            <text>When an event is fired by the application, the container must determine the observers for that event according to the observer resolution
                defined by Section 10.2, "Observer resolution", then then for each observer method, either invoke the observer method immediately or register
                the observer method for later invocation during the transaction completion phase, using a JTA |Synchronization| and honor the priority of
                observer methods as defined in Section 10.6.2, “Observer ordering”.
            </text>
        </assertion>

        <assertion id="ba" testable="false">
            <text>The container calls observer methods as defined in Section 5.5.6, "Invocation of observer methods".</text>
            <note>Tested in 5.5.6.</note>
        </assertion>

        <assertion id="b">
            <text>If the observer method is a transactional observer method and there is currently a JTA transaction in progress, the container calls the
                observer method during the appropriate transaction completion phase. ~Otherwise, the container calls the observer immediately.~
            </text>
        </assertion>

        <assertion id="bca">
            <text>If there is no context active for the scope to which the bean declaring the observer method belongs, then the observer method should not be
                called.
            </text>
        </assertion>

        <assertion id="bda">
            <text>Any observer method called before completion of a transaction may call |setRollbackOnly()| to force a transaction rollback.</text>
        </assertion>

        <assertion id="bdb" testable="false">
            <text>An observer method may not directly initiate, commit or rollback JTA transactions.</text>
            <note>Doesn't specify what happens if they do</note>
        </assertion>


        <group>
            <text>Observers may throw exceptions:</text>
            <assertion id="ca" testable="false">
                <text>If an observer method is a transactional observer method, any exception is caught and logged by the container.</text>
                <note>We can't verify what is logged</note>
            </assertion>

            <assertion id="cb">
                <text>If the observer method is asynchronous, the exception aborts processing of the observer but not of the event.</text>
            </assertion>

            <assertion id="cd">
                <text>Otherwise, the exception aborts processing of the event. No other observer methods of that event will be called. The
                    BeanManager.fireEvent() or Event.fire() method rethrows the exception. If the exception is a checked exception, it is wrapped and rethrown
                    as an (unchecked) ObserverException.
                </text>
            </assertion>
        </group>

        <group>
            <text>For a custom implementation of the |ObserverMethod| interface defined in Section 11.1.3, "The ObserverMethod interface", the container must
                call |getTransactionPhase()| to determine if the observer method is a transactional observer method, and |notify()| which accepts
                |jakarta.enterprise.inject.spi.EventContext| to invoke the method.
            </text>
            <assertion id="fa">
                <text>Check |getTransactionPhase()| is called.</text>
            </assertion>
            <assertion id="fb">
                <text>Check |notify()| is called.</text>
            </assertion>
        </group>

    </section>

    <section id="async_exception" title="Handling multiple exceptions thrown during an asynchronous event" level="3">
        <assertion id="a">
            <text>If an event is asynchronous, and an exception is thrown by any of its notified observers, the CompletionStage returned by fireAsync will
                complete exceptionally with java.util.concurrent.CompletionException exception.
            </text>
        </assertion>

        <assertion id="b">
            <text>java.util.concurrent.CompletionException contains all exceptions thrown by observers as suppressed exceptions. They can be accessed as an
                array of throwable with the getSuppressed method.
            </text>
        </assertion>
    </section>

    <section id="observer_ordering" title="Observer ordering" level="3">

        <group>
            <text>Before the actual observer notification, the container determines an order in which the observer methods for a certain event are invoked. The
                priority of an observer method may be declared using the @Priority annotation
            </text>
            <assertion id="a">
                <text>If no @Priority annotation is specified, the default priority APPLICATION + 500 is assumed</text>
            </assertion>
            <assertion id="b">
                <text>Observers with smaller priority values are called first</text>
            </assertion>

            <assertion id="c" testable="false">
                <text>The order of more than one observer with the same priority is undefined and the observer methods are notified therefore in a non
                    predictable order.
                </text>
            </assertion>
        </group>

    </section>

    <section id="observer_method_invocation_context" title="Observer method invocation context" level="3">

        <group>
            <text>If the observer method is asynchronous, it is called:</text>
            <assertion id="aa">
                <text>in a new lifecycle contexts.</text>
            </assertion>

            <assertion id="ab">
                <text>in a new transaction context.</text>
            </assertion>
        </group>

        <assertion id="a">
            <text>If the observer method is a before completion transactional observer method, it is called within the context of the transaction that is about
                to complete and with the same client security context and lifecycle contexts.
            </text>
        </assertion>

        <assertion id="b">
            <text>If the observer method is any other kind of transactional observer method, it is called in an unspecified transaction context, but with the
                same client security context and lifecycle contexts as the transaction that just completed.
            </text>
        </assertion>

        <assertion id="c">
            <text>If an observer method is not a before completion transactional method, and not any other kind of transactional observer method, then the
                observer method is called in the same transaction context, client security context and lifecycle contexts as the invocation of |Event.fire()| or
                |BeanManager.fireEvent()|.
            </text>
        </assertion>
    </section>

    <section id="spi" title="Portable extensions" level="1">
        <assertion id="a" testable="false">
            <text>A portable extension may integrate with the container by providing its own beans, interceptors and decorators to the container.</text>
        </assertion>

        <assertion id="b" testable="false">
            <text>A portable extension may integrate with the container by injecting dependencies into its own objects using the dependency injection service.
            </text>
        </assertion>

        <assertion id="c" testable="false">
            <text>A portable extension may integrate with the container by providing a context implementation for a custom scope.</text>
        </assertion>

        <assertion id="f" testable="false">
            <text>Augmenting or overriding the annotation-based metadata with metadata from some other source.</text>
        </assertion>
    </section>

    <section id="bean" title="The Bean interface" level="2">

        <group>
            <text>The |BeanAttributes| interface exposes the basic attributes of a bean.</text>

            <assertion id="ba">
                <text>|getTypes()|, |getQualifiers()|, |getScope()|, |getName()| and |getStereotypes()| must return the bean types, qualifiers, scope type, EL
                    name and stereotypes of the bean, as defined in Chapter 2, Concepts.
                </text>
            </assertion>

            <assertion id="bc">
                <text>|isAlternative()| must return |true| if the bean is an alternative, and |false| otherwise.</text>
            </assertion>

        </group>

        <group>
            <text>The interface |jakarta.enterprise.inject.spi.Bean| defines everything the container needs to manage instances of a certain bean.</text>

            <assertion id="bb">
                <text>|getBeanClass()| returns the bean class of the managed bean or of the bean that declares the producer method or field.</text>
            </assertion>

            <assertion id="c">
                <text>|getInjectionPoints()| returns a set of |InjectionPoint| objects, defined in Section 5.5.7, "Injection point metadata", representing
                    injection points of the bean, that will be validated by the container at initialization time.
                </text>
            </assertion>

            <assertion id="bd" testable="false">
                <text>|isNullable()| is deprecated in CDI 1.1 and should be ignored by the container.</text>
            </assertion>

        </group>

        <assertion id="aa">
            <text>Implementations of |Bean| must also implement the inherited operations defined by the |Contextual| interface defined in Section 6.1, "The
                Contextual interface".
            </text>
        </assertion>

        <assertion id="f">
            <text>An instance of |Bean| exists for every enabled bean.</text>
        </assertion>

        <assertion id="g" testable="false">
            <text>A portable extension may add support for new kinds of beans beyond those defined by the this specification (managed beans, session beans,
                producer methods, producer fields and resources) by implementing |Bean| and registering beans with the container, using the mechanism defined in
                Section 11.5.2, "AfterBeanDiscovery event".
            </text>
        </assertion>
    </section>

    <section id="decorator" title="The Decorator interface" level="3">
        <assertion id="a">
            <text>The |Bean| object for a decorator must implement the interface |jakarta.enterprise.inject.spi.Decorator|.</text>
        </assertion>

        <assertion id="b">
            <text>|getDecoratedTypes()| returns the decorated types of the decorator.</text>
        </assertion>

        <assertion id="c">
            <text>|getDelegateType()| and |getDelegateQualifiers()| return the delegate type and qualifiers of the decorator.</text>
        </assertion>

        <assertion id="d">
            <text>An instance of |Decorator| exists for every enabled decorator.</text>
        </assertion>
    </section>

    <section id="interceptor" title="The Interceptor interface" level="3">
        <assertion id="a">
            <text>The |Bean| object for an interceptor must implement |jakarta.enterprise.inject.spi.Interceptor|.</text>
        </assertion>

        <assertion id="b">
            <text>|getInterceptorBindings()| returns the interceptor bindings of the interceptor.</text>
        </assertion>

        <assertion id="c">
            <text>|intercepts()| returns |true| if the interceptor intercepts the specified kind of lifecycle callback or method invocation, and |false|
                otherwise.
            </text>
        </assertion>

        <assertion id="d">
            <text>|intercept()| invokes the specified kind of lifecycle callback or method invocation interception upon the given instance of the interceptor.
            </text>
        </assertion>

        <assertion id="e">
            <text>An |InterceptionType| identifies the kind of lifecycle callback or business method.</text>
        </assertion>

        <assertion id="f">
            <text>An instance of |Interceptor| exists for every enabled interceptor.</text>
        </assertion>
    </section>

    <section id="observer_method" title="The ObserverMethod interface" level="3">
        <assertion id="a" testable="false">
            <text>The interface |jakarta.enterprise.inject.spi.ObserverMethod| defines everything the container needs to know about an observer method.</text>
        </assertion>

        <assertion id="b">
            <text>|getBeanClass()| returns the bean class of the bean that declares the observer method.</text>
        </assertion>

        <assertion id="c">
            <text>|getObservedType()| and |getObservedQualifiers()| return the observed event type and qualifiers.</text>
        </assertion>

        <assertion id="d">
            <text>|getReception()| returns |IF_EXISTS| for a conditional observer and |ALWAYS| otherwise.</text>
        </assertion>

        <assertion id="e">
            <text>|getTransactionPhase()| returns the appropriate transaction phase for a transactional observer method or |IN_PROGRESS| otherwise.</text>
        </assertion>

        <assertion id="ea">
            <text>|getPriority()| returns the priority that will be used by the container to determine the notification order.</text>
        </assertion>

        <assertion id="f">
            <text>|notify()| calls the observer method, as defined in Section 5.5.6 "Invocation of observer methods".</text>
        </assertion>

        <assertion id="g">
            <text>|isAsync()| returns true if the method is an asynchronous observer method otherwise returns false</text>
        </assertion>

        <assertion id="ga">
            <text>An instance of |ObserverMethod| exists for every observer method of every enabled bean.</text>
        </assertion>
    </section>

    <section id="injectiontarget" title="The Producer and InjectionTarget interfaces" level="2">
        <assertion id="a" testable="false">
            <text>The interface |jakarta.enterprise.inject.spi.Producer| provides a generic operation for producing an instance of a type.</text>
            <note>Statement of intent</note>
        </assertion>

        <group>
            <text>For a |Producer| that represents a class, |produce()| calls the constructor annotated |@Inject| if it exists, or the constructor with no
                parameters otherwise, as defined in Section 5.5.1, "Injection using the bean constructor". and returns the resulting instance. If the class has
                interceptors, |produce()| is responsible for building the interceptors and decorators of the instance.
            </text>
            <assertion id="ba">
                <text>Test field injection occurs</text>
            </assertion>
            <assertion id="bb">
                <text>Test initializer methods called</text>
            </assertion>
            <assertion id="bc">
                <text>Test constructor injected</text>
            </assertion>
            <assertion id="bd">
                <text>Test decorator stack built</text>
            </assertion>
            <assertion id="be">
                <text>Test interceptor stack built</text>
            </assertion>
        </group>


        <assertion id="c">
            <text>For a |Producer| that represents a class, |dispose()| does nothing.</text>
        </assertion>

        <group>
            <text>For a |Producer| that represents a class, |getInjectionPoints()| returns a set of |InjectionPoint| objects representing all injected fields,
                bean constructor parameters and initializer method parameters.
            </text>

            <assertion id="da">
                <text>Test injected fields.</text>
            </assertion>

            <assertion id="db">
                <text>Test bean constructor parameters.</text>
            </assertion>

            <assertion id="dc">
                <text>Test initializer method parameters.</text>
            </assertion>
        </group>

        <group>
            <text>For a |Producer| that represents a producer method or field, |produce()| calls the producer method on, or accesses the producer field of, a
                contextual instance of the bean that declares the producer method, as defined in Section 5.5.4, "Invocation of producer or disposer methods".
            </text>

            <assertion id="eaa">
                <text>Test with producer method.</text>
            </assertion>

            <assertion id="eba">
                <text>Test with producer field.</text>
            </assertion>
        </group>

        <group>
            <text>For a Producer that represents a producer method or field, |dispose()| calls the disposer method, if any, on a contextual instance of the bean
                that declares the disposer method, as defined in Section 5.5.4, "Invocation of producer or disposer methods", or performs any additional
                required cleanup, if any, to destroy state associated with a resource.
            </text>

            <assertion id="faa">
                <text>Test with producer method.</text>
            </assertion>

        </group>

        <assertion id="g">
            <text>For a Producer that represents a producer method, |getInjectionPoints()| returns the set of |InjectionPoint| objects representing all
                parameters of the producer method.
            </text>
        </assertion>

        <assertion id="h" testable="false">
            <text>The subinterface |jakarta.enterprise.inject.spi.InjectionTarget| provides operations for performing dependency injection and lifecycle callbacks
                on an instance of a type.
            </text>
            <note>Statement of intent</note>
        </assertion>

        <assertion id="i">
            <text>|inject()| performs dependency injection upon the given object. The container sets the value of all injected fields, and calls all initializer
                methods, as defined in Section 5.5.2, “Injection of fields and initializer methods”.
            </text>
        </assertion>

        <assertion id="j">
            <text>|postConstruct()| calls the |@PostConstruct| callback, if it exists.</text>
        </assertion>

        <assertion id="k">
            <text>|preDestroy()| calls the |@PreDestroy| callback, if it exists.</text>
        </assertion>

        <assertion id="l" testable="false">
            <text>Implementations of |Producer| and |InjectionTarget| must ensure that the set of injection points returned by |getInjectionPoints()| are
                injected by |produce()| or |inject()|.
            </text>
            <note>Targeting extension developers</note>
        </assertion>

    </section>

    <section id="beanmanager" title="The BeanManager object" level="2">
        <group>
            <text>The container provides a built-in bean with bean type |BeanManager|, scope |@Dependent| and qualifier |@Default|.</text>

            <assertion id="aa">
                <text>Test the bean type.</text>
            </assertion>

            <assertion id="ab">
                <text>Test the scope.</text>
            </assertion>

            <assertion id="ac">
                <text>Test the qualifier.</text>
            </assertion>
        </group>

        <group>
            <text>Exception is thrown if the following operations are called before the AfterBeanDiscovery event is fired:</text>

            <assertion id="ad">
                <text>Test getBeans(String)</text>
            </assertion>

            <assertion id="ae">
                <text>Test getBeans(Type, Annotation...)</text>
            </assertion>

            <assertion id="af">
                <text>Test getPassivationCapableBean(String)</text>
            </assertion>

            <assertion id="ag">
                <text>Test resolve(Set)</text>
            </assertion>

            <assertion id="ah">
                <text>Test resolveDecorators(Set, Annotation...)</text>
            </assertion>

            <assertion id="ai">
                <text>Test resolveInterceptors(InterceptionType, Annotation...)</text>
            </assertion>

            <assertion id="aj">
                <text>Test resolveObserverMethods(Object, Annotation...)</text>
            </assertion>

            <assertion id="ak">
                <text>Test validate(InjectionPoint)</text>
            </assertion>
        </group>
        <group>
            <text>Exception is thrown if the following operations are called before the {@Link AfterDeploymentValidation} event is fired:</text>

            <assertion id="al">
                <text>Test |createInstance()|</text>
            </assertion>

            <assertion id="am">
                <text>Test |getReference(Bean, Type, CreationalContext)|</text>
            </assertion>

            <assertion id="an">
                <text>Test |getInjectableReference(InjectionPoint, CreationalContext)|</text>
            </assertion>
        </group>

        <assertion id="b">
            <text>The built-in implementation must be a passivation capable dependency, as defined in Section 6.6.2, "Passivation capable dependencies".</text>
        </assertion>

        <assertion id="c">
            <text>Any bean may obtain an instance of |BeanManager| by injecting it.</text>
        </assertion>

        <assertion id="e" testable="false">
            <text>Any operation of |BeanManager| may be called at any time during the execution of the application.</text>
            <note>Note that all operations have dedicated assertions.</note>
        </assertion>
    </section>

    <section id="provider" title="Obtaining a reference to the CDI container" level="3">

        <group>
            <text>
                A portable extension or other object may obtain a reference to the current container by calling |CDI.current()|. |CDI.getBeanManager()| may be
                called at any time after the container fires the |BeforeBeanDiscovery| container
                lifecycle event until the container fires the |BeforeShutdown| container lifecycle event. Other methods on CDI may be called after the
                application initialization is completed until the application shutdown starts.
            </text>
            <assertion id="aa">
                <text>Test |CDI.getBeanManager()| is called before the application initialization is completed.</text>
            </assertion>
            <assertion id="ab">
                <text>Test |CDI.getBeanManager()| is called after the application initialization is completed.</text>
            </assertion>
            <assertion id="ac">
                <text>Test lookup of bean instances after the application initialization is completed.</text>
            </assertion>
        </group>

        <assertion id="b">
            <text>
                |CDI| implements |jakarta.enterprise.inject.Instance| and therefore might be used to perform
                programmatic lookup as defined in "The Instance interface". If no qualifier is passed to |CDI.select()|
                method, the |@Default| qualifier is assumed.
            </text>
        </assertion>

        <assertion id="c">
            <text>
                When |CDI.current()| is called, |getCDI()| method is called on |jakarta.enterprise.inject.spi.CDIProvider|.
            </text>
        </assertion>

        <group>
            <text>
                The |CDIProvider| to use may be set by the application or container using the |setCDIProvider()| method. If the |setCDIProvider()| has not been
                called, the service provider with highest priority of the service
                jakarta.enterprise.inject.spi.CDIProvider declared in META-INF/services is used. The order of more
                than one CDIProvider with the same priority is undefined.. If no provider is available an |IllegalStateException| is thrown.
            </text>
            <assertion id="da">
                <text>
                    Test using |CDIProvider| set by the application.
                </text>
                <note>Priority ordering is tested in CDI API.</note>
            </assertion>

        </group>

    </section>

    <section id="bm_obtain_contextual_reference" title="Obtaining a contextual reference for a bean" level="3">
        <assertion id="a">
            <text>The method |BeanManager.getReference()| returns a contextual reference for a given bean and bean type, as defined in Section 6.5.3,
                "Contextual reference for a bean".
            </text>
        </assertion>

        <assertion id="b">
            <text>The first parameter is the |Bean| object representing the bean. The second parameter represents the bean type that must be implemented by any
                client proxy that is returned. The third parameter is an instance of |CreationalContext| that may be used to destroy any object with scope
                |@Dependent| that is created.
            </text>
        </assertion>

        <assertion id="c">
            <text>If the given type is not a bean type of the given bean, an |IllegalArgumentException| is thrown.</text>
        </assertion>
    </section>

    <section id="bm_obtain_injectable_reference" title="Obtaining an injectable reference" level="3">
        <assertion id="a">
            <text>The method |BeanManager.getInjectableReference()| returns an injectable reference for a given injection point, as defined in Section 6.5.5,
                "Injectable references".
            </text>
        </assertion>

        <assertion id="ab">
            <text>The first parameter represents the target injection point. The second parameter is an instance of |CreationalContext| that may be used to
                destroy any object with scope |@Dependent| that is created.
            </text>
        </assertion>

        <assertion id="b">
            <text>If the |InjectionPoint| represents a decorator delegate injection point, |getInjectableReference()| returns a delegate, as defined in Section
                8.1.2, "Decorator delegate injection points".
            </text>
        </assertion>

        <assertion id="bb">
            <text>If typesafe resolution results in an unsatisfied dependency, the container must throw an |UnsatisfiedResolutionException|.</text>
        </assertion>

        <assertion id="bc">
            <text>If typesafe resolution results in an unresolvable ambiguous dependency, the container must throw an |AmbiguousResolutionException|.</text>
        </assertion>

        <assertion id="c">
            <text>Implementations of |Bean| usually maintain a reference to an instance of |BeanManager|. When the |Bean| implementation performs dependency
                injection, it must obtain the contextual instances to inject by calling |BeanManager.getInjectableReference()|, passing an instance of
                |InjectionPoint| that represents the injection point and the instance of |CreationalContext| that was passed to |Bean.create()|.
            </text>
            <note>This cannot be well tested at the moment.</note>
        </assertion>

    </section>

    <section id="bm_obtain_unmanaged_instance" title="Obtaining non-contextual instance" level="3">

        <group>
            <text>A helper class, |Unmanaged| provides a set of methods optimized for working with unmanaged instances.</text>
            <assertion id="a">
                <text>Test creating an injector for the given class, using the current bean manager.</text>
            </assertion>
            <assertion id="b">
                <text>Test creating an injector for the given class.</text>
                <note>Let the container identify the current bean manager.</note>
            </assertion>
        </group>

        <group>
            <text>|UnmanagedInstance| methods throws IllegalStateException in following cases:</text>
            <assertion id="c" implied="true">
                <text>|produce()| is called on an already produced instance.</text>
                <note>CDI-602</note>
            </assertion>
            <assertion id="d" implied="true">
                <text>|produce()| is called on an instance that has already been disposed</text>
                <note>CDI-602</note>
            </assertion>
            <assertion id="e" implied="true">
                <text>|inject()| is called before produce() is called</text>
                <note>CDI-602</note>
            </assertion>
            <assertion id="f" implied="true">
                <text>|inject()| is called on an instance that has already been disposed</text>
                <note>CDI-602</note>
            </assertion>
            <assertion id="g" implied="true">
                <text>|postConstruct()| is called before produce() is called</text>
                <note>CDI-602</note>
            </assertion>
            <assertion id="h" implied="true">
                <text>|postConstruct()| is called on an instance that has already been disposed</text>
                <note>CDI-602</note>
            </assertion>
            <assertion id="i" implied="true">
                <text>|preDestroy()| is called before produce() is called</text>
                <note>CDI-602</note>
            </assertion>
            <assertion id="j" implied="true">
                <text>|preDestroy()| is called on an instance that has already been disposed</text>
                <note>CDI-602</note>
            </assertion>
            <assertion id="k" implied="true">
                <text>|dispose()| is called before produce() is called</text>
                <note>CDI-602</note>
            </assertion>
            <assertion id="l" implied="true">
                <text>|dispose()| is called on an instance that has already been disposed</text>
                <note>CDI-602</note>
            </assertion>
        </group>

    </section>

    <section id="bm_obtain_creationalcontext" title="Obtaining a CreationalContext" level="3">
        <assertion id="a">
            <text>An instance of |CreationalContext| for a certain instance of |Contextual| may be obtained by calling
                |BeanManager.createCreationalContext()|.
            </text>
        </assertion>

        <assertion id="b">
            <text>An instance of |CreationalContext| for a non-contextual object may be obtained by passing a null value to |createCreationalContext()|.</text>
        </assertion>
    </section>

    <section id="bm_obtain_bean_by_type" title="Obtaining a Bean by type" level="3">

        <group>
            <text>The method |BeanManager.getBeans()| returns the set of beans which have the given required type and qualifiers and are available for injection
                in the module or library containing the class into which the |BeanManager| was injected or or the class from whose JNDI environment namespace
                the |BeanManager| was obtained, according to the rules for candidates of typesafe resolution defined in Section 5.2.1, “Performing typesafe
                resolution”.
            </text>
            <assertion id="aa">
                <text>Test simple scenario.</text>
            </assertion>
            <assertion id="ab" implied="true">
                <text>Test alternatives are not filtered.</text>
                <note>CDI-231</note>
            </assertion>
        </group>

        <assertion id="b">
            <text>The first parameter is a required bean type. The remaining parameters are required qualifiers.</text>
        </assertion>

        <assertion id="c">
            <text>If no qualifiers are passed to |getBeans()|, the default qualifier |@Default| is assumed.</text>
        </assertion>

        <assertion id="da">
            <text>If the given type represents a type variable, an |IllegalArgumentException| is thrown.</text>
        </assertion>

        <assertion id="e">
            <text>If two instances of the same non repeating qualifier type are given, an |IllegalArgumentException| is thrown.</text>
        </assertion>

        <assertion id="f">
            <text>If an instance of an annotation that is not a qualifier type is given, an |IllegalArgumentException| is thrown.</text>
        </assertion>

    </section>

    <section id="bm_obtain_bean_by_name" title="Obtaining a Bean by name" level="3">
        <assertion id="aa">
            <text>The method |BeanManager.getBeans()| which accepts a string returns the set of beans which have the given bean name and are available for
                injection in the module or library containing the class into which the |BeanManager| was injected or the class from whose JNDI environment
                namespace the |BeanManager| was obtained, according to the rules of name resolution defined in Section 5.3, "Name resolution".
            </text>
        </assertion>

        <assertion id="b">
            <text>The parameter is a bean name.</text>
        </assertion>
    </section>

    <section id="bm_obtain_passivation_capable_bean" title="Obtaining a passivation capable bean by identifier" level="3">
        <assertion id="a">
            <text>The method |BeanManager.getPassivationCapableBean()| returns the |PassivationCapable| bean with the given identifier (see Section 6.6.1,
                "Passivation capable beans").
            </text>
        </assertion>
    </section>

    <section id="bm_resolve_ambiguous_dep" title="Resolving an ambiguous dependency" level="3">
        <assertion id="a">
            <text>The method |BeanManager.resolve()| applies the ambiguous dependency resolution rules defined in Section 5.2.1, "Unsatisfied and ambiguous
                dependencies" to a set of |Bean|s.
            </text>
        </assertion>

        <assertion id="b">
            <text>If the ambiguous dependency resolution rules fail, the container must throw an |AmbiguousResolutionException|.</text>
        </assertion>

        <group>
            <text>The method |BeanManager.resolve()| must return null, if:</text>
            <assertion id="c">
                <text>null is passed to |resolve()|,</text>
            </assertion>
            <assertion id="d">
                <text>no beans are passed to |resolve()|,</text>
            </assertion>
        </group>

    </section>

    <section id="bm_validate_ip" title="Validating an injection point" level="3">
        <assertion id="a">
            <text>The |BeanManager.validate()| operation validates an injection point and throws an |InjectionException| if there is a deployment problem (for
                example, an unsatisfied or unresolvable ambiguous dependency) associated with the injection point.
            </text>
        </assertion>
    </section>

    <section id="bm_fire_event" title="Firing an event" level="3">
        <assertion id="a">
            <text>The method |BeanManager.fireEvent()| fires an event and notifies observers, according to Section 10.5, "Observer notification".</text>
        </assertion>

        <assertion id="b">
            <text>The first argument is the event object. The remaining parameters are event qualifiers.</text>
        </assertion>

        <assertion id="c">
            <text>If the runtime type of the event object contains a type variable, an |IllegalArgumentException| is thrown.</text>
        </assertion>

        <assertion id="d">
            <text>If two instances of the same non repeating qualifier type are given, an |IllegalArgumentException| is thrown.</text>
        </assertion>

        <assertion id="e">
            <text>If an instance of an annotation that is not a qualifier type is given, an |IllegalArgumentException| is thrown.</text>
        </assertion>

        <assertion id="f">
            <text>If the runtime type of the event object is assignable to the type of a container lifecycle event, |IllegalArgumentException| is thrown.</text>
        </assertion>

    </section>

    <section id="bm_observer_method_resolution" title="Observer method resolution" level="3">
        <assertion id="a">
            <text>The method |BeanManager.resolveObserverMethods()| resolves observer methods for an event according to the rules of observer resolution defined
                in Section 10.4, "Observer resolution".
            </text>
        </assertion>

        <assertion id="b">
            <text>The first parameter of |resolveObserverMethods()| is the event object. The remaining parameters are event qualifiers.</text>
        </assertion>

        <assertion id="c">
            <text>If the runtime type of the event object contains a type variable, an |IllegalArgumentException| is thrown.</text>
        </assertion>

        <assertion id="d">
            <text>If two instances of the same non repeating qualifier type are given, an |IllegalArgumentException| is thrown.</text>
        </assertion>

        <assertion id="e">
            <text>If an instance of an annotation that is not a qualifier type is given, an |IllegalArgumentException| is thrown.</text>
        </assertion>

    </section>

    <section id="bm_decorator_resolution" title="Decorator resolution" level="3">
        <assertion id="a">
            <text>The method |BeanManager.resolveDecorators()| returns the ordered list of decorators for a set of bean types and a set of qualifiers which are
                enabled in the module or library containing the class into which the |BeanManager| was injected or the class from whose JNDI environment
                namespace the |BeanManager| was obtained, as defined in Section 8.3, "Decorator resolution".
            </text>
        </assertion>

        <assertion id="b">
            <text>The first argument is the set of bean types of the decorated bean. The annotations are qualifiers declared by the decorated bean.</text>
        </assertion>

        <assertion id="c">
            <text>If two instances of the same non repeating qualifier type are given, an |IllegalArgumentException| is thrown.</text>
        </assertion>

        <assertion id="d">
            <text>If an instance of an annotation that is not a qualifier type is given, an |IllegalArgumentException| is thrown.</text>
        </assertion>

        <assertion id="e">
            <text>If the set of bean types is empty, an |IllegalArgumentException| is thrown.</text>
        </assertion>

    </section>

    <section id="bm_interceptor_resolution" title="Interceptor resolution" level="3">
        <assertion id="a">
            <text>The method |BeanManager.resolveInterceptors()| returns the ordered list of interceptors for a set of interceptor bindings and a type of
                interception which are enabled in the module or library containing the class into which the |BeanManager| was injected or the class from whose
                JNDI environment namespace the |BeanManager| was obtained, as defined in Section 9.5, "Interceptor resolution".
            </text>
        </assertion>

        <assertion id="b">
            <text>If two instances of the same non repeating interceptor binding type are given, an |IllegalArgumentException| is thrown.</text>
        </assertion>

        <assertion id="c">
            <text>If no interceptor binding type instance is given, an |IllegalArgumentException| is thrown.</text>
        </assertion>

        <assertion id="d">
            <text>If an instance of an annotation that is not an interceptor binding type is given, an |IllegalArgumentException| is thrown.</text>
        </assertion>
    </section>

    <section id="bm_determining_annotation" title="Determining if an annotation is a qualifier type, scope type, stereotype or interceptor binding type"
             level="3">
        <group>
            <text>A portable extension may test an annotation to determine if it is a qualifier type, scope type, stereotype or interceptor binding type, obtain
                the set of meta-annotations declared by a stereotype or interceptor binding type, or determine if a scope type is a normal or passivating scope.
            </text>

            <assertion id="aa">
                <text>Test qualifier type.</text>
            </assertion>

            <assertion id="ab">
                <text>Test scope type.</text>
            </assertion>

            <assertion id="ac">
                <text>Test stereotype.</text>
            </assertion>

            <assertion id="ad">
                <text>Test interceptor binding type.</text>
            </assertion>

            <assertion id="ae">
                <text>Test meta-annotations for stereotype.</text>
            </assertion>

            <assertion id="af">
                <text>Test meta-annotations for interceptor binding type.</text>
            </assertion>

            <assertion id="ag">
                <text>Test obtaining a |ScopeType|.</text>
            </assertion>
        </group>
    </section>

    <section id="bm_determining_hash" title="Determining the hash code and equivalence of qualifiers and interceptor bindings" level="3">
        <group>
            <text>A portable extension may determine if two qualifiers or two interceptor bindings are considered equivalent for the purposes of typesafe
                resolution, as defined in Section 5.2.1, "Performing typesafe resolution".
            </text>
            <assertion id="a">
                <text>Test equivalence of qualifiers using |BeanManager.areQualifiersEquivalent()|.</text>
            </assertion>
            <assertion id="b">
                <text>Test equivalence of interceptor bindings using |BeanManager.areInterceptorBindingsEquivalent()|.</text>
            </assertion>
        </group>
        <group>
            <text>A portable extension may determine the hash code of a qualifier or and interceptor binding, ignoring any members annotated with
                |@Nonbinding|.
            </text>
            <assertion id="c">
                <text>Determine the hash code of a qualifier using |BeanManager.getQualifierHashCode()|.</text>
            </assertion>
            <assertion id="d">
                <text>Determine the hash code of an interceptor binding using |BeanManager.getInterceptorBindingHashCode()|.</text>
            </assertion>
        </group>
    </section>

    <section id="bm_obtain_active_context" title="Obtaining the active Context for a scope" level="3">
        <assertion id="a">
            <text>The method |BeanManager.getContext()| retrieves an active context object associated with the a given scope, as defined in Section 6.5.1, "The
                active context object for a scope".
            </text>
        </assertion>
    </section>

    <section id="bm_obtain_elresolver" title="Obtaining the ELResolver" level="3">
        <assertion id="a">
            <text>The method |BeanManager.getELResolver()| returns the |jakarta.el.ELResolver| specified in Section 12.4, "Integration with Unified EL".</text>
        </assertion>
    </section>

    <section id="bm_obtain_annotatedtype" title="Obtaining an AnnotatedType for a class" level="3">
        <assertion id="a">
            <text>The method |BeanManager.createAnnotatedType()| returns an |AnnotatedType| that may be used to read the annotations of a given Java class or
                interface.
            </text>
        </assertion>
    </section>

    <section id="bm_obtain_injectiontarget" title="Obtaining an InjectionTarget for a class" level="3">

        <group>
            <text>The method |BeanManager.createInjectionTarget()| returns a container provided implementation of |InjectionTarget| for a given |AnnotatedType|
                or throws an |IllegalArgumentException| if there is a definition error associated with any injection point of the type.
            </text>
            <assertion id="aa">
                <text>Check |InjectionTarget| is provided.</text>
            </assertion>

            <assertion id="ab">
                <text>Check |IllegalArgumentException| is thrown.</text>
            </assertion>
        </group>

        <assertion id="b">
            <text>configure() method returns an AnnotatedTypeConfigurator as defined in AnnotatedTypeConfigurator SPI to configure
                the AnnotatedType used to create the InjectionTargetFactory. Subsequent invocations of the configure() method
                within one InjectionTargetFactory instance will always return the same AnnotatedTypeConfigurator instance.
            </text>
        </assertion>

        <assertion id="c">
            <text>Once |createInjectionTarget()| method has been invoked, any invocations of |configure()| throws an |IllegalStateException|.</text>
        </assertion>

    </section>

    <section id="bm_obtain_producer" title="Obtaining a Producer for a field or method" level="3">
        <group>
            <text>The method |BeanManager.createProducer()| returns a container provided implementation of |Producer| for a given |AnnotatedMethod| or
                |AnnotatedField| or throws an |IllegalArgumentException| if there is a definition error associated with the producer method or field.
            </text>
            <assertion id="a">
                <text>Test that the method |BeanManager.createProducer()| returns a container provided implementation of |Producer| for a given
                    |AnnotatedMethod|.
                </text>
            </assertion>
            <assertion id="b">
                <text>Test that the method |BeanManager.createProducer()| returns a container provided implementation of |Producer| for a given
                    |AnnotatedField|.
                </text>
            </assertion>
            <assertion id="c">
                <text>Test that the method |BeanManager.createProducer()| throws an |IllegalArgumentException| if there is a definition error associated with
                    the producer method.
                </text>
            </assertion>
            <assertion id="d">
                <text>Test that the method |BeanManager.createProducer()| throws an |IllegalArgumentException| if there is a definition error associated with
                    the producer field.
                </text>
            </assertion>
        </group>
    </section>

    <section id="bm_obtain_injectionpoint" title="Obtaining an InjectionPoint" level="3">
        <group>
            <text>The method |BeanManager.createInjectionPoint()| returns a container provided implementation of |InjectionPoint| for a given |AnnotatedField|
                or |AnnotatedParameter| or throws an |IllegalArgumentException| if there is a definition error associated with the injection point.
            </text>
            <assertion id="a">
                <text>Test that the method |BeanManager.createInjectionPoint()| returns a container provided implementation of |InjectionPoint| for a given
                    |AnnotatedField|.
                </text>
            </assertion>
            <assertion id="b">
                <text>Test that the method |BeanManager.createInjectionPoint()| returns a container provided implementation of |InjectionPoint| for a given
                    |AnnotatedParameter|.
                </text>
            </assertion>
            <assertion id="c">
                <text>Test that the method |BeanManager.createInjectionPoint()| throws an |IllegalArgumentException| if there is a definition error associated
                    with the injection point.
                </text>
            </assertion>
        </group>
    </section>

    <section id="bm_obtain_beanattributes" title="Obtaining a BeanAttributes" level="3">
        <group>
            <text>The method |BeanManager.createBeanAttributes()| returns a container provided implementation of |BeanAttributes| by reading the annotations of
                a given |AnnotatedType| or |AnnotatedMember|, according to the rules define in |Chapter 2, Concepts|, or throws an |IllegalArgumentException| if
                there is a definition error associated with the declared bean attributes.
            </text>
            <assertion id="a">
                <text>Test that the method |BeanManager.createBeanAttributes()| returns a container provided implementation of |BeanAttributes| by reading the
                    annotations of a given |AnnotatedType|.
                </text>
            </assertion>
            <assertion id="b">
                <text>Test that the method |BeanManager.createBeanAttributes()| returns a container provided implementation of |BeanAttributes| by reading the
                    annotations of a given |AnnotatedMember|.
                </text>
            </assertion>
            <assertion id="c">
                <text>Test that the method |BeanManager.createBeanAttributes()| throws an |IllegalArgumentException| if there is a definition error associated
                    with the declared bean attributes.
                </text>
            </assertion>
        </group>
    </section>

    <section id="bm_obtain_bean" title="Obtaining a Bean" level="3">
        <group>
            <text>The method |BeanManager.createBean()| returns a container provided implementation of |Bean|. The method accepts a |BeanAttributes|, which
                determines the bean types, qualifiers, scope, name and stereotypes of the returned |Bean|, and the return values of |isAlternative()| and
                |isNullable()|, and a class, which determines the return value of |Bean.getClass()|.
            </text>
        </group>
        <assertion id="a">
            <text>Test the first version of the method |BeanManager.createBean()| that also accepts an |InjectionTarget|, which is used to create and destroy
                instances of the bean, to perform dependency injection and lifecycle callbacks, and which determines the return value of
                |Bean.getInjectionPoints()|.
            </text>
        </assertion>
        <assertion id="b">
            <text>Test the second version of the method |BeanManager.createBean()| that also accepts a |Producer|, which is used to create and destroy instances
                of the bean, and which determines the return value of |Bean.getInjectionPoints()|.
            </text>
        </assertion>
    </section>

    <section id="bm_obtain_extension" title="Obtaining the instance of an Extension" level="3">
        <group>
            <text>The method |BeanManager.getExtension()| returns the container's instance of an |Extension| class declared in |META-INF/services|, or throws an
                |IllegalArgumentException| if the container has no instance of the given class.
            </text>
            <assertion id="a">
                <text>Test that the method |BeanManager.getExtension()| returns the container's instance of an |Extension| class declared in
                    |META-INF/services|.
                </text>
            </assertion>
            <assertion id="b">
                <text>Test that the method |BeanManager.getExtension()| throws an |IllegalArgumentException| if the container has no instance of the given
                    class.
                </text>
            </assertion>
        </group>
    </section>

    <section id="bm_obtain_interception_factory" title="Obtain an InterceptionFactory" level="3">
        <assertion id="a">
            <text>
                The method BeanManager.getInterceptionFactory() returns an InterceptionFactory for the provided type
                as defined in `Apply interceptor programmatically`.
            </text>
        </assertion>
    </section>

    <section id="bm_obtain_instance" title="Obtain an Instance" level="3">
        <assertion id="a">
            <text>
                The method |BeanManager.createInstance()| returns an |Instance&lt;Object&gt;| to request bean instances
                programmatically as described in "The Instance interface".
            </text>
        </assertion>
        <assertion id="b">
            <text>
                If no qualifier is passed to |Instance.select()| method, the |@Default| qualifier is assumed.
            </text>
        </assertion>
    </section>

    <section id="alternative_metadata_sources" title="Alternative metadata sources" level="2">
        <assertion id="a" testable="false">
            <text>The interfaces |AnnotatedType|, |AnnotatedField|, |AnnotatedMethod|, |AnnotatedConstructor| and |AnnotatedParameter| in the package
                |jakarta.enterprise.inject.spi| allow a portable extension to specify metadata that overrides the annotations that exist on a bean class. The
                portable extension is responsible for implementing the interfaces, thereby exposing the metadata to the container.
            </text>
            <note>Statement of intent. In fact some assertions in this section do test metadata constructed by container as defined in sections "11.3.18.
                Obtaining an AnnotatedType for a class" and "11.5.6. ProcessAnnotatedType event".
            </note>
        </assertion>

        <group>
            <text>The interface |jakarta.enterprise.inject.spi.AnnotatedType| exposes the |Class| object and members.</text>
            <assertion id="aaa">
                <text>Test that |getConstructors()| returns all default-access, public, protected or private constructors declared for the type.</text>
            </assertion>
            <assertion id="aab">
                <text>Test that |getMethods()| returns all default-access, public, protected or private methods declared on the type and those declared on any
                    supertypes.
                </text>
            </assertion>
            <assertion id="aac">
                <text>The container should call |AnnotatedMethod.getJavaMember().getDeclaringClass()| to determine the type in the type hierarchy that declared
                    the method.
                </text>
            </assertion>
            <assertion id="aad">
                <text>Test that |getFields()| returns all default-access, public, protected or private fields declared on the type and those declared on any
                    supertypes.
                </text>
            </assertion>
        </group>

        <assertion id="b">
            <text>When determining annotations on a type, the container must only consider the special inheritance rules defined for scope types in Section 4.1,
                "Inheritance of type-level metadata".
            </text>
        </assertion>

        <group>
            <text>The interface |jakarta.enterprise.inject.spi.Annotated| exposes the overriding annotations and type declarations.</text>
            <assertion id="c">
                <text>|getBaseType()| returns the type of the program element.</text>
            </assertion>

            <assertion id="d">
                <text>|getTypeClosure()| returns all types to which the base type should be considered assignable.</text>
            </assertion>

            <assertion id="e">
                <text>|getAnnotation()| returns the program element annotation of the given annotation type, or a null value.</text>
            </assertion>

            <assertion id="f">
                <text>|getAnnotations()| returns all annotations of the program element.</text>
            </assertion>

            <assertion id="g">
                <text>|isAnnotationPresent()| returns |true| if the program element has an annotation of the given annotation type, or |false| otherwise.</text>
            </assertion>

        </group>

        <group>
            <text>The container must use the operations of |Annotated| and its subinterfaces to discover program element types and annotations. The container
                must not directly call the Java Reflection API. In particular, the container must call |Annotated.getBaseType()| to determine the type of an
                injection point, event parameter or disposed parameter, call |Annotated.getTypeClosure()| to determine the bean types of any kind of bean, call
                |Annotated.getAnnotations()| to determine the scope, qualifiers, stereotypes and interceptor bindings of a bean, call
                |Annotated.isAnnotationPresent()| and |Annotated.getAnnotation()| to read any bean annotations defined by this specification, and call
                |AnnotatedType.getConstructors()|, |AnnotatedType.getMethods()| and |AnnotatedType.getFields()| to determine the members of a bean class.
            </text>

            <assertion id="h">
                <text>Check that the container uses the operations of |Annotated| and its subinterfaces to discover program element types and annotations. and
                    that the container does not use the Java Reflection API.
                </text>
            </assertion>

            <assertion id="ha">
                <text>Check that |getBaseType()| is used to determine the type of _a field injection point_. The base type should be different from the original
                    type specified in the class definition
                </text>
            </assertion>

            <assertion id="hb">
                <text>Check that |getBaseType()| is used to determine the type of _an initializer method injection point_. The base type should be different
                    from the original type specified in the class definition
                </text>
            </assertion>

            <assertion id="hc">
                <text>Check that |getBaseType()| is used to determine the type of _a constructor injection point_. The base type should be different from the
                    original type specified in the class definition
                </text>
            </assertion>

            <assertion id="hd">
                <text>Check that |getBaseType()| is used to determine the type of _a producer method injection point_. The base type should be different from
                    the original type specified in the class definition
                </text>
            </assertion>

            <assertion id="he">
                <text>Check that |getBaseType()| is used to determine the type of _a observer method injection point_. The base type should be different from
                    the original type specified in the class definition
                </text>
            </assertion>

            <assertion id="hf">
                <text>Check that |getBaseType()| is used to determine the type of _a disposer method injection point_. The base type should be different from
                    the original type specified in the class definition
                </text>
            </assertion>

            <assertion id="i">
                <text>Check that |getBaseType()| is used to determine the type of _an event parameter_. The base type should be different from the original type
                    specified in the class definition
                </text>
            </assertion>

            <assertion id="j">
                <text>Check that |getBaseType()| is used to determine the type of _disposed parameter_. The base type should be different from the original type
                    specified in the class definition
                </text>
            </assertion>

            <assertion id="ka">
                <text>Check that a |getTypeClosure()| is used to determine the bean types for a managed bean. The type closure should be different from the
                    original type specified in the class definition.
                </text>
            </assertion>

            <assertion id="kc">
                <text>Check that a |getTypeClosure()| is used to determine the bean types for a producer field. The type closure should be different from the
                    original type specified in the class definition.
                </text>
            </assertion>

            <assertion id="kd">
                <text>Check that a |getTypeClosure()| is used to determine the bean types for a producer method. The type closure should be different from the
                    original type specified in the class definition.
                </text>
            </assertion>

            <assertion id="l">
                <text>Check that |getAnnotations()| is used to determine the bean scope. The annotations should be different from the original type specified in
                    the class definition.
                </text>
            </assertion>

            <assertion id="m">
                <text>Check that |getAnnotations()| is used to determine the bean qualifiers. The annotations should be different from the original type
                    specified in the class definition.
                </text>
            </assertion>

            <assertion id="n">
                <text>Check that |getAnnotations()| is used to determine the bean stereotypes. The annotations should be different from the original type
                    specified in the class definition.
                </text>
            </assertion>

            <assertion id="p">
                <text>Check that |getAnnotations()| is used to determine the bean interceptors. The annotations should be different from the original type
                    specified in the class definition.
                </text>
            </assertion>

            <assertion id="q" testable="false">
                <text>Check that |isAnnotationPresent()| returns the provided annotations</text>
                <note>No testable behavior</note>
            </assertion>

            <assertion id="r">
                <text>Check that a previously non-inject-annotated constructor is used by the container to instantiate a bean.</text>
            </assertion>

            <assertion id="s">
                <text>Check that a qualifier added to a constructor parameter is used by the container to instantiate a bean.</text>
            </assertion>

            <assertion id="t">
                <text>Check that a previously non-inject-annotated field is injected.</text>
            </assertion>

            <assertion id="u">
                <text>Check that an extra qualifier is applied to a field.</text>
            </assertion>

            <assertion id="v">
                <text>Check that |@Produces| added creates a producer field.</text>
            </assertion>

            <assertion id="w">
                <text>Check that a previously non-inject-annotated method is injected.</text>
            </assertion>

            <assertion id="x">
                <text>Check that an extra qualifier is applied to an injectable method</text>
            </assertion>

            <assertion id="y">
                <text>Check that |@Produces| added creates a producer method</text>
            </assertion>

            <assertion id="z">
                <text>Check that an extra qualifier is applied to a producer method.</text>
            </assertion>

            <assertion id="aa">
                <text>Check that a qualifer added to a producer method parameter is applied.</text>
            </assertion>

            <assertion id="ab">
                <text>Check that |@Disposes| added to a parameter creates a disposes method</text>
            </assertion>

            <assertion id="ac">
                <text>Check that an extra qualifier is applied to a disposes method parameter.</text>
            </assertion>

            <assertion id="ad">
                <text>Check that a qualifer added to a disposes method injectable parameter is applied.</text>
            </assertion>

            <assertion id="ae">
                <text>Check that |@Observes| added to a parameter creates a observer method</text>
            </assertion>

            <assertion id="af">
                <text>Check that an extra qualifier is applied to an observes method parameter.</text>
            </assertion>

            <assertion id="ag">
                <text>Check that a qualifer added to a observes method injectable parameter is applied.</text>
            </assertion>

        </group>
    </section>

    <section id="annotated_type_configurator" title="AnnotatedTypeConfigurator SPI" level="3">

        <group>
            <text>This SPI is composed of the following interfaces:</text>
            <assertion id="aa" testable="false">
                <text>`jakarta.enterprise.inject.spi.builder.AnnotatedTypeConfigurator` to configure an AnnotatedType</text>
            </assertion>
            <assertion id="ab" testable="false">
                <text>`jakarta.enterprise.inject.spi.builder.AnnotatedFieldConfigurator` to configure an AnnotatedField</text>
            </assertion>
            <assertion id="ac" testable="false">
                <text>`jakarta.enterprise.inject.spi.builder.AnnotatedConstructorConfigurator` to configure an AnnotatedConstructor</text>
            </assertion>
            <assertion id="ad" testable="false">
                <text>`jakarta.enterprise.inject.spi.builder.AnnotatedMethodConfigurator` to configure an AnnotatedMethod</text>
            </assertion>
            <assertion id="ae" testable="false">
                <text>`jakarta.enterprise.inject.spi.builder.AnnotatedParameterConfigurator` to configure an AnnotatedParameter</text>
            </assertion>
        </group>


        <group>
            <text>|AnnotatedTypeConfigurator| is the entry point for this SPI.</text>
            <assertion id="bc">
                <text>Test |getAnnotated()| returns the original AnnotatedType with which this configurator was initialized.</text>
            </assertion>

            <assertion id="bd">
                <text>Test |add()| adds an annotation to the configured element.</text>
            </assertion>

            <assertion id="be">
                <text>Test |remove()| method removes annotations that match the specified predicate from the configured element.</text>
            </assertion>

            <assertion id="bf">
                <text>Test |removeAll()| removes all annotations from the configured element.</text>
            </assertion>

            <assertion id="bg">
                <text>Test |methods()| returns a set of |AnnotatedMethodConfigurator| to configure annotations on methods.</text>
            </assertion>

            <assertion id="bh">
                <text>Test |filterMethods()| returns a `Stream &lt; AnnotatedMethodsConfigurator &gt;` filtered by applying the provided Predicate on
                    methods().
                </text>
            </assertion>

            <assertion id="bi">
                <text>Test |fields()| returns a set of |AnnotatedFieldConfigurator| to configure annotations on fields.</text>
            </assertion>

            <assertion id="bj">
                <text>Test |filterFields()| returns a `Stream &lt; AnnotatedFieldConfigurator &gt;` filtered by applying the provided Predicate on fields().
                </text>
            </assertion>

            <assertion id="bk">
                <text>Test |constructors()| returns a set of |AnnotatedConstructorConfigurator| to configure annotations on constructors.</text>
            </assertion>

            <assertion id="bl">
                <text>Test |filterConstructors()| returns a |Stream `&lt;AnnotatedConstructorConfigurator &gt;`| filtered by applying the provided Predicate on
                    Constructors().
                </text>
            </assertion>
        </group>
    </section>

    <section id="annotated_method_configurator" title="AnnotatedMethodConfigurator" level="4">

        <group>
            <text>AnnotatedMethodConfigurator</text>
            <assertion id="a">
                <text>Test |getAnnotated()| returns the original `AnnotatedMethod` with which this configurator was initialized.</text>
            </assertion>

            <assertion id="b">
                <text>Test add() adds an annotation to the configured element.</text>
            </assertion>

            <assertion id="c">
                <text>Test |remove()| method removes annotations that match the specified predicate from the configured element.</text>
            </assertion>

            <assertion id="d">
                <text>Test |removeAll()| removes all annotations from the configured element.</text>
            </assertion>

            <assertion id="e">
                <text>Test |params()| returns a list of AnnotatedParameterConfigurator to configure annotations on parameters.</text>
            </assertion>

            <assertion id="f">
                <text>Test |filterParams(Predicate `&lt; AnnotatedParameter &lt;T &gt;&gt;` predicate)| returns a `Stream &lt;AnnotatedParameterConfigurator&gt;`
                    filtered by applying the provided Predicate on params().
                </text>
            </assertion>
        </group>
    </section>

    <section id="annotated_constructor_configurator" title="AnnotatedConstructorConfigurator" level="4">

        <group>
            <text>AnnotatedConstructorConfigurator</text>
            <assertion id="a">
                <text>Test |getAnnotated()| returns the original `AnnotatedConstructor` with which this configurator was initialized.</text>
            </assertion>

            <assertion id="b">
                <text>Test |add()| adds an annotation to the configured element.</text>
            </assertion>

            <assertion id="c">
                <text>Test |remove()| method removes annotations that match the specified predicate from the configured element.</text>
            </assertion>

            <assertion id="d">
                <text>Test |removeAll()| removes all annotations from the configured element.</text>
            </assertion>

            <assertion id="e">
                <text>Test |params()| returns a list of AnnotatedParameterConfigurator to configure annotations on parameters.</text>
            </assertion>

            <assertion id="f">
                <text>Test |filterParams(Predicate `&lt; AnnotatedParameter &lt;T &gt;&gt;` predicate)| returns a `Stream &lt;AnnotatedParameterConfigurator&gt;`
                    filtered by applying the provided Predicate on params().
                </text>
            </assertion>
        </group>
    </section>

    <section id="annotated_parameter_configurator" title="AnnotatedParameterConfigurator" level="4">
        <group>
            <text>AnnotatedParameterConfigurator</text>
            <assertion id="a">
                <text>Test |getAnnotated()| returns the original `AnnotatedParameter` with which this configurator was initialized.</text>
            </assertion>

            <assertion id="b">
                <text>Test |add()| adds an annotation to the configured element.</text>
            </assertion>

            <assertion id="c">
                <text>Test |remove()| method removes annotations that match the specified predicate from the configured element.</text>
            </assertion>

            <assertion id="d">
                <text>Test |removeAll()| removes all annotations from the configured element.</text>
            </assertion>
        </group>

    </section>

    <section id="annotated_field_configurator" title="AnnotatedFieldConfigurator" level="4">
        <group>
            <text>AnnotatedFieldConfigurator</text>
            <assertion id="a">
                <text>Test |getAnnotated()| returns the original `AnnotatedField` with which this configurator was initialized.</text>
            </assertion>

            <assertion id="b">
                <text>Test |add()| adds an annotation to the configured element.</text>
            </assertion>

            <assertion id="c">
                <text>Test |remove()| method removes annotations that match the specified predicate from the configured element.</text>
            </assertion>

            <assertion id="d">
                <text>Test |removeAll()| removes all annotations from the configured element.</text>
            </assertion>
        </group>

    </section>

    <section id="init_events" title="Container lifecycle events" level="2">
        <assertion id="a" testable="false">
            <text>During the application initialization process, the container fires a series of events, allowing portable extensions to integrate with the
                container initialization process defined in Section 12.2, "Application initialization lifecycle".
            </text>
            <note>Generic statement</note>
        </assertion>

        <assertion id="b">
            <text>Observer methods of these events must belong to extensions. An extension is a service provider of the service
                |jakarta.enterprise.inject.spi.Extension| declared in |META-INF/services|.
            </text>
        </assertion>

        <assertion id="bb">
            <text>Service providers may have observer methods, which may observer any event, including any container lifecycle event, and obtain an injected
                |BeanManager| reference.
            </text>
        </assertion>

        <assertion id="bc">
            <text>An extension may use |BeanManager.fireEvent()| to deliver events to observer methods defined on extensions.</text>
        </assertion>

        <assertion id="bd" testable="false">
            <text>The container is not required to deliver events fired during application initialization to observer methods defined on beans.</text>
            <note>Non-portable behavior</note>
        </assertion>

        <assertion id="be">
            <text>Any decorators associated with BeanManager will not be applied.</text>
        </assertion>

        <assertion id="d">
            <text>The container instantiates a single instance of each extension at the beginning of the application initialization process and maintains a
                reference to it until the application shuts down. The container delivers event notifications to this instance by calling its observer methods.
            </text>
        </assertion>

        <assertion id="da" testable="false">
            <text>
                If an extension declares a static observer method whose event parameter type is a container lifecycle event, or is |java.lang.Object| and the
                event parameter has either no qualifiers or a single qualifier |@Any|, non-portable behavior results.
            </text>
        </assertion>

        <assertion id="e">
            <text>The notification order for observer methods within extensions follows the same ordering rule as defined in Observer ordering for non-extension
                observers. The priority of an observer method may be declared using the @Priority annotation.
            </text>
        </assertion>

        <assertion id="f">
            <text>For each service provider, the container must provide a bean of scope |@ApplicationScoped| and qualifier |@Default|, supporting injection of a
                reference to the service provider instance. The bean types of this bean include the class of the service provider and all superclases and
                interfaces.
            </text>
        </assertion>
    </section>

    <section id="before_bean_discovery" title="BeforeBeanDiscovery event" level="3">
        <assertion id="a">
            <text>The container must fire an event before it begins the bean discovery process. The event object must be of type
                |jakarta.enterprise.inject.spi.BeforeBeanDiscovery|.
            </text>
        </assertion>

        <group>
            <text>|addQualifier()| declares an annotation type as a qualifier type.</text>
            <assertion id="ab">
                <text>Test |Class| method parameter.</text>
            </assertion>
            <assertion id="aba">
                <text>Test |AnnotatedType| method parameter.</text>
            </assertion>
        </group>

        <assertion id="ac">
            <text>|addScope()| declares an annotation type as a scope type.</text>
        </assertion>

        <assertion id="ad">
            <text>|addStereotype()| declares an annotation type as a stereotype, and specifies its meta-annotations.</text>
        </assertion>

        <group>
            <text>|addInterceptorBinding()| declares an annotation type as an interceptor binding type, and specifies its meta-annotations.</text>
            <assertion id="ae">
                <text>Test |Class| method parameter.</text>
            </assertion>
            <assertion id="aea">
                <text>Test |AnnotatedType| method parameter.</text>
            </assertion>
        </group>

        <group>
            <text>|addAnnotatedType()| adds a given |AnnotatedType| to the set of types which will be scanned during bean discovery, with an optional
                identifier.
            </text>
            <assertion id="af">
                <text>Test the |addAnnotatedType()| method.</text>
            </assertion>
            <assertion id="afa">
                <text>Test that more than one |AnnotatedType| may use the same base type.</text>
            </assertion>
            <assertion id="afb">
                <text>Test adding |AnnotatedType| if any other |AnnotatedType| with the same identifier already exists in the set of types.</text>
            </assertion>
        </group>

        <assertion id="b">
            <text>Test |AnnotatedTypeConfigurator&lt;?&gt; addAnnotatedType(String id)| returns a new AnnotatedTypeConfigurator as defined in
                AnnotatedTypeConfigurator interface to easily configure the AnnotatedType which will be added at the end of the observer invocation.
                The returned AnnotatedTypeConfigurator is initialized with type and annotations of the provided class.
            </text>
        </assertion>

        <assertion id="c">
            <text>|configureQualifier()| returns a new |AnnotatedTypeConfigurator| as defined in
                AnnotatedTypeConfigurator SPI to configure a new |AnnotatedType| and declares it as a qualifier type.
            </text>
        </assertion>

        <assertion id="d">
            <text>|configureInterceptorBinding()| returns a new |AnnotatedTypeConfigurator| as defined in
                |AnnotatedTypeConfigurator| SPI to configure a new |AnnotatedType| and declares it as an interceptor
                binding.
            </text>
        </assertion>

        <assertion id="e">
            <text>If any observer method of the |BeforeBeanDiscovery| event throws an exception, the exception is treated as a definition error by the
                container.
            </text>
        </assertion>
        <assertion id="f">
            <text>If any BeforeBeanDiscovery method is called outside of the observer method invocation, an IllegalStateException is thrown.</text>
        </assertion>

    </section>

    <section id="after_type_discovery" title="AfterTypeDiscovery event" level="3">
        <assertion id="a">
            <text>The container must fire an event when it has fully completed the type discovery process and before it begins the bean discovery process. The
                event object must be of type |jakarta.enterprise.inject.spi.AfterTypeDiscovery|.
            </text>
        </assertion>

        <assertion id="b">
            <text>|getAlternatives()| returns list of enabled alternatives for the application, sorted by priority in ascending order. Alternatives enabled for
                a bean archive are not included.
            </text>
        </assertion>

        <assertion id="c">
            <text>|getInterceptors()| returns the list of enabled interceptors for the application, sorted by priority in ascending order. Interceptors enabled
                for a bean archive are not included.
            </text>
        </assertion>

        <assertion id="d">
            <text>|getDecorators()| returns list of enabled decorators for the application, sorted by priority in ascending order. Decorators enabled for a bean
                archive are not included.
            </text>
        </assertion>

        <assertion id="e">
            <text>|addAnnotatedType()| adds a given AnnotatedType to the set of types which will be scanned during bean discovery, with an identifier.</text>
        </assertion>

        <assertion id="ea">
            <text>Test |AnnotatedTypeConfigurator&lt;?&gt; addAnnotatedType(String id)| returns a new AnnotatedTypeConfigurator as defined in
                AnnotatedTypeConfigurator interface to easily configure the AnnotatedType which will be added at the end of observer invocation.
                The returned AnnotatedTypeConfigurator is initialized with type and annotations of the provided class.
            </text>
        </assertion>

        <assertion id="f" testable="false">
            <text>If an alternative, interceptor or decorator is added using |AfterTypeDiscovery.addAnnotatedType()|, non-portable behavior results.</text>
            <note>Non-portable behavior</note>
        </assertion>

        <group>
            <text>Any observer of this event is permitted to add classes to, or remove classes from, the list of alternatives, list of interceptors or list of
                decorators. The container must use the final values of these collections, after all observers of |AfterTypeDiscovery| have been called, to
                determine the order of the enabled alternatives, interceptors, and decorators for application.
            </text>
            <assertion id="ga">
                <text>Test the final values of the list of alternatives.</text>
            </assertion>
            <assertion id="gb">
                <text>Test the final values of the list of interceptors.</text>
            </assertion>
            <assertion id="gc">
                <text>Test the final values of the list of decorators.</text>
            </assertion>
        </group>

        <group>
            <text>The initial values of these collections is defined by the |@Priority| annotation.</text>
            <assertion id="ha">
                <text>Test the initial values of the list of alternatives.</text>
            </assertion>
            <assertion id="hb">
                <text>Test the initial values of the list of interceptors.</text>
            </assertion>
            <assertion id="hc">
                <text>Test the initial values of the list of decorators.</text>
            </assertion>
        </group>

        <assertion id="i">
            <text>If any observer method of an |AfterTypeDiscovery| event throws an exception, the exception is treated as a definition error by the
                container.
            </text>
        </assertion>

        <assertion id="j">
            <text>If any AfterTypeDiscovery method is called outside of the observer method invocation, an IllegalStateException is thrown.</text>
        </assertion>
    </section>

    <section id="after_bean_discovery" title="AfterBeanDiscovery event" level="3">
        <assertion id="a">
            <text>The container must fire an event when it has fully completed the bean discovery process, validated that there are no definition errors
                relating to the discovered beans, and registered |Bean| and |ObserverMethod| objects for the discovered beans, but before detecting deployment
                problems. The event object must be of type |jakarta.enterprise.inject.spi.AfterBeanDiscovery|.
            </text>
        </assertion>

        <assertion id="ca">
            <text>|addDefinitionError()| registers a definition error with the container, causing the container to abort deployment after all observers have
                been notified.
            </text>
        </assertion>

        <group>
            <text>|addBean()| fires an event of type |ProcessSyntheticBean| containing the given |Bean| and then registers the |Bean| with the container,
                thereby making
                it available for injection into other beans. The given |Bean| may implement |Interceptor| or |Decorator|.
            </text>

            <assertion id="da">
                <text>Check that |ProcessSyntheticBean| is fired</text>
            </assertion>

            <assertion id="db">
                <text>Check that a bean is registered</text>
            </assertion>

            <assertion id="dc">
                <text>Check that a decorator is registered</text>
            </assertion>

            <assertion id="dd">
                <text>Check that an interceptor is registered</text>
            </assertion>
        </group>

        <assertion id="de">
            <text>Test |BeanConfigurator&lt;?&gt; addBean()| returns a new BeanConfigurator as defined in BeanConfigurator interface to easily configure the
                Bean which will be added at the end of observer invocation.
            </text>
        </assertion>

        <group>
            <text>|addObserverMethod()| fires an event of type |ProcessSyntheticObserverMethod| containing the given |ObserverMethod| and then registers the
                |ObserverMethod| with the container, thereby making it available for event notifications.
            </text>
            <assertion id="ea">
                <text>Check that the |ProcessSynthethicObserverMethod| is fired</text>
            </assertion>
            <assertion id="eb">
                <text>Check that the observer method is registered</text>
            </assertion>
        </group>

        <assertion id="ec">
            <text>If the given ObserverMethod does not override either |ObserverMethod.notify(T)| or
                |ObserverMethod.notify(EventContext&lt;T&gt;)|, the container automatically detects the problem and treats it as a definition error.
            </text>
        </assertion>

        <assertion id="ed">
            <text>Test |ObserverMethodConfigurator&lt;?&gt; addObserverMethod()| returns a new ObserverMethodConfigurator as defined in
                ObserverMethodConfigurator interface to easily configure the ObserverMethod which will be added at the end of observer invocation.
            </text>
        </assertion>

        <assertion id="ee">
            <text>If the container is unable to process the |ObserverMethodConfigurator| it
                automatically detects the problem and treats it as a deployment problem.
            </text>
        </assertion>

        <assertion id="f">
            <text>|addContext()| registers a custom |Context| object with the container.</text>
            <note>Right now only the registration process is tested</note>
        </assertion>

        <assertion id="g">
            <text>If any observer method of the |AfterBeanDiscovery| event throws an exception, the exception is treated as a definition error by the
                container.
            </text>
        </assertion>

        <assertion id="h">
            <text>|getAnnotatedType()| returns the |AnnotatedType| discovered or added during container initialization. If the |id| passed is null, the
                container should substitute the container generated id.
            </text>
        </assertion>

        <assertion id="i">
            <text>|getAnnotatedTypes()| returns the |AnnotatedType|s discovered or added during container initialization.</text>
        </assertion>

        <assertion id="fb" testable="false">
            <text>A portable extension may take advantage of this event to register beans, interceptors, decorators, observer methods and custom context objects
                with the container.
            </text>
            <note>See d*, e* and f</note>
        </assertion>

        <assertion id="j">
            <text>If any AfterBeanDiscovery method is called outside of the observer method invocation, an IllegalStateException is thrown.</text>
        </assertion>

    </section>

    <section id="bean_configurator" title="BeanConfigurator interface" level="4">
        <group>
            <text>With BeanConfigurator you can perform all the operations defined in BeanAttributesConfigurator interface plus the following:</text>
            <assertion id="aa">
                <text>Initialize the bean metadata with one of its |read()| methods. It can be done from an existing
                    |BeanAttributes| or by reading metadata on a given |AnnotatedType|, according to the rules defined in
                    Concepts.
                </text>
            </assertion>
            <assertion id="ab">
                <text>Set the class of the bean with |beanClass| method.</text>
            </assertion>
            <assertion id="b">
                <text>Add an injection point for the bean with |addInjectionPoint| method.</text>
            </assertion>
            <assertion id="c">
                <text>Add multiple injection points for the bean with |addInjectionPoints| methods.</text>
            </assertion>
            <assertion id="d">
                <text>Replace all injection points for the bean with |injectionPoints| methods.</text>
            </assertion>
            <assertion id="e">
                <text>Make the bean implements `PassivationCapable` and set its id with |id| method.</text>
            </assertion>
            <assertion id="f">
                <text>Set a callback to create a bean instance with createWith() or produceWith() method.</text>
            </assertion>
            <assertion id="g">
                <text>Set a callback to destroy a bean instance with destroyWith() or disposeWith() method.</text>
            </assertion>
        </group>
        <assertion id="h">
            <text>If a |BeanConfigurator| has no scope specified, the default scope rules, defined in the Default Scope rules apply.</text>
        </assertion>
    </section>

    <section id="observer_method_configurator" title="ObserverMethodConfigurator interface" level="4">
        <group>
            <text>`ObserverMethodConfigurator` must be initialized from a `java.lang.reflect.Method`, `AnnotatedMethod` or an existing `ObserverMethod` with one
                of its `read()` methods.
            </text>
            <assertion id="aa">
                <text>Test initialization of `ObserverMethodConfigurator` from a `java.lang.reflect.Method`.</text>
            </assertion>
            <assertion id="ab">
                <text>Test initialization of `ObserverMethodConfigurator` from a `AnnotatedMethod`.</text>
            </assertion>
            <assertion id="ac">
                <text>Test initialization of `ObserverMethodConfigurator` from an existing `ObserverMethod`.</text>
            </assertion>
        </group>

        <group>
            <text>With ObserverMethodConfigurator you can perform the following operations:</text>
            <assertion id="ba">
                <text>Set the `ObserverMethod` bean class with |beanClass| method.</text>
            </assertion>
            <assertion id="baa">
                <text>If the class of the bean is not set, the extension class is used.</text>
                <note>Defined in javadoc of |beanClass| method</note>
            </assertion>
            <assertion id="bb">
                <text>Set the type of the observed event with |observedType| method.</text>
            </assertion>
            <assertion id="bc">
                <text>Add a qualifier with |addQualifier| method.</text>
            </assertion>
            <assertion id="bd">
                <text>Set or add multiple qualifiers with |addQualifiers| and |qualifiers| methods.</text>
            </assertion>
            <assertion id="be">
                <text>Set the `Reception` type with |reception| method.</text>
            </assertion>
            <assertion id="bf">
                <text>Set the `TransactionPhase` type with |transactionPhase| method.</text>
            </assertion>
            <assertion id="bg">
                <text>Set the priority with |priority| method.</text>
            </assertion>
            <assertion id="bh">
                <text>Define the `Consumer` to call on notification with |notifyWith| method.</text>
            </assertion>
            <assertion id="bi">
                <text>Make the observer asynchronous with |async| method.</text>
            </assertion>
        </group>

    </section>

    <section id="after_deployment_validation" title="AfterDeploymentValidation event" level="3">
        <assertion id="a">
            <text>The container must fire an event after it has validated that there are no deployment problems and before creating contexts or processing
                requests. The event object must be of type |jakarta.enterprise.inject.spi.AfterDeploymentValidation|.
            </text>
        </assertion>

        <assertion id="b">
            <text>|addDeploymentProblem()| registers a deployment problem with the container, causing the container to abort deployment after all observers have
                been notified.
            </text>
        </assertion>

        <assertion id="c">
            <text>If any observer method of the |AfterDeploymentValidation| event throws an exception, the exception is treated as a deployment problem by the
                container.
            </text>
        </assertion>

        <assertion id="d">
            <text>The container must not allow any request to be processed by the deployment until all observers of this event return.</text>
        </assertion>

        <assertion id="e">
            <text>If any AfterDeploymentValidation method is called outside of the observer method invocation,an IllegalStateException is thrown.</text>
        </assertion>
    </section>

    <section id="before_shutdown" title="BeforeShutdown event" level="3">
        <assertion id="a">
            <text>The container must fire a final event after it has finished processing requests and destroyed all contexts. The event object must be of type
                |jakarta.enterprise.inject.spi.BeforeShutdown|.
            </text>
        </assertion>

        <assertion id="ba" testable="false">
            <text>If any observer method of the |BeforeShutdown| event throws an exception, the exception is ignored by the container.</text>
            <note>This is not testable in a portable way - the only way would be to check successful undeploy.</note>
        </assertion>
    </section>

    <section id="process_annotated_type" title="ProcessAnnotatedType event" level="3">

        <group>
            <text>The container must fire an event, before it processes a type, for every Java class, interface (excluding the special kind of interface
                declaration annotation type) or enum discovered.
            </text>
            <assertion id="aa">
                <text>Test class discovered in a bean archive.</text>
            </assertion>
            <assertion id="ab">
                <text>Test interface discovered in a bean archive.</text>
            </assertion>
            <assertion id="ac">
                <text>Test enum discovered in a bean archive.</text>
            </assertion>
            <assertion id="ae">
                <text>Test class added by |BeforeBeanDiscovery.addAnnotatedType()|.</text>
            </assertion>
            <assertion id="af">
                <text>Test interface added by |BeforeBeanDiscovery.addAnnotatedType()|.</text>
            </assertion>
            <assertion id="ag">
                <text>Test enum added by |BeforeBeanDiscovery.addAnnotatedType()|.</text>
            </assertion>
            <assertion id="ah">
                <text>Excluding the special kind of interface declaration annotation type.</text>
            </assertion>
        </group>

        <group>
            <text>An event is not fired for any type annotated with |@Vetoed|, or in a package annotated with |@Vetoed|.</text>
            <assertion id="ia">
                <text>Test |@Vetoed| class discovered in a bean archive.</text>
            </assertion>
            <assertion id="ib">
                <text>Test |@Vetoed| interface discovered in a bean archive.</text>
            </assertion>
            <assertion id="ie">
                <text>Test |@Vetoed| class added by |BeforeBeanDiscovery.addAnnotatedType()|.</text>
            </assertion>
            <assertion id="if">
                <text>Test |@Vetoed| interface added by |BeforeBeanDiscovery.addAnnotatedType()|.</text>
            </assertion>
            <assertion id="ii">
                <text>Test |@Vetoed| package.</text>
            </assertion>
        </group>

        <assertion id="j">
            <text>The event object must be of type |jakarta.enterprise.inject.spi.ProcessAnnotatedType&lt;X&gt;|, where X is the class, for types discovered in a
                bean archive, or of type |jakarta.enterprise.inject.spi.ProcessSyntheticAnnotatedType&lt;X&gt;| for types added by
                |BeforeBeanDiscovery.addAnnotatedType()|.
            </text>
        </assertion>

        <group>
            <text>The annotation |@WithAnnotations| may be applied to the event parameter. If the annotation is applied, the container must only deliver
                |ProcessAnnotatedType| events for types which contain at least one of the annotations specified. The annotation can appear on the annotated
                type, or on any member, or any parameter of any member of the annotated type, as defined in Section 11.4.
            </text>
            <assertion id="fa">
                <text>Test annotation on the annotated type.</text>
            </assertion>
            <assertion id="fb">
                <text>Test annotation on the field declared by the annotated type.</text>
            </assertion>
            <assertion id="fc">
                <text>Test annotation on the method declared by the annotated type.</text>
            </assertion>
            <assertion id="fd">
                <text>Test annotation on the constructor declared by the annotated type.</text>
            </assertion>
            <assertion id="fe">
                <text>Test annotation on the parameter of the method declared by the annotated type.</text>
            </assertion>
            <assertion id="ff">
                <text>Test annotation on the parameter of the constructor declared by the annotated type.</text>
            </assertion>
        </group>

        <assertion id="g">
            <text>The annotation may be applied as a meta-annotation on any annotation considered.</text>
        </assertion>

        <assertion id="h">
            <text>If the |@WithAnnotations| annotation is applied to any other event parameter, the container automatically detects the problem and treats it as
                a definition error.
            </text>
        </assertion>

        <assertion id="ba">
            <text>|getAnnotatedType()| returns the |AnnotatedType| object that will be used by the container to read the declared annotations.</text>
        </assertion>

        <assertion id="bb">
            <text>|setAnnotatedType()| replaces the |AnnotatedType|.</text>
        </assertion>

        <assertion id="bba">
            <text>|configureAnnotatedType()| returns an |AnnotatedTypeConfigurator| (as defined in AnnotatedTypeConfigurator interface) initialized with the
                |AnnotatedType| processed by the event to easily configure the AnnotatedType which will be used to replace the original one at the end of
                observer invocation.
            </text>
        </assertion>

        <assertion id="bbb">
            <text>|configureAnnotatedType()| method always returns the same |AnnotatedTypeConfigurator|.
            </text>
        </assertion>

        <assertion id="bc">
            <text>|veto()| forces the container to ignore the type.</text>
        </assertion>

        <assertion id="bd">
            <text>|getSource()| returns the |Extension| instance that added the annotated type.</text>
        </assertion>

        <group>
            <text>Any observer of this event is permitted to wrap and/or replace the |AnnotatedType|. The container must use the final value of this property,
                after all observers have been called, as the only source of types and annotations for the the program elements.
            </text>
            <assertion id="ca">
                <text>Test replacing |AnnotatedType| added by |BeforeBeanDiscovery.addAnnotatedType()|.</text>
            </assertion>
        </group>

        <assertion id="k">
            <text>Any observer of this event is permitted to wrap and/or replace the |AnnotatedType| by calling either |setAnnotatedType()| or
                |configureAnnotatedType()|.
                If both methods are called within an observer notification an |IllegalStateException| is thrown.
            </text>
        </assertion>

        <assertion id="e">
            <text>If any observer method of a |ProcessAnnotatedType| event throws an exception, the exception is treated as a definition error by the
                container.
            </text>
        </assertion>

        <assertion id="f">
            <text>If any ProcessAnnotatedType method is called outside of the observer method invocation, an IllegalStateException is thrown.</text>
        </assertion>
    </section>

    <section id="process_injection_point" title="ProcessInjectionPoint event" level="3">

        <assertion id="a">
            <text>The container must fire an event for every injection point of every bean, interceptor and decorator. The event object must be of type
                |jakarta.enterprise.inject.spi.ProcessInjectionPoint&lt;T, X&gt;| where |T| is the bean class and |X| is the declared type of the injection point.
            </text>
        </assertion>

        <assertion id="ba">
            <text>|getInjectionPoint()| returns the |InjectionPoint| object that will be used by the container to perform injection.</text>
        </assertion>

        <assertion id="bb">
            <text>|setInjectionPoint()| replaces the |InjectionPoint|.</text>
        </assertion>

        <assertion id="bba">
            <text>|configureInjectionPoint()| returns an |InjectionPointConfigurator| (as defined in InjectionPointConfigurator interface) initialized with the
                |InjectionPoint| processed by the event to easily configure the InjectionPoint which will be used to replace the original one at the end of
                observer invocation.
            </text>
        </assertion>

        <assertion id="bbb">
            <text>|configureInjectionPoint()| method always returns the same |InjectionPointConfigurator|.</text>
        </assertion>

        <assertion id="bc">
            <text>|addDefinitionError()| registers a definition error with the container, causing the container to abort deployment after bean discovery is
                complete.
            </text>
        </assertion>

        <assertion id="c">
            <text>Any observer of this event is permitted to wrap and/or replace the |InjectionPoint|. The container must use the final value of this property,
                after all observers have been called, whenever it performs injection upon the injection point.
            </text>
        </assertion>

        <assertion id="g">
            <text>Any observer of this event is permitted to wrap and/or replace the |AnnotatedType| by calling either |setAnnotatedType()| or
                |configureAnnotatedType()|.
                If both methods are called within an observer notification an |IllegalStateException| is thrown.
            </text>
        </assertion>

        <assertion id="d">
            <text>If any observer method of a |ProcessInjectionPoint| event throws an exception, the exception is treated as a definition error by the
                container.
            </text>
        </assertion>

        <assertion id="e">
            <text>If any |ProcessInjectionPoint| method is called outside of the observer method invocation, an |IllegalStateException| is thrown.</text>
        </assertion>

    </section>

    <section id="injection_point_configurator" title="InjectionPointConfigurator interface" level="4">
        <group>
            <text>With |InjectionPointConfigurator| you can perform the following operation:</text>
            <assertion id="ba">
                <text>Set the type of `InjectionPoint` with |type| method.</text>
            </assertion>
            <assertion id="bb">
                <text>Add a qualifier with |addQualifier| method.</text>
            </assertion>
            <assertion id="bc">
                <text>Set or add multiple qualifiers with |addQualifiers| and |qualifiers| methods.</text>
            </assertion>
            <assertion id="be">
                <text>Make the injection point delegate with |delegate| method.</text>
            </assertion>
            <assertion id="bf">
                <text>Make the injection point a transient field with |transientField| method.</text>
            </assertion>
        </group>

    </section>

    <section id="process_injection_target" title="ProcessInjectionTarget event" level="3">
        <group>
            <text>The container must fire an event for every bean, interceptor or decorator. The event object must be of type
                |jakarta.enterprise.inject.spi.ProcessInjectionTarget&lt;X&gt;|, where |x| is the managed bean class.
            </text>
            <assertion id="aaa">
                <text>Test event is fired for a managed bean</text>
            </assertion>
        </group>

        <group>
            <text>|getAnnotatedType()| returns the |AnnotatedType| representing the managed bean class.</text>
            <assertion id="aba">
                <text>Test type for a managed bean</text>
            </assertion>
        </group>

        <assertion id="ba">
            <text>|getInjectionTarget()| returns the |InjectionTarget| object that will be used by the container to perform injection.</text>
        </assertion>

        <assertion id="bb">
            <text>|setInjectionTarget()| replaces the |InjectionTarget|.</text>
        </assertion>

        <assertion id="da">
            <text>|addDefinitionError()| registers a definition error with the container, causing the container to abort deployment after bean discovery is
                complete.
            </text>
        </assertion>

        <group>
            <text>Any observer of this event is permitted to wrap and/or replace the |InjectionTarget|. The container must use the final value of this property,
                after all observers have been called, whenever it performs injection upon the managed bean.
            </text>
            <assertion id="ea">
                <text>Test type for a managed bean</text>
            </assertion>
        </group>

        <assertion id="f">
            <text>If any observer method of a |ProcessInjectionTarget| event throws an exception, the exception is treated as a definition error by the
                container.
            </text>
        </assertion>

        <assertion id="g">
            <text>If any ProcessInjectionTarget method is called outside of the observer method invocation, an IllegalStateException is thrown.</text>
        </assertion>
    </section>

    <section id="process_bean_attributes" title="ProcessBeanAttributes event" level="3">

        <group>
            <text>The container must fire an event for each enabled bean, interceptor or decorator deployed in a bean archive, before registering the |Bean|
                object. No event is fired for any |@New| qualified bean, defined in Section 3.14, "@New qualified beans" or beans added programmatically using
                |AfterBeanDiscovery.addBean()| or for any built-in beans. The event object must be of type |jakarta.enterprise.inject.spi.ProcessBeanAttributes&lt;T&gt;|
                where |T| is the bean class of the bean, the return type of the producer method, or the type of the producer field.
            </text>
            <assertion id="aa">
                <text>Event is fired for enabled bean.</text>
            </assertion>
            <assertion id="ab">
                <text>Event is fired for enabled interceptor.</text>
            </assertion>
            <assertion id="ac">
                <text>Event is fired for enabled decorator.</text>
            </assertion>
            <assertion id="ad">
                <text>No event is fired for any |@New| qualified bean.</text>
            </assertion>
            <assertion id="ae">
                <text>No event is fired for beans added programmatically using |AfterBeanDiscovery.addBean()|.</text>
            </assertion>
            <assertion id="af">
                <text>No event is fired for any built-in bean.</text>
            </assertion>
        </group>

        <group>
            <text>|getAnnotated()| returns the |AnnotatedType| representing the bean class, the |AnnotatedMethod| representing the producer field, or the
                |AnnotatedField| representing the producer field.
            </text>
            <assertion id="baa">
                <text>Test managed bean.</text>
            </assertion>
            <assertion id="bac">
                <text>Test producer method.</text>
            </assertion>
            <assertion id="bad">
                <text>Test producer field.</text>
            </assertion>
        </group>

        <assertion id="bb">
            <text>|getBeanAttributes()| returns the |BeanAttributes| object that will be used by the container to manage instances of the bean.</text>
        </assertion>

        <assertion id="bc">
            <text>|setBeanAttributes()| replaces the |BeanAttributes|.</text>
        </assertion>

        <assertion id="bca">
            <text>|configureBeanAttributes()| returns a |BeanAttributesConfigurator| (as defined in BeanAttributesConfigurator interface) initialized with the
                |BeanAttributes| processed by the event to easily configure the |BeanAttributes| which will be used to replace the original one at the end of
                observer invocation.
            </text>
        </assertion>

        <assertion id="bcb">
            <text>|configureBeanAttributes()| method always returns the same |BeanAttributesConfigurator|</text>
        </assertion>

        <assertion id="bd">
            <text>|addDefinitionError()| registers a definition error with the container, causing the container to abort deployment after bean discovery is
                complete.
            </text>
        </assertion>

        <assertion id="be">
            <text>|veto()| forces the container to ignore the bean.</text>
        </assertion>

        <assertion id="bf">
            <text>|ignoreFinalMethods()| method instructs the container to ignore all non-static, final methods with public,
                protected or default visibility declared on any bean type of the specific bean during validation of
                injection points that require proxyable bean type. These method should never be invoked upon
                bean instances. Otherwise, unpredictable behavior results. It will bypass standard rules defined in
                Unproxyable bean types.
            </text>
        </assertion>

        <group>
            <text>Any observer of this event is permitted to wrap and/or replace the |BeanAttributes|. The container must use the final value of this property,
                after all observers have been called, to manage instances of the bean. Changes to BeanAttributes are not propagated to the annotated type from
                which the bean definition was created.
            </text>
            <assertion id="ca">
                <text>Test the final value of this property is used.</text>
            </assertion>
            <assertion id="cc">
                <text>Test the changes are not propagated.</text>
            </assertion>
        </group>

        <assertion id="d">
            <text>If any observer method of a |ProcessBeanAttributes| event throws an exception, the exception is treated as a definition error by the
                container.
            </text>
        </assertion>

        <assertion id="g">
            <text>Any observer of this event is permitted to wrap and/or replace the |AnnotatedType| by calling either |setAnnotatedType()| or
                |configureAnnotatedType()|.
                If both methods are called within an observer notification an |IllegalStateException| is thrown.
            </text>
        </assertion>

        <assertion id="e">
            <text>Any bean which has its bean attributes altered must have it’s definition validated during deployment validation.</text>
        </assertion>

        <assertion id="f">
            <text>If any ProcessBeanAttributes method is called outside of the observer method invocation, an IllegalStateException is thrown.</text>
        </assertion>
    </section>

    <section id="bean_attributes_configurator" title="BeanAttributesConfigurator interface" level="4">
        <assertion id="a">
            <text>|BeanAttributesConfigurator| is obtainable during |ProcessBeanAttributes| event and is therefore
                automatically initialized from existing |BeanAttributes|.
            </text>
        </assertion>

        <group>
            <text>With `BeanAttributesConfigurator` you can perform the following operation:</text>
            <assertion id="ba">
                <text>Add type with |addType| or |addTransitiveTypeClosure| methods.</text>
            </assertion>
            <assertion id="bb">
                <text>Set multiple types with |types| methods.</text>
            </assertion>
            <assertion id="bc">
                <text>Set scope with |scope| method.</text>
            </assertion>
            <assertion id="bd">
                <text>Add a qualifier with |addQualifier| method.</text>
            </assertion>
            <assertion id="be">
                <text>Set or add multiple qualifiers with |addQualifiers| and |qualifiers| methods.</text>
            </assertion>
            <assertion id="bf">
                <text>Add a stereotype with |addStereotype| method.</text>
            </assertion>
            <assertion id="bg">
                <text>Set or add multiple stereotypes with |addStereotypes| and |stereotypes| methods.</text>
            </assertion>
            <assertion id="bh">
                <text>Set the bean name |name| method.</text>
            </assertion>
            <assertion id="bi">
                <text>Make the bean an alternative with |alternative| methods.</text>
            </assertion>
        </group>

    </section>

    <section id="process_bean" title="ProcessBean event" level="3">
        <assertion id="aa">
            <text>The container must fire an event for each bean, interceptor or decorator deployed in a bean archive, after firing the |ProcessBeanAttributes|
                for the bean and before registering the |Bean| object. No event is fired for any |@New| qualified bean, defined in Section 3.12, "@New qualified
                beans".
            </text>
        </assertion>

        <assertion id="ba">
            <text>For a managed bean with bean class |X|, the container must raise an event of type |ProcessManagedBean&lt;X&gt;|.</text>
        </assertion>

        <assertion id="bb">
            <text>Test |ProcessManagedBean| is fired after |ProcessBeanAttributes|.</text>
        </assertion>

        <assertion id="eaa">
            <text>For a producer method with method return type |X| of a bean with bean class |T|, the container must raise an event of type
                |ProcessProducerMethod&lt;T, X&gt;|.
            </text>
        </assertion>

        <assertion id="eab">
            <text>Test |ProcessProducerMethod| is fired after |ProcessBeanAttributes|.</text>
        </assertion>

        <assertion id="eba">
            <text>For a producer field with field type |X| of a bean with bean class |T|, the container must raise an event of type |ProcessProducerField&lt;T,
                X&gt;|.
            </text>
        </assertion>

        <assertion id="ebb">
            <text>Test |ProcessProducerField| is fired after |ProcessBeanAttributes|.</text>
        </assertion>

        <assertion id="eca">
            <text>For a custom implementation of |Bean|, the container must raise an event of type |ProcessSyntheticBean &lt;X&gt;|.</text>
        </assertion>

        <assertion id="ec">
            <text>Resources are considered to be producer fields.</text>
        </assertion>

        <group>
            <text>The interface |jakarta.enterprise.inject.spi.ProcessBean| is a supertype of all these event types.</text>
            <assertion id="eda">
                <text>Test |ProcessManagedBean|</text>
            </assertion>
            <assertion id="edc">
                <text>Test |ProcessProducerMethod|</text>
            </assertion>
            <assertion id="edd">
                <text>Test |ProcessProducerField|</text>
            </assertion>
        </group>

        <group>
            <text>|getAnnotated()| returns the |AnnotatedType| representing the bean class, the |AnnotatedMethod| representing the producer method, or the
                |AnnotatedField| representing the producer field. If invoked upon a |ProcessSyntheticBean| event, non-portable behavior results and the returned
                value
                should be ignored.
            </text>
            <assertion id="efa">
                <text>Test |ProcessManagedBean|</text>
            </assertion>
            <assertion id="efc">
                <text>Test |ProcessProducerMethod|</text>
            </assertion>
            <assertion id="efd">
                <text>Test |ProcessProducerField|</text>
            </assertion>
        </group>

        <group>
            <text>|getBean()| returns the |Bean| object that is about to be registered. The |Bean| may implement |Interceptor| or |Decorator|.</text>
            <assertion id="fa">
                <text>Test |ProcessManagedBean|</text>
            </assertion>
            <assertion id="fc">
                <text>Test |ProcessProducerMethod|</text>
            </assertion>
            <assertion id="fd">
                <text>Test |ProcessProducerField|</text>
            </assertion>
        </group>

        <assertion id="h">
            <text>|addDefinitionError()| registers a definition error with the container, causing the container to abort deployment after bean discovery is
                complete.
            </text>
        </assertion>

        <assertion id="hd">
            <text>If any observer method of a |ProcessBean| event throws an exception, the exception is treated as a definition error by the container.</text>
        </assertion>

        <assertion id="i" implied="true">
            <text>Check the |getAnnotatedProducerMethod()|</text>
        </assertion>

        <assertion id="j" implied="true">
            <text>Check the |getAnnotatedDisposesParameter()|</text>
        </assertion>

        <group>
            <text>Check the |getAnnotatedBeanClass()|</text>
            <assertion id="l" implied="true">
                <text>Check for managed bean</text>
            </assertion>
        </group>

        <assertion id="n" implied="true">
            <text>Check the |getAnnotatedProducerField()|</text>
        </assertion>

        <assertion id="o">
            <text>If any ProcessBean method is called outside of the observer method invocation, an IllegalStateException is thrown.</text>
        </assertion>

    </section>

    <section id="process_producer" title="ProcessProducer event" level="3">
        <group>
            <text>The container must fire an event for each producer method or field of each enabled bean, including resources.</text>
            <assertion id="aa">
                <text>Test producer method</text>
            </assertion>
            <assertion id="ab">
                <text>Test producer field</text>
            </assertion>
            <assertion id="ac">
                <text>Test resource producer field</text>
            </assertion>
        </group>

        <group>
            <text>The event object must be of type |jakarta.enterprise.inject.spi.ProcessProducer&lt;T, X&gt;|, where |T| is the bean class of the bean that
                declares the producer method or field and |X| is the return type of the producer method or the type of the producer field.
            </text>
            <assertion id="ba">
                <text>Test producer method</text>
            </assertion>
            <assertion id="bb">
                <text>Test producer field</text>
            </assertion>
        </group>

        <group>
            <text>|getAnnotatedMember()| returns the |AnnotatedField| representing the producer field or the |AnnotatedMethod| representing the producer
                method.
            </text>
            <assertion id="ca">
                <text>Test producer method</text>
            </assertion>
            <assertion id="cb">
                <text>Test producer field</text>
            </assertion>
        </group>

        <group>
            <text>|getProducer()| returns the |Producer| object that will be used by the container to call the producer method or read the producer field.
            </text>
            <assertion id="da">
                <text>Test producer method</text>
            </assertion>
            <assertion id="db">
                <text>Test producer field</text>
            </assertion>
        </group>

        <assertion id="e">
            <text>|setProducer()| replaces the |Producer|.</text>
        </assertion>

        <assertion id="f">
            <text>|configureProducer()| returns a |ProducerConfigurator| (as defined in ProducerConfigurator interface)
                initialized with the |Producer| processed by this event to configure the |Producer| that will replace the
                original one at the end of the observer invocation. Each call returns the same configurator instance
                within an observer notification
            </text>
        </assertion>

        <assertion id="g">
            <text>|addDefinitionError()| registers a definition error with the container, causing the container to abort deployment after bean discovery is
                complete.
            </text>
        </assertion>

        <group>
            <text>Any observer of this event is permitted to wrap and/or replace the |Producer| by calling either
                |setProducer()| or |configureProducer()|. If both methods are called within an observer notification an
                IllegalStateException is thrown. The container must use the final value of this property, after
                all observers have been called, whenever it calls the producer or disposer.
            </text>
            <assertion id="ga">
                <text>Test producer method</text>
            </assertion>
            <assertion id="gb">
                <text>Test producer field</text>
            </assertion>
            <assertion id="gc">
                <text>If both methods |setProducer()| and |configureProducer()| are called within an observer notification an
                    IllegalStateException is thrown.
                </text>
            </assertion>
        </group>

        <assertion id="h">
            <text>If any observer method of a |ProcessProducer| event throws an exception, the exception is treated as a definition error by the container.
            </text>
        </assertion>

        <assertion id="i">
            <text>If any ProcessProducer method is called outside of the observer method invocation, an IllegalStateException is thrown.</text>
        </assertion>
    </section>

    <section id="producer_configurator" title="ProducerConfigurator interface" level="4">
        <group>
            <text>With |ProducerConfigurator| you can perform the following operations:</text>
            <assertion id="a">
                <text>Set a callback to produce a new instance with |produceWith()| method.</text>
            </assertion>
            <assertion id="b">
                <text>Set a callback to destroy the produced instance with |disposeWith()| method.</text>
            </assertion>
        </group>

    </section>

    <section id="process_observer_method" title="ProcessObserverMethod event" level="3">
        <assertion id="aaa">
            <text>The container must fire an event for each observer method of each enabled bean, before registering the |ObserverMethod| object. The event
                object must be of type |jakarta.enterprise.inject.spi.ProcessObserverMethod&lt;T, X&gt;| where |T| is the bean class of the bean that declares the
                observer method and |X| is the observed event type of the observer method.
            </text>
        </assertion>

        <assertion id="aab">
            <text>
                For a custom implementation of jakarta.enterprise.inject.spi.ObserverMethod, the container must raise an event of type
                |jakarta.enterprise.inject.spi.ProcessSyntheticObserverMethod&lt;T, X&gt;|, where |T| is the observed
                event type of the observer method and |X| is the return value of |ObserverMethod.getBeanClass()|.
            </text>
        </assertion>

        <assertion id="aba">
            <text>|getAnnotatedMethod()| returns the |AnnotatedMethod| representing the observer method. If invoked
                upon a |ProcessSyntheticObserverMethod| event, non-portable behavior results and the returned
                value should be ignored.
            </text>
        </assertion>

        <assertion id="ba">
            <text>|getObserverMethod()| returns the |ObserverMethod| object that will be used by the container to call the observer method.</text>
        </assertion>

        <assertion id="da">
            <text>|addDefinitionError()| registers a definition error with the container, causing the container to abort deployment after bean discovery is
                complete.
            </text>
        </assertion>

        <assertion id="daa">
            <text>|setObserverMethod()| replaces the ObserverMethod.</text>
        </assertion>

        <assertion id="dab">
            <text>|configureObserverMethod()| returns an |ObserverMethodConfigurator| (as defined in
                ObserverMethodConfigurator interface) initialized with the ObserverMethod processed by the event to easily configure the |ObserverMethod| which
                will be used to replace the original one at the end of observer invocation.
            </text>
        </assertion>

        <assertion id="dac">
            <text>|configureObserverMethod()| method always returns the same |ObserverMethodConfigurator|</text>
        </assertion>

        <assertion id="dad">
            <text>|veto()| forces the container to ignore the ObserverMethod.</text>
        </assertion>

        <assertion id="dae">
            <text>|getSource()| returns the |Extension| instance that added the observer method.</text>
        </assertion>

        <assertion id="e">
            <text>Any observer of this event is permitted to wrap and/or replace the |AnnotatedType| by calling either |setAnnotatedType()| or
                |configureAnnotatedType()|.
                If both methods are called within an observer notification an |IllegalStateException| is thrown.
            </text>
        </assertion>

        <assertion id="db">
            <text>If any observer method of a |ProcessObserverMethod| event throws an exception, the exception is treated as a definition error by the
                container.
            </text>
        </assertion>

        <assertion id="dc">
            <text>If any |ProcessObserverMethod| method is called outside of the observer method invocation, an |IllegalStateException| is thrown.</text>
        </assertion>
    </section>

    <section id="configurators" title="Configurators interfaces" level="2">

        <group>
            <text>CDI 2.0 introduced the following Configurators interface:</text>
            <assertion id="aa" testable="false">
                <text>|AnnotatedTypeConfigurator| for |AnnotatedType| configuration.</text>
                <note>Tested in related lifecycle event.</note>
            </assertion>
            <assertion id="ab" testable="false">
                <text>|InjectionPointConfigurator| for |InjectionPoint| configuration</text>
                <note>Tested in related lifecycle event.</note>
            </assertion>
            <assertion id="ac" testable="false">
                <text>|BeanAttributesConfigurator| for |BeanAttributes| configuration</text>
                <note>Tested in related lifecycle event.</note>
            </assertion>
            <assertion id="ad" testable="false">
                <text>|BeanConfigurator| for |Bean| configuration</text>
                <note>Tested in related lifecycle event.</note>
            </assertion>
            <assertion id="ae" testable="false">
                <text>|ObserverMethodConfigurator| for |ObserverMethod| configuration.</text>
                <note>Tested in related lifecycle event.</note>
            </assertion>
            <assertion id="af" testable="false">
                <text>|ProducerConfigurator| interface for |Producer| configuration</text>
            </assertion>
            <assertion id="ag" testable="false">
                <text>The container must provide implementation for all these configurators and make them available in matching container lifecycle events as
                    defined in `Container lifecycle events`.
                </text>
            </assertion>
        </group>

    </section>

    <section id="interception_factory" title="The InterceptionFactory interface" level="2">
        <assertion id="a">
            <text>
                Method |ignoreFinalMethods()| instructs the container to ignore all non-static, final methods with public,
                protected or default visibility declared by any class in the type hierarchy of the intercepted
                instance during invocation of createInterceptedInstance() method. Ignored methods should never
                be invoked upon the wrapper instance. Otherwise, unpredictable behavior results.
            </text>
        </assertion>
        <assertion id="b">
            <text>
                Method configure() returns an |AnnotatedTypeConfigurator| (as defined in AnnotatedTypeConfigurator SPI) initialized with the |AnnotatedType|
                created either for the class passed to |BeanManager.createInterceptionFactory(CreationalContext, Class)| or derived from the InterceptionFactory
                parameter injection point. The method always return the same AnnotatedTypeConfigurator
            </text>
        </assertion>
        <group>
            <text>Method |createInterceptedInstance()|</text>
            <assertion id="ca">
                <text>
                    returns a wrapper instance whose method invocations are intercepted by method interceptors and forwarded to a provided instance.
                </text>
            </assertion>
            <assertion id="cb">
                <text>
                    can be only called once, subsequent calls will throw an |IllegalStateException|.
                </text>
            </assertion>
            <assertion id="cd">
                <text>
                    If it is called at the type of the instance which is not proxyable as defined in `Unproxyable
                    bean types` an |UnproxyableResolutionException| exception is thrown.
                </text>
            </assertion>
            <assertion id="ce" testable="false">
                <text>
                    If the provided instance is an internal container construct (such as client proxy), non-portable behavior results.
                </text>
            </assertion>
        </group>

        <assertion id="f">
            <text>
                An |InterceptionFactory| can be obtain be calling |BeanManager.createInterceptionFactory| as defined in `Obtain an InterceptionFactory`
            </text>
        </assertion>
        <assertion id="g">
            <text>
                The container must provide a bean with scope `@Dependent`, bean type |InterceptionFactory| and qualifier `@Default`.
            </text>
        </assertion>
        <assertion id="h">
            <text>
                If an injection point of type |InterceptionFactory| and qualifier |@Default| exists and is not a parameter of
                a producer method, the container automatically detects the problem and treats it as a definition error.
            </text>
        </assertion>
    </section>

    <section id="packaging_deployment" title="Packaging and deployment" level="1">
        <assertion id="a" testable="false">
            <text>When an application is started, the container must perform bean discovery, detect definition errors and deployment problems and raise events
                that allow portable extensions to integrate with the deployment lifecycle.
            </text>
        </assertion>

        <group>
            <text>Bean discovery is the process of determining:</text>
            <assertion id="ba" testable="false">
                <text>The bean archives that exist in the application, and the beans they contain</text>
            </assertion>
            <assertion id="bb" testable="false">
                <text>Which alternatives, interceptors and decorators are enabled for each bean archive</text>
            </assertion>
            <assertion id="bc" testable="false">
                <text>The ordering of enabled interceptors and decorators</text>
            </assertion>
        </group>

        <assertion id="c" testable="false">
            <text>Additional beans may be registered programmatically with the container by the application or a portable extension after the automatic bean
                discovery completes. Portable extensions may even integrate with the process of building the |Bean| object for a bean, to enhance the
                container’s
                built-in functionality.
            </text>
        </assertion>

    </section>

    <section id="bean_archive" title="Bean archives" level="2">
        <assertion id="a" testable="false">
            <text>Bean classes of enabled beans must be deployed in bean archives.</text>
        </assertion>

        <assertion id="oa">
            <text>An archive which contains a |beans.xml| file with the |bean-discovery-mode| of |none| is not a bean archive.</text>
        </assertion>

        <assertion id="ob">
            <text>An archive which contains an extension and no |beans.xml| file is not a bean archive.</text>
        </assertion>

        <group>
            <text>An explicit bean archive is an archive which contains a |beans.xml| file with a version number of 1.1 (or later), with the
                |bean-discovery-mode| of |all|, or with no version number, or that is an empty file.
            </text>
            <assertion id="ba">
                <text>Test an archive which contains a |beans.xml| file with a version number of 1.1, with the |bean-discovery-mode| of |all|.</text>
            </assertion>
            <assertion id="bb">
                <text>Test an archive which contains a |beans.xml| file with no version number.</text>
            </assertion>
            <assertion id="bc">
                <text>Test an archive which contains an empty |beans.xml|.</text>
            </assertion>
        </group>

        <assertion id="ca">
            <text>An implicit bean archive is any other archive which contains one or more bean classes with a bean defining annotation as defined in Section
                2.5.1, “Bean defining annotations”.
            </text>
        </assertion>

        <group>
            <text>When determining which archives are bean archives, the container must consider:</text>
            <assertion id="da" testable="false">
                <text>Library jars</text>
                <note>Covered elsewhere in this section.</note>
            </assertion>
            <assertion id="dc" testable="false">
                <text>Directories in the JVM classpath.</text>
                <note>Covered elsewhere in this section</note>
            </assertion>
        </group>

        <group>
            <text>The |beans.xml| file must be named:</text>
            <assertion id="fa" testable="false">
                <text>|META-INF/beans.xml|</text>
                <note>Covered elsewhere in this section.</note>
            </assertion>
        </group>

        <assertion id="h" testable="false">
            <text>If |beans.xml| file with version 1.1 is used, the |bean-discovery-mode| attribute is required.</text>
            <note>As defined in beans_1_1.xsd.</note>
        </assertion>

        <assertion id="i" testable="false">
            <text>For compatibility with Contexts and Dependency 1.0, products must contain an option to cause an archive to be ignored by the container when no
                |beans.xml| is present.
            </text>
            <note>Implementation specific.</note>
        </assertion>

        <assertion id="k" testable="false">
            <text>If a bean class is deployed in two different bean archives, non-portable behaviour results. Portable applications must deploy each bean class
                in no more than one bean archive.
            </text>
            <note>Describes undefined behavior</note>
        </assertion>

        <assertion id="l" testable="false">
            <text>Explicit bean archives may contain classes which are not deployed as beans. For example a bean archive might contain an abstract class not
                annotated with @Decorator.
            </text>
        </assertion>

        <assertion id="m" testable="false">
            <text>Implicit bean archives are likely to contain classes which are not deployed as beans.</text>
        </assertion>

        <assertion id="n">
            <text>An extension may be deployed in any archive, including those that are not bean archives.</text>
        </assertion>

    </section>

    <section id="initialization" title="Application initialization lifecycle" level="2">
        <assertion id="a" testable="false">
            <text>When an application is started, the container performs the following steps.</text>
            <note>Description</note>
        </assertion>

        <assertion id="b">
            <text>First, the container must search for service providers for the service |jakarta.enterprise.inject.spi.Extension| defined in Section 11.5,
                "Container lifecycle events", instantiate a single instance of each service provider, and search the service provider class for observer methods
                of initialization events.
            </text>
        </assertion>

        <assertion id="c">
            <text>Next, the container must fire an event of type |BeforeBeanDiscovery|, as defined in Section 11.5.1, "BeforeBeanDiscovery event".</text>
        </assertion>

        <assertion id="i">
            <text>Next, the container must perform type discovery, as defined in Section 12.4.1, “Type discovery”</text>
        </assertion>

        <assertion id="j">
            <text>Next, the container must fire an event of type |AfterTypeDiscovery|, as defined in Section 11.5.2., "AfterTypeDiscovery event".</text>
        </assertion>

        <assertion id="ja">
            <text>Next, the container must perform bean discovery, as defined in Section 12.4.3, “Bean discovery”</text>
        </assertion>

        <assertion id="e">
            <text>Next, the container must fire an event of type |AfterBeanDiscovery|, as defined in Section 11.5.2, "AfterBeanDiscovery event", and abort
                initialization of the application if any observer registers a definition error.
            </text>
        </assertion>

        <assertion id="f">
            <text>Next, the container must detect deployment problems by validating bean dependencies and specialization and abort initialization of the
                application if any deployment problems exist, as defined in Section 2.9, "Problems detected automatically by the container".
            </text>
        </assertion>

        <assertion id="g">
            <text>Next, the container must fire an event of type |AfterDeploymentValidation|, as defined in Section 11.5.3, "AfterDeploymentValidation event",
                and abort initialization of the application if any observer registers a deployment problem.
            </text>
        </assertion>

        <assertion id="h">
            <text>Finally, the container begins directing requests to the application.</text>
            <note>Can only check the inverse, that requests aren't directed to the application before</note>
        </assertion>
    </section>

    <section id="shutdown" title="Application shutdown lifecycle" level="2">
        <group>
            <text>When an application is stopped, the container performs the following steps:</text>
            <assertion id="a">
                <text>First, the container must destroy all contexts.</text>
            </assertion>
            <assertion id="b">
                <text>Finally, the container must fire an event of type |BeforeShutdown|, as defined in Section 11.5.4, "BeforeShutdown event".</text>
            </assertion>
        </group>

    </section>

    <section id="type_bean_discovery" title="Type and Bean discovery" level="2">
        <assertion id="a" testable="false">
            <text>The container automatically discovers managed beans (according to the rules of Section 3.1.1, "Which Java classes are managed beans?") in bean
                archives and searches the bean classes for producer methods, producer fields, disposer methods and observer methods.
            </text>
            <note>Statement of intent</note>
        </assertion>
    </section>

    <section id="type_discovery_steps" title="Type discovery" level="3">
        <group>
            <text>First the container must discover types. The container discovers:</text>
            <assertion id="a">
                <text>The container discovers each Java class, interface or enum deployed in an explicit bean archive.</text>
            </assertion>

            <assertion id="b">
                <text>The container discovers each Java class with a bean defining annotation in an implicit bean archive.</text>
            </assertion>
        </group>

        <group>
            <text>For every type discovered the container must create an |AnnotatedType| representing the type and fire an event of type |ProcessAnnotatedType|,
                as defined in Section 11.5.6.
            </text>
            <assertion id="c">
                <text>Check managed bean</text>
            </assertion>
        </group>

        <assertion id="d">
            <text>If an extension calls |BeforeBeanDiscovery.addAnnotatedType()| or |AfterTypeDiscovery.addAnnotatedType()|, the type passed must be added to
                the set of discovered types.
            </text>
        </assertion>

    </section>

    <section id="exclude_filters" title="Exclude filters" level="3">
        <group>
            <text>Exclude filters are defined by &lt;exclude&gt; elements in the |beans.xml| for the bean archive as children of the &lt;scan&gt; element.
            </text>
            <assertion id="a">
                <text>By default an exclude filter is active.</text>
            </assertion>
            <assertion id="b">
                <text>An exclude filter is not active if the definition contains a child element named &lt;if-class-available&gt; with a name attribute, and the
                    classloader for the bean archive can load a class for that name.
                </text>
            </assertion>
            <assertion id="c">
                <text>An exclude filter is not active if the definition contains a child element named &lt;if-class-not-available&gt; with a name attribute, and
                    the classloader for the bean archive cannot load a class for that name.
                </text>
            </assertion>
            <assertion id="d">
                <text>An exclude filter is not active if the definition contains a child element named &lt;if-system-property&gt; with a name attribute, and
                    there is no system property defined for that name.
                </text>
            </assertion>
            <assertion id="e">
                <text>An exclude filter is not active if the definition contains a child element named &lt;if-system-property&gt; with a name attribute and a
                    value attribute, and there is no system property defined for that name with that value.
                </text>
            </assertion>
        </group>

        <assertion id="f">
            <text>The type is excluded from discovery if the fully qualified name of the type being discovered matches the value of the name attribute of the
                exclude filter.
            </text>
        </assertion>

        <assertion id="g">
            <text>The type is excluded from discovery if the package name of the type being discovered matches the value of the name attribute with a suffix
                ".*" of the exclude filter.
            </text>
        </assertion>

        <assertion id="h">
            <text>The type is excluded from discovery if the package name of the type being discovered starts with the value of the name attribute with a suffix
                ".**" of the exclude filter.
            </text>
        </assertion>
    </section>

    <section id="trimmed_bean_archive" title="Trimmed bean archive" level="3">
        <assertion id="a">
            <text>
                If an explicit bean archive contains the &lt;trim/&gt; element in its beans.xml file, types that don’t have
                either a bean defining annotation (as defined in Bean defining annotations) or any scope annotation,
                are removed from the set of discovered types.
            </text>
        </assertion>
    </section>

    <section id="bean_discovery_steps" title="Bean discovery" level="3">
        <group>
            <text>For every type in the set of discovered types (as defined in Type discovery), the container must:</text>

            <assertion id="c" testable="false">
                <text>Inspect the type metadata to determine if it is a bean.</text>
                <note>No consequence</note>
            </assertion>

            <assertion id="d" testable="false">
                <text>detect definition errors by validating the class and its metadata.</text>
                <note>Tested elsewhere</note>
            </assertion>

            <assertion id="e">
                <text>if the class is a managed bean, fire an event of type ProcessInjectionPoint for each injection point in the class, as defined in
                    ProcessInjectionPoint event.
                </text>
            </assertion>

            <assertion id="f">
                <text>if the class is a managed bean, fire an event of type ProcessInjectionTarget, as defined in ProcessInjectionTarget event.</text>
            </assertion>

            <assertion id="g">
                <text>determine which alternatives, interceptors and decorators are enabled, according to the rules defined in Enabled and disabled beans,
                    Interceptor enablement and ordering and Decorator enablement and ordering.
                </text>
            </assertion>

            <assertion id="h">
                <text>if the class is an enabled bean, interceptor or decorator, fire an event of type ProcessBeanAttributes, as defined in
                    ProcessBeanAttributes event.
                </text>
            </assertion>

            <assertion id="i">
                <text>if the class is an enabled bean, interceptor or decorator and if ProcessBeanAttributes.veto() wasn’t called in previous step, fire an
                    event which is a subtype of ProcessBean, as defined in ProcessBean event.
                </text>
            </assertion>
        </group>

        <group>
            <text>For each enabled bean, the container must search the class for producer methods and fields, as defined in Producer methods and in Producer
                fields, including resources, and for each producer:
            </text>
            <assertion id="ja">
                <text>if it is a producer method, fire an event of type ProcessInjectionPoint for each injection point in the method parameters, as defined in
                    ProcessInjectionPoint event
                </text>
            </assertion>
            <assertion id="jb">
                <text>fire an event of type ProcessProducer, as defined in ProcessProducer event.</text>
            </assertion>
            <assertion id="jc">
                <text>if the producer method or field is enabled, fire an event of type ProcessBeanAttributes, as defined in ProcessBeanAttributes event</text>
            </assertion>
            <assertion id="jd">
                <text>if the producer method or field is enabled and if ProcessBeanAttributes.veto() wasn’t called in previous step, fire an event which is a
                    subtype of ProcessBean, as defined in ProcessBean event.
                </text>
            </assertion>
        </group>

        <assertion id="je">
            <text>For each enabled bean, the container must search for disposer methods as defined in Disposer methods, and for each disposer method fire an
                event of type ProcessInjectionPoint for each injection point in the method parameters, as defined in ProcessInjectionPoint event.
            </text>
        </assertion>

        <group>
            <text>For each enabled bean, the container must search the class for observer methods, and for each observer method:</text>
            <assertion id="ka">
                <text>fire an event of type ProcessInjectionPoint for each injection point in the method parameters, as defined in ProcessInjectionPoint event
                </text>
            </assertion>
            <assertion id="kb">
                <text>fire an event of type ProcessObserverMethod, as defined in ProcessObserverMethod event.</text>
            </assertion>
        </group>

        <assertion id="l" testable="false">
            <text>For each enabled bean that is not an interceptor or decorator, the container registers an instance of the |Bean| interface defined in Section
                11.1, "The Bean interface".
            </text>
            <note>Checked above</note>
        </assertion>

        <assertion id="m" testable="false">
            <text>For each enabled interceptor, the container registers an instance of the |Interceptor| interface as defined in Section 11.1.2, "The
                Interceptor interface".
            </text>
            <note>Checked above</note>
        </assertion>

        <assertion id="n" testable="false">
            <text>For each enabled decorator, the container registers an instance of the |Decorator| interface defined in Section 11.1.1, "The Decorator
                interface".
            </text>
            <note>Checked above</note>
        </assertion>

        <assertion id="o">
            <text>For each observer method of every enabled bean, the container registers an instance of the |ObserverMethod| interface defined in Section
                11.1.3, "The ObserverMethod interface".
            </text>
        </assertion>
    </section>

    <!-- SE SECTION FROM HERE -->
    <section id="se_bootstrap" title="Bootstrapping a CDI container in Java SE" level="1">
        <assertion id="a">
            <text>In Java SE, the CDI container must be explicitly bootstrapped by the application. This is performed with `SeContainerInitializer` abstract
                class and its static method `newInstance()`.
            </text>
        </assertion>

        <assertion id="b" testable="false">
            <text>`SeContainerInitializer` is a service provider of the service jakarta.enterprise.inject.se.SeContainerInitializer declared in META-INF/services.
                It allows the configuration of the CDI container before its bootstrapping.
            </text>
        </assertion>

        <assertion id="c">
            <text>The `SeContainerInitializer.initialize()` method bootstraps the container and returns a `SeContainer` instance.</text>
        </assertion>
        <group>
            <text>Unless specified differently each method of `SeContainerInitializer` returns the current `SeContainerInitializer` object.</text>
            <assertion id="da">
                <text>|newInstance()| static method returns an instance of the implementation of `SeContainerInitializer` discovered by java service-provider.
                    Each call returns a new instance of `SeContainerInitializer`.
                </text>
            </assertion>
            <assertion id="db">
                <text>|addBeanClasses()| add classes to the the synthetic bean archive</text>
            </assertion>
            <assertion id="dc">
                <text>|addPackages()| add packages content to the synthetic bean archive. Versions exist by providing classes in the wished package or Package
                    objects themselves. Other version of the method allows recursive addition
                </text>
            </assertion>
            <assertion id="de">
                <text>|addExtensions()| add the provided extensions (class or instance) to the synthetic bean archive.</text>
            </assertion>
            <assertion id="df">
                <text>|enableInterceptors()| adds interceptor classes to the list of enabled interceptors for the synthetic bean archive.</text>
            </assertion>
            <assertion id="dg">
                <text>|enableDecorators()| adds decorator classes to the list of enabled decorators for the synthetic bean archive.</text>
            </assertion>
            <assertion id="dh">
                <text>|selectAlternatives()| adds alternatives classes to the list of selected alternatives for the synthetic bean archive.</text>
            </assertion>
            <assertion id="di">
                <text>|selectAlternativeStereotypes()| adds alternative stereotype classes to the list of selected alternative stereotypes for the synthetic
                    bean archive.
                </text>
            </assertion>
            <assertion id="dj">
                <text>|addProperty()| add a configuration property for the container</text>
            </assertion>
            <assertion id="dk">
                <text>|setProperties()| set the Map of configuration properties for the container. replace previous properties.</text>
            </assertion>
            <assertion id="dm">
                <text>|disableDiscovery()| deactivate automatic type scanning and discovery. All bean archive will be ignored except the implicit bean
                    archive.
                </text>
            </assertion>
            <assertion id="dn">
                <text>|setClassLoader()| change the default class loader for the container</text>
            </assertion>
            <assertion id="do">
                <text>|initialize()| bootstrap the container and returns a `SeContainer` as defined in `SeContainer interface`.</text>
            </assertion>
        </group>

        <assertion id="e">
            <text>Every invocation of the `SeContainerInitializer.initialize()` method returns a new `SeContainer` instance.</text>
        </assertion>

        <assertion id="f">
            <text>The application context is started automatically by the container on start up.</text>
        </assertion>
    </section>

    <section id="se_container_initializer" title="SeContainerInitializer class" level="2">
        <assertion id="a">
            <text>A CDI implementation is required to provide an implementation of `SeContainerInitializer` declared as a service-provider. `newInstance()`
                static method uses java service-provider to obtain an implementation of `SeContainerInitializer` and return an instance of it. There must be
                exactly one provider available, otherwise an `IllegalStateException` is thrown.
            </text>
            <note>Exceptional states tested in CDI API.</note>
        </assertion>
        <assertion id="b">
            <text>`SeContainerInitializer` configuration allows explicit addition of elements to the set of automatically discovered elements. These additions
                are done in an internal synthetic bean archive that is added to the set of bean archives discovered by the container during deployment.
            </text>
        </assertion>
        <assertion id="c" testable="false">
            <text>This synthetic bean archive behaves like an explicit bean archive (as defined in Bean archives).</text>
        </assertion>
    </section>

    <section id="se_container" title="SeContainer interface" level="2">
        <assertion id="a">
            <text>The |jakarta.enterprise.inject.se.SeContainer| interface provides access to the |BeanManager| and programmatic lookup as defined in The Instance
                interface.
            </text>
        </assertion>

        <assertion id="b" testable="false">
            <text>|SeContainer| extends |AutoCloseable|, so when dereferenced, it should shutdown automatically.</text>
        </assertion>

        <group>
            <text>'SeContainer' methods:</text>
            <assertion id="ca">
                <text>|close()| method explicitly shutdown the container. If it is called and the container was already shutdown, it throws an
                    |IllegalStateException|.
                </text>
            </assertion>
            <assertion id="cb">
                <text>|isRunning()| method returns true if called before container shutdown and false after.</text>
            </assertion>
            <assertion id="cc">
                <text>|getBeanManager()| method returns the |BeanManager| (as defined in The BeanManager object) for the running container. if it is called and
                    the container was already shutdown, it throws an |IllegalStateException|.
                </text>
            </assertion>
        </group>

        <assertion id="d">
            <text>
                |SeContainer| implements |jakarta.enterprise.inject.Instance| and therefore might be used to perform
                programmatic lookup as defined in "The Instance interface". If no qualifier is passed to
                |SeContainer.select()| method, the |@Default| qualifier is assumed.
            </text>
        </assertion>

        <assertion id="e">
            <text>If any |Instance.select()| method is called and the container was already shutdown, the |IllegalStateException| is thrown.</text>
        </assertion>
    </section>

    <section id="contexts_se" title="Scopes and contexts in Java SE" level="1">
    </section>

    <section id="builtin_contexts_se" title="Context management for built-in scopes in Java SE" level="2">

    </section>

    <section id="application_context_se" title="Application context lifecycle in Java SE" level="3">
        <assertion id="a">
            <text>The application context is shared between all the beans that execute within the same container</text>
        </assertion>

        <assertion id="b">
            <text>An event with qualifier @Initialized(ApplicationScoped.class) is fired when the application context is initialized</text>
        </assertion>

        <assertion id="c">
            <text>An event with qualifier @Destroyed(ApplicationScoped.class) is fired when the application is destroyed</text>
        </assertion>

        <assertion id="d">
            <text>The event payload is any java.lang.Object</text>
        </assertion>
    </section>

    <section id="packaging_deployment_se" title="Packaging and deployment in Java SE" level="1">
    </section>

    <section id="bean_archive_se" title="Bean archive in Java SE" level="2">

        <group>
            <text>An archive which doesn’t contain a beans.xml file can’t be discovered as an implicit bean archive unless:</text>
            <assertion id="a">
                <text>Application is launched with system property jakarta.enterprise.inject.scan.implicit set to true</text>
            </assertion>
            <assertion id="b">
                <text>the container was initialized with a parameter map containing an entry with jakarta.enterprise.inject.scan.implicit as key and Boolean.TRUE
                    as value
                </text>
            </assertion>
        </group>

    </section>

    <section id="spi_se" title="Portable extensions in Java SE" level="1">

    </section>

    <section id="beanmanager_se" title="The `BeanManager` object in Java SE" level="2">

    </section>

    <section id="provider_se" title="Obtaining a reference to the CDI container in Java SE" level="3">
        <assertion id="a" testable="false">
            <text>In Java SE, while the access to CDI container and `BeanManager` described in `Obtaining a reference to the CDI container` is available, the
                preferred way to access them is through `SeContainer` interface as described in `SeContainer interface`.
            </text>
        </assertion>
    </section>

    <!-- EE SECTION FROM HERE -->
    <section id="concepts_ee" title="Extended Concepts for Jakarta EE" level="1">
    </section>

    <section id="capabilities_ee" title="Functionality provided by the container to the bean in Jakarta EE" level="2">
    </section>

    <section id="bean_types_ee" title="Bean types for Jakarta EE component" level="2">
        <group>
            <text>The bean types of a bean may be restricted by annotating the bean class or producer method or field with the annotation
                |@jakarta.enterprise.inject.Typed|. When a |@Typed| annotation is explicitly specified, only the types whose classes are explicitly listed using
                the |value| member, together with |java.lang.Object| are bean types of the bean.
            </text>
            <assertion id="a">
                <text>Check session bean</text>
            </assertion>
        </group>

        <group>
            <text>If a bean class or producer method or field specifies a |@Typed| annotation, and the |value| member specifies a class which does not
                correspond to a type in the unrestricted set of bean types of a bean, the container automatically detects the problem and treats it as a
                definition error.
            </text>
            <assertion id="b">
                <text>Check session bean</text>
            </assertion>
        </group>
    </section>

    <section id="scopes_ee" title="Scopes" level="2">
    </section>

    <section id="builtin_scopes_ee" title="Built-in scope types in Jakarta EE" level="3">
        <assertion id="a" testable="false">
            <text>When running in Jakarta EE, the implementations of the @RequestScoped, @ApplicationScoped and @SessionScoped annotations provided by the
                container, represent the standard scopes defined by the Java Servlets specification.
            </text>
        </assertion>
    </section>

    <section id="default_bean_discovery_ee" title="Default bean discovery mode for Jakarta EE" level="2">
        <group>
            <text>When running in Jakarta EE, If the bean discovery mode is annotated, the container must extend the rules defined in Default bean discovery mode
                with:
            </text>
            <assertion id="a">
                <text>bean classes of EJB sessions beans, are discovered</text>
            </assertion>
            <assertion id="b">
                <text>producer methods that are on an EJB session bean are discovered</text>
            </assertion>
            <assertion id="c">
                <text>producer fields that are on an EJB session bean are discovered</text>
            </assertion>
            <assertion id="d">
                <text>disposer methods that are on an EJB session bean are discovered</text>
            </assertion>
            <assertion id="e">
                <text>observer methods that are on an EJB session bean are discovered.</text>
            </assertion>
        </group>
    </section>

    <section id="names_ee" title="Bean names in Jakarta EE" level="2">
        <assertion id="a">
            <text>A bean with a name may be referred to by its name in Unified EL expressions.</text>
        </assertion>
    </section>

    <section id="default_name_ee" title="Default bean names for EJB session beans" level="3">
        <assertion id="a" testable="false">
            <text>In the circumstances listed in 2.6.2 "Default bean names", the rule for determining default name for an EJB session bean are defined in 17.2.5
                "Default bean
                name for a session bean".
            </text>
        </assertion>
    </section>

    <section id="implementation_ee" title="Addition to programming model for Jakarta EE" level="1">
    </section>

    <section id="managed_beans_ee" title="Managed beans in Jakarta EE" level="2"></section>

    <section id="what_classes_are_beans_ee" title="Which Java classes are managed beans in Jakarta EE?" level="3">
        <assertion id="a">
            <text>A top-level Java class is not a managed bean if it is annotated with any of the EJB component-defining annotations</text>
        </assertion>

        <assertion id="b">
            <text>A top-level Java class is not a managed bean if it is declared as an EJB bean class in |ejb-jar.xml|</text>
        </assertion>
    </section>

    <section id="session_beans" title="EJB Session beans" level="2">

        <assertion id="aa">
            <text>A session bean is a bean that is implemented by a session bean with an EJB 3.x client view that is not annotated with |@Vetoed| or in a
                package annotated |@Vetoed|.
            </text>
        </assertion>

        <assertion id="ab" testable="false">
            <text>The basic lifecycle and semantics of EJB session beans are defined by the EJB specification.</text>
            <note>This is a reference to the EJB specification</note>
        </assertion>

        <assertion id="b">
            <text>A stateless session bean must belong to the |@Dependent| pseudo-scope</text>
        </assertion>

        <assertion id="c">
            <text>A singleton bean must belong to either the |@ApplicationScoped| scope or to the |@Dependent| pseudo-scope</text>
        </assertion>

        <assertion id="da">
            <text>If a session bean specifies an illegal scope, the container automatically detects the problem and treats it as a definition error.</text>
        </assertion>

        <assertion id="e">
            <text>A stateful session bean may have any scope.</text>
            <note>No way of testing the real intent of this statement, so we check that a SFSB may be scoped</note>
        </assertion>

        <assertion id="f" testable="false">
            <text>When a contextual instance of a session bean is obtained via the dependency injection service, the behavior of
                |SessionContext.getInvokedBusinessInterface()| is specific to the container implementation. Portable applications should not rely upon the value
                returned by this method.
            </text>
            <note>This is describing non-portable behavior</note>
        </assertion>

        <assertion id="g">
            <text>If the bean class of a session bean is annotated |@Interceptor|, the container automatically detects the problem and treats it as a definition
                error.
            </text>
        </assertion>

        <assertion id="h">
            <text>If the bean class of a session bean is annotated |@Decorator|, the container automatically detects the problem and treats it as a definition
                error.
            </text>
        </assertion>

        <assertion id="i">
            <text>If the session bean class is a generic type, it must have scope |@Dependent|. If a session bean with a parameterized bean class declares any
                scope other than |@Dependent|, the container automatically detects the problem and treats it as a definition error.
            </text>
        </assertion>

        <assertion id="j" testable="false">
            <text>If packages annotated |@Vetoed| are split across classpath entries, non-portable behavior results. An application can prevent packages being
                split across jars by sealing the package as defined by the Extension Mechanism Architecture.
            </text>
            <note>Non-portable behavior.</note>
        </assertion>

    </section>

    <section id="session_bean_ejb_remove_method" title="EJB remove methods of session beans" level="3">
        <assertion id="a">
            <text>If a session bean is a stateful session bean, and the scope is |@Dependent|, the application may call any EJB remove method of a contextual
                instance of the session bean.
            </text>
        </assertion>

        <assertion id="b">
            <text>If a session bean is a stateful session bean, and the scope is not |@Dependent|, the application may not directly call any EJB remove method
                of any instance of the session bean. If the application directly calls an EJB remove method of any contextual instance of a session bean that is
                a stateful session bean and declares any scope other than |@Dependent|, an |UnsupportedOperationException| is thrown
            </text>
        </assertion>

        <assertion id="da">
            <text>If the application directly calls an EJB remove method of a contextual instance of a session bean that is a stateful session bean and has
                scope |@Dependent| then no parameters are passed to the method by the container.
            </text>
        </assertion>

        <assertion id="dba">
            <text>If the application directly calls an EJB remove method of a contextual instance of a session bean that is a stateful session bean and has
                scope |@Dependent| then the container ignores the instance instead of destroying it when |Contextual.destroy()| is called, as defined in Section
                6.5, "Lifecycle of stateful session beans"
            </text>
        </assertion>
    </section>

    <section id="session_bean_types" title="Bean types of a session bean" level="3">
        <assertion id="aa">
            <text>The unrestricted set of bean types for a session bean contains all local interfaces of the bean and their superinterfaces.</text>
        </assertion>

        <assertion id="ba">
            <text>If the session bean has a no-interface view, the set of bean types contains the bean class and all superclasses.</text>
        </assertion>

        <assertion id="c">
            <text>|java.lang.Object| is a bean type of every session bean</text>
        </assertion>

        <assertion id="d">
            <text>Remote interfaces are not included in the set of bean types</text>
        </assertion>

        <assertion id="e">
            <text>The resulting set of bean types for a session bean consists only of legal bean types, all other types are
                removed from the set of bean types.
            </text>
        </assertion>
    </section>

    <section id="declaring_session_bean" title="Declaring a session bean" level="3">
        <assertion id="aa">
            <text>A session bean does not require any special annotations apart from the component-defining annotation (or XML declaration) required by the EJB
                specification.
            </text>
        </assertion>

        <group>
            <text>A bean class may also specify a scope, name, stereotypes and/or qualifiers.</text>

            <assertion id="ba">
                <text>Test a bean class with a scope.</text>
            </assertion>

            <assertion id="bb">
                <text>Test a bean class with a name.</text>
            </assertion>

            <assertion id="bd">
                <text>Test a bean class with a stereotype.</text>
            </assertion>

            <assertion id="be">
                <text>Test a bean class with a qualifier.</text>
            </assertion>
        </group>

        <assertion id="c">
            <text>A session bean class may extend another bean class.</text>
        </assertion>
    </section>

    <section id="specialize_session_bean" title="Specializing a session bean" level="3">
        <assertion id="aa">
            <text>If a bean class of a session bean X is annotated |@Specializes|, then the bean class of X must directly extend the bean class of another
                session bean Y. Then X directly specializes Y, as defined in Section 4.3 "Specialization".
            </text>
        </assertion>

        <assertion id="da">
            <text>If the bean class of X does not directly extend the bean class of another session bean, the container automatically detects the problem and
                treats it as a definition error.
            </text>
        </assertion>

        <group>
            <text>When an enabled bean specializes a second bean, we can be certain that the second bean is never instantiated or called by the container. Even
                if the second bean defines a producer or observer method, the method will never be called.
            </text>
            <assertion id="ca" implied="true">
                <text>The second bean is never instantiated.</text>
            </assertion>
        </group>
    </section>

    <section id="session_bean_name" title="Default bean name for a session bean" level="3">
        <assertion id="a">
            <text>The default name for a session bean is the unqualified class name of the session bean class, after converting the first character to lower
                case.
            </text>
        </assertion>
    </section>

    <section id="producer_method_ee" title="Producer methods on EJB session bean" level="2">
        <assertion id="a">
            <text>If the bean is a session bean, the producer method must be either a business method exposed by a local business interface of the EJB or a
                static method of the bean class
            </text>
        </assertion>

        <assertion id="aa" implied="true">
            <text>If a producer method X is annotated |@Specializes|, then it must be non-static and directly override another producer method Y. Then X
                directly specializes Y, as defined in Section 4.3 "Specialization".
            </text>
        </assertion>
    </section>

    <section id="declaring_producer_method_ee" title="Declaring a producer method in an EJB session bean" level="3">
        <assertion id="a">
            <text>If a non-static method of a session bean class is annotated |@Produces|, and the method is not a business method exposed by a local business
                interface of the session bean, the
                container automatically detects the problem and treats it as a definition error.
            </text>
        </assertion>

        <assertion id="c">
            <text>When the container calls a producer method, if the method is non-static the container must obtain a contextual instance of the bean which
                declares the method, as defined by Section 6.5.2 "Contextual instance of a bean", then invoke the method upon this instance.
            </text>
        </assertion>
    </section>

    <section id="producer_field_ee" title="Producer field on EJB session bean" level="2">
        <assertion id="a">
            <text>If the bean is a session bean, the producer field must be a static field of the bean class.</text>
        </assertion>
    </section>

    <section id="declaring_producer_field_ee" title="Declaring a producer field in an EJB session bean" level="3">
        <assertion id="a">
            <text>If a non-static field of a session bean class is annotated |@Produces|, the container automatically detects the problem and treats it as a
                definition error.
            </text>
        </assertion>
    </section>

    <section id="disposer_method_ee" title="Disposer methods on EJB session bean" level="2">
        <assertion id="a">
            <text>If the bean is a session bean, the disposer method must be a business method exposed by a local business interface of the EJB or a static
                method of the bean class.
            </text>
        </assertion>
    </section>

    <section id="declaring_disposer_method_ee" title="Declaring a disposer method on an EJB session bean" level="3">
        <assertion id="a">
            <text>If a non-static method of a session bean class has a parameter annotated |@Disposes|, and the method is not a business method exposed by a
                local business interface of the session
                bean, the container automatically detects the problem and treats it as a definition error.
            </text>
        </assertion>
    </section>

    <section id="javaee_components" title="Jakarta EE components" level="2">

        <group>
            <text>The instance used by the container to service an invocation of a Jakarta EE component will not be the same instance obtained when using
                |@Inject|, instantiated by the container to invoke a producer method, observer method or disposer method, or instantiated by the container to
                access the value of a producer field.
            </text>
            <assertion id="a">
                <text>Test instance obtained using |@Inject|.</text>
            </assertion>
            <assertion id="b">
                <text>Test instance instantiated by the container to invoke a producer method.</text>
            </assertion>
            <assertion id="c">
                <text>Test instance instantiated by the container to invoke a disposer method.</text>
            </assertion>
            <assertion id="d">
                <text>Test instance instantiated by the container to invoke a observer method.</text>
            </assertion>
            <assertion id="e">
                <text>Test instance instantiated by the container to access the value of a producer field.</text>
            </assertion>
        </group>

    </section>


    <section id="resources" title="Resources" level="2">
        <assertion id="ka" testable="false">
            <text>The container is not required to support resources with scope other than |@Dependent|.</text>
            <note>Statement about non-portable behavior</note>
        </assertion>

        <assertion id="l" testable="false">
            <text>A resource may not declare a bean EL name</text>
            <note>Doesn't mention the consequences of this</note>
        </assertion>
    </section>

    <section id="declaring_resource" title="Declaring a resource" level="3">
        <assertion id="aa" testable="false">
            <text>A resource may be declared by specifying a Jakarta EE component environment injection annotation as part of a producer field declaration. The
                producer field may be static.
            </text>
            <note>Introductory text for the following assertions</note>
        </assertion>

        <assertion id="bb">
            <text>For a Jakarta EE resource, |@Resource| must be specified.</text>
        </assertion>

        <assertion id="cc">
            <text>For a persistence context, |@PersistenceContext| must be specified.</text>
        </assertion>

        <assertion id="dd">
            <text>For a persistence unit, |@PersistenceUnit| must be specified.</text>
        </assertion>

        <assertion id="ee">
            <text>For a remote EJB, |@EJB| must be specified.</text>
        </assertion>

        <assertion id="ff">
            <text>For a web service, |@WebServiceRef| must be specified.</text>
        </assertion>

        <assertion id="gg" testable="false">
            <text>The injection annotation specifies the metadata needed to obtain the resources, entity manager, entity manager factory, remote EJB instance or
                web service reference from the component environment.
            </text>
            <note>This is defined in other specs</note>
        </assertion>

        <assertion id="hh">
            <text>The bean type and qualifiers of the resource are determined by the producer field declaration.</text>
        </assertion>

        <assertion id="i">
            <text>If the producer field declaration specifies an EL name, the container automatically detects the problem and treats it as a definition error.
            </text>
        </assertion>

        <assertion id="j">
            <text>If the matching object in the Jakarta EE component environment is not of the same type as the producer field declaration, the container
                automatically detects the problem and treats it as a definition error.
            </text>
        </assertion>

    </section>

    <section id="resource_types" title="Bean types of a resource" level="3">
        <group>
            <text>The unrestricted set of bean types for a resource is determined by the declared type of the producer field, as specified by Section 3.4.1,
                "Bean types of a producer field".
            </text>
            <assertion id="aa">
                <text>Check @Resource</text>
            </assertion>
            <assertion id="ab">
                <text>Check @PersistenceContext</text>
            </assertion>
            <assertion id="ac">
                <text>Check @PersistenceUnit</text>
            </assertion>
            <assertion id="ad">
                <text>Check @EJB</text>
            </assertion>
            <assertion id="ae">
                <text>Check @WebServiceRef</text>
            </assertion>
        </group>
        <assertion id="b" testable="false">
            <text>The resulting set of bean types for a resource consists only of legal bean types, all other types are
                removed from the set of bean types.
            </text>
        </assertion>
    </section>

    <section id="additional_builtin_beans" title="Additional built-in beans" level="2">
        <assertion id="a">
            <text>A Jakarta EE or embeddable EJB container must provide a bean with qualifier |@Default| and bean type |jakarta.transaction.UserTransaction|,
                allowing injection of a reference to the JTA |UserTransaction|.
            </text>
        </assertion>

        <assertion id="b">
            <text>A Jakarta EE or embeddable EJB container must provide a bean with qualifier |@Default| and bean type |javax.security.Principal|, allowing
                injection of a |Principal| representing the current caller identity.
            </text>
        </assertion>

        <assertion id="da">
            <text>A servlet container must provide a bean with qualifier |@Default| and bean type |jakarta.servlet.http.HttpServletRequest|, allowing injection of
                a reference to the |HttpServletRequest|. This bean is passivation capable dependency, as defined in Section 6.6.2, "Passivation capable
                dependencies".
            </text>
        </assertion>

        <assertion id="db">
            <text>A servlet container must provide a bean with qualifier |@Default| and bean type |jakarta.servlet.http.HttpSession|, allowing injection of a
                reference to the |HttpSession|. This bean is passivation capable dependency, as defined in Section 6.6.2, "Passivation capable dependencies".
            </text>
        </assertion>

        <assertion id="dc">
            <text>A servlet container must provide a bean with qualifier |@Default| and bean type |jakarta.servlet.ServletContext|, allowing injection of a
                reference to the |ServletContext|. This bean is passivation capable dependency, as defined in Section 6.6.2, "Passivation capable dependencies".
            </text>
        </assertion>

        <assertion id="e">
            <text>If a Jakarta EE component class has an injection point of type |UserTransaction| and qualifier |@Default|, and may not validly make use of the
                JTA |UserTransaction| according to the Jakarta EE platform specification, the container automatically detects the problem and treats it as a
                definition error.
            </text>
        </assertion>
    </section>

    <section id="injected_fields_ee" title="Injected fields in Jakarta EE" level="2">
        <group>
            <text>An injected field is a non-static, non-final field of a bean class or of any other classes supporting injection.</text>

            <assertion id="b">
                <text>Test a Jakarta EE component class.</text>
            </assertion>

        </group>
    </section>

    <section id="initializer_methods_ee" title="Initializer methods in Jakarta EE" level="2">
        <group>
            <text>An initializer method is a default-access, public, protected or private, non-abstract, non-static, non-generic method of a bean class or of
                any Jakarta EE component class supporting injection.
            </text>

            <assertion id="b">
                <text>Test a Jakarta EE component class.</text>
            </assertion>
        </group>

        <assertion id="e">
            <text>If the bean is a session bean, the initializer method is not required to be a business method of the session bean.</text>
        </assertion>

        <assertion id="f">
            <text>All initializer method parameters are injection points.</text>
        </assertion>
    </section>

    <section id="new_ee" title="@New qualified beans in Jakarta EE" level="2">
        <assertion id="j">
            <text>For each session bean, a second bean exists which has the same bean class.</text>
        </assertion>

        <assertion id="k">
            <text>For each session bean, a second bean exists which has the same bean types.</text>
        </assertion>

        <assertion id="l">
            <text>For each session bean, a second bean exists which has the same bean constructor.</text>
        </assertion>

        <assertion id="m">
            <text>For each session bean, a second bean exists which has the same initializer methods.</text>
        </assertion>

        <assertion id="n">
            <text>For each session bean, a second bean exists which has the same injected fields.</text>
        </assertion>

        <assertion id="o">
            <text>For each session bean, a second bean exists which has the same interceptor bindings.</text>
        </assertion>

        <assertion id="p">
            <text>This second bean has scope |@Dependent|.</text>
        </assertion>

        <assertion id="r">
            <text>This second bean has exactly one qualifier: |@jakarta.enterprise.inject.New(X.class)| where |x| is the bean class.</text>
        </assertion>

        <assertion id="s">
            <text>This second bean has no bean name.</text>
        </assertion>

        <assertion id="t">
            <text>This second bean has no stereotypes.</text>
        </assertion>

        <assertion id="u">
            <text>This second bean has no observer methods.</text>
        </assertion>

        <assertion id="v">
            <text>This second bean has no producer methods.</text>
        </assertion>

        <assertion id="x">
            <text>This second bean has no disposer methods.</text>
        </assertion>

        <group>
            <text>Note that this second bean exists, and may be enabled and available for injection even if the first bean is disabled, as defined by Section
                5.1.2, “Enabled and disabled beans” or if the bean class is deployed outside of a bean deployment archive, as defined in Section 12.1, “Bean
                deployment archives”, and is therefore not discovered during the bean discovery process defined in Chapter 12, Packaging and deployment. The
                container discovers |@New| qualified beans by inspecting injection points of other enabled beans.
            </text>
            <assertion id="yb">
                <text>Check that @New on a field injection point (which is a session bean class) outside the BDA, but in the classpath causes a session bean
                    with qualifier @New and the given type to be created
                </text>
            </assertion>
            <assertion id="yd">
                <text>Check that @New on a initializer method injection point (which is a session bean class) outside the BDA, but in the classpath causes a
                    session bean with qualifier @New and the given type to be created
                </text>
            </assertion>
            <assertion id="yf">
                <text>Check that @New on a constructor injection point (which is a session bean class) outside the BDA, but in the classpath causes a session
                    bean with qualifier @New and the given type to be created
                </text>
            </assertion>
            <assertion id="yh">
                <text>Check that @New on a producer method injection point (which is a session bean class) outside the BDA, but in the classpath causes a
                    session bean with qualifier @New and the given type to be created
                </text>
            </assertion>
            <assertion id="yj">
                <text>Check that @New on a observer method injection point (which is a session bean class) outside the BDA, but in the classpath causes a
                    session bean with qualifier @New and the given type to be created
                </text>
            </assertion>
            <assertion id="yl">
                <text>Check that @New on a disposer method injection point (which is a session bean class) outside the BDA, but in the classpath causes a
                    session bean with qualifier @New and the given type to be created
                </text>
            </assertion>
        </group>
    </section>

    <section id="type_level_inheritance_ee" title="Inheritance of type-level metadata in Jakarta EE" level="2">
        <group>
            <text>Suppose a class X is extended directly or indirectly by the bean class of a managed bean Y. If X is annotated with a qualifier type,
                stereotype or interceptor binding type Z then Y inherits the annotation if and only if Z declares the |@Inherited| meta-annotation and neither Y
                nor any intermediate class that is a subclass of X and a superclass of Y declares an annotation of type Z.
            </text>

            <assertion id="al">
                <text>Test qualifier type for directly extended session bean annotated |@Inherited| is inherited.</text>
            </assertion>

            <assertion id="ala">
                <text>Test qualifier type for directly extended session bean not annotated |@Inherited| is not inherited.</text>
            </assertion>

            <assertion id="am">
                <text>Test stereotype for directly extended session bean annotated |@Inherited| is inherited.</text>
            </assertion>

            <assertion id="ama">
                <text>Test stereotype for directly extended session bean not annotated |@Inherited| is not inherited.</text>
            </assertion>

            <assertion id="an">
                <text>Test interceptor binding type for directly extended session bean annotated |@Inherited| is inherited.</text>
            </assertion>

            <assertion id="ana">
                <text>Test interceptor binding type for directly extended session bean not annotated |@Inherited| is not inherited.</text>
            </assertion>

            <assertion id="ap">
                <text>Test qualifier type for indirectly extended session bean annotated |@Inherited| is inherited.</text>
            </assertion>

            <assertion id="apa">
                <text>Test qualifier type for indirectly extended session bean not annotated |@Inherited| is not inherited.</text>
            </assertion>

            <assertion id="aq">
                <text>Test stereotype for indirectly extended session bean annotated |@Inherited| is inherited.</text>
            </assertion>

            <assertion id="aqa">
                <text>Test stereotype for indirectly extended session bean not annotated |@Inherited| is not inherited.</text>
            </assertion>

            <assertion id="ar">
                <text>Test interceptor binding type for indirectly extended session bean annotated |@Inherited| is inherited.</text>
            </assertion>

            <assertion id="ara">
                <text>Test interceptor binding type for indirectly extended session bean not annotated |@Inherited| is not inherited.</text>
            </assertion>
        </group>

        <group>
            <text>Suppose a class X is extended directly or indirectly by the bean class of a managed bean Y. If X is annotated with a scope type Z then Y
                inherits the annotation if and only if Z declares the |@Inherited| meta-annotation and neither Y nor any intermediate class that is a subclass
                of X and a superclass of Y declares a scope type.
            </text>
            <assertion id="be">
                <text>Test scope type for directly extended session bean annotated |@Inherited| is inherited.</text>
            </assertion>

            <assertion id="bea">
                <text>Test scope type for directly extended session bean not annotated |@Inherited| is not inherited.</text>
            </assertion>

            <assertion id="bh">
                <text>Test scope type for indirectly extended session bean annotated |@Inherited| is inherited.</text>
            </assertion>

            <assertion id="bha">
                <text>Test scope type for indirectly extended session bean not annotated |@Inherited| is not inherited.</text>
            </assertion>
        </group>
        <assertion id="hhj">
            <text>For class X which is extended _directly_ by the bean class of a _session_ bean Y, a scope type explicitly declared by X and inherited by Y
                from X takes precedence over default scopes of stereotypes declared or inherited by Y.
            </text>
        </assertion>

        <assertion id="hhk">
            <text>For class X which is extended _indirectly_ by the bean class of a _session_ bean Y, a scope type explicitly declared by X and inherited by Y
                from X takes precedence over default scopes of stereotypes declared or inherited by Y.
            </text>
        </assertion>
    </section>

    <section id="member_level_inheritance_ee" title="Inheritance of member-level metadata in Jakarta EE" level="2">

        <group>
            <text>Suppose a class X is extended directly or indirectly by the bean class of a managed bean. If X declares an injected field x then Y inherits
                x.
            </text>

            <assertion id="ab">
                <text>Check session bean X _directly_ extends session bean Y</text>
            </assertion>

            <assertion id="ad">
                <text>Check session bean X _indirectly_ extends session bean Y</text>
            </assertion>
        </group>

        <group>
            <text>Suppose a class X is extended directly or indirectly by the bean class of a managed bean Y. If X declares an initializer, non-static observer,
                @PostConstruct or @PreDestroy method x() then Y inherits x() if and only if neither Y nor any intermediate class that is a subclass of X and a
                superclass of Y overrides the method x().
            </text>
            <assertion id="bab">
                <text>Check session bean X _directly_ extends session bean Y with _|@PostConstruct|_</text>
            </assertion>

            <assertion id="bad">
                <text>Check session bean X _indirectly_ extends session bean Y with _|@PostConstruct|_</text>
            </assertion>

            <assertion id="bbb">
                <text>Check session bean X _directly_ extends session bean Y with _|@PostDestroy|_</text>
            </assertion>

            <assertion id="bbd">
                <text>Check session bean X _indirectly_ extends session bean Y with _|@PostDestroy|_</text>
            </assertion>

            <assertion id="df">
                <text>Check session bean X _directly_ extends session bean Y with a _non-static observer method_</text>
            </assertion>

            <assertion id="dl">
                <text>Check session bean X _indirectly_ extends session bean Y with a _non-static observer method_</text>
            </assertion>

            <assertion id="dn">
                <text>Check session bean X _directly_ extends session bean Y with a _initializer method_</text>
            </assertion>

            <assertion id="dp">
                <text>Check session bean X _indirectly_ extends session bean Y with a _initializer method_</text>
            </assertion>

        </group>

        <group>
            <text>Suppose a class X is extended directly or indirectly by the bean class of a managed bean. If X declares a non-static method x() annotated with
                an interceptor binding type Z then Y inherits the binding if and only if neither Y nor any intermediate class that is a subclass of X and a
                superclass of Y overrides the method x().
            </text>

            <assertion id="kb">
                <text>Check session bean X _directly_ extends managed bean Y</text>
            </assertion>

            <assertion id="kd">
                <text>Check session bean X _indirectly_ extends managed bean Y</text>
            </assertion>

        </group>

        <group>
            <text>Suppose a class X is extended directly or indirectly by the bean class of a managed bean or session bean Y. If X declares an initializer,
                non-static observer, @PostConstruct or @PreDestroy method x() then Y inherits x() if and only if neither Y nor any intermediate class that is a
                subclass of X and a superclass of Y overrides the method x().
            </text>
            <assertion id="dd">
                <text>Check session bean X _directly_ extends session bean Y with a _non-static producer method_</text>
            </assertion>

            <assertion id="de">
                <text>Check session bean X _directly_ extends session bean Y with a _non-static disposer method_</text>
            </assertion>

            <assertion id="dj">
                <text>Check session bean X _indirectly_ extends session bean Y with a _non-static producer method_</text>
            </assertion>

            <assertion id="dk">
                <text>Check session bean X _indirectly_ extends session bean Y with a _non-static disposer method_</text>
            </assertion>

        </group>

    </section>

    <section id="specialization_ee" title="Specialization in Jakarta EE" level="2">
    </section>

    <section id="direct_and_indirect_specialization_ee" title="Direct and indirect specialization in Jakarta EE" level="3">

        <assertion id="ia" implied="true">
            <text>A bean X is said to specialize another bean Y if X directly specializes Y.</text>
        </assertion>

        <assertion id="j" implied="true">
            <text>A bean X that specializes bean Y will include all qualifiers of Y, together with all qualifiers declared explicitly by X.</text>
        </assertion>

        <assertion id="k" implied="true">
            <text>A bean X that specializes bean Y will have the same name as Y if Y has a name.</text>
        </assertion>

        <group>
            <text>If Y has a bean name and X declares a bean name explicitly the container automatically detects the problem and treats it as a definition
                error.
            </text>
            <assertion id="lc">
                <text>Test that a specializing enterprise bean with a name throws a definition exception.</text>
            </assertion>
        </group>
    </section>

    <section id="injection_el_resolution_ee" title="Dependency injection, lookup and EL in Jakarta EE" level="1"></section>

    <section id="selection_ee" title="Modularity in Jakarta EE" level="2">
        <group>
            <text>A bean is available for injection in a certain module if the bean is not an interceptor or decorator, the bean is enabled, the bean is either
                not an alternative, or the module is a bean archive and the bean is a selected alternative of the bean archive, and the bean class is required
                to be accessible to classes in the module, according to the class accessibility requirements of the module architecture.
            </text>
            <assertion id="d" implied="true">
                <text>Check an enabled session bean can be injected</text>
            </assertion>

            <assertion id="j" implied="true">
                <text>Check a disabled session bean is not injectable</text>
            </assertion>

            <assertion id="k" implied="true">
                <text>Check a specialized session bean is not injectable</text>
            </assertion>

            <assertion id="p" implied="true">
                <text>Check a selected alternative being session bean is injected</text>
            </assertion>

        </group>
    </section>

    <section id="declaring_selected_alternatives_application_ee" title="Declaring selected alternatives for an application in Jakarta EE" level="3">

        <assertion id="a" implied="true">
            <text>A stereotype may declare an |@Alternative| annotation, which specifies that every bean with the stereotype is an alternative.</text>
        </assertion>

        <group>
            <text>An alternative may be given a priority for the application by placing the |@Priority| annotation on the bean class of a session bean.</text>
            <assertion id="ab">
                <text>Test |@Priority| on the bean class of a session bean.</text>
            </assertion>
        </group>
    </section>

    <section id="declaring_selected_alternatives_bean_archive_ee" title="Declaring selected alternatives for a bean archive in Jakarta EE" level="3">

        <assertion id="a" testable="false">
            <text>An alternative may be explicitly declared using the |&lt;alternatives&gt;| element of the |beans.xml| file of the bean archive. The |&lt;alternative&gt;|
                element contains a list of bean classes and stereotypes.
            </text>
            <note>Statement of intent.</note>
        </assertion>

        <group>
            <text>An alternative is selected for the bean archive if the alternative is a session bean and the bean class of the bean is listed.</text>
            <assertion id="bb">
                <text>Test selected session bean.</text>
            </assertion>
        </group>
    </section>


    <section id="unsatisfied_and_ambig_dependencies_ee" title="Unsatisfied and ambiguous dependencies in Jakarta EE" level="3">
        <group>
            <text>The container must validate all injection points of all enabled beans, all observer methods, all disposer methods and all other Jakarta EE
                component classes supporting injection when the application is initialized to ensure that there are no unsatisfied or ambiguous dependencies. If
                an unsatisfied or ambiguous dependency exists, the container automatically detects the problem and treats it as a deployment problem.
            </text>
            <assertion id="ad">
                <text>Test unsatisfied dependency for Jakarta EE component.</text>
            </assertion>
            <assertion id="ah">
                <text>Test ambiguous dependency for Jakarta EE component.</text>
            </assertion>
        </group>
    </section>

    <section id="name_resolution_ee" title="EL name resolution" level="2">
        <assertion id="a">
            <text>An EL name resolves to a bean if the name can be resolved to a bean according to rules in 5.3, "Name resolution", and the bean is available
                for injection in the war containing the JSP or JSF page with the EL expression.
            </text>
        </assertion>

    </section>

    <section id="ambig_names_ee" title="Ambiguous EL names" level="3">

    </section>

    <section id="injection_ee" title="Dependency injection in Jakarta EE" level="2">
        <assertion id="a">
            <text>The container is required to perform dependency injection whenever it creates a contextual instance of a session bean.</text>
        </assertion>

        <assertion id="c">
            <text>The container is required to perform dependency injection whenever it instantiates non-contextual instances of session beans (for example,
                session beans obtained by the application from JNDI or injected using |@EJB|).
            </text>
        </assertion>

        <group>
            <text>The container is required to perform dependency injection whenever it instantiates instances of any other Jakarta EE component class supporting
                injection.
            </text>
            <assertion id="ea">
                <text>Test injection into a servlet listener</text>
            </assertion>
            <assertion id="eb">
                <text>Test injection into a tag handler</text>
            </assertion>
            <assertion id="ec">
                <text>Test injection into a tag library listener</text>
            </assertion>
            <assertion id="ed">
                <text>Test injection into an EJB Interceptor</text>
            </assertion>
            <assertion id="ee">
                <text>Test injection into a WS endpoint</text>
            </assertion>
            <assertion id="ef">
                <text>Test injection into a servlet</text>
            </assertion>
            <assertion id="eg">
                <text>Test injection into a filter</text>
            </assertion>
        </group>

        <assertion id="f" testable="false">
            <text>A Jakarta EE 5 container is not required to support injection for non-contextual objects.</text>
        </assertion>

    </section>

    <section id="instantiation_ee" title="Injection using the bean constructor in Jakarta EE" level="3">

        <group>
            <text>The bean constructor may be identified by annotating the constructor |@Inject|</text>
            <assertion id="a" implied="true">
                <text>Test an @Inject constructor is used on a session bean</text>
            </assertion>
        </group>

        <group>
            <text>When the container instantiates a session bean with a constructor annotated |@Inject|, the container calls this constructor, passing an
                injectable reference to each parameter. If there is no constructor annotated |@Inject|, the container calls the constructor with no parameters.
            </text>
            <assertion id="ab">
                <text>Test session bean with a constructor annotated |@Inject|.</text>
            </assertion>
            <assertion id="bb">
                <text>Test constructor with no parameters is used for a session bean</text>
            </assertion>
        </group>


    </section>

    <section id="fields_initializer_methods_ee" title="Injection of fields and initializer methods in Jakarta EE" level="3">
        <group>
            <text>When the container creates a new instance of session bean the container must: Initialize the values of all injected fields. The container sets
                the value of each injected field to an injectable reference. Call all initializer methods, passing an injectable reference to each parameter.
            </text>
            <assertion id="aa">
                <text>Test session bean fields injected</text>
            </assertion>
            <assertion id="ab">
                <text>Test session bean initializer methods called</text>
            </assertion>
            <assertion id="ae">
                <text>Test Servlet fields injected</text>
            </assertion>
            <assertion id="af">
                <text>Test Servlet initializer methods called</text>
            </assertion>
            <assertion id="ag">
                <text>Test Servlet Filter fields injected</text>
            </assertion>
            <assertion id="ah">
                <text>Test Servlet Filter initializer methods called</text>
            </assertion>
            <assertion id="ai">
                <text>Test Servlet Listener fields injected</text>
            </assertion>
            <assertion id="aj">
                <text>Test Servlet Listener initializer methods called</text>
            </assertion>
            <assertion id="ak">
                <text>Test non-contextual session bean fields injected</text>
            </assertion>
            <assertion id="al">
                <text>Test non-contextual session bean initializer methods called</text>
            </assertion>
            <assertion id="am">
                <text>Test tag handler fields injected</text>
            </assertion>
            <assertion id="an">
                <text>Test tag handler initializer methods called</text>
            </assertion>
            <assertion id="ao">
                <text>Test EJB interceptor fields injected</text>
            </assertion>
            <assertion id="ap">
                <text>Test EJB interceptor initializer methods called</text>
            </assertion>
            <assertion id="aq">
                <text>Test WS endpoint fields injected</text>
            </assertion>
            <assertion id="ar">
                <text>Test WS endpoint bean initializer methods called</text>
            </assertion>
            <assertion id="as">
                <text>Test tag handler listener fields injected</text>
            </assertion>
            <assertion id="at">
                <text>Test tag handler listener initializer methods called</text>
            </assertion>
            <assertion id="au">
                <text>Test JSF managed bean fields injected</text>
            </assertion>
            <assertion id="av">
                <text>Test JSF managed bean initializer methods called</text>
            </assertion>
        </group>

        <group>
            <text>The container must ensure that: Initializer methods declared by a class X in the type hierarchy of the bean are called after all injected
                fields declared by X or by superclasses of X have been initialized, and after all Jakarta EE component environment resource dependencies declared
                by X or by superclasses of X have been injected. Any |@PostConstruct| callback declared by a class X in the type hierarchy of the bean is called
                after all initializer methods declared by X or by superclasses of X have been called, after all injected fields declared by X or by superclasses
                of X have been initialized, and after all Jakarta EE component environment resource dependencies declared by X
                or by superclasses of X have been injected. Any servlet |init()| method is called after all initializer methods have been called, all injected
                fields have been initialized and all Jakarta EE component environment resource dependencies have been injected.
            </text>
            <assertion id="ba">
                <text>Test session bean initializer methods called after injected field of X</text>
            </assertion>
            <assertion id="bb">
                <text>Test session bean initializer methods called after injected field of superclass of X</text>
            </assertion>
            <assertion id="bc">
                <text>Test session bean initializer methods called after EE resource injection of X</text>
            </assertion>
            <assertion id="bd">
                <text>Test session bean initializer methods called after EE resource injection of superclass of X</text>
            </assertion>
            <assertion id="be">
                <text>Test session bean @PostConstruct called after initializer of X</text>
            </assertion>
            <assertion id="bf">
                <text>Test session bean @PostConstruct called after initializer of superclass of X</text>
            </assertion>
            <assertion id="bi">
                <text>Test managed bean initializer methods called after EE resource injection of X</text>
            </assertion>
            <assertion id="bj">
                <text>Test managed bean initializer methods called after EE resource injection of superclass of X</text>
            </assertion>
            <assertion id="bm">
                <text>Servlet |init()| method called after initializer method</text>
            </assertion>
            <assertion id="bn">
                <text>Servlet |init()| method called after injected fields</text>
            </assertion>
            <assertion id="bo">
                <text>Servlet |init()| method called after Jakarta EE resource injection</text>
            </assertion>
            <assertion id="bp">
                <text>Servlet Filter |init()| method called after initializer method</text>
            </assertion>
            <assertion id="bq">
                <text>Servlet Filter |init()| method called after injected fields</text>
            </assertion>
            <assertion id="br">
                <text>Servlet Filter |init()| method called after Jakarta EE resource injection</text>
            </assertion>
        </group>
    </section>

    <section id="dependent_objects_destruction_ee" title="Destruction of dependent objects in Jakarta EE" level="3">
        <assertion id="a">
            <text>When the container destroys an instance of a bean, the container destroys all dependent objects, as defined in Section 6.4.2, "Destruction of
                objects with scope @Dependent", after the |@PreDestroy| callback completes.
            </text>
        </assertion>
    </section>

    <section id="bean_metadata_ee" title="Bean metadata in Jakarta EE" level="3">
        <assertion id="a">
            <text>Interceptor and decorator instances associated with Jakarta EE components that are not considered beans
                (as defined by this specification) cannot obtain information about the beans they intercept and
                decorate (as defined in Bean metadata) and thus null is injected into relevant injection points.
            </text>
        </assertion>
    </section>

    <section id="contexts_ee" title="Scopes and contexts in Jakarta EE" level="1"></section>

    <section id="dependent_context_ee" title="Dependent pseudo-scope in Jakarta EE" level="2">
        <assertion id="ca">
            <text>When a bean is declared to have |@Dependent| scope, when a unified EL expression in a JSF or JSP page that refers to the bean by its EL name
                is evaluated, at most one instance of the bean is instantiated. This instance exists to service just a single evaluation of the EL expression.
                It is reused if the bean EL name appears multiple times in the EL expression, but is never reused when the EL expression is evaluated again, or
                when another EL expression is evaluated.
            </text>
        </assertion>
    </section>

    <section id="dependent_objects_ee" title="Dependent objects in Jakarta EE" level="3">

    </section>

    <section id="dependent_destruction_ee" title="Destruction of objects with scope @Dependent in Jakarta EE" level="3">

        <group>
            <text>The container must ensure that all dependent objects of a non-contextual instance of a bean or other Jakarta EE component class are destroyed
                when the instance is destroyed by the container.
            </text>
            <assertion id="aaab">
                <text>Test with a Jakarta EE component.</text>
            </assertion>
        </group>
        <assertion id="eee">
            <text>The container must ensure that all |@Dependent| scoped contextual instances created during evaluation of a Unified EL expression in a JSP or
                JSF page are destroyed when the evaluation completes.
            </text>
        </assertion>
    </section>

    <section id="dependent_scope_el" title="Dependent pseudo-scope and Unified EL" level="3">
        <assertion id="a">
            <text>Suppose a Unified EL expression in a JSF or JSP page refers to a bean with scope |@Dependent| by its EL name. Each time the EL expression is
                evaluated the bean is instantiated at most once, and the resulting instance is reused for every appearance of the EL name, and the resulting
                instance is destroyed when the evaluation completes.
            </text>
        </assertion>

        <assertion id="b" testable="false">
            <text>Portable extensions that integrate with the container via Unified EL should also ensure that these rules are enforced.</text>
        </assertion>
    </section>

    <section id="passivating_scope_ee" title="Passivation and passivating scopes in Jakarta EE" level="2"></section>

    <section id="passivation_capable_ee" title="Passivation capable beans in Jakarta EE" level="3">

        <group>
            <text>As defined by the EJB specification, a stateful session bean is passivation capable if interceptors and decorators of the bean are passivation
                capable, and the stateful session bean does not have the |passivationCapable| flag set to false.
            </text>
            <assertion id="aa">
                <text>Test a passivation capable stateful session bean with |passivationCapable| flag set to true.</text>
            </assertion>
            <assertion id="ab">
                <text>Test a stateful session bean with |passivationCapable| flag set to false.</text>
            </assertion>
        </group>

        <assertion id="i" testable="false">
            <text>As defined by the EJB specification, a stateless session bean or a singleton session bean is not passivation capable.</text>
            <note>Not possible to test - a stateless session bean must belong to the @Dependent pseudo-scope, a singleton bean must belong to either the
                @ApplicationScscope or to the @Dependent pseudo-scope.
            </note>
        </assertion>
    </section>

    <section id="passivation_capable_dependency_ee" title="Passivation capable dependencies in java EE" level="3">

        <assertion id="aa">
            <text>The container must guarantee that all stateless session beans are passivation capable dependencies.</text>
        </assertion>

        <assertion id="ab">
            <text>The container must guarantee that all singleton session beans are passivation capable dependencies.</text>
        </assertion>

        <assertion id="ac">
            <text>The container must guarantee that all passivation capable stateful session beans are passivation capable dependencies.</text>
        </assertion>

        <group>
            <text>The container must guarantee that all resources are passivation capable dependencies.</text>
            <assertion id="da">
                <text>Test resource for a Jakarta EE resource.</text>
            </assertion>
            <assertion id="db">
                <text>Test resource for a persistence unit.</text>
            </assertion>
            <assertion id="dc">
                <text>Test resource for a persistence context.</text>
            </assertion>
            <assertion id="dd">
                <text>Test resource for a remote EJB.</text>
            </assertion>
            <assertion id="de">
                <text>Test resource for a web service.</text>
            </assertion>
        </group>

    </section>

    <section id="passivation_validation_ee" title="Validation of passivation capable beans and dependencies in Jakarta EE" level="3">

        <group>
            <text>If a stateful session bean which declares a passivating scope, or a built-in bean is not passivation capable then the container automatically
                detects the problem and treats it as a deployment problem.
            </text>
            <assertion id="aa">
                <text>Test non-transient injected field.</text>
            </assertion>
            <assertion id="b">
                <text>Test stateful session bean.</text>
            </assertion>
        </group>

        <assertion id="ba">
            <text>If a stateful session bean which declares a passivating scope has a non-transient injected field that does not resolve to a passivation
                capable dependency, then the container automatically detects the problem and treats it as a deployment problem.
            </text>
        </assertion>

        <group>
            <text>If a stateful session bean has an interceptor or decorator with a non-transient injected field that does not resolve to a passivation capable
                dependency, then the container automatically detects the problem and treats it as a deployment problem.
            </text>
            <assertion id="bda">
                <text>Test an interceptor with an injected field.</text>
            </assertion>
            <assertion id="bdd">
                <text>Test a decorator with an injected field.</text>
            </assertion>
        </group>

        <group>
            <text>If a bean which declares a passivating scope type has a decorator or interceptor which is not a passivation capable dependency, the container
                automatically detects the problem and treats it as a deployment problem.
            </text>
            <assertion id="hb">
                <text>Test a stateful session bean with decorator which is not a passivation capable dependency.</text>
            </assertion>
            <assertion id="hd">
                <text>Test a stateful session bean with interceptor which is not a passivation capable dependency.</text>
            </assertion>
        </group>

        <assertion id="j" implied="true">
            <text>Stateful session bean which does not declare a passivating scope needn't be passivation capable.</text>
            <note>This was not allowed in CDI 1.0</note>
        </assertion>

        <group>
            <text>If a producer method or field of scope |@Dependent| returns an unserializable object for injection into an injection point that requires a
                passivation capable dependency, the container must throw an |IllegalProductException|
            </text>

            <assertion id="fab">
                <text>Test for a runtime exception with a producer method.</text>
            </assertion>

            <assertion id="fbb">
                <text>Test for a runtime exception with a producer field.</text>
            </assertion>
        </group>
    </section>

    <section id="builtin_contexts_ee" title="Context management for built-in scopes in Jakarta EE" level="2">
        <group>
            <text>The built-in request and application context objects are active during servlet, web service and EJB invocations, and the built in session and
                request context objects are active during servlet and web service invocations. For other kinds of invocations, a portable extension may define a
                custom context object for any or all of the built-in scopes.
            </text>
        </group>
    </section>

    <section id="request_context_ee" title="Request context lifecycle in Jakarta EE" level="3">

        <group>
            <text>The request scope is active during the |service()| method of any servlet in the web application, during the |doFilter()| method of any servlet
                filter and when the container calls any |ServletRequestListener| or |AsyncListener|.
            </text>
            <assertion id="aa">
                <text>Check |service()| method.</text>
            </assertion>
            <assertion id="ab">
                <text>Check |doFilter()| method.</text>
            </assertion>
            <assertion id="ac">
                <text>Check |ServletRequestListener|.</text>
            </assertion>
            <assertion id="ad">
                <text>Check |AsyncListener|.</text>
            </assertion>
        </group>

        <assertion id="b">
            <text>The request scope is active during any Jakarta EE web service invocation.</text>
        </assertion>

        <group>
            <text>The request scope is active during any remote method invocation of any EJB, during any asynchronous method invocation of any EJB, during any
                call to an EJB timeout method and during message delivery to any EJB message-driven bean.
            </text>

            <assertion id="ga">
                <text>Test the request scope is active during a remote method invocation of any EJB.</text>
            </assertion>

            <assertion id="gb">
                <text>Test the request scope is active during any asynchronous method invocation of any EJB.</text>
            </assertion>

            <assertion id="gc">
                <text>Test the request scope is active during any call to an EJB timeout method.</text>
            </assertion>

            <assertion id="gd">
                <text>Test the request scope is active during message delivery to any EJB message-driven bean.</text>
            </assertion>
        </group>

        <group>
            <text>The request context is destroyed at the end of the servlet request, after the |service()| method and all |doFilter()| methods, and all
                |requestDestroyed()| and |onComplete()| notifications return.
            </text>
            <assertion id="ba">
                <text>Check |service()| method.</text>
            </assertion>
            <assertion id="bb">
                <text>Check |doFilter()| methods.</text>
            </assertion>
            <assertion id="bc">
                <text>Check |requestDestroyed()| notification.</text>
            </assertion>
            <assertion id="bd">
                <text>Check |onComplete()| notification.</text>
            </assertion>
        </group>

        <assertion id="d">
            <text>The request context is destroyed after the web service invocation completes.</text>
        </assertion>

        <group>
            <text>The request context is destroyed after the EJB remote method invocation, asynchronous method invocation, timeout or message delivery
                completes.
            </text>

            <assertion id="ha">
                <text>Test the request context is destroyed after an EJB remote method invocation.</text>
            </assertion>

            <assertion id="hb">
                <text>Test the request context is destroyed after an EJB asynchronous method invocation.</text>
            </assertion>

            <assertion id="hc">
                <text>Test the request context is destroyed after the EJB timeout.</text>
            </assertion>

            <assertion id="hd">
                <text>Test the request context is destroyed after the message delivery completes.</text>
            </assertion>
        </group>

        <group>
            <text>An event with qualifier |@Initialized(RequestScoped.class)| is fired when the request context is initialized and an event with qualifier
                |@Destroyed(RequestScoped.class)| when the request context is destroyed.
            </text>
            <assertion id="ja">
                <text>The event payload is the |ServletRequest| if the context is initialized or destroyed due to a servlet request.</text>
            </assertion>
            <assertion id="jb">
                <text>The event payload is the |ServletRequest| if the context is initialized or destroyed due to a web service invocation.</text>
            </assertion>
            <assertion id="jc">
                <text>The event payload is the |java.lang.Object| if the context is initialized or destroyed due to a EJB remote method invocation.</text>
            </assertion>
            <assertion id="jd">
                <text>The event payload is the |java.lang.Object| if the context is initialized or destroyed due to a EJB asynchronous method invocation.</text>
            </assertion>
            <assertion id="je">
                <text>The event payload is the |java.lang.Object| if the context is initialized or destroyed due to a EJB timeout method invocation.</text>
            </assertion>
            <assertion id="jf">
                <text>The event payload is the |java.lang.Object| if the context is initialized or destroyed due to a message delivery to any EJB message-driven
                    bean.
                </text>
            </assertion>
        </group>

    </section>
    <section id="session_context_ee" title="Session context lifecycle in Jakarta EE" level="3">
        <assertion id="aa">
            <text>The session scope is active during the |service()| method of any servlet in the web application.</text>
        </assertion>

        <assertion id="ab">
            <text>The session scope is active during the |doFilter()| method of any servlet filter.</text>
        </assertion>

        <assertion id="ac">
            <text>The session scope is active when the container calls any |HttpSessionListener|.</text>
        </assertion>

        <assertion id="ad">
            <text>The session scope is active when the container calls any |AsyncListener|.</text>
        </assertion>

        <assertion id="ae">
            <text>The session scope is active when the container calls any |ServletRequestListener|.</text>
        </assertion>

        <assertion id="b">
            <text>The session context is shared between all servlet requests that occur in the same HTTP servlet session.</text>
        </assertion>

        <assertion id="ca">
            <text>The session context is destroyed at the very end of any request in which |invalidate()| was called, after all filters and
                |ServletRequestListeners| have been called.
            </text>
        </assertion>

        <assertion id="cb">
            <text>The session context is destroyed when the |HTTPSession| times out, after all |HttpSessionListener|s have been called.</text>
        </assertion>

        <assertion id="da">
            <text>An event with the |HttpSession| as payload and with qualifier |@Initialized(SessionScoped.class)| is synchronously fired when the session
                context is
                initialized.
            </text>
        </assertion>

        <assertion id="db">
            <text>An event with the |HttpSession| as payload and with qualifier |@BeforeDestroyed(SessionScoped.class)| is synchronously
                fired when the session context is about to be destroyed, i.e. before the actual destruction.
            </text>
        </assertion>

        <assertion id="dc">
            <text>An event with the |HttpSession| as payload and with qualifier |@Destroyed(SessionScoped.class)| is synchronously fired when the session
                context is
                destroyed.
            </text>
        </assertion>

    </section>

    <section id="application_context_ee" title="Application context lifecycle in Jakarta EE" level="3">
        <group>
            <text>The application scope is active during the |service()| method of any servlet in the web application, during the |doFilter()| method of any
                servlet filter and when the container calls any |ServletContextListener|, |HttpSessionListener|, |AsyncListener| or |ServletRequestListener|.
            </text>
            <assertion id="aa">
                <text>Check service method</text>
            </assertion>

            <assertion id="ab">
                <text>Check filter.</text>
            </assertion>

            <assertion id="ac">
                <text>Check |ServletContextListener|.</text>
            </assertion>

            <assertion id="ad">
                <text>Check |HttpSessionListener|</text>
            </assertion>

            <assertion id="ae">
                <text>Check |AsyncListener|</text>
            </assertion>

            <assertion id="af">
                <text>Check |ServletRequestListener|</text>
            </assertion>
        </group>

        <assertion id="b">
            <text>The application scope is active during any Jakarta EE web service invocation.</text>
        </assertion>

        <group>
            <text>The application scope is also active during any remote method invocation of any EJB, during any asynchronous method invocation of any EJB,
                during any call to an EJB timeout method and during message delivery to any EJB message-driven bean.
            </text>
            <assertion id="da">
                <text>Test remote method invocation</text>
            </assertion>

            <assertion id="db">
                <text>Test asynchronous method invocation</text>
            </assertion>

            <assertion id="dc">
                <text>Test EJB timeout method</text>
            </assertion>

            <assertion id="dd">
                <text>Test message delivery to any EJB message-driven bean.</text>
            </assertion>
        </group>

        <group>
            <text>The application scope is active when the disposer method or |@PreDestroy| callback of any bean with any normal scope other than
                |@ApplicationScoped| is called.
            </text>
            <assertion id="dg">
                <text>Test disposer method</text>
            </assertion>
            <assertion id="dh">
                <text>Test |@PreDestroy| method</text>
            </assertion>
        </group>

        <assertion id="h">
            <text>The application scope is active during |@PostConstruct| callback of any bean.</text>
        </assertion>

        <assertion id="e">
            <text>The application context is shared between all servlet requests, asynchronous observer method notifications, web service invocations, EJB
                remote method invocations, EJB asynchronous method invocations, EJB timeouts and message deliveries to message driven beans that execute within
                the same application.
            </text>
            <note>A single test needs check *all* these request types</note>
        </assertion>

        <assertion id="f">
            <text>The application context is destroyed when the application is shut down.</text>
        </assertion>

        <group>
            <text>An event with qualifier |@Initialized(ApplicationScoped.class)| is fired when the application context is initialized and an event with
                qualifier |@Destroyed(ApplicationScoped.class)| is fired when the application is destroyed.
            </text>
            <assertion id="ga">
                <text>The event payload is the |ServletContext| if the application is a web application deployed to a Servlet container.</text>
            </assertion>
            <assertion id="gb" testable="false">
                <text>the |java.lang.Object| for other types of application.</text>
            </assertion>
        </group>

    </section>

    <section id="conversation_context_ee" title="Conversation context lifecycle in Jakarta EE" level="3">

        <group>
            <text>The conversation scope is active during all Servlet requests.</text>
            <assertion id="a">
                <text>Test JSF request.</text>
            </assertion>
            <assertion id="aa">
                <text>Test non-JSF servlet request.</text>
                <note>Test required since CDI 1.0 defined conversation for JSF requests only.</note>
            </assertion>
        </group>

        <group>
            <text>An event with qualifier |@Initialized(ConversationContext.class)| is fired when the conversation context is initialized. An event with
                qualifier |@BeforeDestroyed(ConversationScoped.class)| is synchronously fired when the conversation is about to be destroyed, i.e. before the
                actual destruction.An event with qualifier |@Destroyed(ConversationScoped.class)| is fired when the conversation is destroyed. The event payload
                is the conversation id if the conversation context is destroyed and is not associated with a current Servlet request, the |ServletRequestEvent|
                if the application is a web application deployed to a Servlet container, any |java.lang.Object| for other types of application.
            </text>
            <assertion id="ba">
                <text>An event with the |ServletRequest| as the payload and with qualifier |@Initialized(ConversationContext.class)| is synchronously fired when
                    the
                    conversation context is initialized.
                </text>
            </assertion>
            <assertion id="bb">
                <text>An event with the |ServletRequest| as the payload and with qualifier |@BeforeDestroyed(ConversationScoped.class)|
                    is synchronously fired when the conversation is about to be destroyed
                </text>
            </assertion>
            <assertion id="bc">
                <text>An event with the |ServletRequest| as the payload and with qualifier |@Destroyed(ConversationContext.class)| is synchronously fired when
                    the
                    conversation context is destroyed.
                </text>
            </assertion>
            <assertion id="bd">
                <text>An event with the conversation id as the payload and with qualifier |@Destroyed(ConversationContext.class)| is fired when the conversation
                    context is destroyed and is not associated with a current Servlet request.
                </text>
            </assertion>
        </group>

        <assertion id="c" testable="false">
            <text>Any Servlet request has exactly one associated conversation.</text>
            <note>We have no portable way how to test it</note>
        </assertion>

        <assertion id="d">
            <text>The container provides a filter with the name "CDI Conversation Filter", which may be mapped in |web.xml|, allowing the user alter when the
                conversation is associated with the servlet request.
            </text>
        </assertion>

        <group>
            <text>If this filter is not mapped in any |web.xml| in the application, the conversation associated with a Servlet request is determined at the
                beginning of the request before calling any |service()| method of any servlet in the web application, calling the |doFilter()| method of any
                servlet filter in the web application and before the container calls any |ServletRequestListener| or |AsyncListener| in the web application.
            </text>
            <assertion id="da">
                <text>Test |service()| method of a servlet.</text>
                <note>This may only be tested indirectly</note>
            </assertion>
            <assertion id="db">
                <text>Test |doFilter()| method of a servlet filter.</text>
                <note>This may only be tested indirectly</note>
            </assertion>
            <assertion id="dc">
                <text>Test |ServletRequestListener|.</text>
                <note>This may only be tested indirectly</note>
            </assertion>
            <assertion id="dd">
                <text>Test |AsyncListener|.</text>
                <note>This may only be tested indirectly</note>
            </assertion>
        </group>

        <assertion id="e">
            <text>By default, a conversation is transient.</text>
        </assertion>

        <assertion id="f">
            <text>A transient conversation may be marked long-running by calling |Conversation.begin()|</text>
        </assertion>

        <assertion id="g">
            <text>A long-running conversation may be marked transient by calling |Conversation.end()|</text>
        </assertion>

        <assertion id="ha">
            <text>All long-running conversations have a string-valued unique identifier, _which may be set by the application_ when the conversation is marked
                long-running~, or generated by the container~
            </text>
        </assertion>

        <assertion id="hb">
            <text>All long-running conversations have a string-valued unique identifier, _which may be_ ~set by the application when the conversation is marked
                long-running, or~ _generated by the container_
            </text>
        </assertion>

        <assertion id="j">
            <text>If the conversation associated with the current Servlet request is in the transient state at the end of a Servlet request, it is destroyed,
                and the conversation context is also destroyed.
            </text>
        </assertion>

        <assertion id="k">
            <text>If the conversation associated with the current Servlet request is in the long-running state at the end of a Servlet request, it is not
                destroyed.
            </text>
        </assertion>

        <assertion id="n">
            <text>The long-running conversation associated with a request may be propagated to any Servlet request via use of a request parameter named |cid|
                containing the unique identifier of the conversation. In this case, the application must manage this request parameter.
            </text>
        </assertion>

        <assertion id="l">
            <text>The long-running conversation context associated with a request that renders a JSF view is automatically propagated to any faces request (JSF
                form submission) that originates from that rendered page.
            </text>
        </assertion>

        <assertion id="m">
            <text>The long-running conversation context associated with a request that results in a JSF redirect (via a navigation rule) is automatically
                propagated to the resulting non-faces request, and to any other subsequent request to the same URL. This is accomplished via use of a request
                parameter named |cid| containing the unique identifier of the conversation.
            </text>
        </assertion>

        <group>
            <text>When no conversation is propagated to a Servlet request, or if a request parameter named |conversationPropagation| has the value |none| the
                request is associated with a new transient conversation.
            </text>
            <assertion id="o">
                <text>The request is associated with a new transient conversation.</text>
            </assertion>
            <assertion id="oa">
                <text>Test request parameter named |conversationPropagation|.</text>
            </assertion>
        </group>

        <assertion id="p">
            <text>All long-running conversations are scoped to a particular HTTP servlet session and may not cross session boundaries.</text>
        </assertion>

        <assertion id="qa">
            <text>When the HTTP servlet session is invalidated, all long-running conversation contexts created during the current session are destroyed, after
                the servlet |service()| method completes.
            </text>
        </assertion>

        <assertion id="r" testable="false">
            <text>The container is permitted to arbitrarily destroy any long-running conversation that is associated with no current JSF request, in order to
                conserve resources
            </text>
            <note>In other words, this is unspecified</note>
        </assertion>

        <assertion id="ta" testable="false">
            <text>The conversation timeout, which may be specified by calling |Conversation.setTimeout()| is a hint to the container that a conversation should
                not be destroyed if it has been active within the last given interval in milliseconds.
            </text>
            <note>Not required</note>
        </assertion>

        <assertion id="tb">
            <text>If the propagated conversation cannot be restored, the container must associate the request with a new transient conversation and throw an
                exception of type |jakarta.enterprise.context.NonexistentConversationException|.
            </text>
        </assertion>

        <group>
            <text>The container ensures that a long-running conversation may be associated with at most one request at a time, by blocking or rejecting
                concurrent requests. If the container rejects a request, it must associate the request with a new transient conversation and throw an exception
                of type |jakarta.enterprise.context.BusyConversationException|.
            </text>
            <assertion id="ua">
                <text>Test the container blocks the concurrent request.</text>
                <note>This assertion may turn in testable=false, as the container is not actually required to reject the concurrent requests.</note>
            </assertion>
        </group>

    </section>

    <section id="lifecycle_ee" title="Lifecycle of contextual instances" level="1">

    </section>

    <section id="biz_method_ee" title="Container invocations and interception in Jakarta EE" level="2">
        <assertion id="ac">
            <text>When the application invokes a business method of a session bean via an EJB remote or local reference, the invocation is treated as a business
                method invocation.
            </text>
        </assertion>
        <assertion id="ig">
            <text>Invocation of EJB timer service timeouts by the container are not business method invocations, but are intercepted by interceptors for EJB
                timeouts.
            </text>
        </assertion>

        <group>
            <text>Invocations of message listener methods of message-driven beans during message delivery are business method invocations.</text>
            <assertion id="la">
                <text>Verify message listener methods are intercepted</text>
            </assertion>
        </group>

        <group>
            <text>If, and only if, the invocation is a business method invocation it passes through method interceptors and decorators, and in the case of a
                session bean, it is subject to EJB services such a declarative transaction management, concurrency, security and asynchronicity, as defined by
                the EJB specification.
            </text>

            <assertion id="c">
                <text>Verify that a session bean's business methods are intercepted</text>
            </assertion>

            <assertion id="d">
                <text>Verify that a session bean's business methods are decorated</text>
            </assertion>

            <assertion id="f" testable="false">
                <text>Verify that a session bean's business methods receive EJB services</text>
                <note>This is tested by the EJB TCK</note>
            </assertion>

            <assertion id="h">
                <text>Verify that a non-contextual session bean's business methods are intercepted</text>
            </assertion>

            <assertion id="i">
                <text>Verify that a non-contextual session bean's business methods are decorated</text>
            </assertion>

        </group>

    </section>

    <section id="stateful_lifecycle" title="Lifecycle of EJB stateful session beans" level="3">
        <assertion id="aa" testable="false">
            <text>When the |create()| method of a |Bean| object that represents a stateful session bean that is called, the container creates and returns a
                container-specific internal local reference to a new session bean instance. The reference must be passivation capable. This reference is not
                directly exposed to the application.
            </text>
            <note>It's not possible to test container-specific internal local reference that is not directly exposed to the application.</note>
        </assertion>

        <assertion id="bb">
            <text>Before injecting or returning a contextual instance to the application, the container transforms its internal reference into an object that
                implements the bean types expected by the application and delegates method invocations to the underlying stateful session bean instance. This
                object must be passivation capable.
            </text>
        </assertion>

        <assertion id="bc">
            <text>When the |destroy()| method is called, and if the underlying EJB was not already removed by direct invocation of a remove method by the
                application, the container removes the stateful session bean. The |@PreDestroy| callback must be invoked by the container.
            </text>
        </assertion>
    </section>

    <section id="stateless_lifecycle" title="Lifecycle of EJB stateless and singleton session beans" level="3">
        <assertion id="a" testable="false">
            <text>When the |create()| method of a Bean object that represents a stateless session or singleton session bean is called, the container
                creates and returns a container-specific internal local reference to the session bean. This reference is not directly exposed to the
                application.
            </text>
            <note>It's not possible to test container-specific internal local reference that is not directly exposed to the application.</note>
        </assertion>

        <assertion id="b">
            <text>Before injecting or returning a contextual instance to the application, the container transforms its internal reference into an object that
                implements the bean types expected by the application and delegates method invocations to the underlying session bean. This object must be
                passivation capable.
            </text>
        </assertion>

        <assertion id="c">
            <text>When the |destroy()| method is called, the container simply discards this internal reference.</text>
        </assertion>
    </section>

    <section id="resource_lifecycle" title="Lifecycle of resources" level="3">
        <group>
            <text>When the |create()| method of a |Bean| object that represents a resource is called, the container creates and returns a container-specific
                internal reference to the Jakarta EE component environment resource, entity manager, entity manager factory, remote EJB instance or web service
                reference. This reference is not directly exposed to the application.
            </text>

            <assertion id="la">
                <text>Check Jakarta EE component environment resource</text>
            </assertion>

            <assertion id="lb">
                <text>Check Entity Manager</text>
            </assertion>

            <assertion id="lc">
                <text>Check Entity Manager Factory</text>
            </assertion>

            <assertion id="ld">
                <text>Check Remote EJB instance</text>
            </assertion>
            <assertion id="le">
                <text>Check Web Service Reference</text>
            </assertion>
        </group>

        <group>
            <text>Before injecting or returning a contextual instance to the application, the container transforms its internal reference into an object that
                implements the bean types expected by the application and delegates method invocations to the underlying resource, entity manager, entity
                manager factory, remote EJB instance or web service reference. This object must be passivation capable.
            </text>

            <assertion id="ma">
                <text>Check delegations to underlying Jakarta EE component environment resource</text>
            </assertion>

            <assertion id="mb">
                <text>Check injected Jakarta EE component environment resource is passivation capable</text>
            </assertion>

            <assertion id="mc">
                <text>Check delegations to underlying Entity Manager</text>
            </assertion>

            <assertion id="md">
                <text>Check injected Entity Manager is passivation capable</text>
            </assertion>

            <assertion id="me">
                <text>Check delegations to Entity Manager Factory</text>
            </assertion>

            <assertion id="mf">
                <text>Check injected Entity Manager Factory is passivation capable</text>
            </assertion>

            <assertion id="mg">
                <text>Check delegations to underlying Remote EJB instance</text>
            </assertion>

            <assertion id="mh">
                <text>Check injected Remote EJB instance is passivation capable</text>
            </assertion>

            <assertion id="mj">
                <text>Check delegations to underlying Web Service Reference</text>
            </assertion>

            <assertion id="mk">
                <text>Check injected Web Service Reference is passivation capable</text>
            </assertion>
        </group>

        <group>
            <text>The container must perform ordinary Jakarta EE component environment injection upon any non-static field that functions as a resource
                declaration, as defined by the Jakarta EE platform and Common Annotations for the Java platform specifications.
            </text>
            <assertion id="o">
                <text>Check @Resource injection</text>
            </assertion>
        </group>

        <assertion id="p" testable="false">
            <text>The container is not required to perform Jakarta EE component environment injection upon a static field. Portable applications should not rely
                upon the value of a static field that functions as a resource declaration.
            </text>
            <note>Defines non-portable behavior</note>
        </assertion>

        <assertion id="q">
            <text>References to EJBs and web services are always dependent scoped and a new instance must be obtained for every injection performed.</text>
        </assertion>

        <assertion id="r">
            <text>For an entity manager associated with a resource definition, it must behave as though it were injected directly using |@PersistencContext|.
            </text>
            <note>Verify that this assertion is testable.</note>
        </assertion>

        <assertion id="s">
            <text>When the |destroy()| method of a bean which represents a remote stateful EJB reference is called, the container will not automatically destroy
                the EJB reference.
            </text>
        </assertion>

    </section>

    <section id="decorators_ee" title="Decorators in Jakarta EE" level="1">

        <assertion id="a">
            <text>When running in Jakarta EE, the container must extend the rules defined for managed beans in Decorators to EJB session beans.</text>
        </assertion>

        <assertion id="b" implied="true">
            <text>A decorator may be enabled for the entire application by applying the |@Priority| annotation, along with a priority value, on the decorator
                class.
            </text>
        </assertion>

        <assertion id="c" implied="true">
            <text>Decorators with the smaller priority values are called first.</text>
        </assertion>

        <assertion id="d" implied="true">
            <text>A decorator may be explicitly enabled by listing its bean class under the |&lt;decorators&gt;| element of the beans.xml file of the bean
                archive.
            </text>
        </assertion>

        <assertion id="e" implied="true">
            <text>A decorator is declared by annotating the bean class with the |@jakarta.decorator.Decorator| stereotype.</text>
        </assertion>

        <assertion id="f" implied="true">
            <text>Decorators are called after interceptors.</text>
        </assertion>

        <assertion id="g" implied="true">
            <text>The order of the decorator declarations determines the decorator ordering. Decorators which occur earlier in the list are called first.</text>
        </assertion>

    </section>

    <section id="decorator_bean_ee" title="Decorator beans in Jakarta EE" level="2">

        <group>
            <text>Whenever a business method is invoked on an instance of a bean with decorators, the container intercepts the business method invocation and,
                after processing all interceptors of the method, invokes decorators of the bean. The container searches for the first decorator of the instance
                that implements the method that is being invoked as a business method. If such decorator exists, the container calls the method of the
                decorator.
            </text>
            <assertion id="ab">
                <text>Test decorator of session bean is called .</text>
            </assertion>
            <assertion id="aci">
                <text>Test injected HttpServletRequest</text>
            </assertion>
            <assertion id="acj">
                <text>Test injected HttpSession</text>
            </assertion>
            <assertion id="ack">
                <text>Test injected ServletContext</text>
            </assertion>
            <assertion id="acl">
                <text>Test injected InjectionPoint</text>
            </assertion>
            <assertion id="acm">
                <text>Test injected Principal</text>
            </assertion>
            <assertion id="acn">
                <text>Test injected UserTransaction</text>
            </assertion>
        </group>

        <assertion id="d" implied="true">
            <text>The decorator class may be abstract.</text>
        </assertion>

        <assertion id="e">
            <text>Decorators of a session bean must comply with the bean provider programming restrictions defined by the EJB specification.</text>
        </assertion>

        <assertion id="f">
            <text>Decorators of a stateful session bean must comply with the rules for instance passivation and conversational state defined by the EJB
                specification.
            </text>
        </assertion>
    </section>


    <section id="interceptors_ee" title="Interceptor bindings in Jakarta EE" level="1">
        <assertion id="b" implied="true">
            <text>A stereotype may declare one interceptor bindings.</text>
        </assertion>
    </section>

    <section id="interceptor_resolution_ee" title="Interceptor resolution in Jakarta EE" level="2">
        <assertion id="a">
            <text>For a custom implementation of the Interceptor interface defined in Section 11.1.2. "The Interceptor interface", the container also calls
                intercepts() to
                determine if the interceptor intercepts an EJB timeout method invocation.
            </text>
        </assertion>
    </section>

    <section id="events_ee" title="Events in Jakarta EE" level="1"></section>

    <section id="observer_methods_ee" title="Observer methods in EJB session beans" level="2">
        <assertion id="d">
            <text>An observer method may also be a non-abstract method of an EJB session bean class. It must be either a business method exposed by a local
                business interface of the EJB or a
                static method of the bean class.
            </text>
        </assertion>

    </section>

    <section id="observes_ee" title="Declaring an observer method in an EJB" level="3">
        <assertion id="g">
            <text>If a non-static method of a session bean class has a parameter annotated |@Observes|, and the method is not a business method exposed by a
                local business interface of the
                EJB, the container automatically detects the problem and treats it as a definition error.
            </text>
        </assertion>
    </section>

    <section id="observer_method_invocation_context_ee" title="Observer method invocation context in Jakarta EE" level="3">
        <assertion id="a">
            <text>The transaction and security contexts for a business method exposed by a local business interface of an EJB session bean also depend upon the
                transaction attribute and @RunAs descriptor, if any.
            </text>
        </assertion>

        <assertion id="b">
            <text>All kinds of observers are called in the same client security context as the invocation of Event.fire() or Event.fireAsync() or
                BeanManager.fireEvent().
            </text>
        </assertion>

    </section>

    <section id="spi_ee" title="Portable extensions in Jakarta EE" level="1">

    </section>

    <section id="bean_ee" title="The Bean interface in Jakarta EE" level="2">

    </section>

    <section id="interceptor_ee" title="The Interceptor interface in Jakarta EE" level="3">
        <assertion id="a">
            <text>When Running in Jakarta EE, the container must extend the rules defined in Section 11.1.2 "The Interceptor interface" and must also ensure that
                PRE_PASSIVATE,
                POST_ACTIVATE and AROUND_TIMEOUT InterceptorType values are linked to EJB lifecycle callback or timeout method.
            </text>
        </assertion>
    </section>

    <section id="injectiontarget_ee" title="InjectionTarget interface in Jakarta EE" level="2">
        <group>
            <text>When running in Jakarta EE, the container must extend the rules defined for InjectionTarget in The Producer and InjectionTarget interfaces and
                must also ensure that:
            </text>
            <assertion id="a">
                <text>when inject() is called, The container performs Jakarta EE component environment injection, according to the semantics required by the Java
                    EE platform specification, sets the value of all injected fields, and calls all initializer methods, as defined in Injection of fields and
                    initializer methods in Jakarta EE.
                </text>
            </assertion>
            <assertion id="b">
                <text>@PostConstruct callback is called according to the semantics required by the Jakarta EE platform specification.</text>
            </assertion>
            <assertion id="c">
                <text>@PreDestroy callback is called according to the semantics required by the Jakarta EE platform specification.</text>
            </assertion>
        </group>

    </section>

    <section id="beanmanager_ee" title="The BeanManager object in Jakarta EE" level="2">

    </section>

    <section id="provider_ee" title="Obtaining a reference to the CDI container in Jakarta EE" level="3">
        <assertion id="d">
            <text>Jakarta EE components may obtain an instance of |BeanManager| from JNDI by looking up the name |java:comp/BeanManager|.</text>
        </assertion>

        <assertion id="e">
            <text>When running in Jakarta EE, when initialize method of CDIProvider is called an UnsupportedOperationException is thrown.</text>
        </assertion>

    </section>

    <section id="bm_wrap_expressionfactory" title="Wrapping a Unified EL ExpressionFactory" level="3">
        <assertion id="a">
            <text>The method |BeanManager.wrapExpressionFactory()| returns a wrapper |jakarta.el.ExpressionFactory| that delegates |MethodExpression| and
                |ValueExpression| creation to the given |ExpressionFactory|.
            </text>
        </assertion>

        <assertion id="b">
            <text>When a Unified EL expression is evaluated using a |MethodExpression| or |ValueExpression| returned by the wrapper |ExpressionFactory|, the
                rules defined in Section 6.4.3, "Dependent pseudo-scope and Unified EL" are enforced by the container.
            </text>
        </assertion>
    </section>

    <section id="alternative_metadata_sources_ee" title="Alternative metadata sources and EJB" level="2">
        <group>
            <text>The container must use the operations of |Annotated| and its subinterfaces to discover program element types and annotations. The container
                must not directly call the Java Reflection API. In particular, the container must call |Annotated.getBaseType()| to determine the type of an
                injection point, event parameter or disposed parameter, call |Annotated.getTypeClosure()| to determine the bean types of any kind of bean, call
                |Annotated.getAnnotations()| to determine the scope, qualifiers, stereotypes and interceptor bindings of a bean, call
                |Annotated.isAnnotationPresent()| and |Annotated.getAnnotation()| to read any bean annotations defined by this specification, and call
                |AnnotatedType.getConstructors()|, |AnnotatedType.getMethods()| and |AnnotatedType.getFields()| to determine the members of a bean class.
            </text>

            <assertion id="kb">
                <text>Check that a |getTypeClosure()| is used to determine the bean types for a session bean. The type closure should be different from the
                    original type specified in the class definition.
                </text>
            </assertion>
        </group>
    </section>

    <section id="init_events_ee" title="Addition to Container lifecycle events in Jakarta EE" level="2">

    </section>

    <section id="process_injection_point_ee" title="ProcessInjectionPoint event and EJB" level="3">
        <assertion id="a">
            <text>When running in Jakarta EE, the container must also fire an event for every injection point of every Jakarta EE component class supporting injection
                that may be instantiated by the container at runtime, including every managed bean declared using @ManagedBean, EJB session or message-driven
                bean.
            </text>
        </assertion>
    </section>

    <section id="process_injection_target_ee" title="ProcessInjectionTarget event and EJB" level="3">
        <group>
            <text>The container must fire an event for every bean, interceptor or decorator. The event object must be of type
                |jakarta.enterprise.inject.spi.ProcessInjectionTarget&lt;X&gt;|, where |x| is the managed bean class.
            </text>
            <assertion id="aab">
                <text>Test event is fired for a session bean</text>
            </assertion>
            <assertion id="aaba">
                <text>Test event is fired for a message driven bean</text>
            </assertion>
            <assertion id="aac">
                <text>Test event is fired for a servlet listener</text>
            </assertion>
            <assertion id="aad">
                <text>Test event is fired for a tag handler</text>
            </assertion>
            <assertion id="aae">
                <text>Test event is fired for a tag library listener</text>
            </assertion>
            <assertion id="aaf">
                <text>Test event is fired for an EJB Interceptor</text>
            </assertion>
            <assertion id="aag">
                <text>Test event is fired for a WS endpoint</text>
            </assertion>
            <assertion id="aah">
                <text>Test event is fired for a servlet</text>
            </assertion>
            <assertion id="aai">
                <text>Test event is fired for a filter</text>
            </assertion>
            <assertion id="aan" implied="true">
                <text>Test supertype for a servlet listener</text>
                <note>See 10.2. Observer resolution</note>
            </assertion>
            <assertion id="aao" implied="true">
                <text>Test supertype and subtype for a tag handler</text>
                <note>See 10.2. Observer resolution</note>
            </assertion>
            <assertion id="aas" implied="true">
                <text>Test supertype and subtype for a servlet</text>
                <note>See 10.2. Observer resolution|</note>
            </assertion>
        </group>
        <group>
            <text>|getAnnotatedType()| returns the |AnnotatedType| representing the managed bean class.</text>
            <assertion id="abb">
                <text>Test type for a session bean</text>
            </assertion>
            <assertion id="abba">
                <text>Test type for a message driven bean</text>
            </assertion>
            <assertion id="abc">
                <text>Test type for a servlet listener</text>
            </assertion>
            <assertion id="abd">
                <text>Test type for a tag handler</text>
            </assertion>
            <assertion id="abe">
                <text>Test type for a tag library listener</text>
            </assertion>
            <assertion id="abf">
                <text>Test type for an EJB Interceptor</text>
            </assertion>
            <assertion id="abg">
                <text>Test type for a WS endpoint</text>
            </assertion>
            <assertion id="abh">
                <text>Test type for a servlet</text>
            </assertion>
            <assertion id="abi">
                <text>Test type for a filter</text>
            </assertion>
        </group>

        <group>
            <text>Any observer of this event is permitted to wrap and/or replace the |InjectionTarget|. The container must use the final value of this property,
                after all observers have been called, whenever it performs injection upon the managed bean, session bean or other Jakarta EE component class
                supporting injection.
            </text>
            <assertion id="eb">
                <text>Test type for a session bean</text>
            </assertion>
            <assertion id="ec">
                <text>Test type for a servlet listener</text>
            </assertion>
            <assertion id="ed">
                <text>Test type for a tag handler</text>
            </assertion>
            <assertion id="ee">
                <text>Test type for a tag library listener</text>
            </assertion>
            <assertion id="ef">
                <text>Test type for an EJB Interceptor</text>
            </assertion>
            <assertion id="eg">
                <text>Test type for a WS endpoint</text>
            </assertion>
            <assertion id="eh">
                <text>Test type for a servlet</text>
            </assertion>
            <assertion id="ei">
                <text>Test type for a filter</text>
            </assertion>
        </group>
    </section>

    <section id="process_bean_attributes_ee" title="ProcessBeanAttributes event and EJB" level="3">
        <group>
            <text>|getAnnotated()| returns the |AnnotatedType| representing the bean class or session bean class, the |AnnotatedMethod| representing the
                producer field, or the |AnnotatedField| representing the producer field.
            </text>
            <assertion id="bab">
                <text>Test session bean.</text>
            </assertion>
        </group>

    </section>

    <section id="process_bean_ee" title="ProcessBean event and EJB" level="3">
        <assertion id="ca">
            <text>For a session bean with bean class |X|, the container must raise an event of type |ProcessSessionBean&lt;X&gt;|.</text>
        </assertion>

        <assertion id="cb">
            <text>Test |ProcessSessionBean| is fired after |ProcessBeanAttributes|.</text>
        </assertion>

        <group>
            <text>The interface |jakarta.enterprise.inject.spi.ProcessBean| is a supertype of all these event types.</text>
            <assertion id="edb">
                <text>Test |ProcessSessionBean|</text>
            </assertion>
        </group>

        <group>
            <text>|getAnnotated()| returns the |AnnotatedType| representing the bean class, the |AnnotatedMethod| representing the producer method, or the
                |AnnotatedField| representing the producer field.
            </text>
            <assertion id="efb">
                <text>Test |ProcessSessionBean|</text>
            </assertion>
        </group>

        <group>
            <text>|getBean()| returns the |Bean| object that is about to be registered. The |Bean| may implement |Interceptor| or |Decorator|.</text>
            <assertion id="fb">
                <text>Test |ProcessSessionBean|</text>
            </assertion>
        </group>

        <assertion id="hb">
            <text>|getEjbName()| returns the EJB name of the session bean.</text>
        </assertion>

        <assertion id="hc">
            <text>|getSessionBeanType()| returns a |jakarta.enterprise.inject.spi.SessionBeanType| representing the kind of session bean.</text>
        </assertion>

        <assertion id="k" implied="true">
            <text>Check the |getAnnotatedSessionBeanClass()|</text>
        </assertion>

        <group>
            <text>Check the |getAnnotatedBeanClass()|</text>
            <assertion id="m" implied="true">
                <text>Check for session bean</text>
            </assertion>
        </group>
    </section>

    <section id="packaging_deployment_ee" title="Packaging and deployment in Jakarta EE" level="1">

    </section>

    <section id="bean_archive_ee" title="Bean archive with EJB Session Beans" level="2">
        <group>
            <text>When determining which archives are bean archives, the container must consider:</text>
            <assertion id="da" testable="false">
                <text>Library jars, EJB jars or application client jars.</text>
                <note>Covered elsewhere in this section.</note>
            </assertion>
            <assertion id="db" testable="false">
                <text>The WEB-INF/classes directory of a war.</text>
                <note>Covered elsewhere in this section</note>
            </assertion>
            <assertion id="dc" testable="false">
                <text>Directories in the JVM classpath.</text>
                <note>Covered elsewhere in this section</note>
            </assertion>
        </group>
        <assertion id="e" testable="false">
            <text>A Jakarta EE container is required by the Jakarta EE specification to support Jakarta EE modules. Other containers may or may not provide support for
                war, EJB jar or rar bean archives.
            </text>
            <note>Covered elsewhere in this section.</note>
        </assertion>

        <group>
            <text>The |beans.xml| file must be named:</text>
            <assertion id="fb">
                <text>In a war, |WEB-INF/beans.xml| or |WEB-INF/classes/META-INF/beans.xml|</text>
                <note>WEB-INF/beans.xml - by default all TCK web archive deployments.</note>
            </assertion>
        </group>

        <assertion id="g" testable="false">
            <text>If a war has a file named |beans.xml| in both the |WEB-INF| directory and in the |WEB-INF/classes/META-INF| directory, then non-portable
                behavior results. Portable applications must have a beans.xml file in only one of the |WEB-INF| or the |WEB-INF/classes/META-INF| directories.
            </text>
            <note>Non-portable behaviour.</note>
        </assertion>

        <group>
            <text>In an application deployed as an ear, the container searches every bean archive bundled with or referenced by the ear, including bean archives
                bundled with or referenced by wars, EJB jars and rars contained in the ear. The bean archives might be library jars, EJB jars or war
                |WEB-INF/classes| directories.
            </text>
            <assertion id="ja">
                <text>Test an EJB jar in an EAR.</text>
            </assertion>
            <assertion id="jb">
                <text>Test a bundled library in an EAR.</text>
            </assertion>
            <assertion id="jc">
                <text>Test a bundled library in a WAR.</text>
            </assertion>
            <assertion id="jd">
                <text>Test a rar in an EAR.</text>
            </assertion>
            <assertion id="je">
                <text>Test a war in an EAR.</text>
            </assertion>
            <assertion id="jf">
                <text>Test an installed library.</text>
            </assertion>
        </group>

        <group>
            <text>In an application deployed as a war, the container searches every bean archive bundled with or referenced by the war. The bean archives might
                be library jars or the |WEB-INF/classes| directory.
            </text>
            <assertion id="jg">
                <text>Test |WEB-INF/classes| directory.</text>
            </assertion>
            <assertion id="jh">
                <text>Test bundled library.</text>
            </assertion>
            <assertion id="ji">
                <text>Test an installed library.</text>
            </assertion>
        </group>

        <group>
            <text>In an application deployed as an EJB jar, the container searches the EJB jar, if it is a bean archive, and every bean archive referenced by
                the EJB jar.
            </text>
            <assertion id="jj">
                <text>Test classes in the EJB jar.</text>
            </assertion>
        </group>

        <assertion id="jk">
            <text>In an application deployed as a rar, the container searches every bean archive bundled with or referenced by the rar.</text>
        </assertion>

        <assertion id="jl">
            <text>An embeddable EJB container searches each bean archive in the JVM classpath that is listed in the value of the embeddable container
                initialization property |jakarta.ejb.embeddable.modules|, or every bean archive in the JVM classpath if the property is not specified. The bean
                archives might be directories, library jars or EJB jars.
            </text>
        </assertion>

        <group>
            <text>An explicit bean archive is an archive which contains a |beans.xml| file with a version number of 1.1 (or later), with the
                |bean-discovery-mode| of |all|, or with no version number, or that is an empty file.
            </text>
            <assertion id="ba" implied="true">
                <text>Test an archive which contains a |beans.xml| file with a version number of 1.1, with the |bean-discovery-mode| of |all|.</text>
            </assertion>
            <assertion id="bb" implied="true">
                <text>Test an archive which contains a |beans.xml| file with no version number.</text>
            </assertion>
            <assertion id="bc" implied="true">
                <text>Test an archive which contains an empty |beans.xml|.</text>
            </assertion>
        </group>

        <assertion id="oa" implied="true">
            <text>An archive which contains a |beans.xml| file with the |bean-discovery-mode| of |none| is not a bean archive.</text>
        </assertion>

        <assertion id="ob" implied="true">
            <text>An archive which contains an extension and no |beans.xml| file is not a bean archive.</text>
        </assertion>

    </section>

    <section id="type_bean_discovery_ee" title="Type and Bean discovery for EJB" level="2">
        <group>
            <text>For every type discovered the container must create an |AnnotatedType| representing the type and fire an event of type |ProcessAnnotatedType|,
                as defined in Section 11.5.6.
            </text>
            <assertion id="bb">
                <text>Check session bean</text>
            </assertion>
            <assertion id="bd">
                <text>Check JSF managed beans</text>
            </assertion>
            <assertion id="be">
                <text>Check servlet listener</text>
            </assertion>
            <assertion id="bf">
                <text>Check tag handler</text>
            </assertion>
            <assertion id="bg">
                <text>Check tag library listener</text>
            </assertion>
            <assertion id="bh">
                <text>Check EJB Interceptor</text>
            </assertion>
            <assertion id="bi">
                <text>Check WS endpoint</text>
            </assertion>
            <assertion id="bj">
                <text>Check servlet</text>
            </assertion>
            <assertion id="bk">
                <text>Check filter</text>
            </assertion>
        </group>
    </section>

    <section id="bean_discovery_steps_ee" title="Bean discovery in Jakarta EE" level="3">
        <assertion id="tc">
            <text>The container discovers each session bean.</text>
        </assertion>

        <group>
            <text>For every type in the set of discovered types (as defined in Type discovery), the container must fire an event of type ProcessInjectionTarget,
                as defined in ProcessInjectionTarget event,
            </text>
            <assertion id="bb">
                <text>Check session bean</text>
            </assertion>
            <assertion id="bd">
                <text>Check JSF managed beans</text>
            </assertion>
            <assertion id="be">
                <text>Check servlet listener</text>
            </assertion>
            <assertion id="bf">
                <text>Check tag handler</text>
            </assertion>
            <assertion id="bg">
                <text>Check tag library listener</text>
            </assertion>
            <assertion id="bh">
                <text>Check EJB Interceptor</text>
            </assertion>
            <assertion id="bi">
                <text>Check WS endpoint</text>
            </assertion>
            <assertion id="bj">
                <text>Check servlet</text>
            </assertion>
            <assertion id="bk">
                <text>Check filter</text>
            </assertion>
        </group>

        <group>
            <text>For each Java class in any bean archive, the container must, if the class is an enabled bean, interceptor or decorator, create a |Bean| object
                that implements the rules defined in Section 7.3.1, "Lifecycle of managed beans", and fire an event which is a subtype of |ProcessBean|, as
                defined in Section 11.5.8, "ProcessBean event".
            </text>
            <assertion id="fb">
                <text>Check a session bean</text>
            </assertion>
        </group>
    </section>

    <section id="trimmed_bean_archive_ee" title="Trimmed bean archive in Jakarta EE" level="3">
        <assertion id="a">
            <text>When running in Jakarta EE, the container must extend the rules defined in "Trimmed bean archive" and
                must ensure that EJB session beans are not removed from the set of discovered types.
            </text>
        </assertion>
    </section>

    <section id="el" title="Integration with Unified EL" level="2">
        <assertion id="a">
            <text>The container must provide a Unified EL |ELResolver| to the servlet engine and JSF implementation that resolves bean EL names using the rules
                of name resolution defined in 5.3, "Name resolution" and resolving ambiguities according to Section 5.3.1, "Ambiguous names".
            </text>
        </assertion>

        <assertion id="c">
            <text>If a name used in an EL expression does not resolve to any bean, the |ELResolver| must return a null value.</text>
        </assertion>

        <!-- All unresolvable ambiguous EL names are detected by the container when the application is initialized -->
        <!-- assertion id="b"> <text>If a name used in an EL expression resolves to more than one bean, the |ELResolver| must throw an |AmbiguousResolutionException|.</text> </assertion -->

        <assertion id="d">
            <text>Otherwise, if a name used in an EL expression resolves to exactly one bean, the |ELResolver| must return a contextual instance of the bean, as
                defined in Section 6.5.2, "Contextual instance of a bean".
            </text>
        </assertion>
    </section>

</specification>




© 2015 - 2024 Weber Informatics LLC | Privacy Policy