hi ludovic, please try the same with owb 1.2.2 (since there was an issue with bridge methods).
regards, gerhard http://www.irian.at Your JSF/JavaEE powerhouse - JavaEE Consulting, Development and Courses in English and German Professional Support for Apache MyFaces 2014-03-13 13:28 GMT+01:00 [email protected] <[email protected]>: > (maybe an OWB bug, so CC to [email protected]) > > On 13/03/2014 08:55, [email protected] wrote: > >> On 13/03/2014 08:45, [email protected] wrote: >> >>> On 12/03/2014 09:16, Gerhard Petracek wrote: >>> >>>> hi ludovic, >>>> >>>> i've pushed the fallback for full state-saving. >>>> however, please provide the demo which illustrates the issue (it might >>>> be an unexpected issue in myfaces-core). >>>> >>> Hi. >>> >>> I spent some time trying to prepare a simple demo, but could not >>> duplicate the bug in a simple case. Sorry. >>> >>> I suspect a issue related to injection of a SessionScoped bean in the >>> ViewAccessScoped bean, but lack a simple example. >>> >>> I (or my colleague Laurent cottereau) might come back soon with a maybe >>> related issue, maybe on MyFaces list. We noticed a strange behaviour with >>> @ViewAccessScoped beans. >>> >>> It seems that, under some conditions, they are not properly >>> instantiated/destroyed but rather recycled. Moreover, it seems that we do >>> not access the "right" bean in @PostConstruct or @PreDestroy. In fact, it >>> seems that we access a different instance of what should be the same bean >>> when in a call of an EL expression and in @PostConstruct/@PreDestroy. >>> >> Oh and this bug occurs with : >> - MyFaces 2.2.1 >> >> and >> - CODI 1.0.5 >> or >> - DS 0.6-SNAPSHOT (201401312 snapshot) >> >> Working on a simple test... >> > I am failing to reproduce this bug in a simple test... :-( I really tried > a long time, without success. Sorry > > But maybe the following stack traces and other information will help. > > It seems to me that it might be an OpenWebBeans related bug... But I am > not an expert like most of you. > > I heavily use @ViewAccessScoped beans. Almost all my beans are scoped this > way, excepted a few @SessionScoped beans and @ApplicationBeans. > > I inject in almost all my @ViewAccessScoped a @SessionScoped bean. This > @SessionScoped bean holds undo/redo data. The @ViewAccessScoped beans > provides access to collection values in a CRUD fashions. > > Most of those beans classes derive from a base EditionContextWithoutParent > class. In our case, the bean class is like > > @Named > @ViewAccessScoped > public class UploadedFileContext extends > EditionContextWithoutParent<UploadedFile> > { > // the @SessionScoped bean injected there > @Inject CommandContext commandContext; > ... > public UploadedFileContext() { > > } > > @Override > public List<UploadedFile> internalGetValues() { > return Senateurs.getUploadedFilesById(); > } > } > > And the base class is like > > @Log4j > public abstract class EditionContextWithoutParent<Type> extends > EditionContextWithTracking<Type> { > > ... > @Setter > List<Type> values; > > public EditionContextWithoutParent() { > } > > public final List<Type> getValues() { > if(values == null) { > values = internalGetValues(); > } > return values; > } > > @PostConstruct > public void postConstruct() { > values = null; > } > > @PreDestroy > public void preDestroy() { > values = null; > } > } > > If everything was working fine, there would be no need for the > upmentionned postConstruct/preDestroy methods. They are just there for > debug. > > As I stated before, there are "two instances" of the same > UploadedFileContext bean in parallel. > > To be more specific : > - there is a "real" instance of UploadedFileContext, which is correctly > instantiated / PostConstruct-ed / PreDestroy according to what one expects > from a @ViewAccessScoped bean > - there is a "proxied" "instance of UploadedFileContext", which does not > appear as an UploadedFileContext instance in netbeans debugger, but as a > UploadedFileContext$$OwbNormalScopeProxy0 instance. > > The "proxied instance" is used in all EL calls. > > #{UploadedFileContext.values} is passed as the collection to display to a > PrimeFaces p:dataTable component. > The p:dataTable component is used by a tag component, which is used in a > page using layouting with ui:composition/ui:insert. > > I use : > * myfaces 2.2.1 > * OWB 1.2.1 > * primefaces elite 4.0.9 > * omnifaces 1.6.3 > > The webapp is running in a Tomcat 7.0.39 container. > > > If I debug and set breakpoints on previously mentionned methods , I > observe the following > > 1) A call to UploadedFileContext$$OwbNormalScopeProxy0.getValues() > > ***there was no call to UploadedFileContext before *** > > > EditionContextWithoutParent.getValues:108 > NativeMethodAccessorImpl.invoke0 > NativeMethodAccessorImpl.invoke:57 > DelegatingMethodAccessorImpl.invoke:43 > Method.invoke:606 > BeanELResolver.getValue:87 > CompositeELResolver.getValue:67 > FacesCompositeELResolver.getValue:179 > AstValue.getValue:183 > ValueExpressionImpl.getValue:185 > WrappedValueExpression.getValue:70 > ContextAwareTagValueExpression.getValue:96 > _DeltaStateHelper.eval:360 > UIData.getValue:2071 > DataTable.getValue:929 > UIData.getDataModel:624 > UIData.setRowModel:431 > UIData.setRowIndex:423 > UIData.encodeEnd:1715 > CoreRenderer.renderChild:75 > CoreRenderer.renderChildren:58 > OutputPanelRenderer.encodeMarkup:64 > OutputPanelRenderer.encodeEnd:40 > UIComponentBase.encodeEnd:674 > UIComponentBase.encodeAll:554 > UIComponentBase.encodeAll:550 > UIComponentBase.encodeAll:550 > UIComponentBase.encodeAll:550 > FaceletViewDeclarationLanguage.renderView:1891 > ViewHandlerImpl.renderView:313 > ViewHandlerWrapper.renderView:57 > ViewHandlerWrapper.renderView:57 > ViewHandlerWrapper.renderView:57 > ViewHandlerWrapper.renderView:57 > RenderResponseExecutor.execute:116 > LifecycleImpl.render:267 > DeltaSpikeLifecycleWrapper.render:111 > LifecycleWrapper.render:31 > DeltaSpikeLifecycleWrapper.render:111 > LifecycleWrapper.render:31 > FacesServlet.service:198 > ApplicationFilterChain.internalDoFilter:305 > ApplicationFilterChain.doFilter:210 > HibernateNoCacheFilter.doFilter:118 > ApplicationFilterChain.internalDoFilter:243 > ApplicationFilterChain.doFilter:210 > HibernateSessionConversationFilter.doFilter:70 > ApplicationFilterChain.internalDoFilter:243 > ApplicationFilterChain.doFilter:210 > HibernateUserFromPrincipalFilter.doFilter:32 > ApplicationFilterChain.internalDoFilter:243 > ApplicationFilterChain.doFilter:210 > StandardWrapperValve.invoke:222 > StandardContextValve.invoke:123 > AuthenticatorBase.invoke:581 > StandardHostValve.invoke:171 > ErrorReportValve.invoke:99 > AccessLogValve.invoke:947 > StandardEngineValve.invoke:118 > CoyoteAdapter.service:408 > AbstractHttp11Processor.process:1009 > AbstractProtocol$AbstractConnectionHandler.process:589 > JIoEndpoint$SocketProcessor.run:312 > ThreadPoolExecutor.runWorker:1145 > ThreadPoolExecutor$Worker.run:615 > Thread.run:744 > > 2) Call to the constructor of UploadedFileContext > > > UploadedFileContext.<init>:16 > NativeConstructorAccessorImpl.newInstance0 > NativeConstructorAccessorImpl.newInstance:57 > DelegatingConstructorAccessorImpl.newInstance:45 > Constructor.newInstance:526 > InjectableConstructor.doInjection:72 > InjectionTargetImpl.newInstance:325 > InjectionTargetImpl.produce:264 > AbstractOwbBean.create:118 > ManagedBean.create:55 > SerializableBean.create:129 > ContextualStorage.createContextualInstance:117 > AbstractContext.get:124 > ViewAccessContext.get:83 > CustomPassivatingContextImpl.get:46 > NormalScopedBeanInterceptorHandler.getContextualInstance:100 > NormalScopedBeanInterceptorHandler.get:70 > UploadedFileContext$$OwbNormalScopeProxy0.getFilteredValues > GeneratedMethodAccessor440.invoke > DelegatingMethodAccessorImpl.invoke:43 > Method.invoke:606 > BeanELResolver.getValue:87 > CompositeELResolver.getValue:67 > FacesCompositeELResolver.getValue:179 > AstValue.getValue:183 > ValueExpressionImpl.getValue:185 > WrappedValueExpression.getValue:70 > _DeltaStateHelper.eval:377 > DataTable.getFilteredValue:337 > DataTable.getValue:930 > UIData.getDataModel:624 > UIData.setRowModel:431 > UIData.setRowIndex:423 > UIData.encodeEnd:1715 > CoreRenderer.renderChild:75 > CoreRenderer.renderChildren:58 > OutputPanelRenderer.encodeMarkup:64 > OutputPanelRenderer.encodeEnd:40 > UIComponentBase.encodeEnd:674 > UIComponentBase.encodeAll:554 > UIComponentBase.encodeAll:550 > UIComponentBase.encodeAll:550 > UIComponentBase.encodeAll:550 > FaceletViewDeclarationLanguage.renderView:1891 > ViewHandlerImpl.renderView:313 > ViewHandlerWrapper.renderView:57 > ViewHandlerWrapper.renderView:57 > ViewHandlerWrapper.renderView:57 > ViewHandlerWrapper.renderView:57 > RenderResponseExecutor.execute:116 > LifecycleImpl.render:267 > DeltaSpikeLifecycleWrapper.render:111 > LifecycleWrapper.render:31 > DeltaSpikeLifecycleWrapper.render:111 > LifecycleWrapper.render:31 > FacesServlet.service:198 > ApplicationFilterChain.internalDoFilter:305 > ApplicationFilterChain.doFilter:210 > HibernateNoCacheFilter.doFilter:118 > ApplicationFilterChain.internalDoFilter:243 > ApplicationFilterChain.doFilter:210 > HibernateSessionConversationFilter.doFilter:70 > ApplicationFilterChain.internalDoFilter:243 > ApplicationFilterChain.doFilter:210 > HibernateUserFromPrincipalFilter.doFilter:32 > ApplicationFilterChain.internalDoFilter:243 > ApplicationFilterChain.doFilter:210 > StandardWrapperValve.invoke:222 > StandardContextValve.invoke:123 > AuthenticatorBase.invoke:581 > StandardHostValve.invoke:171 > ErrorReportValve.invoke:99 > AccessLogValve.invoke:947 > StandardEngineValve.invoke:118 > CoyoteAdapter.service:408 > AbstractHttp11Processor.process:1009 > AbstractProtocol$AbstractConnectionHandler.process:589 > JIoEndpoint$SocketProcessor.run:312 > ThreadPoolExecutor.runWorker:1145 > ThreadPoolExecutor$Worker.run:615 > Thread.run:744 > > 3) Call to the @PostConstruct-ed postConstruct méthode of > UploadedFileContext > > EditionContextWithoutParent.postConstruct:129 > NativeMethodAccessorImpl.invoke0 > NativeMethodAccessorImpl.invoke:57 > DelegatingMethodAccessorImpl.invoke:43 > Method.invoke:606 > LifecycleInterceptorInvocationContext.proceed:103 > InjectionTargetImpl.postConstruct:472 > AbstractOwbBean.create:123 > ManagedBean.create:55 > SerializableBean.create:129 > ContextualStorage.createContextualInstance:117 > AbstractContext.get:124 > ViewAccessContext.get:83 > CustomPassivatingContextImpl.get:46 > NormalScopedBeanInterceptorHandler.getContextualInstance:100 > NormalScopedBeanInterceptorHandler.get:70 > UploadedFileContext$$OwbNormalScopeProxy0.getFilteredValues > GeneratedMethodAccessor440.invoke > DelegatingMethodAccessorImpl.invoke:43 > Method.invoke:606 > BeanELResolver.getValue:87 > CompositeELResolver.getValue:67 > FacesCompositeELResolver.getValue:179 > AstValue.getValue:183 > ValueExpressionImpl.getValue:185 > WrappedValueExpression.getValue:70 > _DeltaStateHelper.eval:377 > DataTable.getFilteredValue:337 > DataTable.getValue:930 > UIData.getDataModel:624 > UIData.setRowModel:431 > UIData.setRowIndex:423 > UIData.encodeEnd:1715 > CoreRenderer.renderChild:75 > CoreRenderer.renderChildren:58 > OutputPanelRenderer.encodeMarkup:64 > OutputPanelRenderer.encodeEnd:40 > UIComponentBase.encodeEnd:674 > UIComponentBase.encodeAll:554 > UIComponentBase.encodeAll:550 > UIComponentBase.encodeAll:550 > UIComponentBase.encodeAll:550 > FaceletViewDeclarationLanguage.renderView:1891 > ViewHandlerImpl.renderView:313 > ViewHandlerWrapper.renderView:57 > ViewHandlerWrapper.renderView:57 > ViewHandlerWrapper.renderView:57 > ViewHandlerWrapper.renderView:57 > RenderResponseExecutor.execute:116 > LifecycleImpl.render:267 > DeltaSpikeLifecycleWrapper.render:111 > LifecycleWrapper.render:31 > DeltaSpikeLifecycleWrapper.render:111 > LifecycleWrapper.render:31 > FacesServlet.service:198 > ApplicationFilterChain.internalDoFilter:305 > ApplicationFilterChain.doFilter:210 > HibernateNoCacheFilter.doFilter:118 > ApplicationFilterChain.internalDoFilter:243 > ApplicationFilterChain.doFilter:210 > HibernateSessionConversationFilter.doFilter:70 > ApplicationFilterChain.internalDoFilter:243 > ApplicationFilterChain.doFilter:210 > HibernateUserFromPrincipalFilter.doFilter:32 > ApplicationFilterChain.internalDoFilter:243 > ApplicationFilterChain.doFilter:210 > StandardWrapperValve.invoke:222 > StandardContextValve.invoke:123 > AuthenticatorBase.invoke:581 > StandardHostValve.invoke:171 > ErrorReportValve.invoke:99 > AccessLogValve.invoke:947 > StandardEngineValve.invoke:118 > CoyoteAdapter.service:408 > AbstractHttp11Processor.process:1009 > AbstractProtocol$AbstractConnectionHandler.process:589 > JIoEndpoint$SocketProcessor.run:312 > ThreadPoolExecutor.runWorker:1145 > ThreadPoolExecutor$Worker.run:615 > Thread.run:744 > > > 4) Multiple calls to UploadedFileContext$$OwbNormalScopeProxy0.getValues > > EditionContextWithoutParent.getValues:108 > GeneratedMethodAccessor441.invoke > DelegatingMethodAccessorImpl.invoke:43 > Method.invoke:606 > BeanELResolver.getValue:87 > CompositeELResolver.getValue:67 > FacesCompositeELResolver.getValue:179 > AstValue.getValue:183 > ValueExpressionImpl.getValue:185 > WrappedValueExpression.getValue:70 > ContextAwareTagValueExpression.getValue:96 > _DeltaStateHelper.eval:360 > UIData.getValue:2071 > DataTable.getValue:929 > SortFeature.singleSort:134 > DataTableRenderer.preRender:103 > DataTableRenderer.encodeEnd:81 > UIComponentBase.encodeEnd:674 > UIData.encodeEnd:1721 > CoreRenderer.renderChild:75 > CoreRenderer.renderChildren:58 > OutputPanelRenderer.encodeMarkup:64 > OutputPanelRenderer.encodeEnd:40 > UIComponentBase.encodeEnd:674 > UIComponentBase.encodeAll:554 > UIComponentBase.encodeAll:550 > UIComponentBase.encodeAll:550 > UIComponentBase.encodeAll:550 > FaceletViewDeclarationLanguage.renderView:1891 > ViewHandlerImpl.renderView:313 > ViewHandlerWrapper.renderView:57 > ViewHandlerWrapper.renderView:57 > ViewHandlerWrapper.renderView:57 > ViewHandlerWrapper.renderView:57 > RenderResponseExecutor.execute:116 > LifecycleImpl.render:267 > DeltaSpikeLifecycleWrapper.render:111 > LifecycleWrapper.render:31 > DeltaSpikeLifecycleWrapper.render:111 > LifecycleWrapper.render:31 > FacesServlet.service:198 > ApplicationFilterChain.internalDoFilter:305 > ApplicationFilterChain.doFilter:210 > HibernateNoCacheFilter.doFilter:118 > ApplicationFilterChain.internalDoFilter:243 > ApplicationFilterChain.doFilter:210 > HibernateSessionConversationFilter.doFilter:70 > ApplicationFilterChain.internalDoFilter:243 > ApplicationFilterChain.doFilter:210 > HibernateUserFromPrincipalFilter.doFilter:32 > ApplicationFilterChain.internalDoFilter:243 > ApplicationFilterChain.doFilter:210 > StandardWrapperValve.invoke:222 > StandardContextValve.invoke:123 > AuthenticatorBase.invoke:581 > StandardHostValve.invoke:171 > ErrorReportValve.invoke:99 > AccessLogValve.invoke:947 > StandardEngineValve.invoke:118 > CoyoteAdapter.service:408 > AbstractHttp11Processor.process:1009 > AbstractProtocol$AbstractConnectionHandler.process:589 > JIoEndpoint$SocketProcessor.run:312 > ThreadPoolExecutor.runWorker:1145 > ThreadPoolExecutor$Worker.run:615 > Thread.run:744 > > > As a consequence, the data displayed by the table is never updated. > > My web.xml contains : > > <context-param> > <param-name>javax.faces.FACELETS_LIBRARIES</param-name> > <param-value>/WEB-INF/sens.taglib.xml</param-value> > </context-param> > > <welcome-file-list> > <welcome-file>accueil.xhtml</welcome-file> > </welcome-file-list> > > > <context-param> > <param-name>primefaces.SUBMIT</param-name> > <param-value>true</param-value> > </context-param> > > > <!-- JSF standard parameters --> > <context-param> > <param-name>javax.faces.PROJECT_STAGE</param-name> > <param-value>Production</param-value> > </context-param> > > <context-param> > <param-name>javax.faces.PARTIAL_STATE_SAVING</param-name> > <param-value>true</param-value> > </context-param> > > <context-param> > <param-name>javax.faces.DATETIMECONVERTER_DEFAULT_ > TIMEZONE_IS_SYSTEM_TIMEZONE</param-name> > <param-value>true</param-value> > </context-param> > > <context-param> > <description> > If this parameter is set to true and the submitted value of a > component is > the empty string, the submitted value will be set to null > </description> > <param-name>javax.faces.INTERPRET_EMPTY_STRING_SUBMITTED_VALUES_AS_NULL</ > param-name> > <param-value>true</param-value> > </context-param> > > <context-param> > <description>State saving method: "client" or "server" (= default) > See JSF Specification 2.5.3</description> > <param-name>javax.faces.STATE_SAVING_METHOD</param-name> > <param-value>server</param-value> > </context-param> > > <!-- MyFaces specific parameters --> > <context-param> > <description>Only applicable if state saving method is "server" (= > default). > Defines the amount (default = 20) of the latest views are stored in > session.</description> > <param-name>org.apache.myfaces.NUMBER_OF_VIEWS_IN_SESSION</param-name> > <param-value>20</param-value> > </context-param> > <context-param> > <description>Only applicable if state saving method is "server" (= > default). > If true (default) the state will be serialized to a byte stream before > it > is written to the session. > If false the state will not be serialized to a byte > stream.</description> > <param-name>org.apache.myfaces.SERIALIZE_STATE_IN_SESSION</param-name> > <param-value>true</param-value> > </context-param> > <context-param> > <description>Only applicable if state saving method is "server" (= > default) and if > org.apache.myfaces.SERIALIZE_STATE_IN_SESSION is true (= default) > If true (default) the serialized state will be compressed before it > is written to the session. If false the state will not be > compressed.</description> > <param-name>org.apache.myfaces.COMPRESS_STATE_IN_SESSION</param-name> > <param-value>true</param-value> > </context-param> > <context-param> > <description>This parameter tells MyFaces if javascript code should be > allowed in the > rendered HTML output. > If javascript is allowed, command_link anchors will have javascript > code > that submits the corresponding form. > If javascript is not allowed, the state saving info and nested > parameters > will be added as url parameters. > Default: "true"</description> > <param-name>org.apache.myfaces.ALLOW_JAVASCRIPT</param-name> > <param-value>true</param-value> > </context-param> > <context-param> > <param-name>org.apache.myfaces.DETECT_JAVASCRIPT</param-name> > <param-value>false</param-value> > </context-param> > <context-param> > <description>If true, rendered HTML code will be formatted, so that it > is "human readable". > i.e. additional line separators and whitespace will be written, that > do not > influence the HTML code. > Default: "true"</description> > <param-name>org.apache.myfaces.PRETTY_HTML</param-name> > <param-value>true</param-value> > </context-param> > <context-param> > <description>If true, a javascript function will be rendered that is > able to restore the > former vertical scroll on every request. Convenient feature if you > have pages > with long lists and you do not want the browser page to always jump to > the top > if you trigger a link or button action that stays on the same page. > Default: "false"</description> > <param-name>org.apache.myfaces.AUTO_SCROLL</param-name> > <param-value>true</param-value> > </context-param> > > > <!-- les context-param-s suivants sont tous de recherche de performances > --> > <!-- utilisation de JUEL --> > <context-param> > <param-name>org.apache.myfaces.EXPRESSION_FACTORY</param-name> > <param-value>de.odysseus.el.ExpressionFactoryImpl</param-value> > </context-param> > > <!-- utilisation du resolver EL de OpenWebBeans --> > <context-param> > <param-name>org.apache.myfaces.EL_RESOLVER_COMPARATOR</param-name> > <param-value>org.apache.myfaces.el.unified.OpenWebBeansELResolverComparat > or</param-value> > </context-param> > > > <!-- desactivation du support des JSP (voir https://issues.apache.org/ > jira/browse/MYFACES-3078 )--> > <context-param> > <param-name>org.apache.myfaces.SUPPORT_JSP</param-name> > <param-value>false</param-value> > </context-param> > > <!-- ne jamais relire les fichiers XHTML --> > <context-param> > <param-name>javax.faces.FACELETS_REFRESH_PERIOD</param-name> > <param-value>-1</param-value> > </context-param> > > <!-- aucun check de duplicité d'id en prod (voir > http://myfaces.apache.org/core20/myfaces-impl/webconfig. > html#org_apache_myfaces_CHECK_ID_PRODUCTION_MODE) --> > <context-param> > <param-name>org.apache.myfaces.CHECK_ID_PRODUCTION_MODE</param-name> > <param-value>false</param-value> > </context-param> > > <!-- voir http://myfaces.apache.org/core20/myfaces-impl/webconfig. > html#org_apache_myfaces_VIEW_UNIQUE_IDS_CACHE_ENABLED --> > <context-param> > <param-name>org.apache.myfaces.VIEW_UNIQUE_IDS_CACHE_ENABLED</param-name> > <param-value>true</param-value> > </context-param> > > <!-- voir http://myfaces.apache.org/core20/myfaces-impl/webconfig. > html#org_apache_myfaces_CACHE_EL_EXPRESSIONS --> > <context-param> > <param-name>org.apache.myfaces.CACHE_EL_EXPRESSIONS</param-name> > <param-value>strict</param-value> > </context-param> > > > > <!-- voir http://myfaces.apache.org/core20/myfaces-impl/webconfig. > html#org_apache_myfaces_SAVE_STATE_WITH_VISIT_TREE_ON_PSS --> > <context-param> > <param-name>org.apache.myfaces.SAVE_STATE_WITH_VISIT_ > TREE_ON_PSS</param-name> > <param-value>true</param-value> > </context-param> > > > <listener> > <listener-class> > net.sf.ehcache.constructs.web.ShutdownListener > </listener-class> > </listener> > > <!-- Listener for OpenWebBeans configuration --> > <listener> > <listener-class> > org.apache.webbeans.servlet.WebBeansConfigurationListener > </listener-class> > </listener> > > <servlet> > <servlet-name>Faces Servlet</servlet-name> > <servlet-class>javax.faces.webapp.FacesServlet</servlet-class> > <load-on-startup>1</load-on-startup> > </servlet> > <servlet-mapping> > <servlet-name>Faces Servlet</servlet-name> > <url-pattern>*.xhtml</url-pattern> > </servlet-mapping> > > > I tried without setting org.apache.myfaces.EL_RESOLVER_COMPARATOR and > with org.apache.myfaces.SAVE_STATE_WITH_VISIT_TREE_ON_PSS, it changes > nothing. > > Thanks in advance for your attention ! > > > Ludovic > | > | AVANT D'IMPRIMER, PENSEZ A L'ENVIRONNEMENT. > | > >
