branch

git-svn-id: https://svn.apache.org/repos/asf/myfaces/extensions/validator/branches/prepare_r3@922981 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/2_0_3_prepare/assembly/pom.xml b/2_0_3_prepare/assembly/pom.xml
new file mode 100644
index 0000000..bc0d5e2
--- /dev/null
+++ b/2_0_3_prepare/assembly/pom.xml
@@ -0,0 +1,201 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

+    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">

+    <modelVersion>4.0.0</modelVersion>

+    <artifactId>myfaces-extval-assembly12</artifactId>

+    <packaging>pom</packaging>

+    <name>Apache MyFaces Extensions Validator Assembly</name>

+    <description>MyFaces Extensions Validator Assembly is used to generate 

+    .zip and .tar.gz distributions </description>

+

+    <parent>

+        <groupId>org.apache.myfaces.extensions.validator</groupId>

+        <artifactId>myfaces-extval-parent</artifactId>

+        <version>2.0.3-SNAPSHOT</version>

+    </parent>

+

+    <scm>

+        <connection>scm:svn:http://svn.apache.org/repos/asf/myfaces/extensions/validator/branches/1_2_2_rc/assembly</connection>

+        <developerConnection>scm:svn:https://svn.apache.org/repos/asf/myfaces/extensions/validator/branches/1_2_2_rc/assembly</developerConnection>

+        <url>http://svn.apache.org/viewvc/myfaces/extensions/validator/branches/1_2_2_rc/assembly</url>

+    </scm>

+    

+    <build>

+        <plugins>

+            <plugin>

+                <groupId>org.codehaus.mojo</groupId>

+                <artifactId>dependency-maven-plugin</artifactId>

+                <executions>

+                    <execution>

+                        <id>copy-javadoc</id>

+                        <phase>package</phase>

+                        <goals>

+                            <goal>copy</goal>

+                        </goals>

+                        <configuration>

+                            <artifactItems>

+                                <artifactItem>

+                                    <groupId>org.apache.myfaces.extensions.validator</groupId>

+                                    <artifactId>myfaces-extval-core</artifactId>

+                                    <version>${core.version}</version>

+                                    <classifier>javadoc</classifier>

+                                </artifactItem>

+                                <artifactItem>

+                                    <groupId>org.apache.myfaces.extensions.validator.component-support-modules</groupId>

+                                    <artifactId>myfaces-extval-generic-support</artifactId>

+                                    <version>${generic-support.version}</version>

+                                    <classifier>javadoc</classifier>

+                                </artifactItem>

+                                <artifactItem>

+                                    <groupId>org.apache.myfaces.extensions.validator.component-support-modules</groupId>

+                                    <artifactId>myfaces-extval-trinidad-support</artifactId>

+                                    <version>${trinidad-support.version}</version>

+                                    <classifier>javadoc</classifier>

+                                </artifactItem>

+                                <artifactItem>

+                                    <groupId>org.apache.myfaces.extensions.validator.validation-modules</groupId>

+                                    <artifactId>myfaces-extval-property-validation</artifactId>

+                                    <version>${property-validation.version}</version>

+                                    <classifier>javadoc</classifier>

+                                </artifactItem>

+                                <artifactItem>

+                                    <groupId>org.apache.myfaces.extensions.validator.validation-modules</groupId>

+                                    <artifactId>myfaces-extval-bean-validation</artifactId>

+                                    <version>${bean-validation.version}</version>

+                                    <classifier>javadoc</classifier>

+                                </artifactItem>

+                            </artifactItems>

+                            <outputDirectory>${project.build.directory}/javadoc</outputDirectory>

+                        </configuration>

+                    </execution>

+                    <execution>

+                        <id>copy-source</id>

+                        <phase>package</phase>

+                        <goals>

+                            <goal>copy</goal>

+                        </goals>

+                        <configuration>

+                            <artifactItems>

+                                <artifactItem>

+                                    <groupId>org.apache.myfaces.extensions.validator</groupId>

+                                    <artifactId>myfaces-extval-core</artifactId>

+                                    <version>${core.version}</version>

+                                    <classifier>sources</classifier>

+                                </artifactItem>

+                                <artifactItem>

+                                    <groupId>org.apache.myfaces.extensions.validator.component-support-modules</groupId>

+                                    <artifactId>myfaces-extval-generic-support</artifactId>

+                                    <version>${generic-support.version}</version>

+                                    <classifier>sources</classifier>

+                                </artifactItem>

+                                <artifactItem>

+                                    <groupId>org.apache.myfaces.extensions.validator.component-support-modules</groupId>

+                                    <artifactId>myfaces-extval-trinidad-support</artifactId>

+                                    <version>${trinidad-support.version}</version>

+                                    <classifier>sources</classifier>

+                                </artifactItem>

+                                <artifactItem>

+                                    <groupId>org.apache.myfaces.extensions.validator.validation-modules</groupId>

+                                    <artifactId>myfaces-extval-property-validation</artifactId>

+                                    <version>${property-validation.version}</version>

+                                    <classifier>sources</classifier>

+                                </artifactItem>

+                                <artifactItem>

+                                    <groupId>org.apache.myfaces.extensions.validator.validation-modules</groupId>

+                                    <artifactId>myfaces-extval-bean-validation</artifactId>

+                                    <version>${bean-validation.version}</version>

+                                    <classifier>sources</classifier>

+                                </artifactItem>

+                            </artifactItems>

+                            <outputDirectory>${project.build.directory}/src</outputDirectory>

+                        </configuration>

+                    </execution>

+                </executions>

+            </plugin>

+

+            <plugin>

+                <!-- EXECUTE mvn package to generate assembly files -->

+                <artifactId>maven-assembly-plugin</artifactId>

+                <executions>

+                    <execution>

+                        <id>make_assembly_src</id>

+                        <configuration>

+                            <descriptors>

+                                <descriptor>src/main/assembly/coresrc.xml</descriptor>

+                            </descriptors>

+                            <finalName>myfaces-extval12-${version}-src</finalName>

+                            <appendAssemblyId>false</appendAssemblyId>

+                            <outputDirectory>target/assembly/out</outputDirectory>

+                            <workDirectory>target/assembly/work</workDirectory>

+                        </configuration>

+                        <phase>package</phase>

+                        <goals>

+                            <goal>attached</goal>

+                        </goals>

+                    </execution>

+                    <execution>

+                        <id>make_assembly_bin</id>

+                        <configuration>

+                            <descriptors>

+                                <descriptor>${basedir}/src/main/assembly/corebin.xml</descriptor>

+                            </descriptors>

+                            <finalName>myfaces-extval12-${version}-bin</finalName>

+                            <appendAssemblyId>false</appendAssemblyId>

+                            <outputDirectory>target/assembly/out</outputDirectory>

+                            <workDirectory>target/assembly/work</workDirectory>

+                        </configuration>

+                        <phase>package</phase>

+                        <goals>

+                            <goal>attached</goal>

+                        </goals>

+                    </execution>

+                </executions>

+            </plugin>

+        </plugins>

+    </build>

+    <dependencies>

+        <dependency>

+            <groupId>org.apache.myfaces.extensions.validator</groupId>

+            <artifactId>myfaces-extval-core</artifactId>

+            <version>${core.version}</version>

+            <scope>compile</scope>

+        </dependency>

+

+        <dependency>

+            <groupId>org.apache.myfaces.extensions.validator.validation-modules</groupId>

+            <artifactId>myfaces-extval-property-validation</artifactId>

+            <version>${property-validation.version}</version>

+            <scope>compile</scope>

+        </dependency>

+

+        <dependency>

+            <groupId>org.apache.myfaces.extensions.validator.validation-modules</groupId>

+            <artifactId>myfaces-extval-bean-validation</artifactId>

+            <version>${bean-validation.version}</version>

+            <scope>compile</scope>

+        </dependency>

+

+        <dependency>

+            <groupId>org.apache.myfaces.extensions.validator.component-support-modules</groupId>

+            <artifactId>myfaces-extval-trinidad-support</artifactId>

+            <version>${trinidad-support.version}</version>

+            <scope>compile</scope>

+        </dependency>

+

+        <dependency>

+            <groupId>org.apache.myfaces.extensions.validator.component-support-modules</groupId>

+            <artifactId>myfaces-extval-generic-support</artifactId>

+            <version>${generic-support.version}</version>

+            <scope>compile</scope>

+        </dependency>

+    </dependencies>

+

+    <!-- Since extval could be async released, an generated assembly could contain different

+         artifact versions -->

+    <properties>

+        <core.version>2.0.3-SNAPSHOT</core.version>

+        <trinidad-support.version>2.0.3-SNAPSHOT</trinidad-support.version>

+        <generic-support.version>2.0.3-SNAPSHOT</generic-support.version>

+        <property-validation.version>2.0.3-SNAPSHOT</property-validation.version>

+        <bean-validation.version>2.0.3-SNAPSHOT</bean-validation.version>

+    </properties>

+</project>

diff --git a/2_0_3_prepare/assembly/src/main/assembly/corebin.xml b/2_0_3_prepare/assembly/src/main/assembly/corebin.xml
new file mode 100644
index 0000000..0f712f0
--- /dev/null
+++ b/2_0_3_prepare/assembly/src/main/assembly/corebin.xml
@@ -0,0 +1,32 @@
+<assembly>

+  <id>corebin</id>

+  <formats>

+    <format>tar.gz</format>

+    <format>zip</format>

+  </formats>

+  <dependencySets>

+    <dependencySet>

+      <outputDirectory>lib</outputDirectory>

+      <scope>runtime</scope>

+    </dependencySet>

+  </dependencySets>

+  <fileSets>

+    <fileSet>

+    	<directory>src/main/resources</directory>

+    	<outputDirectory></outputDirectory>

+      <includes>

+        <include>README*</include>

+        <include>LICENSE*</include>

+        <include>NOTICE*</include>

+        <include>RELEASE*</include>

+      </includes>

+    </fileSet>

+    <fileSet>

+      <directory>target/javadoc</directory>

+      <outputDirectory>javadoc</outputDirectory>

+      <includes>

+        <include>*.jar</include>

+      </includes>

+    </fileSet>

+  </fileSets>

+</assembly>

diff --git a/2_0_3_prepare/assembly/src/main/assembly/coresrc.xml b/2_0_3_prepare/assembly/src/main/assembly/coresrc.xml
new file mode 100644
index 0000000..7d1ece1
--- /dev/null
+++ b/2_0_3_prepare/assembly/src/main/assembly/coresrc.xml
@@ -0,0 +1,27 @@
+<assembly>

+  <id>coresrc</id>

+  <formats>

+    <format>tar.gz</format>

+    <format>zip</format>

+  </formats>  

+  <fileSets>

+    <fileSet>

+    	<directory>src/main/resources</directory>

+    	<outputDirectory></outputDirectory>

+      <includes>

+        <include>README*</include>

+        <include>LICENSE*</include>

+        <include>NOTICE*</include>

+        <include>RELEASE*</include>

+      </includes>

+    </fileSet>   

+    <fileSet>

+      <directory>target/src</directory>

+      <outputDirectory>src</outputDirectory>

+      <includes>

+        <include>*.jar</include>

+      </includes>

+    </fileSet>

+  </fileSets>

+</assembly>

+ 

diff --git a/2_0_3_prepare/assembly/src/main/resources/LICENSE.txt b/2_0_3_prepare/assembly/src/main/resources/LICENSE.txt
new file mode 100644
index 0000000..c6055ec
--- /dev/null
+++ b/2_0_3_prepare/assembly/src/main/resources/LICENSE.txt
@@ -0,0 +1,174 @@
+                                 Apache License

+                           Version 2.0, January 2004

+                        http://www.apache.org/licenses/

+

+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

+

+   1. Definitions.

+

+      "License" shall mean the terms and conditions for use, reproduction,

+      and distribution as defined by Sections 1 through 9 of this document.

+

+      "Licensor" shall mean the copyright owner or entity authorized by

+      the copyright owner that is granting the License.

+

+      "Legal Entity" shall mean the union of the acting entity and all

+      other entities that control, are controlled by, or are under common

+      control with that entity. For the purposes of this definition,

+      "control" means (i) the power, direct or indirect, to cause the

+      direction or management of such entity, whether by contract or

+      otherwise, or (ii) ownership of fifty percent (50%) or more of the

+      outstanding shares, or (iii) beneficial ownership of such entity.

+

+      "You" (or "Your") shall mean an individual or Legal Entity

+      exercising permissions granted by this License.

+

+      "Source" form shall mean the preferred form for making modifications,

+      including but not limited to software source code, documentation

+      source, and configuration files.

+

+      "Object" form shall mean any form resulting from mechanical

+      transformation or translation of a Source form, including but

+      not limited to compiled object code, generated documentation,

+      and conversions to other media types.

+

+      "Work" shall mean the work of authorship, whether in Source or

+      Object form, made available under the License, as indicated by a

+      copyright notice that is included in or attached to the work

+      (an example is provided in the Appendix below).

+

+      "Derivative Works" shall mean any work, whether in Source or Object

+      form, that is based on (or derived from) the Work and for which the

+      editorial revisions, annotations, elaborations, or other modifications

+      represent, as a whole, an original work of authorship. For the purposes

+      of this License, Derivative Works shall not include works that remain

+      separable from, or merely link (or bind by name) to the interfaces of,

+      the Work and Derivative Works thereof.

+

+      "Contribution" shall mean any work of authorship, including

+      the original version of the Work and any modifications or additions

+      to that Work or Derivative Works thereof, that is intentionally

+      submitted to Licensor for inclusion in the Work by the copyright owner

+      or by an individual or Legal Entity authorized to submit on behalf of

+      the copyright owner. For the purposes of this definition, "submitted"

+      means any form of electronic, verbal, or written communication sent

+      to the Licensor or its representatives, including but not limited to

+      communication on electronic mailing lists, source code control systems,

+      and issue tracking systems that are managed by, or on behalf of, the

+      Licensor for the purpose of discussing and improving the Work, but

+      excluding communication that is conspicuously marked or otherwise

+      designated in writing by the copyright owner as "Not a Contribution."

+

+      "Contributor" shall mean Licensor and any individual or Legal Entity

+      on behalf of whom a Contribution has been received by Licensor and

+      subsequently incorporated within the Work.

+

+   2. Grant of Copyright License. Subject to the terms and conditions of

+      this License, each Contributor hereby grants to You a perpetual,

+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable

+      copyright license to reproduce, prepare Derivative Works of,

+      publicly display, publicly perform, sublicense, and distribute the

+      Work and such Derivative Works in Source or Object form.

+

+   3. Grant of Patent License. Subject to the terms and conditions of

+      this License, each Contributor hereby grants to You a perpetual,

+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable

+      (except as stated in this section) patent license to make, have made,

+      use, offer to sell, sell, import, and otherwise transfer the Work,

+      where such license applies only to those patent claims licensable

+      by such Contributor that are necessarily infringed by their

+      Contribution(s) alone or by combination of their Contribution(s)

+      with the Work to which such Contribution(s) was submitted. If You

+      institute patent litigation against any entity (including a

+      cross-claim or counterclaim in a lawsuit) alleging that the Work

+      or a Contribution incorporated within the Work constitutes direct

+      or contributory patent infringement, then any patent licenses

+      granted to You under this License for that Work shall terminate

+      as of the date such litigation is filed.

+

+   4. Redistribution. You may reproduce and distribute copies of the

+      Work or Derivative Works thereof in any medium, with or without

+      modifications, and in Source or Object form, provided that You

+      meet the following conditions:

+

+      (a) You must give any other recipients of the Work or

+          Derivative Works a copy of this License; and

+

+      (b) You must cause any modified files to carry prominent notices

+          stating that You changed the files; and

+

+      (c) You must retain, in the Source form of any Derivative Works

+          that You distribute, all copyright, patent, trademark, and

+          attribution notices from the Source form of the Work,

+          excluding those notices that do not pertain to any part of

+          the Derivative Works; and

+

+      (d) If the Work includes a "NOTICE" text file as part of its

+          distribution, then any Derivative Works that You distribute must

+          include a readable copy of the attribution notices contained

+          within such NOTICE file, excluding those notices that do not

+          pertain to any part of the Derivative Works, in at least one

+          of the following places: within a NOTICE text file distributed

+          as part of the Derivative Works; within the Source form or

+          documentation, if provided along with the Derivative Works; or,

+          within a display generated by the Derivative Works, if and

+          wherever such third-party notices normally appear. The contents

+          of the NOTICE file are for informational purposes only and

+          do not modify the License. You may add Your own attribution

+          notices within Derivative Works that You distribute, alongside

+          or as an addendum to the NOTICE text from the Work, provided

+          that such additional attribution notices cannot be construed

+          as modifying the License.

+

+      You may add Your own copyright statement to Your modifications and

+      may provide additional or different license terms and conditions

+      for use, reproduction, or distribution of Your modifications, or

+      for any such Derivative Works as a whole, provided Your use,

+      reproduction, and distribution of the Work otherwise complies with

+      the conditions stated in this License.

+

+   5. Submission of Contributions. Unless You explicitly state otherwise,

+      any Contribution intentionally submitted for inclusion in the Work

+      by You to the Licensor shall be under the terms and conditions of

+      this License, without any additional terms or conditions.

+      Notwithstanding the above, nothing herein shall supersede or modify

+      the terms of any separate license agreement you may have executed

+      with Licensor regarding such Contributions.

+

+   6. Trademarks. This License does not grant permission to use the trade

+      names, trademarks, service marks, or product names of the Licensor,

+      except as required for reasonable and customary use in describing the

+      origin of the Work and reproducing the content of the NOTICE file.

+

+   7. Disclaimer of Warranty. Unless required by applicable law or

+      agreed to in writing, Licensor provides the Work (and each

+      Contributor provides its Contributions) on an "AS IS" BASIS,

+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or

+      implied, including, without limitation, any warranties or conditions

+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A

+      PARTICULAR PURPOSE. You are solely responsible for determining the

+      appropriateness of using or redistributing the Work and assume any

+      risks associated with Your exercise of permissions under this License.

+

+   8. Limitation of Liability. In no event and under no legal theory,

+      whether in tort (including negligence), contract, or otherwise,

+      unless required by applicable law (such as deliberate and grossly

+      negligent acts) or agreed to in writing, shall any Contributor be

+      liable to You for damages, including any direct, indirect, special,

+      incidental, or consequential damages of any character arising as a

+      result of this License or out of the use or inability to use the

+      Work (including but not limited to damages for loss of goodwill,

+      work stoppage, computer failure or malfunction, or any and all

+      other commercial damages or losses), even if such Contributor

+      has been advised of the possibility of such damages.

+

+   9. Accepting Warranty or Additional Liability. While redistributing

+      the Work or Derivative Works thereof, You may choose to offer,

+      and charge a fee for, acceptance of support, warranty, indemnity,

+      or other liability obligations and/or rights consistent with this

+      License. However, in accepting such obligations, You may act only

+      on Your own behalf and on Your sole responsibility, not on behalf

+      of any other Contributor, and only if You agree to indemnify,

+      defend, and hold each Contributor harmless for any liability

+      incurred by, or claims asserted against, such Contributor by reason

+      of your accepting any such warranty or additional liability.

diff --git a/2_0_3_prepare/assembly/src/main/resources/NOTICE.txt b/2_0_3_prepare/assembly/src/main/resources/NOTICE.txt
new file mode 100644
index 0000000..4278ef3
--- /dev/null
+++ b/2_0_3_prepare/assembly/src/main/resources/NOTICE.txt
@@ -0,0 +1,9 @@
+Apache MyFaces Extensions Validator

+Copyright 2007-2008 The Apache Software Foundation

+

+This product includes software developed by

+The Apache Software Foundation (http://www.apache.org/).

+

+------------------------------------------------------------------------

+See the file LICENSE.txt

+------------------------------------------------------------------------
\ No newline at end of file
diff --git a/2_0_3_prepare/component-support/generic-support/pom.xml b/2_0_3_prepare/component-support/generic-support/pom.xml
new file mode 100644
index 0000000..acd80e4
--- /dev/null
+++ b/2_0_3_prepare/component-support/generic-support/pom.xml
@@ -0,0 +1,103 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+    Licensed to the Apache Software Foundation (ASF) under one

+    or more contributor license agreements.  See the NOTICE file

+    distributed with this work for additional information

+    regarding copyright ownership.  The ASF licenses this file

+    to you under the Apache License, Version 2.0 (the

+    "License"); you may not use this file except in compliance

+    with the License.  You may obtain a copy of the License at

+

+    http://www.apache.org/licenses/LICENSE-2.0

+

+    Unless required by applicable law or agreed to in writing,

+    software distributed under the License is distributed on an

+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+    KIND, either express or implied.  See the License for the

+    specific language governing permissions and limitations

+    under the License.

+-->

+<project xmlns="http://maven.apache.org/POM/4.0.0"

+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">

+    <modelVersion>4.0.0</modelVersion>

+    <packaging>jar</packaging>

+

+    <groupId>org.apache.myfaces.extensions.validator.component-support-modules</groupId>

+    <artifactId>myfaces-extval-generic-support</artifactId>

+

+    <name>MyFaces Extensions-Validator Generic Support Module</name>

+    <version>2.0.3-SNAPSHOT</version>

+

+    <parent>

+        <groupId>org.apache.myfaces.extensions.validator.component-support-modules</groupId>

+        <artifactId>component-support-modules-project</artifactId>

+        <version>2.0.3-SNAPSHOT</version>

+    </parent>

+

+    <dependencies>

+        <dependency>

+            <groupId>javax.faces</groupId>

+            <artifactId>jsf-api</artifactId>

+            <version>2.0</version>

+            <scope>provided</scope>

+        </dependency>

+

+        <dependency>

+            <groupId>commons-logging</groupId>

+            <artifactId>commons-logging</artifactId>

+            <version>1.1.1</version>

+            <scope>compile</scope>

+        </dependency>

+

+        <dependency>

+            <groupId>cglib</groupId>

+            <artifactId>cglib</artifactId>

+            <version>2.1_3</version>

+            <scope>compile</scope>

+        </dependency>

+    </dependencies>

+

+    <build>

+        <resources>

+            <resource>

+                <directory>src/main/config</directory>

+                <includes>

+                    <include>**/*xml</include>

+                </includes>

+                <targetPath>/META-INF</targetPath>

+            </resource>

+            <resource>

+                <directory>src/main/resources</directory>

+                <includes>

+                    <include>LICENSE.txt</include>

+                    <include>NOTICE.txt</include>

+                </includes>

+                <targetPath>/META-INF</targetPath>

+            </resource>

+            <resource>

+                <directory>src/main/java</directory>

+                <includes>

+                    <include>**/*properties</include>

+                </includes>

+            </resource>

+        </resources>

+        <plugins>

+            <plugin>

+                <inherited>true</inherited>

+                <groupId>org.apache.maven.plugins</groupId>

+                <artifactId>maven-source-plugin</artifactId>

+

+                <executions>

+                    <execution>

+                        <id>attach-sources</id>

+                        <goals>

+                            <goal>jar</goal>

+                        </goals>

+                    </execution>

+                </executions>

+            </plugin>

+        </plugins>

+    </build>

+

+</project>

diff --git a/2_0_3_prepare/component-support/generic-support/src/main/config/faces-config.xml b/2_0_3_prepare/component-support/generic-support/src/main/config/faces-config.xml
new file mode 100644
index 0000000..e2605f3
--- /dev/null
+++ b/2_0_3_prepare/component-support/generic-support/src/main/config/faces-config.xml
@@ -0,0 +1,28 @@
+<!--

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+-->

+<faces-config xmlns="http://java.sun.com/xml/ns/javaee"

+              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

+              xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_1_2.xsd"

+              version="2.0">

+    <lifecycle>

+        <phase-listener>

+            org.apache.myfaces.extensions.validator.generic.startup.GenericModuleStartupListener

+        </phase-listener>

+    </lifecycle>

+</faces-config>
\ No newline at end of file
diff --git a/2_0_3_prepare/component-support/generic-support/src/main/java/org/apache/myfaces/extensions/validator/generic/renderkit/ExtValGenericRenderKit.java b/2_0_3_prepare/component-support/generic-support/src/main/java/org/apache/myfaces/extensions/validator/generic/renderkit/ExtValGenericRenderKit.java
new file mode 100644
index 0000000..7dbed7b
--- /dev/null
+++ b/2_0_3_prepare/component-support/generic-support/src/main/java/org/apache/myfaces/extensions/validator/generic/renderkit/ExtValGenericRenderKit.java
@@ -0,0 +1,87 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.generic.renderkit;

+

+import org.apache.myfaces.extensions.validator.core.renderkit.ExtValRenderKit;

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+import org.apache.myfaces.extensions.validator.util.ProxyUtils;

+

+import javax.faces.render.RenderKit;

+import javax.faces.render.Renderer;

+import java.lang.reflect.Method;

+

+import net.sf.cglib.proxy.MethodInterceptor;

+import net.sf.cglib.proxy.Enhancer;

+import net.sf.cglib.proxy.MethodProxy;

+

+/**

+ * @author Gerhard Petracek

+ * @since 1.x.1

+ */

+@UsageInformation(UsageCategory.INTERNAL)

+public class ExtValGenericRenderKit extends ExtValRenderKit implements MethodInterceptor

+{

+    public static RenderKit newInstance(RenderKit renderKit)

+    {

+        Class currentClass = renderKit.getClass();

+

+        //it's not possible to wrap the converter again - occurs e.g. under solaris + bea weblogic

+        if (ProxyUtils.isProxiedClass(currentClass))

+        {

+            return renderKit;

+        }

+

+        Enhancer enhancer = new Enhancer();

+        enhancer.setSuperclass(renderKit.getClass());

+        enhancer.setCallback(new ExtValGenericRenderKit(renderKit));

+        enhancer.setClassLoader(Thread.currentThread().getContextClassLoader());

+

+        return (RenderKit) enhancer.create();

+    }

+

+    public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable

+    {

+        if(method.getName().equals("getRenderer"))

+        {

+            return getRenderer((String)args[0], (String)args[1]);

+        }

+        else if(method.getName().equals("addRenderer"))

+        {

+            addRenderer((String)args[0], (String)args[1], (Renderer)args[2]);

+        }

+        else

+        {

+            return proxy.invokeSuper(obj, args);

+        }

+

+        return null;

+    }

+

+    public ExtValGenericRenderKit(RenderKit wrapped)

+    {

+        super(wrapped);

+    }

+

+    @Override

+    protected Renderer createWrapper(Renderer renderer)

+    {

+        return ExtValGenericRendererWrapper.newInstance(renderer);

+    }

+}

diff --git a/2_0_3_prepare/component-support/generic-support/src/main/java/org/apache/myfaces/extensions/validator/generic/renderkit/ExtValGenericRendererWrapper.java b/2_0_3_prepare/component-support/generic-support/src/main/java/org/apache/myfaces/extensions/validator/generic/renderkit/ExtValGenericRendererWrapper.java
new file mode 100644
index 0000000..2165575
--- /dev/null
+++ b/2_0_3_prepare/component-support/generic-support/src/main/java/org/apache/myfaces/extensions/validator/generic/renderkit/ExtValGenericRendererWrapper.java
@@ -0,0 +1,106 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.myfaces.extensions.validator.generic.renderkit;
+
+import org.apache.myfaces.extensions.validator.internal.UsageCategory;
+import org.apache.myfaces.extensions.validator.internal.UsageInformation;
+import org.apache.myfaces.extensions.validator.core.renderkit.ExtValRendererWrapper;
+import org.apache.myfaces.extensions.validator.util.ProxyUtils;
+
+import javax.faces.component.UIComponent;
+import javax.faces.context.FacesContext;
+import javax.faces.render.Renderer;
+import java.lang.reflect.Method;
+
+import net.sf.cglib.proxy.MethodInterceptor;
+import net.sf.cglib.proxy.Enhancer;
+import net.sf.cglib.proxy.MethodProxy;
+
+/**
+ * @author Gerhard Petracek
+ * @since 1.x.1
+ */
+@UsageInformation(UsageCategory.INTERNAL)
+public final class ExtValGenericRendererWrapper extends ExtValRendererWrapper implements MethodInterceptor
+{
+    public static Renderer newInstance(Renderer renderer)
+    {
+        Class currentClass = renderer.getClass();
+
+        //to avoid re-wrapping - occurs e.g. under solaris + bea weblogic
+        if (ProxyUtils.isProxiedClass(currentClass))
+        {
+            return renderer;
+        }
+
+        Enhancer enhancer = new Enhancer();
+        enhancer.setSuperclass(renderer.getClass());
+        enhancer.setCallback(new ExtValGenericRendererWrapper(renderer));
+        enhancer.setClassLoader(Thread.currentThread().getContextClassLoader());
+
+        return (Renderer) enhancer.create();
+    }
+
+    public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable
+    {
+        if (method.getName().equals("getConvertedValue") && args[1] instanceof UIComponent)
+        {
+            return getConvertedValue((FacesContext)args[0], (UIComponent)args[1], args[2]);
+        }
+        else if (method.getName().equals("decode") && args[1] instanceof UIComponent)
+        {
+            decode((FacesContext)args[0], (UIComponent)args[1]);
+        }
+        else if (method.getName().equals("encodeBegin") && args[1] instanceof UIComponent)
+        {
+            encodeBegin((FacesContext)args[0], (UIComponent)args[1]);
+        }
+        else if (method.getName().equals("encodeChildren") && args[1] instanceof UIComponent)
+        {
+            encodeChildren((FacesContext)args[0], (UIComponent)args[1]);
+        }
+        else if (method.getName().equals("encodeEnd") && args[1] instanceof UIComponent)
+        {
+            encodeEnd((FacesContext)args[0], (UIComponent)args[1]);
+        }
+        else if (method.getName().equals("convertClientId") && args[1] instanceof String)
+        {
+            return convertClientId((FacesContext)args[0], (String)args[1]);
+        }
+        else if (method.getName().equals("getRendersChildren"))
+        {
+            return getRendersChildren();
+        }
+        else
+        {
+            if(logger.isTraceEnabled())
+            {
+                logger.trace("method " + method.getName() + " called without rendering-interceptors");
+            }
+
+            return proxy.invokeSuper(obj, args);
+        }
+        return null;
+    }
+
+    public ExtValGenericRendererWrapper(Renderer wrapped)
+    {
+        super(wrapped);
+    }
+}
diff --git a/2_0_3_prepare/component-support/generic-support/src/main/java/org/apache/myfaces/extensions/validator/generic/renderkit/GenericRenderKitWrapperFactory.java b/2_0_3_prepare/component-support/generic-support/src/main/java/org/apache/myfaces/extensions/validator/generic/renderkit/GenericRenderKitWrapperFactory.java
new file mode 100644
index 0000000..6d917e6
--- /dev/null
+++ b/2_0_3_prepare/component-support/generic-support/src/main/java/org/apache/myfaces/extensions/validator/generic/renderkit/GenericRenderKitWrapperFactory.java
@@ -0,0 +1,43 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.generic.renderkit;

+

+import org.apache.myfaces.extensions.validator.core.renderkit.AbstractRenderKitWrapperFactory;

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+

+import javax.faces.render.RenderKit;

+

+/**

+ * @author Gerhard Petracek

+ * @since 1.x.1

+ */

+@UsageInformation(UsageCategory.INTERNAL)

+public class GenericRenderKitWrapperFactory extends AbstractRenderKitWrapperFactory

+{

+    protected RenderKit createWrapper(RenderKit renderKit)

+    {

+        if(logger.isTraceEnabled())

+        {

+            logger.trace("extval renderkit wrapper created for " + renderKit.getClass().getName() + " via cglib");

+        }

+

+        return ExtValGenericRenderKit.newInstance(renderKit);

+    }

+}
\ No newline at end of file
diff --git a/2_0_3_prepare/component-support/generic-support/src/main/java/org/apache/myfaces/extensions/validator/generic/startup/GenericModuleStartupListener.java b/2_0_3_prepare/component-support/generic-support/src/main/java/org/apache/myfaces/extensions/validator/generic/startup/GenericModuleStartupListener.java
new file mode 100644
index 0000000..a573314
--- /dev/null
+++ b/2_0_3_prepare/component-support/generic-support/src/main/java/org/apache/myfaces/extensions/validator/generic/startup/GenericModuleStartupListener.java
@@ -0,0 +1,43 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.generic.startup;

+

+import org.apache.myfaces.extensions.validator.core.ExtValContext;

+import org.apache.myfaces.extensions.validator.core.factory.FactoryNames;

+import org.apache.myfaces.extensions.validator.core.renderkit.AbstractRenderKitWrapperFactory;

+import org.apache.myfaces.extensions.validator.core.startup.AbstractStartupListener;

+import org.apache.myfaces.extensions.validator.generic.renderkit.GenericRenderKitWrapperFactory;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+

+/**

+ * @author Gerhard Petracek

+ * @since 1.x.1

+ */

+@UsageInformation(UsageCategory.INTERNAL)

+public class GenericModuleStartupListener extends AbstractStartupListener

+{

+    private static final long serialVersionUID = 4392156032877519556L;

+

+    protected void init()

+    {

+        ExtValContext.getContext().getFactoryFinder().getFactory(FactoryNames.RENDERKIT_WRAPPER_FACTORY,

+                AbstractRenderKitWrapperFactory.class).addRenderKitWrapperFactory(new GenericRenderKitWrapperFactory());

+    }

+}

diff --git a/2_0_3_prepare/component-support/generic-support/src/main/resources/LICENSE.txt b/2_0_3_prepare/component-support/generic-support/src/main/resources/LICENSE.txt
new file mode 100644
index 0000000..c6055ec
--- /dev/null
+++ b/2_0_3_prepare/component-support/generic-support/src/main/resources/LICENSE.txt
@@ -0,0 +1,174 @@
+                                 Apache License

+                           Version 2.0, January 2004

+                        http://www.apache.org/licenses/

+

+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

+

+   1. Definitions.

+

+      "License" shall mean the terms and conditions for use, reproduction,

+      and distribution as defined by Sections 1 through 9 of this document.

+

+      "Licensor" shall mean the copyright owner or entity authorized by

+      the copyright owner that is granting the License.

+

+      "Legal Entity" shall mean the union of the acting entity and all

+      other entities that control, are controlled by, or are under common

+      control with that entity. For the purposes of this definition,

+      "control" means (i) the power, direct or indirect, to cause the

+      direction or management of such entity, whether by contract or

+      otherwise, or (ii) ownership of fifty percent (50%) or more of the

+      outstanding shares, or (iii) beneficial ownership of such entity.

+

+      "You" (or "Your") shall mean an individual or Legal Entity

+      exercising permissions granted by this License.

+

+      "Source" form shall mean the preferred form for making modifications,

+      including but not limited to software source code, documentation

+      source, and configuration files.

+

+      "Object" form shall mean any form resulting from mechanical

+      transformation or translation of a Source form, including but

+      not limited to compiled object code, generated documentation,

+      and conversions to other media types.

+

+      "Work" shall mean the work of authorship, whether in Source or

+      Object form, made available under the License, as indicated by a

+      copyright notice that is included in or attached to the work

+      (an example is provided in the Appendix below).

+

+      "Derivative Works" shall mean any work, whether in Source or Object

+      form, that is based on (or derived from) the Work and for which the

+      editorial revisions, annotations, elaborations, or other modifications

+      represent, as a whole, an original work of authorship. For the purposes

+      of this License, Derivative Works shall not include works that remain

+      separable from, or merely link (or bind by name) to the interfaces of,

+      the Work and Derivative Works thereof.

+

+      "Contribution" shall mean any work of authorship, including

+      the original version of the Work and any modifications or additions

+      to that Work or Derivative Works thereof, that is intentionally

+      submitted to Licensor for inclusion in the Work by the copyright owner

+      or by an individual or Legal Entity authorized to submit on behalf of

+      the copyright owner. For the purposes of this definition, "submitted"

+      means any form of electronic, verbal, or written communication sent

+      to the Licensor or its representatives, including but not limited to

+      communication on electronic mailing lists, source code control systems,

+      and issue tracking systems that are managed by, or on behalf of, the

+      Licensor for the purpose of discussing and improving the Work, but

+      excluding communication that is conspicuously marked or otherwise

+      designated in writing by the copyright owner as "Not a Contribution."

+

+      "Contributor" shall mean Licensor and any individual or Legal Entity

+      on behalf of whom a Contribution has been received by Licensor and

+      subsequently incorporated within the Work.

+

+   2. Grant of Copyright License. Subject to the terms and conditions of

+      this License, each Contributor hereby grants to You a perpetual,

+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable

+      copyright license to reproduce, prepare Derivative Works of,

+      publicly display, publicly perform, sublicense, and distribute the

+      Work and such Derivative Works in Source or Object form.

+

+   3. Grant of Patent License. Subject to the terms and conditions of

+      this License, each Contributor hereby grants to You a perpetual,

+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable

+      (except as stated in this section) patent license to make, have made,

+      use, offer to sell, sell, import, and otherwise transfer the Work,

+      where such license applies only to those patent claims licensable

+      by such Contributor that are necessarily infringed by their

+      Contribution(s) alone or by combination of their Contribution(s)

+      with the Work to which such Contribution(s) was submitted. If You

+      institute patent litigation against any entity (including a

+      cross-claim or counterclaim in a lawsuit) alleging that the Work

+      or a Contribution incorporated within the Work constitutes direct

+      or contributory patent infringement, then any patent licenses

+      granted to You under this License for that Work shall terminate

+      as of the date such litigation is filed.

+

+   4. Redistribution. You may reproduce and distribute copies of the

+      Work or Derivative Works thereof in any medium, with or without

+      modifications, and in Source or Object form, provided that You

+      meet the following conditions:

+

+      (a) You must give any other recipients of the Work or

+          Derivative Works a copy of this License; and

+

+      (b) You must cause any modified files to carry prominent notices

+          stating that You changed the files; and

+

+      (c) You must retain, in the Source form of any Derivative Works

+          that You distribute, all copyright, patent, trademark, and

+          attribution notices from the Source form of the Work,

+          excluding those notices that do not pertain to any part of

+          the Derivative Works; and

+

+      (d) If the Work includes a "NOTICE" text file as part of its

+          distribution, then any Derivative Works that You distribute must

+          include a readable copy of the attribution notices contained

+          within such NOTICE file, excluding those notices that do not

+          pertain to any part of the Derivative Works, in at least one

+          of the following places: within a NOTICE text file distributed

+          as part of the Derivative Works; within the Source form or

+          documentation, if provided along with the Derivative Works; or,

+          within a display generated by the Derivative Works, if and

+          wherever such third-party notices normally appear. The contents

+          of the NOTICE file are for informational purposes only and

+          do not modify the License. You may add Your own attribution

+          notices within Derivative Works that You distribute, alongside

+          or as an addendum to the NOTICE text from the Work, provided

+          that such additional attribution notices cannot be construed

+          as modifying the License.

+

+      You may add Your own copyright statement to Your modifications and

+      may provide additional or different license terms and conditions

+      for use, reproduction, or distribution of Your modifications, or

+      for any such Derivative Works as a whole, provided Your use,

+      reproduction, and distribution of the Work otherwise complies with

+      the conditions stated in this License.

+

+   5. Submission of Contributions. Unless You explicitly state otherwise,

+      any Contribution intentionally submitted for inclusion in the Work

+      by You to the Licensor shall be under the terms and conditions of

+      this License, without any additional terms or conditions.

+      Notwithstanding the above, nothing herein shall supersede or modify

+      the terms of any separate license agreement you may have executed

+      with Licensor regarding such Contributions.

+

+   6. Trademarks. This License does not grant permission to use the trade

+      names, trademarks, service marks, or product names of the Licensor,

+      except as required for reasonable and customary use in describing the

+      origin of the Work and reproducing the content of the NOTICE file.

+

+   7. Disclaimer of Warranty. Unless required by applicable law or

+      agreed to in writing, Licensor provides the Work (and each

+      Contributor provides its Contributions) on an "AS IS" BASIS,

+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or

+      implied, including, without limitation, any warranties or conditions

+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A

+      PARTICULAR PURPOSE. You are solely responsible for determining the

+      appropriateness of using or redistributing the Work and assume any

+      risks associated with Your exercise of permissions under this License.

+

+   8. Limitation of Liability. In no event and under no legal theory,

+      whether in tort (including negligence), contract, or otherwise,

+      unless required by applicable law (such as deliberate and grossly

+      negligent acts) or agreed to in writing, shall any Contributor be

+      liable to You for damages, including any direct, indirect, special,

+      incidental, or consequential damages of any character arising as a

+      result of this License or out of the use or inability to use the

+      Work (including but not limited to damages for loss of goodwill,

+      work stoppage, computer failure or malfunction, or any and all

+      other commercial damages or losses), even if such Contributor

+      has been advised of the possibility of such damages.

+

+   9. Accepting Warranty or Additional Liability. While redistributing

+      the Work or Derivative Works thereof, You may choose to offer,

+      and charge a fee for, acceptance of support, warranty, indemnity,

+      or other liability obligations and/or rights consistent with this

+      License. However, in accepting such obligations, You may act only

+      on Your own behalf and on Your sole responsibility, not on behalf

+      of any other Contributor, and only if You agree to indemnify,

+      defend, and hold each Contributor harmless for any liability

+      incurred by, or claims asserted against, such Contributor by reason

+      of your accepting any such warranty or additional liability.

diff --git a/2_0_3_prepare/component-support/generic-support/src/main/resources/NOTICE.txt b/2_0_3_prepare/component-support/generic-support/src/main/resources/NOTICE.txt
new file mode 100644
index 0000000..4278ef3
--- /dev/null
+++ b/2_0_3_prepare/component-support/generic-support/src/main/resources/NOTICE.txt
@@ -0,0 +1,9 @@
+Apache MyFaces Extensions Validator

+Copyright 2007-2008 The Apache Software Foundation

+

+This product includes software developed by

+The Apache Software Foundation (http://www.apache.org/).

+

+------------------------------------------------------------------------

+See the file LICENSE.txt

+------------------------------------------------------------------------
\ No newline at end of file
diff --git a/2_0_3_prepare/component-support/generic-support/src/site/apt/index.apt b/2_0_3_prepare/component-support/generic-support/src/site/apt/index.apt
new file mode 100644
index 0000000..659a8e8
--- /dev/null
+++ b/2_0_3_prepare/component-support/generic-support/src/site/apt/index.apt
@@ -0,0 +1,9 @@
+ ------

+Apache MyFaces Extensions Validator Generic Support Module

+ ------

+

+Apache MyFaces Extensions Validator Generic Support Module Overview

+

+    MyFaces Extensions Validator Generic Support Module provides generic Support for JSF component frameworks which have special requirements (e.g. RichFaces, MyFaces Tobago, ...).

+

+    MyFaces Extensions Validator is compatible with JSF 1.1.x and JSF 1.2.x. Both versions require Java 1.5+
\ No newline at end of file
diff --git a/2_0_3_prepare/component-support/pom.xml b/2_0_3_prepare/component-support/pom.xml
new file mode 100644
index 0000000..87854dd
--- /dev/null
+++ b/2_0_3_prepare/component-support/pom.xml
@@ -0,0 +1,62 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+    Licensed to the Apache Software Foundation (ASF) under one

+    or more contributor license agreements.  See the NOTICE file

+    distributed with this work for additional information

+    regarding copyright ownership.  The ASF licenses this file

+    to you under the Apache License, Version 2.0 (the

+    "License"); you may not use this file except in compliance

+    with the License.  You may obtain a copy of the License at

+

+    http://www.apache.org/licenses/LICENSE-2.0

+

+    Unless required by applicable law or agreed to in writing,

+    software distributed under the License is distributed on an

+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+    KIND, either express or implied.  See the License for the

+    specific language governing permissions and limitations

+    under the License.

+-->

+<project xmlns="http://maven.apache.org/POM/4.0.0"

+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">

+    <modelVersion>4.0.0</modelVersion>

+

+    <packaging>pom</packaging>

+

+    <groupId>org.apache.myfaces.extensions.validator.component-support-modules</groupId>

+    <artifactId>component-support-modules-project</artifactId>

+

+    <name>MyFaces Extensions-Validator Component-Support Modules</name>

+    <version>2.0.3-SNAPSHOT</version>

+

+    <parent>

+        <groupId>org.apache.myfaces.extensions.validator</groupId>

+        <artifactId>myfaces-extval-parent</artifactId>

+        <version>2.0.3-SNAPSHOT</version>

+    </parent>

+

+    <scm>

+        <connection>scm:svn:http://svn.apache.org/repos/asf/myfaces/extensions/validator/branches/1_2_2_rc/component-support</connection>

+        <developerConnection>scm:svn:https://svn.apache.org/repos/asf/myfaces/extensions/validator/branches/1_2_2_rc/component-support</developerConnection>

+        <url>http://svn.apache.org/viewvc/myfaces/extensions/validator/branches/1_2_2_rc/component-support</url>

+    </scm>

+

+    <modules>

+        <!--module>trinidad-support</module-->

+        <module>generic-support</module>

+    </modules>

+

+    <dependencies>

+        <dependency>

+            <groupId>org.apache.myfaces.extensions.validator</groupId>

+            <artifactId>myfaces-extval-core</artifactId>

+            <version>2.0.3-SNAPSHOT</version>

+            <scope>compile</scope>

+        </dependency>

+    </dependencies>

+

+    <properties>

+        <trinidad.version>1.2.9</trinidad.version>

+    </properties>

+</project>

diff --git a/2_0_3_prepare/core/pom.xml b/2_0_3_prepare/core/pom.xml
new file mode 100644
index 0000000..c7ac02e
--- /dev/null
+++ b/2_0_3_prepare/core/pom.xml
@@ -0,0 +1,108 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+    Licensed to the Apache Software Foundation (ASF) under one

+    or more contributor license agreements.  See the NOTICE file

+    distributed with this work for additional information

+    regarding copyright ownership.  The ASF licenses this file

+    to you under the Apache License, Version 2.0 (the

+    "License"); you may not use this file except in compliance

+    with the License.  You may obtain a copy of the License at

+

+    http://www.apache.org/licenses/LICENSE-2.0

+

+    Unless required by applicable law or agreed to in writing,

+    software distributed under the License is distributed on an

+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+    KIND, either express or implied.  See the License for the

+    specific language governing permissions and limitations

+    under the License.

+-->

+<project xmlns="http://maven.apache.org/POM/4.0.0"

+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">

+    <modelVersion>4.0.0</modelVersion>

+

+    <parent>

+        <groupId>org.apache.myfaces.extensions.validator</groupId>

+        <artifactId>myfaces-extval-parent</artifactId>

+        <version>2.0.3-SNAPSHOT</version>

+    </parent>

+

+    <groupId>org.apache.myfaces.extensions.validator</groupId>

+    <artifactId>myfaces-extval-core</artifactId>

+    <name>MyFaces Extensions-Validator Core</name>

+    <version>2.0.3-SNAPSHOT</version>

+    <packaging>jar</packaging>

+

+    <scm>

+        <connection>scm:svn:http://svn.apache.org/repos/asf/myfaces/extensions/validator/branches/1_2_2_rc/core</connection>

+        <developerConnection>scm:svn:https://svn.apache.org/repos/asf/myfaces/extensions/validator/branches/1_2_2_rc/core</developerConnection>

+        <url>http://svn.apache.org/viewvc/myfaces/extensions/validator/branches/1_2_2_rc/core</url>

+    </scm>

+    

+    <dependencies>

+        <dependency>

+            <groupId>javax.faces</groupId>

+            <artifactId>jsf-api</artifactId>

+            <version>2.0</version>

+            <scope>provided</scope>

+        </dependency>

+

+        <dependency>

+            <groupId>commons-logging</groupId>

+            <artifactId>commons-logging</artifactId>

+            <version>1.1.1</version>

+            <scope>compile</scope>

+        </dependency>

+

+         <dependency>

+            <groupId>javax.el</groupId>

+            <artifactId>el-api</artifactId>

+            <version>1.0</version>

+            <scope>provided</scope>

+        </dependency>

+    </dependencies>

+

+    <build>

+        <resources>

+            <resource>

+                <directory>src/main/config</directory>

+                <includes>

+                    <include>**/*xml</include>

+                </includes>

+                <targetPath>/META-INF</targetPath>

+            </resource>

+            <resource>

+                <directory>src/main/resources</directory>

+                <includes>

+                    <include>LICENSE.txt</include>

+                    <include>NOTICE.txt</include>

+                </includes>

+                <targetPath>/META-INF</targetPath>

+            </resource>

+            <resource>

+                <directory>src/main/java</directory>

+                <includes>

+                    <include>**/*properties</include>

+                </includes>

+            </resource>

+        </resources>

+        <plugins>

+            <plugin>

+                <inherited>true</inherited>

+                <groupId>org.apache.maven.plugins</groupId>

+                <artifactId>maven-source-plugin</artifactId>

+

+                <executions>

+                    <execution>

+                        <id>attach-sources</id>

+                        <goals>

+                            <goal>jar</goal>

+                        </goals>

+                    </execution>

+                </executions>

+            </plugin>

+        </plugins>

+    </build>

+

+</project>

diff --git a/2_0_3_prepare/core/src/main/config/faces-config.xml b/2_0_3_prepare/core/src/main/config/faces-config.xml
new file mode 100644
index 0000000..6dc7f47
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/config/faces-config.xml
@@ -0,0 +1,31 @@
+<!--

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+-->

+

+<faces-config xmlns="http://java.sun.com/xml/ns/javaee"

+              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

+              xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_1_2.xsd"

+              version="2.0">

+    <factory>

+        <render-kit-factory>org.apache.myfaces.extensions.validator.core.renderkit.ExtValRenderKitFactory</render-kit-factory>

+    </factory>

+

+    <lifecycle>

+        <phase-listener>org.apache.myfaces.extensions.validator.core.startup.ExtValStartupListener</phase-listener>

+    </lifecycle>

+</faces-config>
\ No newline at end of file
diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/ExtValInformation.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/ExtValInformation.java
new file mode 100644
index 0000000..77d5d1c
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/ExtValInformation.java
@@ -0,0 +1,37 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator;

+

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+import org.apache.myfaces.extensions.validator.util.ClassUtils;

+

+/**

+ * dont't move to an other package!!!

+ *

+ * @author Gerhard Petracek

+ * @since 1.x.1

+ */

+@UsageInformation(UsageCategory.INTERNAL)

+public interface ExtValInformation

+{

+    static final String EXTENSIONS_VALIDATOR_BASE_PACKAGE_NAME = ExtValInformation.class.getPackage().getName();

+    static final String WEBXML_PARAM_PREFIX = ExtValInformation.class.getPackage().getName();

+    static final String VERSION = ClassUtils.getJarVersion(ExtValInformation.class);

+}

diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/CustomInformation.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/CustomInformation.java
new file mode 100644
index 0000000..62da39e
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/CustomInformation.java
@@ -0,0 +1,63 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.core;

+

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+

+/**

+ * @author Gerhard Petracek

+ * @since 1.x.1

+ */

+@UsageInformation({UsageCategory.API})

+public enum CustomInformation

+{

+    BASE_PACKAGE,

+

+    COMPONENT_META_DATA_EXTRACTOR,

+    VALIDATION_PARAMETER_EXTRACTOR,

+

+    VALIDATION_STRATEGY_POSTFIX,

+    VALIDATION_ERROR_MESSAGE_RESOLVER_POSTFIX,

+    META_DATA_TRANSFORMER_POSTFIX,

+

+    VALIDATION_STRATEGY_TO_MSG_RESOLVER_NAME_MAPPER,

+    META_DATA_TO_VALIDATION_STRATEGY_NAME_MAPPER,

+    VALIDATION_STRATEGY_TO_META_DATA_TRANSFORMER_NAME_MAPPER,

+

+    STARTUP_LISTENER,

+    COMPONENT_INITIALIZER,

+    VALIDATION_EXCEPTION_INTERCEPTOR,

+    PROPERTY_VALIDATION_INTERCEPTOR,

+    META_DATA_EXTRACTION_INTERCEPTOR,

+

+    MESSAGE_RESOLVER_FACTORY,

+    VALIDATION_STRATEGY_FACTORY,

+    COMPONENT_META_DATA_EXTRACTOR_FACTORY,

+    VALIDATION_PARAMETER_EXTRACTOR_FACTORY,

+    VALIDATION_PARAMETER_FACTORY,

+    META_DATA_TRANSFORMER_FACTORY,

+    FACES_MESSAGE_FACTORY,

+    STORAGE_MANAGER_FACTORY,

+

+    MESSAGE_BUNDLE_NAME,

+    STATIC_STRATEGY_MAPPING_SOURCE,

+

+    META_DATA_STORAGE_FILTER

+}

diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/DefaultProjectStageResolver.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/DefaultProjectStageResolver.java
new file mode 100644
index 0000000..034d10a
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/DefaultProjectStageResolver.java
@@ -0,0 +1,63 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.core;

+

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+import org.apache.myfaces.extensions.validator.util.ExtValUtils;

+

+import javax.faces.context.FacesContext;

+

+/**

+ * @author Gerhard Petracek

+ * @since x.x.3

+ */

+@UsageInformation(UsageCategory.INTERNAL)

+public class DefaultProjectStageResolver implements ProjectStageResolver

+{

+    public ProjectStage getCurrentProjectStage()

+    {

+        //don't use the default extval mechanism to avoid too early evaluation with mojarra

+        String result;

+        try

+        {

+            result = FacesContext.getCurrentInstance().getApplication().getProjectStage().toString();

+        }

+        catch (Throwable t)

+        {

+            return createProjectStage(getDefaultProjectStage());

+        }

+

+        if(result == null || "".equals(result))

+        {

+            return createProjectStage(getDefaultProjectStage());

+        }

+        return createProjectStage(ProjectStage.createStageName(result.trim()));

+    }

+

+    protected ProjectStage createProjectStage(ProjectStageName projectStageName)

+    {

+        return ProjectStage.createStage(projectStageName);

+    }

+

+    private ProjectStageName getDefaultProjectStage()

+    {

+        return ExtValUtils.getDefaultStageName();

+    }

+}
\ No newline at end of file
diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/ExtValContext.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/ExtValContext.java
new file mode 100644
index 0000000..52895bf
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/ExtValContext.java
@@ -0,0 +1,412 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.myfaces.extensions.validator.core;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.myfaces.extensions.validator.core.factory.DefaultFactoryFinder;
+import org.apache.myfaces.extensions.validator.core.factory.FactoryFinder;
+import org.apache.myfaces.extensions.validator.core.initializer.component.ComponentInitializer;
+import org.apache.myfaces.extensions.validator.core.initializer.configuration.StaticConfiguration;
+import org.apache.myfaces.extensions.validator.core.initializer.configuration.StaticConfigurationNames;
+import org.apache.myfaces.extensions.validator.core.interceptor.MetaDataExtractionInterceptor;
+import org.apache.myfaces.extensions.validator.core.interceptor.PropertyValidationInterceptor;
+import org.apache.myfaces.extensions.validator.core.interceptor.RendererInterceptor;
+import org.apache.myfaces.extensions.validator.core.interceptor.ValidationExceptionInterceptor;
+import org.apache.myfaces.extensions.validator.core.metadata.MetaDataEntry;
+import org.apache.myfaces.extensions.validator.core.recorder.ProcessedInformationRecorder;
+import org.apache.myfaces.extensions.validator.core.validation.SkipValidationEvaluator;
+import org.apache.myfaces.extensions.validator.core.validation.parameter.ViolationSeverityInterpreter;
+import org.apache.myfaces.extensions.validator.core.validation.strategy.ValidationStrategy;
+import org.apache.myfaces.extensions.validator.internal.UsageCategory;
+import org.apache.myfaces.extensions.validator.internal.UsageInformation;
+import org.apache.myfaces.extensions.validator.util.ClassUtils;
+
+import javax.faces.component.UIComponent;
+import javax.faces.context.FacesContext;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @author Gerhard Petracek
+ * @since 1.x.1
+ */
+@UsageInformation(UsageCategory.API)
+public class ExtValContext
+{
+    private final Log logger = LogFactory.getLog(getClass());
+
+    private static ExtValContext extValContext;
+
+    //don't try to resolve it dynamically e.g. via InformationProviderBean - there's a mojarra issue
+    private static final String CUSTOM_EXTVAL_CONTEXT_CLASS_NAME =
+            ExtValContext.class.getName().replace(".core.", ".custom.");
+
+    private ViolationSeverityInterpreter violationSeverityInterpreter;
+    private FactoryFinder factoryFinder = DefaultFactoryFinder.getInstance();
+    private Map<String, RendererInterceptor> rendererInterceptors = new HashMap<String, RendererInterceptor>();
+    private List<String> deniedInterceptors = new ArrayList<String>();
+    private List<ProcessedInformationRecorder> processedInformationRecorders =
+            new ArrayList<ProcessedInformationRecorder>();
+
+    private SkipValidationEvaluator skipValidationEvaluator;
+
+    private Map<String, Object> globalProperties = new HashMap<String, Object>();
+
+    private Map<StaticConfigurationNames, List<StaticConfiguration<String, String>>> staticConfigMap
+            = new HashMap<StaticConfigurationNames, List<StaticConfiguration<String, String>>>();
+
+    private ExtValContextInternals contextHelper;
+    private ExtValContextInvocationOrderAwareInternals invocationOrderAwareContextHelper;
+
+    protected ExtValContext()
+    {
+        this.contextHelper = new ExtValContextInternals();
+        this.invocationOrderAwareContextHelper = new ExtValContextInvocationOrderAwareInternals(this.contextHelper);
+    }
+
+    public static ExtValContext getContext()
+    {
+        if (extValContext == null)
+        {
+            extValContext = new ExtValContext();
+
+            tryToCreateCustomExtValContext();
+        }
+        return extValContext;
+    }
+
+    private static void tryToCreateCustomExtValContext()
+    {
+        Object customExtValContext = ClassUtils.tryToInstantiateClassForName(CUSTOM_EXTVAL_CONTEXT_CLASS_NAME);
+
+        if (customExtValContext instanceof ExtValContext)
+        {
+            extValContext = (ExtValContext) customExtValContext;
+        }
+    }
+
+    public void setViolationSeverityInterpreter(ViolationSeverityInterpreter violationSeverityInterpreter)
+    {
+        setViolationSeverityInterpreter(violationSeverityInterpreter, true);
+    }
+
+    public void setViolationSeverityInterpreter(
+            ViolationSeverityInterpreter violationSeverityInterpreter, boolean forceOverride)
+    {
+        if (this.violationSeverityInterpreter == null || forceOverride)
+        {
+            if (this.logger.isInfoEnabled() && violationSeverityInterpreter != null)
+            {
+                this.logger.info(violationSeverityInterpreter.getClass() + " is used");
+            }
+            this.violationSeverityInterpreter = violationSeverityInterpreter;
+        }
+    }
+
+    public ViolationSeverityInterpreter getViolationSeverityInterpreter()
+    {
+        ViolationSeverityInterpreter requestScopedInterpreter = this.contextHelper
+                .getRequestScopedViolationSeverityInterpreter();
+
+        if(requestScopedInterpreter != null)
+        {
+            return requestScopedInterpreter;
+        }
+
+        return this.violationSeverityInterpreter;
+    }
+
+    /*
+    * FactoryFinder
+    */
+    public FactoryFinder getFactoryFinder()
+    {
+        return this.factoryFinder;
+    }
+
+    public void setFactoryFinder(FactoryFinder factoryFinder)
+    {
+        if (factoryFinder != null)
+        {
+            this.factoryFinder = factoryFinder;
+        }
+    }
+
+    /*
+     * SkipValidationEvaluator
+     */
+    public void setSkipValidationEvaluator(SkipValidationEvaluator skipValidationEvaluator)
+    {
+        setSkipValidationEvaluator(skipValidationEvaluator, true);
+    }
+
+    public void setSkipValidationEvaluator(SkipValidationEvaluator skipValidationEvaluator, boolean forceOverride)
+    {
+        if (this.skipValidationEvaluator == null || forceOverride)
+        {
+            if (this.logger.isInfoEnabled() && skipValidationEvaluator != null)
+            {
+                this.logger.info(skipValidationEvaluator.getClass() + " is used");
+            }
+            this.skipValidationEvaluator = skipValidationEvaluator;
+        }
+    }
+
+    public SkipValidationEvaluator getSkipValidationEvaluator()
+    {
+        if (this.skipValidationEvaluator == null)
+        {
+            return new SkipValidationEvaluator()
+            {
+                public boolean skipValidation(FacesContext facesContext, UIComponent uiComponent,
+                                              ValidationStrategy validationStrategy, MetaDataEntry entry)
+                {
+                    return false;
+                }
+            };
+        }
+
+        return this.skipValidationEvaluator;
+    }
+
+    /*
+     * RendererInterceptors
+     */
+    public List<RendererInterceptor> getRendererInterceptors()
+    {
+        return new ArrayList<RendererInterceptor>(this.rendererInterceptors.values());
+    }
+
+    public boolean registerRendererInterceptor(RendererInterceptor rendererInterceptor)
+    {
+        synchronized (ExtValContext.class)
+        {
+            if (this.deniedInterceptors.contains(rendererInterceptor.getInterceptorId()))
+            {
+                return false;
+            }
+
+            this.rendererInterceptors.put(rendererInterceptor.getInterceptorId(), rendererInterceptor);
+        }
+        return true;
+    }
+
+    public void deregisterRendererInterceptor(Class<? extends RendererInterceptor> rendererInterceptorClass)
+    {
+        RendererInterceptor rendererInterceptor = ClassUtils.tryToInstantiateClass(rendererInterceptorClass);
+
+        synchronized (ExtValContext.class)
+        {
+            this.rendererInterceptors.remove(rendererInterceptor.getInterceptorId());
+        }
+    }
+
+    //if an interceptor hasn't been registered so far, it should be denied at future registrations
+    public void denyRendererInterceptor(Class<? extends RendererInterceptor> rendererInterceptorClass)
+    {
+        RendererInterceptor rendererInterceptor = ClassUtils.tryToInstantiateClass(rendererInterceptorClass);
+
+        synchronized (ExtValContext.class)
+        {
+            if (!this.deniedInterceptors.contains(rendererInterceptor.getInterceptorId()))
+            {
+                this.deniedInterceptors.add(rendererInterceptor.getInterceptorId());
+            }
+        }
+        deregisterRendererInterceptor(rendererInterceptorClass);
+    }
+
+    /*
+     * ComponentInitializers
+     */
+    public void addComponentInitializer(ComponentInitializer componentInitializer)
+    {
+        this.invocationOrderAwareContextHelper.lazyInitComponentInitializers();
+        this.invocationOrderAwareContextHelper.addComponentInitializer(componentInitializer);
+    }
+
+    public List<ComponentInitializer> getComponentInitializers()
+    {
+        this.invocationOrderAwareContextHelper.lazyInitComponentInitializers();
+        return this.invocationOrderAwareContextHelper.getComponentInitializers();
+    }
+
+    /*
+     * ValidationExceptionInterceptors
+     */
+    public void addValidationExceptionInterceptor(ValidationExceptionInterceptor validationExceptionInterceptor)
+    {
+        this.invocationOrderAwareContextHelper.lazyInitValidationExceptionInterceptors();
+        this.invocationOrderAwareContextHelper.addValidationExceptionInterceptor(validationExceptionInterceptor);
+    }
+
+    public List<ValidationExceptionInterceptor> getValidationExceptionInterceptors()
+    {
+        this.invocationOrderAwareContextHelper.lazyInitValidationExceptionInterceptors();
+        return this.invocationOrderAwareContextHelper.getValidationExceptionInterceptors();
+    }
+
+    /*
+     * PropertyValidationInterceptors
+     */
+    public void addPropertyValidationInterceptor(PropertyValidationInterceptor propertyValidationInterceptor)
+    {
+        this.invocationOrderAwareContextHelper.lazyInitPropertyValidationInterceptors();
+        this.invocationOrderAwareContextHelper.addPropertyValidationInterceptor(propertyValidationInterceptor);
+    }
+
+    /**
+     * @return all global validation interceptors
+     */
+    public List<PropertyValidationInterceptor> getPropertyValidationInterceptors()
+    {
+        this.invocationOrderAwareContextHelper.lazyInitPropertyValidationInterceptors();
+        return this.invocationOrderAwareContextHelper.getPropertyValidationInterceptors();
+    }
+
+    public List<PropertyValidationInterceptor> getPropertyValidationInterceptorsFor(Class moduleKey)
+    {
+        this.invocationOrderAwareContextHelper.lazyInitPropertyValidationInterceptors();
+        return this.invocationOrderAwareContextHelper.getPropertyValidationInterceptorsFor(moduleKey);
+    }
+
+    /*
+     * MetaDataExtractionInterceptors
+     */
+    public void addMetaDataExtractionInterceptor(MetaDataExtractionInterceptor metaDataExtractionInterceptor)
+    {
+        this.invocationOrderAwareContextHelper.lazyInitMetaDataExtractionInterceptors();
+        this.invocationOrderAwareContextHelper.addMetaDataExtractionInterceptor(metaDataExtractionInterceptor);
+    }
+
+    /**
+     * @return all global meta-data extraction interceptors
+     */
+    public List<MetaDataExtractionInterceptor> getMetaDataExtractionInterceptors()
+    {
+        this.invocationOrderAwareContextHelper.lazyInitMetaDataExtractionInterceptors();
+        return this.invocationOrderAwareContextHelper.getMetaDataExtractionInterceptors();
+    }
+
+    public List<MetaDataExtractionInterceptor> getMetaDataExtractionInterceptorsFor(Class moduleKey)
+    {
+        Map<String, Object> properties = new HashMap<String, Object>();
+
+        if(moduleKey != null)
+        {
+            properties.put(ValidationModuleKey.class.getName(), moduleKey);
+        }
+        return getMetaDataExtractionInterceptorsWith(properties);
+    }
+
+    public List<MetaDataExtractionInterceptor> getMetaDataExtractionInterceptorsWith(Map<String, Object> properties)
+    {
+        this.invocationOrderAwareContextHelper.lazyInitMetaDataExtractionInterceptors();
+        return this.invocationOrderAwareContextHelper.getMetaDataExtractionInterceptorsWith(properties);
+    }
+
+    /*
+     * ProcessedInformationRecorders
+     */
+    public List<ProcessedInformationRecorder> getProcessedInformationRecorders()
+    {
+        return this.processedInformationRecorders;
+    }
+
+    public void addProcessedInformationRecorder(ProcessedInformationRecorder processedInformationRecorder)
+    {
+        this.processedInformationRecorders.add(processedInformationRecorder);
+    }
+
+    /*
+     * InformationProviderBean
+     */
+    public InformationProviderBean getInformationProviderBean()
+    {
+        return this.contextHelper.getInformationProviderBean();
+    }
+
+    /*
+     * StaticConfiguration
+     */
+    public List<StaticConfiguration<String, String>> getStaticConfiguration(StaticConfigurationNames name)
+    {
+        if (!this.staticConfigMap.containsKey(name))
+        {
+            List<StaticConfiguration<String, String>> staticConfigList =
+                    new ArrayList<StaticConfiguration<String, String>>();
+            this.staticConfigMap.put(name, staticConfigList);
+        }
+        return this.staticConfigMap.get(name);
+    }
+
+    public void addStaticConfiguration(StaticConfigurationNames name, StaticConfiguration<String, String> staticConfig)
+    {
+        synchronized (this)
+        {
+            List<StaticConfiguration<String, String>> staticConfigList;
+            if (!this.staticConfigMap.containsKey(name))
+            {
+                staticConfigList = new ArrayList<StaticConfiguration<String, String>>();
+                this.staticConfigMap.put(name, staticConfigList);
+            }
+            this.staticConfigMap.get(name).add(staticConfig);
+        }
+    }
+
+    /*
+     * Global properties
+     */
+    public boolean addGlobalProperty(String name, Object value)
+    {
+        return addGlobalProperty(name, value, true);
+    }
+
+    public boolean addGlobalProperty(String name, Object value, boolean forceOverride)
+    {
+        if (this.globalProperties.containsKey(name))
+        {
+            if (!forceOverride)
+            {
+                return false;
+            }
+
+            if (this.logger.isInfoEnabled())
+            {
+                this.logger.info("override global property '" + name + "'");
+            }
+        }
+
+        if(JsfProjectStage.is(JsfProjectStage.Development) && this.logger.isInfoEnabled())
+        {
+            this.logger.info("global property [" + name + "] added");
+        }
+
+        this.globalProperties.put(name, value);
+        return true;
+    }
+
+    public Object getGlobalProperty(String name)
+    {
+        return this.globalProperties.get(name);
+    }
+}
diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/ExtValContextInternals.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/ExtValContextInternals.java
new file mode 100644
index 0000000..d2cfd5c
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/ExtValContextInternals.java
@@ -0,0 +1,104 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.myfaces.extensions.validator.core;
+
+import org.apache.myfaces.extensions.validator.core.storage.ViolationSeverityInterpreterStorage;
+import org.apache.myfaces.extensions.validator.core.validation.parameter.ViolationSeverityInterpreter;
+import org.apache.myfaces.extensions.validator.internal.UsageCategory;
+import org.apache.myfaces.extensions.validator.internal.UsageInformation;
+import org.apache.myfaces.extensions.validator.util.ClassUtils;
+import org.apache.myfaces.extensions.validator.util.ExtValUtils;
+
+import javax.faces.context.FacesContext;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @author Gerhard Petracek
+ * @since x.x.3
+ */
+@UsageInformation(UsageCategory.INTERNAL)
+class ExtValContextInternals
+{
+    boolean isComponentInitializationActivated()
+    {
+        return !"true".equalsIgnoreCase(WebXmlParameter.DEACTIVATE_COMPONENT_INITIALIZATION);
+    }
+
+    @SuppressWarnings({"unchecked"})
+    InformationProviderBean initInformationProviderBean(Map applicationMap)
+    {
+        List<String> informationProviderBeanClassNames = new ArrayList<String>();
+
+        informationProviderBeanClassNames.add(WebXmlParameter.CUSTOM_INFORMATION_PROVIDER_BEAN);
+        informationProviderBeanClassNames.add(InformationProviderBean.CUSTOM_BEAN);
+
+        InformationProviderBean informationProviderBean;
+        for (String className : informationProviderBeanClassNames)
+        {
+            informationProviderBean = (InformationProviderBean) ClassUtils.tryToInstantiateClassForName(className);
+
+            if (informationProviderBean != null)
+            {
+                applicationMap.put(InformationProviderBean.BEAN_NAME, informationProviderBean);
+                return informationProviderBean;
+            }
+        }
+
+        tryToInitCustomConfiguredInformationProviderBeanClassName(applicationMap);
+
+        if (applicationMap.containsKey(InformationProviderBean.BEAN_NAME))
+        {
+            return (InformationProviderBean) applicationMap.get(InformationProviderBean.BEAN_NAME);
+        }
+        return new InformationProviderBean();
+    }
+
+    @SuppressWarnings({"unchecked"})
+    void tryToInitCustomConfiguredInformationProviderBeanClassName(Map applicationMap)
+    {
+        InformationProviderBean bean = (InformationProviderBean) ExtValUtils.getELHelper()
+                .getBean(InformationProviderBean.CUSTOM_BEAN.replace(".", "_"));
+
+        if (bean != null)
+        {
+            applicationMap.put(InformationProviderBean.BEAN_NAME, bean);
+        }
+    }
+
+    InformationProviderBean getInformationProviderBean()
+    {
+        Map applicationMap = FacesContext.getCurrentInstance().getExternalContext().getApplicationMap();
+        InformationProviderBean bean = (InformationProviderBean) applicationMap.get(InformationProviderBean.BEAN_NAME);
+
+        if (bean == null)
+        {
+            return initInformationProviderBean(applicationMap);
+        }
+        return bean;
+    }
+
+    ViolationSeverityInterpreter getRequestScopedViolationSeverityInterpreter()
+    {
+        return ExtValUtils.getStorage(
+                ViolationSeverityInterpreterStorage.class, ViolationSeverityInterpreterStorage.class.getName())
+                .getViolationSeverityInterpreter();
+    }
+}
\ No newline at end of file
diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/ExtValContextInvocationOrderAwareInternals.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/ExtValContextInvocationOrderAwareInternals.java
new file mode 100644
index 0000000..e19366c
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/ExtValContextInvocationOrderAwareInternals.java
@@ -0,0 +1,478 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.myfaces.extensions.validator.core;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.myfaces.extensions.validator.core.initializer.component.ComponentInitializer;
+import org.apache.myfaces.extensions.validator.core.interceptor.MetaDataExtractionInterceptor;
+import org.apache.myfaces.extensions.validator.core.interceptor.PropertyValidationInterceptor;
+import org.apache.myfaces.extensions.validator.core.interceptor.ValidationExceptionInterceptor;
+import org.apache.myfaces.extensions.validator.internal.UsageCategory;
+import org.apache.myfaces.extensions.validator.internal.UsageInformation;
+import org.apache.myfaces.extensions.validator.util.ClassUtils;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Collections;
+
+/**
+ * @author Gerhard Petracek
+ * @since x.x.3
+ */
+@UsageInformation(UsageCategory.INTERNAL)
+class ExtValContextInvocationOrderAwareInternals
+{
+    private final Log logger = LogFactory.getLog(getClass());
+
+    private List<MetaDataExtractionInterceptor> metaDataExtractionInterceptors = null;
+    private Map<Class, List<MetaDataExtractionInterceptor>> moduleSpecificMetaDataExtractionInterceptors = null;
+    private List<ValidationExceptionInterceptor> validationExceptionInterceptors = null;
+    private List<PropertyValidationInterceptor> propertyValidationInterceptors = null;
+    private Map<Class, List<PropertyValidationInterceptor>> moduleSpecificPropertyValidationInterceptors = null;
+    private List<ComponentInitializer> componentInitializers = null;
+
+    private ExtValContextInternals contextHelper;
+
+    ExtValContextInvocationOrderAwareInternals(ExtValContextInternals contextHelper)
+    {
+        this.contextHelper = contextHelper;
+    }
+
+    /*
+     * ComponentInitializers
+     */
+    void addComponentInitializer(ComponentInitializer componentInitializer)
+    {
+        this.componentInitializers.add(componentInitializer);
+        sortComponentInitializers();
+    }
+
+    List<ComponentInitializer> getComponentInitializers()
+    {
+        return this.contextHelper.isComponentInitializationActivated() ?
+                this.componentInitializers : new ArrayList<ComponentInitializer>();
+    }
+
+    /*
+     * ValidationExceptionInterceptors
+     */
+    void addValidationExceptionInterceptor(ValidationExceptionInterceptor validationExceptionInterceptor)
+    {
+        this.validationExceptionInterceptors.add(validationExceptionInterceptor);
+        sortValidationExceptionInterceptors();
+    }
+
+    List<ValidationExceptionInterceptor> getValidationExceptionInterceptors()
+    {
+        return this.validationExceptionInterceptors;
+    }
+
+    /*
+     * PropertyValidationInterceptors
+     */
+    void addPropertyValidationInterceptor(PropertyValidationInterceptor propertyValidationInterceptor)
+    {
+        if (propertyValidationInterceptor instanceof ValidationModuleAware)
+        {
+            addPropertyValidationInterceptorForModules(propertyValidationInterceptor);
+            sortModuleSpecificPropertyValidationInterceptors();
+        }
+        else
+        {
+            addPropertyValidationInterceptorForModule(null, propertyValidationInterceptor);
+            sortPropertyValidationInterceptors();
+        }
+    }
+
+    List<PropertyValidationInterceptor> getPropertyValidationInterceptors()
+    {
+        return this.propertyValidationInterceptors;
+    }
+
+    List<PropertyValidationInterceptor> getPropertyValidationInterceptorsFor(Class moduleKey)
+    {
+        List<PropertyValidationInterceptor> result = new ArrayList<PropertyValidationInterceptor>();
+
+        result.addAll(getPropertyValidationInterceptors());
+
+        if (moduleKey != null && this.moduleSpecificPropertyValidationInterceptors.containsKey(moduleKey))
+        {
+            result.addAll(this.moduleSpecificPropertyValidationInterceptors.get(moduleKey));
+        }
+        return sortPropertyValidationInterceptorList(result);
+    }
+
+    private void addPropertyValidationInterceptorForModules(PropertyValidationInterceptor propertyValidationInterceptor)
+    {
+        Class moduleKey;
+        for (String currentModuleKey : ((ValidationModuleAware) propertyValidationInterceptor).getModuleKeys())
+        {
+            moduleKey = ClassUtils.tryToLoadClassForName(currentModuleKey);
+
+            if (moduleKey == null)
+            {
+                continue;
+            }
+
+            addPropertyValidationInterceptorForModule(moduleKey, propertyValidationInterceptor);
+        }
+    }
+
+    private void addPropertyValidationInterceptorForModule(
+            Class moduleKey, PropertyValidationInterceptor propertyValidationInterceptor)
+    {
+        if (moduleKey == null)
+        {
+            this.propertyValidationInterceptors.add(propertyValidationInterceptor);
+
+            if (logger.isTraceEnabled())
+            {
+                logger.trace(propertyValidationInterceptor.getClass().getName() + " added as global interceptor");
+            }
+        }
+        else
+        {
+            List<PropertyValidationInterceptor> propertyValidationInterceptorList;
+            if (this.moduleSpecificPropertyValidationInterceptors.containsKey(moduleKey))
+            {
+                propertyValidationInterceptorList = this.moduleSpecificPropertyValidationInterceptors.get(moduleKey);
+            }
+            else
+            {
+                propertyValidationInterceptorList = new ArrayList<PropertyValidationInterceptor>();
+                this.moduleSpecificPropertyValidationInterceptors.put(moduleKey, propertyValidationInterceptorList);
+            }
+            propertyValidationInterceptorList.add(propertyValidationInterceptor);
+
+            if (logger.isTraceEnabled())
+            {
+                logger.trace(propertyValidationInterceptor.getClass().getName() + " added for " + moduleKey.getName());
+            }
+        }
+    }
+
+    /*
+     * MetaDataExtractionInterceptors
+     */
+    void addMetaDataExtractionInterceptor(MetaDataExtractionInterceptor metaDataExtractionInterceptor)
+    {
+        if(metaDataExtractionInterceptor instanceof ValidationModuleAware)
+        {
+            addMetaDataExtractionInterceptorForModules(metaDataExtractionInterceptor);
+            sortModuleSpecificMetaDataExtractionInterceptors();
+        }
+        else
+        {
+            addMetaDataExtractionInterceptorForModule(null, metaDataExtractionInterceptor);
+            sortMetaDataExtractionInterceptors();
+        }
+    }
+
+    private void addMetaDataExtractionInterceptorForModules(MetaDataExtractionInterceptor metaDataExtractionInterceptor)
+    {
+        Class moduleKey;
+        for (String currentModuleKey : ((ValidationModuleAware) metaDataExtractionInterceptor).getModuleKeys())
+        {
+            moduleKey = ClassUtils.tryToLoadClassForName(currentModuleKey);
+
+            if (moduleKey == null)
+            {
+                continue;
+            }
+
+            addMetaDataExtractionInterceptorForModule(moduleKey, metaDataExtractionInterceptor);
+        }
+    }
+
+    private void addMetaDataExtractionInterceptorForModule(
+            Class moduleKey, MetaDataExtractionInterceptor metaDataExtractionInterceptor)
+    {
+        if (moduleKey == null)
+        {
+            this.metaDataExtractionInterceptors.add(metaDataExtractionInterceptor);
+
+            if (logger.isTraceEnabled())
+            {
+                logger.trace(metaDataExtractionInterceptor.getClass().getName() + " added as global interceptor");
+            }
+        }
+        else
+        {
+            List<MetaDataExtractionInterceptor> metaDataExtractionInterceptorList;
+            if (this.moduleSpecificMetaDataExtractionInterceptors.containsKey(moduleKey))
+            {
+                metaDataExtractionInterceptorList = this.moduleSpecificMetaDataExtractionInterceptors.get(moduleKey);
+            }
+            else
+            {
+                metaDataExtractionInterceptorList = new ArrayList<MetaDataExtractionInterceptor>();
+                this.moduleSpecificMetaDataExtractionInterceptors.put(moduleKey, metaDataExtractionInterceptorList);
+            }
+            metaDataExtractionInterceptorList.add(metaDataExtractionInterceptor);
+
+            if (logger.isTraceEnabled())
+            {
+                logger.trace(metaDataExtractionInterceptor.getClass().getName() + " added for " + moduleKey.getName());
+            }
+        }
+    }
+
+    List<MetaDataExtractionInterceptor> getMetaDataExtractionInterceptors()
+    {
+        return this.metaDataExtractionInterceptors;
+    }
+
+    List<MetaDataExtractionInterceptor> getMetaDataExtractionInterceptorsWith(Map<String, Object> properties)
+    {
+        List<MetaDataExtractionInterceptor> result = new ArrayList<MetaDataExtractionInterceptor>();
+
+        result.addAll(getMetaDataExtractionInterceptors());
+
+        Class moduleKey = tryToResolveModuleKey(properties);
+        if(moduleKey != null && this.moduleSpecificMetaDataExtractionInterceptors.containsKey(moduleKey))
+        {
+            result.addAll(this.moduleSpecificMetaDataExtractionInterceptors.get(moduleKey));
+        }
+
+        return sortMetaDataExtractionInterceptorList(result);
+    }
+
+    private Class tryToResolveModuleKey(Map<String, Object> properties)
+    {
+        Class moduleKey = null;
+        if(properties != null && properties.containsKey(ValidationModuleKey.class.getName()))
+        {
+            Object foundValue = properties.get(ValidationModuleKey.class.getName());
+            if(foundValue instanceof Class)
+            {
+                moduleKey = (Class)foundValue;
+            }
+        }
+        return moduleKey;
+    }
+
+    /*
+     * init
+     */
+
+    void lazyInitValidationExceptionInterceptors()
+    {
+        if (validationExceptionInterceptors != null)
+        {
+            return;
+        }
+
+        validationExceptionInterceptors = new ArrayList<ValidationExceptionInterceptor>();
+        List<String> validationExceptionInterceptorClassNames = new ArrayList<String>();
+
+        validationExceptionInterceptorClassNames
+                .add(WebXmlParameter.CUSTOM_VALIDATION_EXCEPTION_INTERCEPTOR);
+        validationExceptionInterceptorClassNames
+                .add(this.contextHelper.getInformationProviderBean().get(
+                        CustomInformation.VALIDATION_EXCEPTION_INTERCEPTOR));
+
+        ValidationExceptionInterceptor validationExceptionInterceptor;
+        for (String validationExceptionInterceptorName : validationExceptionInterceptorClassNames)
+        {
+            validationExceptionInterceptor =
+                    (ValidationExceptionInterceptor)
+                            ClassUtils.tryToInstantiateClassForName(validationExceptionInterceptorName);
+
+            if (validationExceptionInterceptor != null)
+            {
+                validationExceptionInterceptors.add(validationExceptionInterceptor);
+
+                if (logger.isTraceEnabled())
+                {
+                    logger.trace(validationExceptionInterceptor.getClass().getName() + " added");
+                }
+            }
+        }
+    }
+
+    void lazyInitMetaDataExtractionInterceptors()
+    {
+        if (metaDataExtractionInterceptors != null)
+        {
+            return;
+        }
+
+        metaDataExtractionInterceptors = new ArrayList<MetaDataExtractionInterceptor>();
+        moduleSpecificMetaDataExtractionInterceptors = new HashMap<Class, List<MetaDataExtractionInterceptor>>();
+
+        List<String> metaDataExtractionInterceptorClassNames = new ArrayList<String>();
+
+        metaDataExtractionInterceptorClassNames
+                .add(WebXmlParameter.CUSTOM_META_DATA_EXTRACTION_INTERCEPTOR);
+        metaDataExtractionInterceptorClassNames
+                .add(this.contextHelper.getInformationProviderBean().get(
+                        CustomInformation.META_DATA_EXTRACTION_INTERCEPTOR));
+
+        MetaDataExtractionInterceptor metaDataExtractionInterceptor;
+        for (String validationExceptionInterceptorName : metaDataExtractionInterceptorClassNames)
+        {
+            metaDataExtractionInterceptor =
+                    (MetaDataExtractionInterceptor)
+                            ClassUtils.tryToInstantiateClassForName(validationExceptionInterceptorName);
+
+            if (metaDataExtractionInterceptor != null)
+            {
+                addMetaDataExtractionInterceptor(metaDataExtractionInterceptor);
+            }
+        }
+    }
+
+    void lazyInitComponentInitializers()
+    {
+        if (componentInitializers != null)
+        {
+            return;
+        }
+
+        componentInitializers = new ArrayList<ComponentInitializer>();
+        List<String> componentInitializerClassNames = new ArrayList<String>();
+        componentInitializerClassNames
+                .add(WebXmlParameter.CUSTOM_COMPONENT_INITIALIZER);
+        componentInitializerClassNames
+                .add(this.contextHelper.getInformationProviderBean().get(CustomInformation.COMPONENT_INITIALIZER));
+
+        ComponentInitializer componentInitializer;
+        for (String componentInitializerName : componentInitializerClassNames)
+        {
+            componentInitializer =
+                    (ComponentInitializer) ClassUtils.tryToInstantiateClassForName(componentInitializerName);
+
+            if (componentInitializer != null)
+            {
+                componentInitializers.add(componentInitializer);
+
+                if (logger.isTraceEnabled())
+                {
+                    logger.trace(componentInitializer.getClass().getName() + " added");
+                }
+            }
+        }
+    }
+
+    void lazyInitPropertyValidationInterceptors()
+    {
+        if (propertyValidationInterceptors != null)
+        {
+            return;
+        }
+
+        propertyValidationInterceptors = new ArrayList<PropertyValidationInterceptor>();
+        moduleSpecificPropertyValidationInterceptors = new HashMap<Class, List<PropertyValidationInterceptor>>();
+
+        List<String> validationInterceptorClassNames = new ArrayList<String>();
+
+        validationInterceptorClassNames
+                .add(WebXmlParameter.CUSTOM_PROPERTY_VALIDATION_INTERCEPTOR);
+        validationInterceptorClassNames
+                .add(this.contextHelper.getInformationProviderBean().get(
+                        CustomInformation.PROPERTY_VALIDATION_INTERCEPTOR));
+
+        PropertyValidationInterceptor propertyValidationInterceptor;
+        for (String validationInterceptorName : validationInterceptorClassNames)
+        {
+            propertyValidationInterceptor =
+                    (PropertyValidationInterceptor)
+                            ClassUtils.tryToInstantiateClassForName(validationInterceptorName);
+
+            if (propertyValidationInterceptor != null)
+            {
+                if (propertyValidationInterceptor instanceof ValidationModuleAware)
+                {
+                    addPropertyValidationInterceptorForModules(propertyValidationInterceptor);
+                }
+                else
+                {
+                    addPropertyValidationInterceptorForModule(null, propertyValidationInterceptor);
+                }
+            }
+        }
+    }
+
+    /*
+     * sort
+     */
+    private void sortComponentInitializers()
+    {
+        Collections.sort(this.componentInitializers, new InvocationOrderComparator<ComponentInitializer>());
+    }
+
+    private void sortPropertyValidationInterceptors()
+    {
+        Collections.sort(this.propertyValidationInterceptors,
+                new InvocationOrderComparator<PropertyValidationInterceptor>());
+    }
+
+    //sort all - it isn't a huge overhead since it's just done during the init-phase
+    private void sortModuleSpecificPropertyValidationInterceptors()
+    {
+        for(List<PropertyValidationInterceptor> propertyValidationInterceptorList :
+                this.moduleSpecificPropertyValidationInterceptors.values())
+        {
+            sortPropertyValidationInterceptorList(propertyValidationInterceptorList);
+        }
+    }
+
+    private List<PropertyValidationInterceptor> sortPropertyValidationInterceptorList(
+            List<PropertyValidationInterceptor> propertyValidationInterceptorList)
+    {
+        Collections.sort(propertyValidationInterceptorList,
+                    new InvocationOrderComparator<PropertyValidationInterceptor>());
+
+        return propertyValidationInterceptorList;
+    }
+
+    private void sortValidationExceptionInterceptors()
+    {
+        Collections.sort(this.validationExceptionInterceptors,
+                new InvocationOrderComparator<ValidationExceptionInterceptor>());
+    }
+
+    private void sortMetaDataExtractionInterceptors()
+    {
+        Collections.sort(this.metaDataExtractionInterceptors,
+                new InvocationOrderComparator<MetaDataExtractionInterceptor>());
+    }
+
+    //sort all - it isn't a huge overhead since it's just done during the init-phase
+    private void sortModuleSpecificMetaDataExtractionInterceptors()
+    {
+        for(List<MetaDataExtractionInterceptor> metaDataExtractionInterceptorList :
+                this.moduleSpecificMetaDataExtractionInterceptors.values())
+        {
+            sortMetaDataExtractionInterceptorList(metaDataExtractionInterceptorList);
+        }
+    }
+
+    private List<MetaDataExtractionInterceptor> sortMetaDataExtractionInterceptorList(
+            List<MetaDataExtractionInterceptor> metaDataExtractionInterceptorList)
+    {
+        Collections.sort(metaDataExtractionInterceptorList,
+                    new InvocationOrderComparator<MetaDataExtractionInterceptor>());
+
+        return metaDataExtractionInterceptorList;
+    }
+}
\ No newline at end of file
diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/InformationProviderBean.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/InformationProviderBean.java
new file mode 100644
index 0000000..65587a5
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/InformationProviderBean.java
@@ -0,0 +1,172 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.core;

+

+import org.apache.myfaces.extensions.validator.ExtValInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.commons.logging.Log;

+import org.apache.commons.logging.LogFactory;

+

+import java.util.Map;

+import java.util.HashMap;

+

+/**

+ * centralized in order that these information aren't spread over the complete code base

+ * + some of them can be customized within a custom impl. of the bean

+ * (extend this class and provide it via convention or web.xml)

+ * <p/>

+ * the static api should only be used

+ *

+ * @author Gerhard Petracek

+ * @since 1.x.1

+ */

+@UsageInformation({UsageCategory.API, UsageCategory.CUSTOMIZABLE})

+public class InformationProviderBean

+{

+    protected final Log logger = LogFactory.getLog(getClass());

+

+    public static final String BEAN_NAME = ExtValInformation.EXTENSIONS_VALIDATOR_BASE_PACKAGE_NAME

+        + "." + InformationProviderBean.class.getSimpleName();

+    //custom class which is an optional replacement for this class (has to extend this class)

+    public static final String CUSTOM_BEAN = (ExtValInformation.EXTENSIONS_VALIDATOR_BASE_PACKAGE_NAME

+        + ".custom." + InformationProviderBean.class.getSimpleName());

+

+    public InformationProviderBean()

+    {

+        if(logger.isDebugEnabled())

+        {

+            logger.debug(getClass().getName() + " instantiated");

+        }

+

+        setupCustomizableInformation();

+        applyCustomValues(this.customizableInfos);

+    }

+

+    private Map<CustomInformation, String> customizableInfos = new HashMap<CustomInformation, String>();

+

+    private void setupCustomizableInformation()

+    {

+        String basePackage = WebXmlParameter.CUSTOM_BASE_PACKAGE;

+

+        if (basePackage == null)

+        {

+            basePackage = ExtValInformation.EXTENSIONS_VALIDATOR_BASE_PACKAGE_NAME + ".custom.";

+        }

+        if (!basePackage.endsWith("."))

+        {

+            basePackage = basePackage + ".";

+        }

+

+        customizableInfos.put(CustomInformation.BASE_PACKAGE, basePackage);

+        

+        customizableInfos.put(CustomInformation.COMPONENT_META_DATA_EXTRACTOR,

+                "ComponentMetaDataExtractor");

+        customizableInfos.put(CustomInformation.VALIDATION_PARAMETER_EXTRACTOR,

+                "ValidationParameterExtractor");

+

+        customizableInfos.put(CustomInformation.VALIDATION_STRATEGY_POSTFIX,

+                "ValidationStrategy");

+        customizableInfos.put(CustomInformation.META_DATA_TRANSFORMER_POSTFIX,

+                "MetaDataTransformer");

+        customizableInfos.put(CustomInformation.VALIDATION_ERROR_MESSAGE_RESOLVER_POSTFIX,

+                "ValidationErrorMessageResolver");

+

+        customizableInfos.put(CustomInformation.COMPONENT_INITIALIZER,

+                "ComponentInitializer");

+        customizableInfos.put(CustomInformation.VALIDATION_EXCEPTION_INTERCEPTOR,

+                "ValidationExceptionInterceptor");

+        customizableInfos.put(CustomInformation.PROPERTY_VALIDATION_INTERCEPTOR,

+                "PropertyValidationInterceptor");

+        customizableInfos.put(CustomInformation.META_DATA_EXTRACTION_INTERCEPTOR,

+                "MetaDataExtractionInterceptor");

+

+        customizableInfos.put(CustomInformation.VALIDATION_STRATEGY_TO_MSG_RESOLVER_NAME_MAPPER,

+                "ValidationStrategyToMsgResolverNameMapper");

+        customizableInfos.put(CustomInformation.META_DATA_TO_VALIDATION_STRATEGY_NAME_MAPPER,

+                "MetaDataToValidationStrategyNameMapper");

+        customizableInfos.put(CustomInformation.VALIDATION_STRATEGY_TO_META_DATA_TRANSFORMER_NAME_MAPPER,

+                "ValidationStrategyToMetaDataTransformerNameMapper");

+

+        customizableInfos.put(CustomInformation.STARTUP_LISTENER,

+                "StartupListener");

+

+        customizableInfos.put(CustomInformation.MESSAGE_RESOLVER_FACTORY,

+                "MessageResolverFactory");

+        customizableInfos.put(CustomInformation.VALIDATION_STRATEGY_FACTORY,

+                "ValidationStrategyFactory");

+        customizableInfos.put(CustomInformation.COMPONENT_META_DATA_EXTRACTOR_FACTORY,

+                "ComponentMetaDataExtractorFactory");

+        customizableInfos.put(CustomInformation.VALIDATION_PARAMETER_EXTRACTOR_FACTORY,

+                "ValidationParameterExtractorFactory");

+        customizableInfos.put(CustomInformation.VALIDATION_PARAMETER_FACTORY,

+                "ValidationParameterFactory");

+        customizableInfos.put(CustomInformation.META_DATA_TRANSFORMER_FACTORY,

+                "MetaDataTransformerFactory");

+        customizableInfos.put(CustomInformation.FACES_MESSAGE_FACTORY,

+                "FacesMessageFactory");

+        customizableInfos.put(CustomInformation.STORAGE_MANAGER_FACTORY,

+                "StorageManagerFactory");

+

+        //conventions (the rest of the conventions are built with the help of name mappers,...

+        customizableInfos.put(CustomInformation.MESSAGE_BUNDLE_NAME,

+                "validation_messages");

+        //static strategy mappings (name of property files)

+        customizableInfos.put(CustomInformation.STATIC_STRATEGY_MAPPING_SOURCE,

+                "strategy_mappings");

+

+        customizableInfos.put(CustomInformation.META_DATA_STORAGE_FILTER,

+                "MetaDataStorageFilter");

+    }

+

+    @SuppressWarnings({"UnusedDeclaration"})

+    protected void applyCustomValues(Map<CustomInformation, String> map)

+    {

+        //override to customize information

+    }

+

+    public final String get(CustomInformation customInformation)

+    {

+        String value = customizableInfos.get(customInformation);

+

+        switch (customInformation)

+        {

+            case BASE_PACKAGE:

+                return value;

+

+            /*

+             * postfix used by the SimpleAnnotationToValidationStrategyNameMapper

+             * the SimpleAnnotationToValidationStrategyNameMapper is for custom strategies only

+             * (not for public validation modules)

+             * so it's fine to customize it

+             */

+            case VALIDATION_STRATEGY_POSTFIX:

+                return value;

+

+            case VALIDATION_ERROR_MESSAGE_RESOLVER_POSTFIX:

+                return value;

+

+            case META_DATA_TRANSFORMER_POSTFIX:

+                return value;

+

+            default:

+                return customizableInfos.get(CustomInformation.BASE_PACKAGE) + value;

+        }

+    }

+}

diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/InternalConventionProvider.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/InternalConventionProvider.java
new file mode 100644
index 0000000..8d9f869
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/InternalConventionProvider.java
@@ -0,0 +1,113 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.core;

+

+import org.apache.myfaces.extensions.validator.core.validation.strategy.ValidationStrategy;

+import org.apache.myfaces.extensions.validator.internal.Priority;

+import org.apache.myfaces.extensions.validator.internal.ToDo;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+

+/**

+ * @author Gerhard Petracek

+ * @since 1.x.1

+ */

+@UsageInformation(UsageCategory.INTERNAL)

+public class InternalConventionProvider

+{

+    public static String getModuleMessageBundleName(String packageName)

+    {

+        String newPackageName;

+        if (packageName.endsWith(".resolver"))

+        {

+            newPackageName = packageName.replace(".resolver", ".bundle");

+        }

+        else

+        {

+            newPackageName = packageName.replace(".resolver.", ".bundle.");

+        }

+

+        return newPackageName + ".validation_messages";

+    }

+

+    /**

+     * use a custom name mapper to implement custom conventions

+     */

+    @ToDo(value = Priority.MEDIUM, description = "logging")

+    public static String getMessageResolverClassName(

+        Class<? extends ValidationStrategy> validationStrategyClass, String targetClassName)

+    {

+        return getValidationStrategyBasedName(validationStrategyClass, ".message.resolver.", targetClassName);

+    }

+

+    public static String getMetaDataTransformerClassName(

+        Class<? extends ValidationStrategy> validationStrategyClass, String targetClassName)

+    {

+        return getValidationStrategyBasedName(validationStrategyClass, ".metadata.transformer.", targetClassName);

+    }

+

+    private static String getValidationStrategyBasedName(Class<? extends ValidationStrategy> validationStrategyClass,

+                                                  String targetPackageName, String targetClassName)

+    {

+        String validationStrategyClassName = validationStrategyClass.getName();

+

+        validationStrategyClassName = validationStrategyClassName.replace(".strategy.", targetPackageName);

+

+        if (targetClassName == null || validationStrategyClassName.lastIndexOf(".") == -1)

+        {

+            return null;

+        }

+        return validationStrategyClassName

+                .substring(0, validationStrategyClassName.lastIndexOf(".")) + "." + targetClassName;

+    }

+

+    /**

+     * use a custom name mapper to implement custom conventions

+     */

+    public static String getMessageResolverClassName(String validationStrategyName)

+    {

+        return getValidationStrategyBasedName(validationStrategyName, "ValidationErrorMessageResolver");

+    }

+

+    /**

+     * use a custom name mapper to implement custom conventions

+     */

+    public static String getValidationStrategyClassName(String metaDataKey)

+    {

+        return metaDataKey.replace(".annotation.", ".strategy.") + "Strategy";

+    }

+

+    public static String getMetaDataTransformerClassName(String validationStrategyName)

+    {

+        return getValidationStrategyBasedName(validationStrategyName, "MetaDataTransformer");

+    }

+

+    public static String getValidationStrategyBasedName(String validationStrategyName, String targetPostfix)

+    {

+        if (validationStrategyName.endsWith("ValidationStrategy"))

+        {

+            return validationStrategyName.substring(0, validationStrategyName.length() - 18) + targetPostfix;

+        }

+        else if (validationStrategyName.endsWith("Strategy"))

+        {

+            return validationStrategyName.substring(0, validationStrategyName.length() - 8) + targetPostfix;

+        }

+        return validationStrategyName + targetPostfix;

+    }

+}

diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/InvocationOrder.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/InvocationOrder.java
new file mode 100644
index 0000000..cdffad8
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/InvocationOrder.java
@@ -0,0 +1,64 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.core;

+

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+

+import java.lang.annotation.Target;

+import java.lang.annotation.Retention;

+import java.lang.annotation.Documented;

+import static java.lang.annotation.RetentionPolicy.RUNTIME;

+import static java.lang.annotation.ElementType.TYPE;

+

+@Target(TYPE)

+@Retention(RUNTIME)

+@Documented

+/**

+ * allowed to use for classes which implement interfaces which have the marker @InvocationOrderSupport

+ *

+ * suggested ranges (mainly for name-mappers):

+ * negative values for "extreme" cases

+ *

+ * 0-49 for custom artifacts which should have the highest priority

+ * 50-99 for add-ons which provide artifacts which should have a higher priority than the default artifacts

+ * 100-999 internal artifacts

+ * 1000+ for custom artifacts

+ *

+ * suggested ranges for artifacts like interceptors,...

+ * 1xx ... artifacts of the core

+ * 2xx ... artifacts of validation modules

+ * 3xx ... artifacts of component support modules

+ *

+ * a priority should be unique within one artifact-type - that means

+ * if a name-mapper has priority 100, it's ok that an exception-interceptor also has priority 100.

+ * but a 2nd name-mapper shouldn't have priority 100

+ *

+ * @author Gerhard Petracek

+ * @since x.x.3

+ */

+@UsageInformation(UsageCategory.API)

+public @interface InvocationOrder

+{

+    /**

+     * default priority for custom artifacts (if they should get added after the internal versions

+     * @return the priority of an artifact annotated with this annotation

+     */

+    int value() default 1000;

+}

diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/InvocationOrderComparator.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/InvocationOrderComparator.java
new file mode 100644
index 0000000..818071e
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/InvocationOrderComparator.java
@@ -0,0 +1,61 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.core;

+

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+

+import java.util.Comparator;

+

+/**

+ * @author Gerhard Petracek

+ * @since x.x.3

+ */

+@UsageInformation(UsageCategory.INTERNAL)

+public class InvocationOrderComparator<T> implements Comparator<T>

+{

+    public int compare(T nm1, T nm2)

+    {

+        if (hasPriority(nm1) && hasPriority(nm2))

+        {

+            return isPriorityHigher(nm1.getClass().getAnnotation(InvocationOrder.class),

+                    nm2.getClass().getAnnotation(InvocationOrder.class));

+        }

+        if (!hasPriority(nm1) && !hasPriority(nm2))

+        {

+            return 0;

+        }

+        return hasPriority(nm1) ? -1 : 1;

+    }

+

+    private int isPriorityHigher(InvocationOrder priority1, InvocationOrder priority2)

+    {

+        if (priority1.value() == priority2.value())

+        {

+            return 0;

+        }

+

+        return priority1.value() < priority2.value() ? -1 : 1;

+    }

+

+    private boolean hasPriority(Object nm)

+    {

+        return nm.getClass().isAnnotationPresent(InvocationOrder.class);

+    }

+}

diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/InvocationOrderSupport.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/InvocationOrderSupport.java
new file mode 100644
index 0000000..bd34e79
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/InvocationOrderSupport.java
@@ -0,0 +1,41 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.core;

+

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+

+import java.lang.annotation.Target;

+import java.lang.annotation.Documented;

+import static java.lang.annotation.ElementType.TYPE;

+

+@Target(TYPE)

+@Documented

+/**

+ * marker annotation for easier usage

+ * it marks interfaces - instances of classes implementing these interfaces will be sorted

+ * @see InvocationOrderComparator

+ *

+ * @author Gerhard Petracek

+ * @since x.x.3

+ */

+@UsageInformation(UsageCategory.API)

+public @interface InvocationOrderSupport

+{

+}
\ No newline at end of file
diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/JsfProjectStage.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/JsfProjectStage.java
new file mode 100644
index 0000000..d2b30ba
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/JsfProjectStage.java
@@ -0,0 +1,55 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.core;

+

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+

+/**

+ * project stage equivalent to jsf 2.0

+ * extval 2.x has a special resolver which redirects the call to the new jsf api

+ *

+ * @author Gerhard Petracek

+ * @since x.x.3

+ */

+@UsageInformation(UsageCategory.INTERNAL)

+public enum JsfProjectStage

+{

+    Development(ProjectStage.createStageName("Development")),

+    UnitTest(ProjectStage.createStageName("UnitTest")),

+    SystemTest(ProjectStage.createStageName("SystemTest")),

+    Production(ProjectStage.createStageName("Production"));

+

+    private final ProjectStageName value;

+

+    JsfProjectStage(ProjectStageName value)

+    {

+        this.value = value;

+    }

+

+    public static boolean is(JsfProjectStage jsfProjectStage)

+    {

+        return ProjectStage.is(jsfProjectStage.getValue());

+    }

+

+    public ProjectStageName getValue()

+    {

+        return this.value;

+    }

+}

diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/Nested.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/Nested.java
new file mode 100644
index 0000000..00691e8
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/Nested.java
@@ -0,0 +1,42 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.core;

+

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+

+import java.lang.annotation.Target;

+import java.lang.annotation.Retention;

+import java.lang.annotation.Documented;

+import static java.lang.annotation.RetentionPolicy.RUNTIME;

+import static java.lang.annotation.ElementType.TYPE;

+

+/**

+ * marker annotation e.g. to mark sub-name-mappers

+ * 

+ * @author Gerhard Petracek

+ * @since x.x.3

+ */

+@Target(TYPE)

+@Retention(RUNTIME)

+@Documented

+@UsageInformation(UsageCategory.API)

+public @interface Nested

+{

+}
\ No newline at end of file
diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/PhaseIdRecordingPhaseListener.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/PhaseIdRecordingPhaseListener.java
new file mode 100644
index 0000000..0695542
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/PhaseIdRecordingPhaseListener.java
@@ -0,0 +1,83 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.core;

+

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.util.ExtValUtils;

+import org.apache.myfaces.extensions.validator.core.storage.FacesInformationStorage;

+

+import javax.faces.event.PhaseListener;

+import javax.faces.event.PhaseEvent;

+import javax.faces.event.PhaseId;

+

+/**

+ * e.g. to allow in metadata extraction interceptors to know if they are invoked during validation or

+ * component initialization (if needed)

+ * example: client-side validation - some functionality shouldn't be processed during rendering

+ *

+ * @author Gerhard Petracek

+ * @since x.x.3

+ */

+@UsageInformation(UsageCategory.INTERNAL)

+public class PhaseIdRecordingPhaseListener implements PhaseListener

+{

+    private static final long serialVersionUID = 2791240514014867457L;

+

+    public void afterPhase(PhaseEvent phaseEvent)

+    {

+    }

+

+    public void beforePhase(PhaseEvent phaseEvent)

+    {

+        FacesInformationStorage facesInformationStorage = ExtValUtils

+                .getStorage(FacesInformationStorage.class, FacesInformationStorage.class.getName());

+

+        facesInformationStorage.setCurrentPhaseId(phaseEvent.getPhaseId());

+    }

+

+    public PhaseId getPhaseId()

+    {

+        return PhaseId.ANY_PHASE;

+    }

+

+    /*

+     * generated

+     */

+    @Override

+    public boolean equals(Object o)

+    {

+        if (this == o)

+        {

+            return true;

+        }

+        if (!(o instanceof PhaseIdRecordingPhaseListener))

+        {

+            return false;

+        }

+

+        return true;

+    }

+

+    @Override

+    public int hashCode()

+    {

+        return super.hashCode();

+    }

+}

diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/ProjectStage.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/ProjectStage.java
new file mode 100644
index 0000000..9ba444d
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/ProjectStage.java
@@ -0,0 +1,73 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.core;

+

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+import org.apache.myfaces.extensions.validator.util.ExtValUtils;

+

+/**

+ * extensible project stage implementation

+ *

+ * @author Gerhard Petracek

+ * @since x.x.3

+ */

+@UsageInformation(UsageCategory.INTERNAL)

+public class ProjectStage

+{

+    private ProjectStageName value;

+

+    private ProjectStage(ProjectStageName value)

+    {

+        this.value = value;

+    }

+

+    public static ProjectStageName createStageName(String name)

+    {

+        return ExtValUtils.createProjectStageName(name);

+    }

+

+    public static ProjectStage createStage(ProjectStageName name)

+    {

+        return new ProjectStage(name);

+    }

+

+    public static boolean is(ProjectStageName projectStage)

+    {

+        return getCurrentProjectStage().equals(projectStage);

+    }

+

+    private static ProjectStageName getCurrentProjectStage()

+    {

+        //set ProjectStageResolver to null to tweak the performance

+        Object projectStageResolver = ExtValContext.getContext()

+                .getGlobalProperty(ProjectStageResolver.class.getName());

+

+        if(projectStageResolver instanceof ProjectStageResolver)

+        {

+            return ((ProjectStageResolver)projectStageResolver).getCurrentProjectStage().getValue();

+        }

+        return ExtValUtils.getDefaultStageName();

+    }

+

+    public ProjectStageName getValue()

+    {

+        return this.value;

+    }

+}

diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/ProjectStageName.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/ProjectStageName.java
new file mode 100644
index 0000000..1d22b86
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/ProjectStageName.java
@@ -0,0 +1,31 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.core;

+

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+

+/**

+ * @author Gerhard Petracek

+ */

+@UsageInformation(UsageCategory.INTERNAL)

+public interface ProjectStageName

+{

+    String getName();

+}

diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/ProjectStageResolver.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/ProjectStageResolver.java
new file mode 100644
index 0000000..144f27a
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/ProjectStageResolver.java
@@ -0,0 +1,32 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.core;

+

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+

+/**

+ * @author Gerhard Petracek

+ * @since x.x.3

+ */

+@UsageInformation(UsageCategory.INTERNAL)

+public interface ProjectStageResolver

+{

+    ProjectStage getCurrentProjectStage();

+}

diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/ValidationModuleAware.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/ValidationModuleAware.java
new file mode 100644
index 0000000..45420f5
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/ValidationModuleAware.java
@@ -0,0 +1,44 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.core;

+

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+

+/**

+ * if an artifact (which supports this concept) should be used just for a/some specific module(s),

+ * the artifact has to implement this interface

+ *

+ * @author Gerhard Petracek

+ * @since x.x.3

+ */

+@UsageInformation(UsageCategory.API)

+public interface ValidationModuleAware

+{

+    /**

+     * during the registration process the information gets evaluated<br/>

+     * instead of a class array a string array is used so that it's possible to implement

+     * an artifact for different modules. if an add-on restricts an artifact to specific modules,

+     * not all modules have to be used by the webapp. if a module key is unknown, the artifact won't get registered

+     * for this module. if an artifact doesn't implement this interface, it gets registered for all modules

+     *

+     * @return an array of fully qualified class names of the module keys

+     */

+    String[] getModuleKeys();

+}

diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/ValidationModuleKey.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/ValidationModuleKey.java
new file mode 100644
index 0000000..805340d
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/ValidationModuleKey.java
@@ -0,0 +1,42 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.core;

+

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+

+import java.lang.annotation.Target;

+import java.lang.annotation.Retention;

+import java.lang.annotation.Documented;

+import static java.lang.annotation.RetentionPolicy.RUNTIME;

+import static java.lang.annotation.ElementType.TYPE;

+

+@Target(TYPE)

+@Retention(RUNTIME)

+@Documented

+/**

+ * marker annotation for module keys

+ *

+ * @author Gerhard Petracek

+ * @since x.x.3

+ */

+@UsageInformation(UsageCategory.API)

+public @interface ValidationModuleKey

+{

+}
\ No newline at end of file
diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/WebXmlParameter.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/WebXmlParameter.java
new file mode 100644
index 0000000..f18a179
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/WebXmlParameter.java
@@ -0,0 +1,158 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.core;

+

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.util.WebXmlUtils;

+

+/**

+ * centralized in order that these information aren't spread over the complete code base

+ *

+ * @author Gerhard Petracek

+ * @since 1.x.1

+ */

+@UsageInformation(UsageCategory.INTERNAL)

+public interface WebXmlParameter

+{

+    /*

+     * misc

+     */

+    static final String CUSTOM_MESSAGE_BUNDLE = WebXmlUtils

+        .getInitParameter("CUSTOM_MESSAGE_BUNDLE");

+

+    static final String CUSTOM_BASE_PACKAGE = WebXmlUtils

+        .getInitParameter("CUSTOM_BASE_PACKAGE");

+

+    static final String CUSTOM_INFORMATION_PROVIDER_BEAN = WebXmlUtils

+        .getInitParameter("CUSTOM_INFORMATION_PROVIDER_BEAN");

+

+    static final String CUSTOM_COMPONENT_META_DATA_EXTRACTOR = WebXmlUtils

+        .getInitParameter("CUSTOM_COMPONENT_META_DATA_EXTRACTOR");

+

+    static final String CUSTOM_VALIDATION_PARAMETER_EXTRACTOR = WebXmlUtils

+        .getInitParameter("CUSTOM_VALIDATION_PARAMETER_EXTRACTOR");

+

+    static final String CUSTOM_VALIDATION_PARAMETER_FACTORY = WebXmlUtils

+        .getInitParameter("CUSTOM_VALIDATION_PARAMETER_FACTORY");

+

+    static final String CUSTOM_STATIC_VALIDATION_STRATEGY_MAPPING = WebXmlUtils

+        .getInitParameter("CUSTOM_STATIC_VALIDATION_STRATEGY_MAPPING");

+

+    static final String CUSTOM_COMPONENT_INITIALIZER = WebXmlUtils

+        .getInitParameter("CUSTOM_COMPONENT_INITIALIZER");

+

+    static final String CUSTOM_VALIDATION_EXCEPTION_INTERCEPTOR = WebXmlUtils

+        .getInitParameter("CUSTOM_VALIDATION_EXCEPTION_INTERCEPTOR");

+

+    static final String CUSTOM_PROPERTY_VALIDATION_INTERCEPTOR = WebXmlUtils

+        .getInitParameter("CUSTOM_PROPERTY_VALIDATION_INTERCEPTOR");

+

+    static final String CUSTOM_META_DATA_EXTRACTION_INTERCEPTOR = WebXmlUtils

+        .getInitParameter("CUSTOM_META_DATA_EXTRACTION_INTERCEPTOR");

+

+    static final String CUSTOM_PROXY_HELPER = WebXmlUtils

+        .getInitParameter("CUSTOM_PROXY_HELPER");

+

+    /*

+     * name mapper

+     */

+    static final String CUSTOM_VALIDATION_STRATEGY_TO_MESSAGE_RESOLVER_NAME_MAPPER = WebXmlUtils

+        .getInitParameter("CUSTOM_VALIDATION_STRATEGY_TO_MESSAGE_RESOLVER_NAME_MAPPER");

+

+    static final String CUSTOM_META_DATA_TO_VALIDATION_STRATEGY_NAME_MAPPER = WebXmlUtils

+        .getInitParameter("CUSTOM_META_DATA_TO_VALIDATION_STRATEGY_NAME_MAPPER");

+

+    static final String CUSTOM_VALIDATION_STRATEGY_TO_META_DATA_TRANSFORMER_NAME_MAPPER = WebXmlUtils

+        .getInitParameter("CUSTOM_VALIDATION_STRATEGY_TO_META_DATA_TRANSFORMER_NAME_MAPPER");

+

+    /*

+     * filter

+     */

+    static final String CUSTOM_META_DATA_STORAGE_FILTER = WebXmlUtils

+        .getInitParameter("CUSTOM_META_DATA_STORAGE_FILTER");

+    

+    /*

+     * factories

+     */

+    static final String CUSTOM_VALIDATION_STRATEGY_FACTORY = WebXmlUtils

+        .getInitParameter("CUSTOM_VALIDATION_STRATEGY_FACTORY");

+

+    static final String CUSTOM_MESSAGE_RESOLVER_FACTORY = WebXmlUtils

+        .getInitParameter("CUSTOM_MESSAGE_RESOLVER_FACTORY");

+

+    static final String CUSTOM_COMPONENT_META_DATA_EXTRACTOR_FACTORY = WebXmlUtils

+        .getInitParameter("CUSTOM_COMPONENT_META_DATA_EXTRACTOR_FACTORY");

+

+    static final String CUSTOM_VALIDATION_PARAMETER_EXTRACTOR_FACTORY = WebXmlUtils

+        .getInitParameter("CUSTOM_VALIDATION_PARAMETER_EXTRACTOR_FACTORY");

+

+    static final String CUSTOM_META_DATA_TRANSFORMER_FACTORY = WebXmlUtils

+        .getInitParameter("CUSTOM_META_DATA_TRANSFORMER_FACTORY");

+

+    static final String CUSTOM_STORAGE_MANAGER_FACTORY = WebXmlUtils

+        .getInitParameter("CUSTOM_STORAGE_MANAGER_FACTORY");

+

+    static final String CUSTOM_FACES_MESSAGE_FACTORY = WebXmlUtils

+        .getInitParameter("CUSTOM_FACES_MESSAGE_FACTORY");

+

+    /*

+     * activate

+     */

+    static final String ACTIVATE_REQUIRED_INITIALIZATION = WebXmlUtils

+        .getInitParameter("ACTIVATE_REQUIRED_INITIALIZATION");

+    

+    /*

+     * deactivate

+     */

+    @Deprecated

+    static final String DEACTIVATE_RENDERKIT = WebXmlUtils

+        .getInitParameter("DEACTIVATE_RENDERKIT");

+

+    //currently just used by AbstractValidationErrorMessageResolver

+    static final String DEACTIVATE_DEFAULT_CONVENTION = WebXmlUtils

+        .getInitParameter("DEACTIVATE_DEFAULT_CONVENTION");

+

+    static final String DEACTIVATE_DEFAULT_NAME_MAPPERS = WebXmlUtils

+        .getInitParameter("DEACTIVATE_DEFAULT_NAME_MAPPERS");

+    

+    static final String DEACTIVATE_EL_RESOLVER = WebXmlUtils

+        .getInitParameter("DEACTIVATE_EL_RESOLVER");

+

+    static final String DEACTIVATE_COMPONENT_INITIALIZATION = WebXmlUtils

+        .getInitParameter("DEACTIVATE_COMPONENT_INITIALIZATION");

+

+    static final String DEACTIVATE_VALIDATION_PARAMETERS = WebXmlUtils

+        .getInitParameter("DEACTIVATE_VALIDATION_PARAMETERS");

+

+    static final String DEACTIVATE_RENDER_KIT_FACTORY = WebXmlUtils

+        .getInitParameter("DEACTIVATE_RENDER_KIT_FACTORY");

+

+    //there is nothing like DEACTIVATE_DEFAULT_VALIDATION_INTERCEPTOR

+    //use ExtValContext.getContext().denyRendererInterceptor(...) within an extval-StartupListener

+

+    /*

+     * spec parameters

+     */

+    static final String INTERPRET_EMPTY_STRING_SUBMITTED_VALUES_AS_NULL = WebXmlUtils

+        .getInitParameter("javax.faces", "INTERPRET_EMPTY_STRING_SUBMITTED_VALUES_AS_NULL");

+

+    static final String VALIDATE_EMPTY_FIELDS = WebXmlUtils

+        .getInitParameter("javax.faces", "VALIDATE_EMPTY_FIELDS");

+}

diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/el/AbstractELHelperFactory.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/el/AbstractELHelperFactory.java
new file mode 100644
index 0000000..4a43f25
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/el/AbstractELHelperFactory.java
@@ -0,0 +1,70 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.core.el;

+

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+import org.apache.commons.logging.Log;

+import org.apache.commons.logging.LogFactory;

+

+/**

+ * details

+ * @see DefaultELHelper

+ * 

+ * @author Gerhard Petracek

+ * @since 1.x.1

+ */

+@UsageInformation({UsageCategory.INTERNAL, UsageCategory.CUSTOMIZABLE})

+public abstract class AbstractELHelperFactory

+{

+    protected final Log logger = LogFactory.getLog(getClass());

+    protected AbstractELHelperFactory customELHelperFactory;

+

+    protected AbstractELHelperFactory()

+    {

+        if(logger.isDebugEnabled())

+        {

+            logger.debug(getClass().getName() + " instantiated");

+        }

+    }

+

+    public void setCustomELHelperFactory(AbstractELHelperFactory elHelperFactory)

+    {

+        this.customELHelperFactory = elHelperFactory;

+    }

+

+    public final ELHelper create()

+    {

+        ELHelper result = null;

+

+        if(this.customELHelperFactory != null)

+        {

+            result = this.customELHelperFactory.createELHelper();

+        }

+

+        if(result == null)

+        {

+            return createELHelper();

+        }

+

+        return result;

+    }

+

+    protected abstract ELHelper createELHelper();

+}
\ No newline at end of file
diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/el/DefaultELHelper.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/el/DefaultELHelper.java
new file mode 100644
index 0000000..43109f0
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/el/DefaultELHelper.java
@@ -0,0 +1,344 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.core.el;

+

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+import org.apache.myfaces.extensions.validator.internal.ToDo;

+import org.apache.myfaces.extensions.validator.internal.Priority;

+import org.apache.myfaces.extensions.validator.util.ExtValUtils;

+import org.apache.myfaces.extensions.validator.util.ReflectionUtils;

+import org.apache.myfaces.extensions.validator.util.ProxyUtils;

+import org.apache.myfaces.extensions.validator.core.WebXmlParameter;

+import org.apache.myfaces.extensions.validator.core.property.PropertyDetails;

+import org.apache.commons.logging.Log;

+import org.apache.commons.logging.LogFactory;

+

+import javax.el.ValueExpression;

+import javax.el.ELContext;

+import javax.faces.component.UIComponent;

+import javax.faces.context.FacesContext;

+import javax.faces.el.ValueBinding;

+import java.io.Externalizable;

+import java.lang.reflect.Method;

+import java.util.Map;

+

+/**

+ * in order to centralize the jsf version dependency within the core

+ *

+ * this el-helper supports jsp and facelets (tested with 1.1.14)

+ *

+ * @author Gerhard Petracek

+ * @since 1.x.1

+ */

+/*

+ * there is a special facelets workaround for el-expressions of custom components

+ * it's pluggable in order to support special mechanisms of different technologies (than jsp and facelets)

+ * so you can plug in your own impl. which implements a custom workaround (like the facelets workaround of this impl.)

+ */

+@UsageInformation(UsageCategory.INTERNAL)

+public class DefaultELHelper implements ELHelper

+{

+    private static final String DEACTIVATE_EL_RESOLVER = WebXmlParameter.DEACTIVATE_EL_RESOLVER;

+

+    protected final Log logger = LogFactory.getLog(getClass());

+

+    public DefaultELHelper()

+    {

+        if(logger.isDebugEnabled())

+        {

+            logger.debug(getClass().getName() + " instantiated");

+        }

+    }

+

+    public Class getTypeOfExpression(FacesContext facesContext, ValueBindingExpression valueBindingExpression)

+    {

+        //due to a restriction with the ri

+        Object bean = getValueOfExpression(facesContext, valueBindingExpression);

+        return (bean != null) ? ProxyUtils.getUnproxiedClass(bean.getClass()) : null;

+    }

+

+    public Object getBean(String beanName)

+    {

+        FacesContext facesContext = FacesContext.getCurrentInstance();

+        return facesContext.getApplication().getELResolver().getValue(facesContext.getELContext(), null, beanName);

+    }

+

+    public Object getValueOfExpression(FacesContext facesContext,

+                                                   ValueBindingExpression valueBindingExpression)

+    {

+        return (valueBindingExpression != null) ? facesContext.getApplication().evaluateExpressionGet(

+            facesContext, valueBindingExpression.getExpressionString(), Object.class) : null;

+    }

+

+    public boolean isELTermValid(FacesContext facesContext, String valueBindingExpression)

+    {

+        try

+        {

+            facesContext.getApplication().evaluateExpressionGet(facesContext, valueBindingExpression, Object.class);

+        }

+        catch (Throwable t)

+        {

+            return false;

+        }

+        return true;

+    }

+

+    private ValueBindingExpression getValueBindingExpression(UIComponent uiComponent, boolean allowBlankCharacters)

+    {

+        String valueBindingExpression = getOriginalValueBindingExpression(uiComponent);

+

+        //for input components without value-binding

+        //(e.g. for special component libs -> issue with ExtValRendererWrapper#encodeBegin)

+        if(valueBindingExpression == null)

+        {

+            if(this.logger.isTraceEnabled())

+            {

+                this.logger.trace(

+                        uiComponent.getClass() + " has no value binding - component id: " + uiComponent.getId());

+            }

+            return null;

+        }

+

+        if(!allowBlankCharacters)

+        {

+            valueBindingExpression = valueBindingExpression.replace(" ", "");

+        }

+

+        if (getTypeOfExpression(FacesContext.getCurrentInstance(),

+            new ValueBindingExpression(valueBindingExpression).getBaseExpression()) == null)

+        {

+            ValueBindingExpression result = FaceletsTaglibExpressionHelper.

+                tryToCreateValueBindingForFaceletsBinding(uiComponent);

+

+            if(result == null)

+            {

+                if(logger.isWarnEnabled())

+                {

+                    logger.warn("couldn't resolve expression: " + valueBindingExpression);

+                }

+                return null;

+            }

+

+            Class entityClass = ExtValUtils.getELHelper()

+                .getTypeOfExpression(FacesContext.getCurrentInstance(), result.getBaseExpression());

+

+            if(entityClass == null)

+            {

+                if(logger.isWarnEnabled())

+                {

+                    logger.warn("couldn't resolve expression: " + result.getExpressionString());

+                }

+

+                return null;

+            }

+            return result;

+        }

+        return new ValueBindingExpression(valueBindingExpression);

+    }

+

+    @ToDo(value = Priority.HIGH, description = "check if it works with nested composite components")

+    public PropertyDetails getPropertyDetailsOfValueBinding(UIComponent uiComponent)

+    {

+        if("true".equalsIgnoreCase(DEACTIVATE_EL_RESOLVER))

+        {

+            return getPropertyDetailsViaReflectionFallback(uiComponent);

+        }

+

+        FacesContext facesContext = FacesContext.getCurrentInstance();

+

+        ValueExpression valueExpression = uiComponent.getValueExpression("value");

+

+        if(valueExpression == null)

+        {

+            return null;

+        }

+

+        ExtValELResolver elResolver = createWrappedELContext(facesContext);

+        inspectTarget(valueExpression,

+                ExtValELResolver.createContextWrapper(facesContext.getELContext(), elResolver), false);

+

+        ExtValELResolver compositeComponentELResolver = null;

+

+        //re-check to get full key for cross-validation

+        if (elResolver.getCompositeComponentExpression() != null)

+        {

+            ValueExpression compositeExpression = elResolver.getCompositeComponentExpression();

+            

+            compositeComponentELResolver = createWrappedELContext(facesContext);

+            inspectTarget(compositeExpression,

+                    ExtValELResolver.createContextWrapper(

+                            facesContext.getELContext(), compositeComponentELResolver), true);

+        }

+

+        if(elResolver.getPath() == null || elResolver.getBaseObject() == null || elResolver.getProperty() == null)

+        {

+            return null;

+        }

+

+        String key;

+        if(compositeComponentELResolver != null)

+        {

+            key = compositeComponentELResolver.getPath() +

+                    elResolver.getPath().substring(elResolver.getPath().indexOf("."));

+        }

+        else

+        {

+            key = elResolver.getPath();

+        }

+

+        return new PropertyDetails(key, elResolver.getBaseObject(), elResolver.getProperty());

+    }

+

+    private void inspectTarget(ValueExpression valueExpression, ELContext elContext, boolean inspectCompositeComponent)

+    {

+        try

+        {

+            valueExpression.setValue(elContext, null);

+        }

+        catch (Throwable t)

+        {

+            if(inspectCompositeComponent)

+            {

+                throw new IllegalStateException(

+                        "error at binding: " + valueExpression.getExpressionString() +

+                                " -- an el-resolver error occurred! maybe you used an invalid binding.", t);

+            }

+        }

+    }

+

+    private ExtValELResolver createWrappedELContext(FacesContext facesContext)

+    {

+        return new ExtValELResolver(facesContext.getApplication().getELResolver());

+    }

+

+    //keep in sync with DefaultELHelper#getPropertyDetailsOfValueBinding of branch!!!

+    private PropertyDetails getPropertyDetailsViaReflectionFallback(UIComponent uiComponent)

+    {

+        FacesContext facesContext = FacesContext.getCurrentInstance();

+        ValueBindingExpression valueBindingExpression = getValueBindingExpression(uiComponent, false);

+        ValueBindingExpression currentValueBindingExpression =

+            new ValueBindingExpression(valueBindingExpression.getExpressionString());

+

+        String path = null;

+

+        while(currentValueBindingExpression.getBaseExpression() != null)

+        {

+            if(path == null)

+            {

+                path = getPropertyName(currentValueBindingExpression);

+            }

+            else

+            {

+                path = getPropertyName(currentValueBindingExpression) + "." + path;

+            }

+

+            currentValueBindingExpression = currentValueBindingExpression.getBaseExpression();

+        }

+

+        path = currentValueBindingExpression.getProperty() + "." + path;

+

+        Object baseObject = getValueOfExpression(facesContext, valueBindingExpression.getBaseExpression());

+

+        //in case of e.g.: #{bean[bean.passwordRepeatedPropertyName]}

+        //-> bean.passwordRepeatedPropertyName is not the final property name

+        return new PropertyDetails(path, baseObject, getPropertyName(valueBindingExpression));

+    }

+

+    private String getPropertyName(ValueBindingExpression valueBindingExpression)

+    {

+        String propertyName = valueBindingExpression.getProperty();

+

+        if(propertyName.contains("."))

+        {

+            propertyName = extractPropertyNameOfPropertyPath(propertyName);

+        }

+

+        return propertyName;

+    }

+

+    @ToDo(value = Priority.MEDIUM, description = "support for more dynamic bindings - details see inline")

+    private String extractPropertyNameOfPropertyPath(String propertyChain)

+    {

+        String[] properties = propertyChain.split("\\.");

+

+        Object currentPropertyValue = ExtValUtils.getELHelper().getBean(properties[0]);

+

+        Method currentMethod;

+        String currentPropertyName;

+        Class currentClassOfPropertyValue;

+        for(int i = 1; i < properties.length; i++)

+        {

+            currentPropertyName = properties[i];

+            currentClassOfPropertyValue = ProxyUtils.getUnproxiedClass(currentPropertyValue.getClass());

+            currentMethod = ReflectionUtils.tryToGetMethod(currentClassOfPropertyValue,

+                "get" + currentPropertyName.substring(0, 1).toUpperCase() + currentPropertyName.substring(1));

+

+            if(currentMethod == null && currentPropertyValue instanceof Map)

+            {

+                //it's ok for the simple map case - but not for e.g.:

+                //#{bean1[bean2.propertyNameProvider[ bean3.index]]}

+                //or every other complex replacement for bean3.index

+                //it might also require an adjustment at FaceletsTaglibExpressionHelper#tryToTransformToRealBinding

+                ((Map)currentPropertyValue).get(currentPropertyName);

+            }

+            else

+            {

+                currentPropertyValue = ReflectionUtils.tryToInvokeMethod(currentPropertyValue, currentMethod);

+            }

+        }

+

+        if(currentPropertyValue instanceof String)

+        {

+            return (String)currentPropertyValue;

+        }

+        else

+        {

+            if(this.logger.isErrorEnabled())

+            {

+                this.logger.error("unexpected value within map syntax: " + propertyChain +

+                        " last property name: " + currentPropertyValue);

+            }

+            return null;

+        }

+    }

+

+    static String getOriginalValueBindingExpression(UIComponent uiComponent)

+    {

+        ValueExpression valueExpression = uiComponent.getValueExpression("value");

+

+        return (valueExpression != null) ? valueExpression.getExpressionString() : null;

+    }

+

+    public boolean isELTermWellFormed(Object o)

+    {

+        if (o instanceof ValueBinding || o instanceof Externalizable)

+        {

+            return false;

+        }

+

+        String s = o.toString();

+        return ((s.contains("#") || s.contains("$")) && s.contains("{") && s.contains("}"));

+    }

+

+    public Object getBindingOfComponent(UIComponent uiComponent, String name)

+    {

+        return uiComponent.getValueExpression(name);

+    }

+}

diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/el/DefaultELHelperFactory.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/el/DefaultELHelperFactory.java
new file mode 100644
index 0000000..2cfe56c
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/el/DefaultELHelperFactory.java
@@ -0,0 +1,37 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.core.el;

+

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+

+/**

+ * @author Gerhard Petracek

+ * @since 1.x.1

+ */

+@UsageInformation(UsageCategory.INTERNAL)

+public class DefaultELHelperFactory extends AbstractELHelperFactory

+{

+    private ELHelper elHelper = new DefaultELHelper();

+    

+    protected ELHelper createELHelper()

+    {

+        return this.elHelper;

+    }

+}
\ No newline at end of file
diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/el/ELHelper.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/el/ELHelper.java
new file mode 100644
index 0000000..deb2553
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/el/ELHelper.java
@@ -0,0 +1,50 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.core.el;

+

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+import org.apache.myfaces.extensions.validator.core.property.PropertyDetails;

+

+import javax.faces.component.UIComponent;

+import javax.faces.context.FacesContext;

+

+/**

+ * in order to centralize the jsf version dependency within the core

+ *

+ * @author Gerhard Petracek

+ * @since 1.x.1

+ */

+@UsageInformation(UsageCategory.API)

+public interface ELHelper

+{

+    Object getBean(String beanName);

+

+    Object getValueOfExpression(FacesContext facesContext, ValueBindingExpression valueBindingExpression);

+

+    Class getTypeOfExpression(FacesContext facesContext, ValueBindingExpression valueBindingExpression);

+

+    PropertyDetails getPropertyDetailsOfValueBinding(UIComponent uiComponent);

+

+    boolean isELTermValid(FacesContext facesContext, String valueBindingExpression);

+

+    boolean isELTermWellFormed(Object o);

+

+    Object getBindingOfComponent(UIComponent uiComponent, String name);

+}

diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/el/ExtValELResolver.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/el/ExtValELResolver.java
new file mode 100644
index 0000000..1cb1d58
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/el/ExtValELResolver.java
@@ -0,0 +1,285 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.myfaces.extensions.validator.core.el;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.myfaces.extensions.validator.internal.UsageInformation;
+import org.apache.myfaces.extensions.validator.internal.UsageCategory;
+import org.apache.myfaces.extensions.validator.util.ProxyUtils;
+
+import javax.el.ELResolver;
+import javax.el.ELContext;
+import javax.el.VariableMapper;
+import javax.el.ValueExpression;
+import javax.el.FunctionMapper;
+import javax.faces.el.CompositeComponentExpressionHolder;
+import java.util.Iterator;
+import java.util.Locale;
+import java.util.Map;
+import java.beans.FeatureDescriptor;
+
+/**
+ * @author Gerhard Petracek
+ * @since 1.x.1
+ */
+@UsageInformation(UsageCategory.INTERNAL)
+public class ExtValELResolver extends ELResolver
+{
+    protected final Log logger = LogFactory.getLog(getClass());
+
+    private ELResolver wrapped;
+    private Object baseObject;
+    private String property;
+    //forms the id for cross-validation within complex components
+    private String expression;
+    private boolean isPathRecordingStopped = false;
+    private CompositeComponentExpressionHolder compositeComponentExpressionHolder;
+    private String compositeComponentExpressionBase;
+
+    public ExtValELResolver(ELResolver elResolver)
+    {
+        this.wrapped = elResolver;
+    }
+
+    public Object getBaseObject()
+    {
+        return baseObject;
+    }
+
+    public String getProperty()
+    {
+        return property;
+    }
+
+    public String getPath()
+    {
+        if(this.logger.isTraceEnabled())
+        {
+            this.logger.trace("extracted path: " + this.expression);
+        }
+        return this.expression;
+    }
+
+    public void reset()
+    {
+        this.baseObject = null;
+        this.property = null;
+        this.expression = null;
+    }
+
+    /**
+     * path recording is performed to get a key for cross-validation<br/>
+     * every base after the first call which is null stops recording<br/>
+     * with a dynamic map syntax the last property in the middle of an expression has to be a string.
+     * such a string result continues the path recording at the next call for the current expression.
+     * <p/>
+     * example: #{bean[bean.propertyNameProvider['nameOfProperty1']]['dynBean'].property}
+     * <p/>
+     * limitation for cross-validation: nameOfProperty1 has to be of type string.
+     * other key types aren't supported yet
+     *
+     * @param elContext wrapped el-context
+     * @param base current base
+     * @param property property to resolve
+     * @return result of the delegated method call
+     */
+    public Object getValue(ELContext elContext, Object base, Object property)
+    {
+        Object result = this.wrapped.getValue(elContext, base, property);
+
+        if(this.compositeComponentExpressionHolder != null && this.compositeComponentExpressionBase == null)
+        {
+            this.compositeComponentExpressionBase = (String)property;
+        }
+
+        if(this.compositeComponentExpressionHolder == null && result instanceof CompositeComponentExpressionHolder)
+        {
+            this.compositeComponentExpressionHolder = ((CompositeComponentExpressionHolder)result);
+        }
+
+        //very first call for an expression
+        if(this.expression == null)
+        {
+            this.expression = (String)property;
+        }
+        //#{bean[dynBase.propertyName]} -> base of dynBase is null -> stop path recording
+        else if(base == null)
+        {
+            this.isPathRecordingStopped = true;
+        }
+        else
+        {
+            boolean propertyExists = false;
+            String propertyName = (String)property;
+            propertyName = propertyName.substring(0, 1).toUpperCase() + propertyName.substring(1);
+
+            try
+            {
+                if(base instanceof Map)
+                {
+                    if(((Map)base).containsKey(property))
+                    {
+                        propertyExists = true;
+                    }
+                }
+                else if(ProxyUtils.getUnproxiedClass(base.getClass()).getMethod("get" + propertyName) != null)
+                {
+                    propertyExists = true;
+                }
+            }
+            catch (NoSuchMethodException e)
+            {
+                try
+                {
+                    if(ProxyUtils.getUnproxiedClass(base.getClass()).getMethod("is" + propertyName) != null)
+                    {
+                        propertyExists = true;
+                    }
+                }
+                catch (NoSuchMethodException e1)
+                {
+                    if(this.logger.isTraceEnabled() && !"attrs".equals(property))
+                    {
+                        this.logger.trace("property: " + property +
+                                " isn't used for path - it isn't a property of " + base.getClass());
+                    }
+                }
+            }
+            catch (Throwable t)
+            {
+                return result;
+            }
+
+            //e.g.: #{bean.subBase.property} -> here we are at subBase
+            if(propertyExists && !this.isPathRecordingStopped)
+            {
+                this.expression += "." + property;
+            }
+            else if(propertyExists && result instanceof String)
+            {
+                this.isPathRecordingStopped = false;
+            }
+        }
+
+        /*
+        if(this.isPathRecordingStopped && result instanceof String)
+        {
+            this.expression += "." + property;
+        }
+        */
+
+        return result;
+    }
+
+    public Class<?> getType(ELContext elContext, Object o, Object o1)
+    {
+        return wrapped.getType(elContext, o, o1);
+    }
+
+    public void setValue(ELContext elContext, Object o, Object o1, Object o2)
+    {
+        expression += "." + o1;
+        property = (String)o1;
+        baseObject = o;
+        elContext.setPropertyResolved(true);
+    }
+
+    public boolean isReadOnly(ELContext elContext, Object o, Object o1)
+    {
+        return wrapped.isReadOnly(elContext, o, o1);
+    }
+
+    public Iterator<FeatureDescriptor> getFeatureDescriptors(ELContext elContext, Object o)
+    {
+        return wrapped.getFeatureDescriptors(elContext, o);
+    }
+
+    public Class<?> getCommonPropertyType(ELContext elContext, Object o)
+    {
+        return wrapped.getCommonPropertyType(elContext, o);
+    }
+
+    public static ELContext createContextWrapper(final ELContext context, final ELResolver resolver)
+    {
+        return new ELContext()
+        {
+            @Override
+            public Locale getLocale()
+            {
+                return context.getLocale();
+            }
+
+            @Override
+            public void setPropertyResolved(boolean value)
+            {
+                super.setPropertyResolved(value);
+                context.setPropertyResolved(value);
+            }
+
+            @Override
+            public void putContext(Class clazz, Object object)
+            {
+                super.putContext(clazz, object);
+                context.putContext(clazz, object);
+            }
+
+            @Override
+            public Object getContext(Class clazz)
+            {
+                return context.getContext(clazz);
+            }
+
+            @Override
+            public void setLocale(Locale locale)
+            {
+                super.setLocale(locale);
+                context.setLocale(locale);
+            }
+
+            @Override
+            public ELResolver getELResolver()
+            {
+                return resolver;
+            }
+
+            @Override
+            public FunctionMapper getFunctionMapper()
+            {
+                return context.getFunctionMapper();
+            }
+
+            @Override
+            public VariableMapper getVariableMapper()
+            {
+                return context.getVariableMapper();
+            }
+
+        };
+    }
+
+    public ValueExpression getCompositeComponentExpression()
+    {
+        if(this.compositeComponentExpressionHolder != null)
+        {
+            return this.compositeComponentExpressionHolder.getExpression(this.compositeComponentExpressionBase);
+        }
+        return null;
+    }
+}
diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/el/FaceletsTaglibExpressionHelper.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/el/FaceletsTaglibExpressionHelper.java
new file mode 100644
index 0000000..5f2b89f
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/el/FaceletsTaglibExpressionHelper.java
@@ -0,0 +1,546 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.core.el;

+

+import org.apache.myfaces.extensions.validator.internal.ToDo;

+import org.apache.myfaces.extensions.validator.internal.Priority;

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+import org.apache.myfaces.extensions.validator.util.ExtValUtils;

+

+import javax.faces.component.UIComponent;

+import javax.faces.context.FacesContext;

+import java.lang.reflect.AccessibleObject;

+import java.lang.reflect.Array;

+import java.lang.reflect.Field;

+import java.lang.reflect.Modifier;

+import java.util.ArrayList;

+import java.util.HashMap;

+import java.util.List;

+import java.util.Map;

+import java.util.Iterator;

+

+/**

+ * Helper class to get the real/full value binding - tested with facelets 1.1.14

+ * The target is to get rid of this impl. - currently it's a workaround to support custom facelets components.

+ * An alternative would be an EL-Resolver - there are still some open issues with such an approach

+ * + It isn't available with JSF 1.1.x

+ *

+ * @author Gerhard Petracek

+ * @since 1.x.1

+ */

+@UsageInformation(UsageCategory.INTERNAL)

+class FaceletsTaglibExpressionHelper

+{

+    public static ValueBindingExpression tryToCreateValueBindingForFaceletsBinding(UIComponent uiComponent)

+    {

+        String faceletsValueBindingExpression = DefaultELHelper.getOriginalValueBindingExpression(uiComponent);

+

+        try

+        {

+            List<String> foundBindings = extractELTerms(

+                ExtValUtils.getELHelper().getBindingOfComponent(uiComponent, "value"));

+

+            Map<String, String> mappedFaceletsVars = new HashMap<String, String>();

+            ValueBindingExpression vbe= new ValueBindingExpression(faceletsValueBindingExpression

+                    .substring(0, 1) + "{" + createBinding(foundBindings, mappedFaceletsVars) + "}");

+

+            Class entityClass = ExtValUtils.getELHelper()

+                .getTypeOfExpression(FacesContext.getCurrentInstance(), vbe.getBaseExpression());

+

+            if(entityClass == null)

+            {

+                return tryToReplaceVars(vbe, mappedFaceletsVars);

+            }

+            return vbe;

+        }

+        catch (Throwable t)

+        {

+            return new ValueBindingExpression(faceletsValueBindingExpression);

+        }

+    }

+

+    @ToDo(value = Priority.MEDIUM, description = "logging")

+    private static String createBinding(List<String> expressions, Map<String, String> virtualVars)

+    {

+        String currentBinding;

+

+        int indexOfBindingDetails;

+        String[] foundBindingDetails;

+        String[] bindingDetails;

+

+        Map<String, String> addedVirtualNames = new HashMap<String, String>();

+

+        for (String entry : expressions)

+        {

+            if (entry.startsWith("ValueExpression["))

+            {

+                continue;

+            }

+

+            foundBindingDetails = entry.split(" ");

+            indexOfBindingDetails = findIndexOfBindingDetails(foundBindingDetails);

+

+            if (indexOfBindingDetails == -1)

+            {

+                return null;

+            }

+

+            bindingDetails = foundBindingDetails[indexOfBindingDetails].split("=");

+

+            if (bindingDetails.length < 2)

+            {

+                return null;

+            }

+

+            currentBinding = bindingDetails[1];

+

+            //to support blanks within a binding with map syntax

+            if(currentBinding.contains("{") && !currentBinding.contains("}"))

+            {

+                currentBinding = addFurtherBindingParts(currentBinding, foundBindingDetails, indexOfBindingDetails);

+            }

+

+            if (currentBinding.contains("}"))

+            {

+                //entry for "virtual" facelets beans

+                if(!addedVirtualNames.containsKey(bindingDetails[0]))

+                {

+                    addedVirtualNames.put(bindingDetails[0], currentBinding);

+                }

+            }

+            //entry for "virtual" facelets var

+            if(!(currentBinding.contains("{") || currentBinding.contains("}")))

+            {

+                virtualVars.put(bindingDetails[0], bindingDetails[1].substring(1, bindingDetails[1].length()-2));

+            }

+        }

+

+        String originalBinding = addedVirtualNames.get("value");

+        originalBinding = originalBinding.substring(originalBinding.indexOf("{") + 1, originalBinding.indexOf("}"));

+        addedVirtualNames.remove("value");

+        return tryToTransformToRealBinding(originalBinding, addedVirtualNames, virtualVars);

+    }

+

+    private static String tryToTransformToRealBinding(

+            String originalBinding, Map<String, String> addedVirtualNames, Map<String, String> virtualVars)

+    {

+        originalBinding = "#{" + originalBinding + "}";

+        Iterator nameIterator = addedVirtualNames.keySet().iterator();

+

+        String currentKey;

+        String currentValue;

+        while(nameIterator.hasNext())

+        {

+            currentKey = (String) nameIterator.next();

+

+            currentValue = addedVirtualNames.get(currentKey);

+            currentValue = currentValue.substring(currentValue.indexOf("{") + 1, currentValue.indexOf("}"));

+

+            originalBinding = originalBinding.replace("{" + currentKey + ".", "{" + currentValue + ".");

+            //dynamic base and property

+            originalBinding = originalBinding.replace("{" + currentKey + "[", "{" + currentValue + "[");

+

+            originalBinding = originalBinding.replace("." + currentKey + ".", "." + currentValue + ".");

+            //dynamic base and property

+            originalBinding = originalBinding.replace("." + currentKey + "[", "." + currentValue + "[");

+

+            originalBinding = originalBinding.replace("[" + currentKey + "]", "['" + currentValue + "']");

+            //dynamic base and property

+            originalBinding = originalBinding.replace("[" + currentKey + "[", "[" + currentValue + "[");

+            originalBinding = originalBinding.replace("[" + currentKey + ".", "[" + currentValue + ".");

+        }

+

+        nameIterator = virtualVars.keySet().iterator();

+

+        while(nameIterator.hasNext())

+        {

+            currentKey = (String) nameIterator.next();

+

+            currentValue = virtualVars.get(currentKey);

+

+            originalBinding = originalBinding.replace("{" + currentKey + ".", "{" + currentValue + ".");

+            //dynamic base and property

+            originalBinding = originalBinding.replace("{" + currentKey + "[", "{" + currentValue + "[");

+

+            originalBinding = originalBinding.replace("." + currentKey + ".", "." + currentValue + ".");

+            //dynamic base and property

+            originalBinding = originalBinding.replace("." + currentKey + "[", "." + currentValue + "[");

+

+            originalBinding = originalBinding.replace("[" + currentKey + "]", "['" + currentValue + "']");

+            //dynamic base and property

+            originalBinding = originalBinding.replace("[" + currentKey + "[", "[" + currentValue + "[");

+            originalBinding = originalBinding.replace("[" + currentKey + ".", "[" + currentValue + ".");

+        }

+

+        return originalBinding.substring(2, originalBinding.length() - 1);

+    }

+

+    //to support blanks - e.g. with map syntax

+    private static String addFurtherBindingParts(String currentBinding, String[] foundBindingDetails,

+                                                 int indexOfBindingDetails)

+    {

+        for(int i = indexOfBindingDetails + 1; i < foundBindingDetails.length; i++)

+        {

+            currentBinding += foundBindingDetails[i];

+            if(foundBindingDetails[i].contains("}"))

+            {

+                return currentBinding;

+            }

+        }

+        return currentBinding;

+    }

+

+    private static int findIndexOfBindingDetails(String[] bindingDetails)

+    {

+        int count = 0;

+        for (String entry : bindingDetails)

+        {

+            if (entry.contains("="))

+            {

+                return count;

+            }

+            count++;

+        }

+        return -1;

+    }

+

+    private static List<String> extractELTerms(Object o)

+    {

+        List<String> foundELTerms = new ArrayList<String>();

+        try

+        {

+            if (resolveELTerms(o, new HashMap<Object, Object>(), foundELTerms, 0) > 0)

+            {

+                return foundELTerms;

+            }

+        }

+        catch (Exception ex)

+        {

+            return null;

+        }

+        return null;

+    }

+

+    private static int resolveELTerms(Object o, Map<Object, Object> visited,

+                                      List<String> foundELTerms, int count) throws Exception

+    {

+        if (o == null || visited.containsKey(o) || count > 50)

+        {

+            return 0;

+        }

+

+        visited.put(o, null);

+

+        int elCount = 0;

+        Class c = o.getClass();

+

+        //inspect maps

+        if (o instanceof Map)

+        {

+

+            for (Object entry : ((Map) o).values())

+            {

+                //found entry for "virtual" facelets var

+                if(entry.toString().contains("ValueExpression["))

+                {

+                    foundELTerms.add(entry.toString());

+                }

+                elCount += resolveELTerms(entry, visited, foundELTerms, count + 1);

+            }

+            return elCount;

+        }

+

+        if (ExtValUtils.getELHelper().isELTermWellFormed(o))

+        {

+            if (foundELTerms != null)

+            {

+                foundELTerms.add(o.toString());

+            }

+            return ++elCount;

+        }

+

+        //analyze arrays

+        if (c.isArray())

+        {

+            int length = Array.getLength(o);

+            //check array [L -> no array of primitive types

+            if (o.toString().startsWith("[L"))

+            {

+                for (int i = 0; i < length; i++)

+                {

+                    if (o.toString().startsWith("[Ljava.lang.String"))

+                    {

+                        if (ExtValUtils.getELHelper().isELTermWellFormed(Array.get(o, i)))

+                        {

+                            if (foundELTerms != null)

+                            {

+                                foundELTerms.add(o.toString());

+                            }

+                            elCount++;

+                        }

+                    }

+                    else

+                    {

+                        elCount += resolveELTerms(Array.get(o, i), visited, foundELTerms, count + 1);

+                    }

+                }

+            }

+            return elCount;

+        }

+

+        List<Field> attributes = findAllAttributes(c, new ArrayList<Field>());

+        Field[] fields = attributes.toArray(new Field[attributes.size()]);

+

+        AccessibleObject.setAccessible(fields, true);

+        for (Field currentField : fields)

+        {

+            if (currentField.get(o) == null)

+            {

+                continue;

+            }

+

+            if (currentField.getType().equals(String.class))

+            {

+                if (currentField.get(o) != null && ExtValUtils.getELHelper().isELTermWellFormed(currentField.get(o)))

+                {

+                    if (foundELTerms != null)

+                    {

+                        foundELTerms.add(o.toString());

+                    }

+                    elCount++;

+                }

+            }

+            else if (!currentField.getType().isPrimitive())

+            {

+                elCount += resolveELTerms(currentField.get(o), visited, foundELTerms, count + 1);

+            }

+        }

+        return elCount;

+    }

+

+    private static List<Field> findAllAttributes(Class c, List<Field> attributes)

+    {

+        if (c == null)

+        {

+            return attributes;

+        }

+        findAllAttributes(c.getSuperclass(), attributes);

+

+        Field[] fields = c.getDeclaredFields();

+        for (Field currentField : fields)

+        {

+            if (!Modifier.isStatic(currentField.getModifiers()))

+            {

+                attributes.add(currentField);

+            }

+        }

+

+        return attributes;

+    }

+

+    private static ValueBindingExpression tryToReplaceVars(ValueBindingExpression valueBindingExpression,

+                                                            Map<String, String> mappedFaceletsVars)

+    {

+        String property;

+        String result = "";

+        boolean last = false;

+

+        while(true)

+        {

+            if(valueBindingExpression.getBaseExpression() == null)

+            {

+                last = true;

+            }

+

+

+            property = valueBindingExpression.getProperty();

+

+            valueBindingExpression = ValueBindingExpression

+                .replaceProperty(valueBindingExpression, getNewProperty(property, mappedFaceletsVars));

+

+            if(result.length() == 0)

+            {

+                result = valueBindingExpression.getProperty();

+            }

+            else

+            {

+                result = valueBindingExpression.getProperty() + "." + result;

+            }

+

+            valueBindingExpression = valueBindingExpression.getBaseExpression();

+

+            if(last)

+            {

+                break;

+            }

+        }

+        return new ValueBindingExpression(valueBindingExpression.getPrefix() + "{" + result + "}");

+    }

+

+    private static String getNewProperty(String oldProperty, Map<String, String> mappedFaceletsVars)

+    {

+        List<String> virtualVars = getPotentialVirtualVars(oldProperty);

+

+        for(String virtualVar : virtualVars)

+        {

+            if(mappedFaceletsVars.containsKey(virtualVar))

+            {

+                oldProperty = replacePropertyValue(oldProperty, virtualVar, mappedFaceletsVars.get(virtualVar));

+            }

+        }

+        return oldProperty;

+    }

+

+    private static List<String> getPotentialVirtualVars(String oldProperty)

+    {

+        int start = -1;

+        int end = -1;

+

+        List<String> virtualVarList = new ArrayList<String>();

+

+        for(int i = 0; i < oldProperty.length(); i++)

+        {

+            if(start == - 1 && oldProperty.charAt(i) == '[')

+            {

+                start = i + 1;

+            }

+            else if((start != - 1 && oldProperty.charAt(i) == '[') || oldProperty.charAt(i) == ']')

+            {

+                end = i;

+            }

+

+            if(start != -1 && end != -1)

+            {

+                virtualVarList.add(oldProperty.substring(start, end));

+                if(oldProperty.charAt(i) == '[')

+                {

+                    start = i + 1;

+                }

+                else

+                {

+                    start = -1;

+                }

+                end = -1;

+            }

+        }

+

+        return virtualVarList;

+    }

+

+    private static String replacePropertyValue(String oldProperty, String targetVar, String newValue)

+    {

+        int index = oldProperty.indexOf(targetVar);

+

+        if(index == -1)

+        {

+            return oldProperty;

+        }

+

+        String result = oldProperty.substring(0, index);

+        result += newValue;

+        return result + oldProperty.substring(index + targetVar.length(), oldProperty.length());

+    }

+

+    /*

+     * replace virtual facelets vars (map syntax)

+     * tested styles (simple and nested): test[ix[ix2[ix3]]]

+     */

+    /*

+    private static String _createBinding(List<String> expressions, Map<String, String> virtualVars)

+    {

+        String result = "";

+

+        String prevFaceletsAttributeName = null;

+        String currentBinding;

+        String partOfBinding;

+

+        int indexOfBindingDetails;

+        String[] foundBindingDetails;

+        String[] bindingDetails;

+

+        List<String> addedVirtualNames = new ArrayList<String>();

+

+        for (String entry : expressions)

+        {

+            if (entry.startsWith("ValueExpression["))

+            {

+                continue;

+            }

+

+            foundBindingDetails = entry.split(" ");

+            indexOfBindingDetails = findIndexOfBindingDetails(foundBindingDetails);

+

+            if (indexOfBindingDetails == -1)

+            {

+                return null;

+            }

+

+            bindingDetails = foundBindingDetails[indexOfBindingDetails].split("=");

+

+            if (bindingDetails.length < 2)

+            {

+                return null;

+            }

+

+            currentBinding = bindingDetails[1];

+

+            //to support blanks within a binding with map syntax

+            if(currentBinding.contains("{") && !currentBinding.contains("}"))

+            {

+                currentBinding = addFurtherBindingParts(currentBinding, foundBindingDetails, indexOfBindingDetails);

+            }

+

+            if (prevFaceletsAttributeName != null && currentBinding.contains("}"))

+            {

+                //entry for "virtual" facelets beans

+                if(!addedVirtualNames.contains(bindingDetails[0]))

+                {

+                    partOfBinding = currentBinding.substring(currentBinding.indexOf(prevFaceletsAttributeName)

+                        + prevFaceletsAttributeName.length(), currentBinding.indexOf("}"));

+

+                    addedVirtualNames.add(bindingDetails[0]);

+                    result = result + partOfBinding;

+                }

+                else

+                {

+                    continue;

+                }

+            }

+            //entry for "virtual" facelets var

+            else if(!(currentBinding.contains("{") || currentBinding.contains("}")))

+            {

+                virtualVars.put(bindingDetails[0], bindingDetails[1].substring(1, bindingDetails[1].length()-2));

+                continue;

+            }

+            else

+            {

+                if(!addedVirtualNames.contains(bindingDetails[0]))

+                {

+                    addedVirtualNames.add(bindingDetails[0]);

+                    result = currentBinding.substring(currentBinding.indexOf("{") + 1, currentBinding.indexOf("}"));

+                }

+            }

+

+            prevFaceletsAttributeName = bindingDetails[0];

+        }

+        return result;

+    }

+    */

+}

diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/el/ValueBindingExpression.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/el/ValueBindingExpression.java
new file mode 100644
index 0000000..d78eb66
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/el/ValueBindingExpression.java
@@ -0,0 +1,235 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.core.el;

+

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.ToDo;

+import org.apache.myfaces.extensions.validator.internal.Priority;

+import org.apache.myfaces.extensions.validator.util.ExtValUtils;

+

+/**

+ * @author Gerhard Petracek

+ * @since 1.x.1

+ */

+@ToDo(value = Priority.MEDIUM, description = "difference between [ and [' - test with more constellations")

+@UsageInformation({UsageCategory.API})

+public class ValueBindingExpression

+{

+    private ValueBindingExpression base;

+    private String value;

+    private String prefix;

+    private String token;

+

+    public static ValueBindingExpression replaceOrAddProperty(ValueBindingExpression valueBindingExpression,

+                                                              String newProperty)

+    {

+        if(valueBindingExpression.getBaseExpression() != null)

+        {

+            return replaceProperty(valueBindingExpression, newProperty);

+        }

+        else

+        {

+            return addProperty(valueBindingExpression, newProperty);

+        }

+    }

+

+    public static ValueBindingExpression replaceProperty(ValueBindingExpression valueBindingExpression,

+                                                         String newProperty)

+    {

+        //TODO adjustments for isDynamicBaseAndProperty

+        if(valueBindingExpression.getProperty().endsWith("']"))

+        {

+            valueBindingExpression = valueBindingExpression.getBaseExpression();

+        }

+

+        if(valueBindingExpression.getBaseExpression() != null)

+        {

+            return addProperty(valueBindingExpression.getBaseExpression(), newProperty);

+        }

+        else

+        {

+            return addProperty(valueBindingExpression, newProperty);

+        }

+    }

+

+    public static ValueBindingExpression addProperty(ValueBindingExpression valueBindingExpression, String newProperty)

+    {

+        String sourceExpression = valueBindingExpression.getExpressionString();

+        String result = sourceExpression.substring(0, sourceExpression.length() - 1);

+

+        //TODO adjustments for isDynamicBaseAndProperty

+        if(newProperty.startsWith("['"))

+        {

+            return new ValueBindingExpression(result + newProperty + "}");

+        }

+        else

+        {

+            return new ValueBindingExpression(result + "." + newProperty + "}");

+        }

+    }

+

+    public ValueBindingExpression(String expression)

+    {

+        if(!ExtValUtils.getELHelper().isELTermWellFormed(expression))

+        {

+            throw new IllegalStateException(expression + " is no valid el-expression");

+        }

+

+        boolean isDynamicBaseAndProperty = expression.lastIndexOf("']") == -1;

+        int index1 = isDynamicBaseAndProperty ? expression.lastIndexOf("]") : expression.lastIndexOf("']");

+        int index2 = expression.lastIndexOf(".");

+

+        if(index1 > index2)

+        {

+            expression = expression.substring(0, index1);

+

+            int index3 = findIndexOfStartingBracket(expression);

+            if(isDynamicBaseAndProperty)

+            {

+                this.value = expression.substring(index3 + 1, index1);

+

+            }

+            else

+            {

+                this.value = expression.substring(index3 + 2, index1);

+            }

+

+            this.base = new ValueBindingExpression(expression.substring(0, index3) + "}");

+            this.token = isDynamicBaseAndProperty ? "[" : "['";

+        }

+        else if( index2 > index1)

+        {

+            this.value = expression.substring(index2 + 1, expression.length() - 1 );

+            this.base = new ValueBindingExpression(expression.substring(0, index2) + "}");

+            this.token = ".";

+        }

+        else

+        {

+            this.value = expression.substring(2, expression.length() - 1);

+            this.prefix = expression.substring(0, 1);

+        }

+    }

+

+    public String getProperty()

+    {

+        this.value = this.value.trim();

+        

+        if("[".equals(this.token))

+        {

+            if(this.value.startsWith("'"))

+            {

+                return this.value.substring(1, this.value.length() - 1);

+            }

+            //return this.base.value + this.token + this.value.substring(0, this.value.length()) + "']";

+        }

+        return value;

+    }

+

+    public ValueBindingExpression getBaseExpression()

+    {

+        return base;

+    }

+

+    public String getExpressionString()

+    {

+        if(this.base != null)

+        {

+            String baseExpression = this.base.getExpressionString();

+

+            if("['".equals(this.token))

+            {

+                return baseExpression.substring(0, baseExpression.length() - 1) + this.token + this.value + "']}";

+            }

+            else if("[".equals(this.token))

+            {

+                return baseExpression.substring(0, baseExpression.length() - 1) + this.token + this.value + "]}";

+            }

+            return baseExpression.substring(0, baseExpression.length() - 1) + this.token + this.value + "}";

+        }

+        else

+        {

+            return this.prefix + "{" + this.value + "}";

+        }

+    }

+

+    public String getPrefix()

+    {

+        if(this.base != null)

+        {

+            return this.base.getPrefix();

+        }

+        else

+        {

+            return prefix;

+        }

+    }

+

+    public void setPrefix(String prefix)

+    {

+        if(this.base != null)

+        {

+            this.base.setPrefix(prefix);

+        }

+        else

+        {

+            this.prefix = prefix;

+        }

+    }

+

+    @Override

+    public String toString()

+    {

+        return getExpressionString();

+    }

+

+    @Override

+    public int hashCode()

+    {

+        return getExpressionString().hashCode();

+    }

+

+    @Override

+    public boolean equals(Object target)

+    {

+        return target instanceof ValueBindingExpression && getExpressionString()

+            .equals(((ValueBindingExpression) target).getExpressionString());

+    }

+

+    private int findIndexOfStartingBracket(String expression)

+    {

+        int closeCount = 0;

+        for(int i = expression.length() - 1; i > 0; i--)

+        {

+            if(expression.charAt(i) == '[')

+            {

+                closeCount--;

+                if(closeCount < 0)

+                {

+                    return i;

+                }

+            }

+            else if(expression.charAt(i) == ']')

+            {

+                closeCount++;

+            }

+        }

+        return 0;

+    }

+}

diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/factory/AbstractNameMapperAwareFactory.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/factory/AbstractNameMapperAwareFactory.java
new file mode 100644
index 0000000..33100b3
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/factory/AbstractNameMapperAwareFactory.java
@@ -0,0 +1,80 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.core.factory;

+

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+import org.apache.myfaces.extensions.validator.core.mapper.NameMapper;

+import org.apache.myfaces.extensions.validator.core.InvocationOrderComparator;

+

+import java.util.Iterator;

+import java.util.List;

+import java.util.ArrayList;

+import java.util.Collections;

+import java.util.Comparator;

+

+/**

+ * @author Gerhard Petracek

+ * @since 1.x.2

+ */

+@UsageInformation(UsageCategory.API)

+public abstract class AbstractNameMapperAwareFactory<T> implements NameMapperAwareFactory<NameMapper<T>>

+{

+    private List<Class> deniedNameMapperList = new ArrayList<Class>();

+

+    public synchronized void register(NameMapper<T> nameMapper)

+    {

+        if(!deniedNameMapperList.contains(nameMapper.getClass()))

+        {

+            getNameMapperList().add(nameMapper);

+            Collections.sort(getNameMapperList(), getComparator());

+        }

+    }

+

+    protected Comparator<NameMapper<T>> getComparator()

+    {

+        return new InvocationOrderComparator<NameMapper<T>>();

+    }

+

+    public synchronized void deregister(Class<? extends NameMapper> classToDeregister)

+    {

+        Iterator<NameMapper<T>> nameMapperIterator = getNameMapperList().iterator();

+        while(nameMapperIterator.hasNext())

+        {

+            if(nameMapperIterator.next().getClass().getName().equals(classToDeregister.getName()))

+            {

+                nameMapperIterator.remove();

+                //don't break - e.g. to deregister all wrappers...

+                //break;

+            }

+        }

+    }

+

+    public void deny(Class<? extends NameMapper> classToDeny)

+    {

+        deregister(classToDeny);

+

+        synchronized (getClass())

+        {

+            deniedNameMapperList.add(classToDeny);

+        }

+    }

+

+    protected abstract List<NameMapper<T>> getNameMapperList();

+}

diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/factory/ClassMappingFactory.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/factory/ClassMappingFactory.java
new file mode 100644
index 0000000..d366070
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/factory/ClassMappingFactory.java
@@ -0,0 +1,32 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.core.factory;

+

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+

+/**

+ * @author Gerhard Petracek

+ * @since 1.x.1

+ */

+@UsageInformation(UsageCategory.API)

+public interface ClassMappingFactory<P, R>

+{

+    R create(P source);

+}

diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/factory/DefaultFactoryFinder.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/factory/DefaultFactoryFinder.java
new file mode 100644
index 0000000..c69755f
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/factory/DefaultFactoryFinder.java
@@ -0,0 +1,360 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.core.factory;

+

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.ToDo;

+import org.apache.myfaces.extensions.validator.internal.Priority;

+import org.apache.myfaces.extensions.validator.core.metadata.extractor.DefaultComponentMetaDataExtractorFactory;

+import org.apache.myfaces.extensions.validator.core.WebXmlParameter;

+import org.apache.myfaces.extensions.validator.core.ExtValContext;

+import org.apache.myfaces.extensions.validator.core.CustomInformation;

+import org.apache.myfaces.extensions.validator.core.storage.DefaultStorageManagerFactory;

+import org.apache.myfaces.extensions.validator.core.el.DefaultELHelperFactory;

+import org.apache.myfaces.extensions.validator.core.renderkit.DefaultRenderKitWrapperFactory;

+import org.apache.myfaces.extensions.validator.core.metadata.transformer.DefaultMetaDataTransformerFactory;

+import org.apache.myfaces.extensions.validator.core.validation.strategy.DefaultValidationStrategyFactory;

+import org.apache.myfaces.extensions.validator.core.validation.message.resolver.DefaultMessageResolverFactory;

+import org.apache.myfaces.extensions.validator.core.validation.message.DefaultFacesMessageFactory;

+import org.apache.myfaces.extensions.validator.core.validation.parameter.DefaultValidationParameterExtractorFactory;

+import org.apache.myfaces.extensions.validator.core.validation.parameter.DefaultValidationParameterFactory;

+import org.apache.myfaces.extensions.validator.util.ClassUtils;

+import org.apache.commons.logging.Log;

+import org.apache.commons.logging.LogFactory;

+

+import java.util.Map;

+import java.util.HashMap;

+import java.util.List;

+import java.util.ArrayList;

+

+/**

+ * @author Gerhard Petracek

+ * @since 1.x.1

+ */

+//dynamic approach to create the factories during the first request, when a faces-context is available

+@UsageInformation(UsageCategory.INTERNAL)

+public class DefaultFactoryFinder implements FactoryFinder

+{

+    protected final Log logger = LogFactory.getLog(getClass());

+    protected Map<FactoryNames, Object> factoryMap = new HashMap<FactoryNames, Object>();

+

+    private static FactoryFinder factoryFinder = new DefaultFactoryFinder();

+

+    protected DefaultFactoryFinder()

+    {

+        if(logger.isDebugEnabled())

+        {

+            logger.debug(getClass().getName() + " instantiated");

+        }

+    }

+

+    public static FactoryFinder getInstance()

+    {

+        return factoryFinder;

+    }

+

+    @SuppressWarnings({"unchecked"})

+    public final <T> T getFactory(FactoryNames factoryName, Class<T> targetClass)

+    {

+        if(!(factoryMap.containsKey(factoryName)))

+        {

+            initFactory(factoryName);

+        }

+

+        return (T)factoryMap.get(factoryName);

+    }

+

+    private void initFactory(FactoryNames factoryName)

+    {

+        Object factory = null;

+        switch (factoryName)

+        {

+            case COMPONENT_META_DATA_EXTRACTOR_FACTORY:

+                factory = createComponentMetaDataExtractorFactory();

+                break;

+

+            case VALIDATION_STRATEGY_FACTORY:

+                factory = createValidationStrategyFactory();

+                break;

+

+            case MESSAGE_RESOLVER_FACTORY:

+                factory = createMessageResolverFactory();

+                break;

+

+            case META_DATA_TRANSFORMER_FACTORY:

+                factory = createMetaDataTransformerFactory();

+                break;

+

+            case RENDERKIT_WRAPPER_FACTORY:

+                factory = createRenderKitWrapperFactory();

+                break;

+

+            case EL_HELPER_FACTORY:

+                factory = createELHelperFactory();

+                break;

+

+            case FACES_MESSAGE_FACTORY:

+                factory = createFacesMessageFactory();

+                break;

+

+            case VALIDATION_PARAMETER_EXTRACTOR_FACTORY:

+                factory = createValidationParameterExtractorFactory();

+                break;

+

+            case STORAGE_MANAGER_FACTORY:

+                factory = createStorageManagerFactory();

+                break;

+

+            case VALIDATION_PARAMETER_FACTORY:

+                factory = createValidationParameterFactory();

+                break;

+             

+            default: //required by checkstyle

+        }

+

+        if(factory == null)

+        {

+            throw new IllegalStateException("not possible to create factory " + factoryName);

+        }

+

+        factoryMap.put(factoryName, factory);

+    }

+

+    @ToDo(value = Priority.MEDIUM, description = "add global property extension point")

+    protected Object createComponentMetaDataExtractorFactory()

+    {

+        Object factory = null;

+

+        List<String> metaDataExtractorFactoryClassNames = new ArrayList<String>();

+

+        metaDataExtractorFactoryClassNames.add(WebXmlParameter.CUSTOM_COMPONENT_META_DATA_EXTRACTOR_FACTORY);

+        metaDataExtractorFactoryClassNames

+            .add(ExtValContext.getContext().getInformationProviderBean()

+                .get(CustomInformation.COMPONENT_META_DATA_EXTRACTOR_FACTORY));

+        metaDataExtractorFactoryClassNames.add(DefaultComponentMetaDataExtractorFactory.class.getName());

+

+        for (String className : metaDataExtractorFactoryClassNames)

+        {

+            factory = ClassUtils.tryToInstantiateClassForName(className);

+

+            if (factory != null)

+            {

+                break;

+            }

+        }

+        return factory;

+    }

+

+    @ToDo(value = Priority.MEDIUM, description = "add global property extension point")

+    protected Object createValidationStrategyFactory()

+    {

+        Object factory = null;

+

+        List<String> validationStrategyFactoryClassNames = new ArrayList<String>();

+

+        validationStrategyFactoryClassNames.add(WebXmlParameter.CUSTOM_VALIDATION_STRATEGY_FACTORY);

+        validationStrategyFactoryClassNames

+            .add(ExtValContext.getContext().getInformationProviderBean()

+                    .get(CustomInformation.VALIDATION_STRATEGY_FACTORY));

+        validationStrategyFactoryClassNames.add(DefaultValidationStrategyFactory.class.getName());

+

+        for (String className : validationStrategyFactoryClassNames)

+        {

+            factory = ClassUtils.tryToInstantiateClassForName(className);

+

+            if (factory != null)

+            {

+                break;

+            }

+        }

+

+        return factory;

+    }

+

+    @ToDo(value = Priority.MEDIUM, description = "add global property extension point")

+    protected Object createMessageResolverFactory()

+    {

+        Object factory = null;

+        List<String> messageResolverFactoryClassNames = new ArrayList<String>();

+

+        messageResolverFactoryClassNames.add(WebXmlParameter.CUSTOM_MESSAGE_RESOLVER_FACTORY);

+        messageResolverFactoryClassNames

+            .add(ExtValContext.getContext().getInformationProviderBean()

+                    .get(CustomInformation.MESSAGE_RESOLVER_FACTORY));

+        messageResolverFactoryClassNames

+            .add(DefaultMessageResolverFactory.class.getName());

+

+        for (String className : messageResolverFactoryClassNames)

+        {

+            factory = ClassUtils.tryToInstantiateClassForName(className);

+

+            if (factory != null)

+            {

+                break;

+            }

+        }

+

+        return factory;

+    }

+

+    @ToDo(value = Priority.MEDIUM, description = "add global property extension point")

+    protected Object createMetaDataTransformerFactory()

+    {

+        Object factory = null;

+        List<String> metaDataTransformerFactoryClassNames = new ArrayList<String>();

+

+        metaDataTransformerFactoryClassNames.add(WebXmlParameter.CUSTOM_META_DATA_TRANSFORMER_FACTORY );

+        metaDataTransformerFactoryClassNames

+            .add(ExtValContext.getContext().getInformationProviderBean()

+                    .get(CustomInformation.META_DATA_TRANSFORMER_FACTORY));

+        metaDataTransformerFactoryClassNames.add(DefaultMetaDataTransformerFactory.class.getName());

+

+        for (String className : metaDataTransformerFactoryClassNames)

+        {

+            factory = ClassUtils.tryToInstantiateClassForName(className);

+

+            if (factory != null)

+            {

+                break;

+            }

+        }

+

+        return factory;

+    }

+

+    protected Object createRenderKitWrapperFactory()

+    {

+        return new DefaultRenderKitWrapperFactory();

+    }

+

+    @ToDo(value = Priority.MEDIUM, description = "add global property extension point")

+    protected Object createFacesMessageFactory()

+    {

+        Object factory = null;

+

+        List<String> facesMessageFactoryClassNames = new ArrayList<String>();

+

+        facesMessageFactoryClassNames.add(WebXmlParameter.CUSTOM_FACES_MESSAGE_FACTORY);

+        facesMessageFactoryClassNames

+            .add(ExtValContext.getContext().getInformationProviderBean()

+                    .get(CustomInformation.FACES_MESSAGE_FACTORY));

+

+        Object target = ExtValContext.getContext().getGlobalProperty(CustomInformation.FACES_MESSAGE_FACTORY.name());

+        if(target != null && target instanceof String)

+        {

+            facesMessageFactoryClassNames.add((String)target);

+        }

+        facesMessageFactoryClassNames.add(DefaultFacesMessageFactory.class.getName());

+

+        for (String className : facesMessageFactoryClassNames)

+        {

+            factory = ClassUtils.tryToInstantiateClassForName(className);

+

+            if (factory != null)

+            {

+                break;

+            }

+        }

+

+        return factory;

+    }

+

+    protected Object createELHelperFactory()

+    {

+        return new DefaultELHelperFactory();

+    }

+

+    @ToDo(value = Priority.MEDIUM, description = "add global property extension point")

+    protected Object createValidationParameterExtractorFactory()

+    {

+        Object factory = null;

+

+        List<String> validationParameterExtractorFactoryClassNames = new ArrayList<String>();

+

+        validationParameterExtractorFactoryClassNames

+                .add(WebXmlParameter.CUSTOM_VALIDATION_PARAMETER_EXTRACTOR_FACTORY);

+        validationParameterExtractorFactoryClassNames

+            .add(ExtValContext.getContext().getInformationProviderBean()

+                .get(CustomInformation.VALIDATION_PARAMETER_EXTRACTOR_FACTORY));

+        validationParameterExtractorFactoryClassNames.add(DefaultValidationParameterExtractorFactory.class.getName());

+

+        for (String className : validationParameterExtractorFactoryClassNames)

+        {

+            factory = ClassUtils.tryToInstantiateClassForName(className);

+

+            if (factory != null)

+            {

+                break;

+            }

+        }

+        return factory;

+    }

+

+    protected Object createStorageManagerFactory()

+    {

+        Object factory = null;

+

+        List<String> storageManagerFactoryClassNames = new ArrayList<String>();

+

+        storageManagerFactoryClassNames

+                .add(WebXmlParameter.CUSTOM_STORAGE_MANAGER_FACTORY);

+        storageManagerFactoryClassNames

+            .add(ExtValContext.getContext().getInformationProviderBean()

+                .get(CustomInformation.STORAGE_MANAGER_FACTORY));

+        storageManagerFactoryClassNames.add(DefaultStorageManagerFactory.class.getName());

+

+        for (String className : storageManagerFactoryClassNames)

+        {

+            factory = ClassUtils.tryToInstantiateClassForName(className);

+

+            if (factory != null)

+            {

+                break;

+            }

+        }

+        return factory;

+    }

+

+    private Object createValidationParameterFactory()

+    {

+        Object factory = null;

+

+        List<String> validationParameterFactoryClassNames = new ArrayList<String>();

+

+        validationParameterFactoryClassNames

+                .add(WebXmlParameter.CUSTOM_VALIDATION_PARAMETER_FACTORY);

+        validationParameterFactoryClassNames

+            .add(ExtValContext.getContext().getInformationProviderBean()

+                .get(CustomInformation.VALIDATION_PARAMETER_FACTORY));

+        validationParameterFactoryClassNames.add(DefaultValidationParameterFactory.class.getName());

+

+        for (String className : validationParameterFactoryClassNames)

+        {

+            factory = ClassUtils.tryToInstantiateClassForName(className);

+

+            if (factory != null)

+            {

+                break;

+            }

+        }

+        return factory;

+    }

+

+}

diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/factory/FacesMessageFactory.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/factory/FacesMessageFactory.java
new file mode 100644
index 0000000..97bd8a3
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/factory/FacesMessageFactory.java
@@ -0,0 +1,36 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.core.factory;

+

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+

+import javax.faces.application.FacesMessage;

+

+/**

+ * @author Gerhard Petracek

+ * @since 1.x.2

+ */

+@UsageInformation(UsageCategory.API)

+public interface FacesMessageFactory

+{

+    FacesMessage convert(FacesMessage facesMessage);

+

+    FacesMessage create(FacesMessage.Severity severity, String summary, String detail);

+}

diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/factory/FactoryFinder.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/factory/FactoryFinder.java
new file mode 100644
index 0000000..a4f2625
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/factory/FactoryFinder.java
@@ -0,0 +1,32 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.myfaces.extensions.validator.core.factory;
+
+import org.apache.myfaces.extensions.validator.internal.UsageInformation;
+import org.apache.myfaces.extensions.validator.internal.UsageCategory;
+
+/**
+ * @author Gerhard Petracek
+ * @since 1.x.1
+ */
+@UsageInformation(UsageCategory.API)
+public interface FactoryFinder
+{
+    <T> T getFactory(FactoryNames factoryName, Class<T> targetClass);
+}
diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/factory/FactoryNames.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/factory/FactoryNames.java
new file mode 100644
index 0000000..912b15e
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/factory/FactoryNames.java
@@ -0,0 +1,46 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.myfaces.extensions.validator.core.factory;
+
+import org.apache.myfaces.extensions.validator.internal.UsageInformation;
+import org.apache.myfaces.extensions.validator.internal.UsageCategory;
+
+/**
+ * @author Gerhard Petracek
+ * @since 1.x.1
+ */
+@UsageInformation({UsageCategory.API})
+public enum FactoryNames
+{
+    COMPONENT_META_DATA_EXTRACTOR_FACTORY,
+
+    VALIDATION_PARAMETER_EXTRACTOR_FACTORY,
+    VALIDATION_PARAMETER_FACTORY,
+
+    VALIDATION_STRATEGY_FACTORY,
+    MESSAGE_RESOLVER_FACTORY,
+    META_DATA_TRANSFORMER_FACTORY,
+
+    FACES_MESSAGE_FACTORY,
+
+    RENDERKIT_WRAPPER_FACTORY,
+    EL_HELPER_FACTORY,
+
+    STORAGE_MANAGER_FACTORY
+}
diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/factory/NameMapperAwareFactory.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/factory/NameMapperAwareFactory.java
new file mode 100644
index 0000000..bd2d1f0
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/factory/NameMapperAwareFactory.java
@@ -0,0 +1,35 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.core.factory;

+

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+import org.apache.myfaces.extensions.validator.core.mapper.NameMapper;

+

+/**

+ * @author Gerhard Petracek

+ * @since 1.x.2

+ */

+@UsageInformation(UsageCategory.API)

+public interface NameMapperAwareFactory<T extends NameMapper>

+{

+    void register(T classToAdd);

+    void deregister(Class<? extends NameMapper> classToDeregister);

+    void deny(Class<? extends NameMapper> classToDeny);

+}

diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/initializer/component/AbstractHtmlCoreComponentsComponentInitializer.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/initializer/component/AbstractHtmlCoreComponentsComponentInitializer.java
new file mode 100644
index 0000000..6f500c3
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/initializer/component/AbstractHtmlCoreComponentsComponentInitializer.java
@@ -0,0 +1,128 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.core.initializer.component;

+

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+import org.apache.myfaces.extensions.validator.internal.ToDo;

+import org.apache.myfaces.extensions.validator.internal.Priority;

+import org.apache.myfaces.extensions.validator.util.ExtValUtils;

+import org.apache.myfaces.extensions.validator.util.ReflectionUtils;

+import org.apache.myfaces.extensions.validator.core.metadata.CommonMetaDataKeys;

+

+import javax.faces.context.FacesContext;

+import javax.faces.component.UIComponent;

+import javax.faces.component.html.HtmlInputText;

+import javax.faces.component.html.HtmlInputSecret;

+import javax.faces.component.html.HtmlSelectBooleanCheckbox;

+import javax.faces.component.html.HtmlSelectOneListbox;

+import javax.faces.component.html.HtmlSelectOneMenu;

+import javax.faces.component.html.HtmlSelectOneRadio;

+import javax.faces.component.html.HtmlSelectManyCheckbox;

+import javax.faces.component.html.HtmlSelectManyListbox;

+import javax.faces.component.html.HtmlSelectManyMenu;

+import javax.faces.component.html.HtmlInputTextarea;

+import java.util.Map;

+

+/**

+ * @author Gerhard Petracek

+ * @since x.x.3

+ */

+@UsageInformation(UsageCategory.REUSE)

+public abstract class AbstractHtmlCoreComponentsComponentInitializer implements ComponentInitializer

+{

+    public void configureComponent(FacesContext facesContext, UIComponent uiComponent, Map<String, Object> metaData)

+    {

+        if(processComponent(uiComponent))

+        {

+            if(validateEmptyFields() && ExtValUtils.isRequiredInitializationActive())

+            {

+                configureRequiredAttribute(facesContext, uiComponent, metaData);

+            }

+

+            configureMaxLengthAttribute(facesContext, uiComponent, metaData);

+        }

+    }

+

+    protected boolean validateEmptyFields()

+    {

+        return ExtValUtils.validateEmptyFields();

+    }

+

+    protected abstract void configureRequiredAttribute(FacesContext facesContext,

+                                              UIComponent uiComponent,

+                                              Map<String, Object> metaData);

+

+    protected boolean processComponent(UIComponent uiComponent)

+    {

+        return uiComponent instanceof HtmlInputText ||

+                uiComponent instanceof HtmlInputSecret ||

+                uiComponent instanceof HtmlSelectBooleanCheckbox ||

+                uiComponent instanceof HtmlSelectOneListbox ||

+                uiComponent instanceof HtmlSelectOneMenu ||

+                uiComponent instanceof HtmlSelectOneRadio ||

+                uiComponent instanceof HtmlSelectManyCheckbox ||

+                uiComponent instanceof HtmlSelectManyListbox ||

+                uiComponent instanceof HtmlSelectManyMenu ||

+                uiComponent instanceof HtmlInputTextarea;

+    }

+

+    /**

+     * if there is no special attribute at the component which should overrule

+     * the annotated property return true!

+     *

+     * @param uiComponent component which implements the EditableValueHolder interface

+     * @return false to overrule the annotated property e.g. if component is readonly

+     */

+    @ToDo(value = Priority.MEDIUM, description = "refactor")

+    protected Boolean isComponentRequired(UIComponent uiComponent)

+    {

+        boolean isReadOnly = !Boolean.FALSE.equals(ReflectionUtils.tryToInvokeMethod(

+                uiComponent, ReflectionUtils.tryToGetMethod(uiComponent.getClass(), "isReadonly")));

+        boolean isDisabled = !Boolean.FALSE.equals(ReflectionUtils.tryToInvokeMethod(

+                uiComponent, ReflectionUtils.tryToGetMethod(uiComponent.getClass(), "isDisabled")));

+

+        return !(isReadOnly || isDisabled);

+    }

+

+    protected void configureMaxLengthAttribute(FacesContext facesContext,

+                                             UIComponent uiComponent,

+                                             Map<String, Object> metaData)

+    {

+        if(metaData.containsKey(CommonMetaDataKeys.MAX_LENGTH))

+        {

+            Object maxLength = metaData.get(CommonMetaDataKeys.MAX_LENGTH);

+

+            if(!(maxLength instanceof Integer))

+            {

+                return;

+            }

+            if(uiComponent instanceof HtmlInputText)

+            {

+                HtmlInputText htmlInputText = (HtmlInputText)uiComponent;

+                htmlInputText.setMaxlength((Integer)maxLength);

+            }

+            else if(uiComponent instanceof HtmlInputSecret)

+            {

+                HtmlInputSecret htmlInputSecret = (HtmlInputSecret)uiComponent;

+                htmlInputSecret.setMaxlength((Integer)maxLength);

+            }

+        }

+    }

+}

diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/initializer/component/ComponentInitializer.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/initializer/component/ComponentInitializer.java
new file mode 100644
index 0000000..ec8e355
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/initializer/component/ComponentInitializer.java
@@ -0,0 +1,41 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.core.initializer.component;

+

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.core.InvocationOrderSupport;

+

+import javax.faces.component.UIComponent;

+import javax.faces.context.FacesContext;

+import java.util.Map;

+

+/**

+ * Allows to initialize components beforeEncodeBegin.<br/>

+ * e.g.: you can add information for client-side validation mechanisms,...

+ *

+ * @author Gerhard Petracek

+ * @since 1.x.1

+ */

+@InvocationOrderSupport

+@UsageInformation(UsageCategory.API)

+public interface ComponentInitializer

+{

+    void configureComponent(FacesContext facesContext, UIComponent uiComponent, Map<String, Object> metaData);

+}
\ No newline at end of file
diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/initializer/configuration/StaticConfiguration.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/initializer/configuration/StaticConfiguration.java
new file mode 100644
index 0000000..359c041
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/initializer/configuration/StaticConfiguration.java
@@ -0,0 +1,35 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.core.initializer.configuration;

+

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+

+import java.util.List;

+

+/**

+ * @author Gerhard Petracek

+ * @since 1.x.1

+ */

+@UsageInformation(UsageCategory.API)

+public interface StaticConfiguration<T, R>

+{

+    void setSourceOfMapping(String path);

+    List<StaticConfigurationEntry<T, R>> getMapping();

+}
\ No newline at end of file
diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/initializer/configuration/StaticConfigurationEntry.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/initializer/configuration/StaticConfigurationEntry.java
new file mode 100644
index 0000000..2b84af5
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/initializer/configuration/StaticConfigurationEntry.java
@@ -0,0 +1,53 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.core.initializer.configuration;

+

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+

+/**

+ * @author Gerhard Petracek

+ * @since 1.x.1

+ */

+@UsageInformation(UsageCategory.API)

+public class StaticConfigurationEntry<T, R>

+{

+    private T source;

+    private R target;

+

+    public T getSource()

+    {

+        return source;

+    }

+

+    public void setSource(T source)

+    {

+        this.source = source;

+    }

+

+    public R getTarget()

+    {

+        return target;

+    }

+

+    public void setTarget(R target)

+    {

+        this.target = target;

+    }

+}
\ No newline at end of file
diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/initializer/configuration/StaticConfigurationNames.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/initializer/configuration/StaticConfigurationNames.java
new file mode 100644
index 0000000..cd75bf4
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/initializer/configuration/StaticConfigurationNames.java
@@ -0,0 +1,38 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.myfaces.extensions.validator.core.initializer.configuration;
+
+import org.apache.myfaces.extensions.validator.internal.UsageInformation;
+import org.apache.myfaces.extensions.validator.internal.UsageCategory;
+
+/**
+ * @author Gerhard Petracek
+ * @since 1.x.1
+ */
+@UsageInformation({UsageCategory.API})
+public enum StaticConfigurationNames
+{
+    META_DATA_TO_VALIDATION_STRATEGY_CONFIG,
+    VALIDATION_STRATEGY_TO_MESSAGE_RESOLVER_CONFIG,
+    VALIDATION_STRATEGY_TO_META_DATA_TRANSFORMER_CONFIG,
+    STORAGE_TYPE_TO_STORAGE_MANAGER_CONFIG,
+
+    SKIP_VALIDATION_SUPPORT_CONFIG,
+    VALIDATION_PARAMETER_CONFIG
+}
\ No newline at end of file
diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/initializer/configuration/StaticInMemoryConfiguration.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/initializer/configuration/StaticInMemoryConfiguration.java
new file mode 100644
index 0000000..60cb6f4
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/initializer/configuration/StaticInMemoryConfiguration.java
@@ -0,0 +1,53 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.myfaces.extensions.validator.core.initializer.configuration;
+
+import org.apache.myfaces.extensions.validator.internal.UsageInformation;
+import org.apache.myfaces.extensions.validator.internal.UsageCategory;
+
+import java.util.List;
+import java.util.ArrayList;
+
+/**
+ * @author Gerhard Petracek
+ * @since 1.x.1
+ */
+@UsageInformation({UsageCategory.INTERNAL, UsageCategory.REUSE})
+public class StaticInMemoryConfiguration implements StaticConfiguration<String, String>
+{
+    private List<StaticConfigurationEntry<String, String>> mappings
+        = new ArrayList<StaticConfigurationEntry<String, String>>();
+
+    public void setSourceOfMapping(String path)
+    {
+    }
+
+    public List<StaticConfigurationEntry<String, String>> getMapping()
+    {
+        return mappings;
+    }
+
+    public void addMapping(String source, String target)
+    {
+        StaticConfigurationEntry<String, String> entry = new StaticConfigurationEntry<String, String>();
+        entry.setSource(source);
+        entry.setTarget(target);
+        this.mappings.add(entry);
+    }
+}
\ No newline at end of file
diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/initializer/configuration/StaticResourceBundleConfiguration.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/initializer/configuration/StaticResourceBundleConfiguration.java
new file mode 100644
index 0000000..81a63c4
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/initializer/configuration/StaticResourceBundleConfiguration.java
@@ -0,0 +1,85 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.myfaces.extensions.validator.core.initializer.configuration;
+
+import org.apache.myfaces.extensions.validator.internal.UsageInformation;
+import org.apache.myfaces.extensions.validator.internal.UsageCategory;
+
+import java.util.List;
+import java.util.ResourceBundle;
+import java.util.Enumeration;
+import java.util.ArrayList;
+
+/**
+ * @author Gerhard Petracek
+ * @since 1.x.1
+ */
+@UsageInformation({UsageCategory.INTERNAL, UsageCategory.REUSE})
+public class StaticResourceBundleConfiguration implements StaticConfiguration<String, String>
+{
+    private String path;
+    private List<StaticConfigurationEntry<String, String>> mappings;
+
+    public void setSourceOfMapping(String path)
+    {
+        this.path = path;
+        //force reload
+        mappings = null;
+    }
+
+    public List<StaticConfigurationEntry<String, String>> getMapping()
+    {
+        if(mappings != null)
+        {
+            return mappings;
+        }
+
+        mappings = new ArrayList<StaticConfigurationEntry<String, String>>();
+
+        ResourceBundle mapping = ResourceBundle.getBundle(path);
+
+        if (mapping == null)
+        {
+            //logging
+            return new ArrayList<StaticConfigurationEntry<String, String>>();
+        }
+
+        Enumeration keys = mapping.getKeys();
+
+        String metaDataKey;
+        String validationStrategyClassName;
+
+        while (keys.hasMoreElements())
+        {
+            metaDataKey = (String) keys.nextElement();
+            validationStrategyClassName = mapping.getString(metaDataKey);
+
+            addMapping(metaDataKey, validationStrategyClassName);
+        }
+        return mappings;
+    }
+
+    private void addMapping(String metaDataKey, String validationStrategyClassName)
+    {
+        StaticConfigurationEntry<String, String> entry = new StaticConfigurationEntry<String, String>();
+        entry.setSource(metaDataKey);
+        entry.setTarget(validationStrategyClassName);
+        this.mappings.add(entry);
+    }
+}
diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/interceptor/AbstractRendererInterceptor.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/interceptor/AbstractRendererInterceptor.java
new file mode 100644
index 0000000..6993968
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/interceptor/AbstractRendererInterceptor.java
@@ -0,0 +1,118 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.myfaces.extensions.validator.core.interceptor;
+
+import org.apache.myfaces.extensions.validator.internal.UsageCategory;
+import org.apache.myfaces.extensions.validator.internal.UsageInformation;
+import org.apache.myfaces.extensions.validator.core.renderkit.exception.SkipRendererDelegationException;
+import org.apache.myfaces.extensions.validator.core.renderkit.exception.SkipBeforeInterceptorsException;
+import org.apache.myfaces.extensions.validator.core.renderkit.exception.SkipAfterInterceptorsException;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import javax.faces.context.FacesContext;
+import javax.faces.component.UIComponent;
+import javax.faces.convert.ConverterException;
+import javax.faces.render.Renderer;
+import java.io.IOException;
+
+/**
+ * @author Gerhard Petracek
+ * @since 1.x.1
+ */
+@UsageInformation(UsageCategory.INTERNAL)
+public abstract class AbstractRendererInterceptor implements RendererInterceptor
+{
+    protected final Log logger = LogFactory.getLog(getClass());
+
+    protected AbstractRendererInterceptor()
+    {
+        if(logger.isDebugEnabled())
+        {
+            logger.debug(getClass().getName() + " instantiated");
+        }
+    }
+
+    public final String getInterceptorId()
+    {
+        return getClass().getName();
+    }
+
+    public Object getReturnValueOnSkipRendererDelegationException(
+        SkipRendererDelegationException skipRendererDelegationException, Object currentReturnValue)
+    {
+        return currentReturnValue;
+    }
+
+    /*
+    * before
+    */
+    public void beforeDecode(FacesContext facesContext, UIComponent uiComponent, Renderer wrapped)
+        throws SkipBeforeInterceptorsException, SkipRendererDelegationException
+    {
+    }
+
+    public void beforeEncodeBegin(FacesContext facesContext, UIComponent uiComponent, Renderer wrapped)
+        throws IOException, SkipBeforeInterceptorsException, SkipRendererDelegationException
+    {
+    }
+
+    public void beforeEncodeChildren(FacesContext facesContext, UIComponent uiComponent, Renderer wrapped)
+        throws IOException, SkipBeforeInterceptorsException, SkipRendererDelegationException
+    {
+    }
+
+    public void beforeEncodeEnd(FacesContext facesContext, UIComponent uiComponent, Renderer wrapped)
+        throws IOException, SkipBeforeInterceptorsException, SkipRendererDelegationException
+    {
+    }
+
+    public void beforeGetConvertedValue(FacesContext facesContext, UIComponent uiComponent, Object o, Renderer wrapped)
+        throws ConverterException, SkipBeforeInterceptorsException, SkipRendererDelegationException
+    {
+    }
+
+    /*
+     * after
+     */
+    public void afterDecode(FacesContext facesContext, UIComponent uiComponent, Renderer wrapped)
+        throws SkipAfterInterceptorsException
+    {
+    }
+
+    public void afterEncodeBegin(FacesContext facesContext, UIComponent uiComponent, Renderer wrapped)
+        throws IOException, SkipAfterInterceptorsException
+    {
+    }
+
+    public void afterEncodeChildren(FacesContext facesContext, UIComponent uiComponent, Renderer wrapped)
+        throws IOException, SkipAfterInterceptorsException
+    {
+    }
+
+    public void afterEncodeEnd(FacesContext facesContext, UIComponent uiComponent, Renderer wrapped)
+        throws IOException, SkipAfterInterceptorsException
+    {
+    }
+
+    public void afterGetConvertedValue(FacesContext facesContext, UIComponent uiComponent, Object o, Renderer wrapped)
+        throws ConverterException, SkipAfterInterceptorsException
+    {
+    }
+}
\ No newline at end of file
diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/interceptor/AbstractValidationInterceptor.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/interceptor/AbstractValidationInterceptor.java
new file mode 100644
index 0000000..1427129
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/interceptor/AbstractValidationInterceptor.java
@@ -0,0 +1,307 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.myfaces.extensions.validator.core.interceptor;
+
+import org.apache.myfaces.extensions.validator.internal.UsageCategory;
+import org.apache.myfaces.extensions.validator.internal.UsageInformation;
+import org.apache.myfaces.extensions.validator.core.ExtValContext;
+import org.apache.myfaces.extensions.validator.core.WebXmlParameter;
+import org.apache.myfaces.extensions.validator.core.ValidationModuleKey;
+import org.apache.myfaces.extensions.validator.core.metadata.extractor.MetaDataExtractor;
+import org.apache.myfaces.extensions.validator.core.property.PropertyInformation;
+import org.apache.myfaces.extensions.validator.core.storage.RendererInterceptorPropertyStorage;
+import org.apache.myfaces.extensions.validator.core.renderkit.exception.SkipBeforeInterceptorsException;
+import org.apache.myfaces.extensions.validator.core.renderkit.exception.SkipRendererDelegationException;
+import org.apache.myfaces.extensions.validator.core.renderkit.exception.SkipAfterInterceptorsException;
+import org.apache.myfaces.extensions.validator.core.recorder.ProcessedInformationRecorder;
+import org.apache.myfaces.extensions.validator.util.ExtValUtils;
+
+import javax.faces.context.FacesContext;
+import javax.faces.component.UIComponent;
+import javax.faces.component.EditableValueHolder;
+import javax.faces.convert.ConverterException;
+import javax.faces.render.Renderer;
+import javax.faces.validator.ValidatorException;
+import javax.el.PropertyNotFoundException;
+import java.io.IOException;
+import java.util.Map;
+import java.util.HashMap;
+
+/**
+ * @author Gerhard Petracek
+ * @since x.x.3
+ */
+@UsageInformation(UsageCategory.REUSE)
+public abstract class AbstractValidationInterceptor extends AbstractRendererInterceptor
+{
+    protected boolean isRequiredInitializationSupported()
+    {
+        return false;
+    }
+
+    @Override
+    public void afterDecode(FacesContext facesContext, UIComponent uiComponent, Renderer wrapped)
+            throws SkipAfterInterceptorsException
+    {
+        /*
+         * component initialization sets a component to required if there are constraints which indicate it
+         * the required flag in a component leads to problems with h:messages (additional message) as well as
+         * incompatibilities with skip validation and severities
+         */
+        if(uiComponent instanceof EditableValueHolder && ExtValUtils.isRequiredResetActivated() &&
+                isRequiredInitializationSupported() && ExtValUtils.isRequiredInitializationActive())
+        {
+            ((EditableValueHolder)uiComponent).setRequired(false);
+        }
+    }
+
+    @Override
+    public void beforeEncodeBegin(FacesContext facesContext, UIComponent uiComponent, Renderer wrapped)
+            throws IOException, SkipBeforeInterceptorsException, SkipRendererDelegationException
+    {
+        if(processComponent(uiComponent) && !isComponentInitializationDeactivated())
+        {
+            initComponent(facesContext, uiComponent);
+        }
+    }
+
+    protected abstract void initComponent(FacesContext facesContext, UIComponent uiComponent);
+
+    @Override
+    public void beforeGetConvertedValue(FacesContext facesContext, UIComponent uiComponent, Object o, Renderer wrapped)
+            throws ConverterException, SkipBeforeInterceptorsException, SkipRendererDelegationException
+    {
+        Object convertedObject;
+
+        try
+        {
+            convertedObject = wrapped.getConvertedValue(facesContext, uiComponent, o);
+        }
+        catch (PropertyNotFoundException r)
+        {
+            if(this.logger.isFatalEnabled())
+            {
+                this.logger.fatal("it seems you are using an invalid binding. " + wrapped.getClass().getName()
+                        + ": conversion failed. normally this is >not< a myfaces extval issue!", r);
+            }
+
+            throw r;
+        }
+
+        setRendererInterceptorProperties(uiComponent);
+        
+        if(recordProcessedInformation())
+        {
+            //recorde user input e.g. for cross-component validation
+            for(ProcessedInformationRecorder recorder : ExtValContext.getContext().getProcessedInformationRecorders())
+            {
+                recorder.recordUserInput(uiComponent, convertedObject);
+
+                if(logger.isTraceEnabled())
+                {
+                    logger.trace(recorder.getClass().getName() + " called");
+                }
+            }
+        }
+
+        try
+        {
+            if(processComponent(uiComponent))
+            {
+                convertedObject = transformValueForValidation(convertedObject);
+
+                if(validateValue(convertedObject) &&
+                        processBeforeValidation(facesContext, uiComponent, convertedObject))
+                {
+                    processValidation(facesContext, uiComponent, convertedObject);
+                }
+            }
+        }
+        catch (ValidatorException e)
+        {
+            try
+            {
+                //ViolationSeverityInterpreter might decide that it isn't an exception
+                ExtValUtils.tryToThrowValidatorExceptionForComponent(uiComponent, e.getFacesMessage(), e);
+            }
+            catch (ValidatorException finalException)
+            {
+                throw new ConverterException(e.getFacesMessage(), e);
+            }
+        }
+        finally
+        {
+            processAfterValidation(facesContext, uiComponent, convertedObject);
+            resetRendererInterceptorProperties(uiComponent);
+        }
+    }
+
+    protected boolean processBeforeValidation(FacesContext facesContext, UIComponent uiComponent, Object value)
+    {
+        return ExtValUtils.executeGlobalBeforeValidationInterceptors(facesContext, uiComponent, value,
+                PropertyInformation.class.getName(), getPropertyInformation(facesContext, uiComponent), getModuleKey());
+    }
+
+    protected void processAfterValidation(FacesContext facesContext, UIComponent uiComponent, Object value)
+    {
+        ExtValUtils.executeGlobalAfterValidationInterceptors(facesContext, uiComponent, value,
+                PropertyInformation.class.getName(), getPropertyInformation(facesContext, uiComponent), getModuleKey());
+    }
+
+    protected PropertyInformation getPropertyInformation(FacesContext facesContext, UIComponent uiComponent)
+    {
+        Map<String, Object> properties = getPropertiesForComponentMetaDataExtractor(uiComponent);
+
+        MetaDataExtractor metaDataExtractor = getComponentMetaDataExtractor(properties);
+
+        return metaDataExtractor.extract(facesContext, uiComponent);
+    }
+
+    protected Map<String, Object> getPropertiesForComponentMetaDataExtractor(UIComponent uiComponent)
+    {
+        Map<String, Object> properties = new HashMap<String, Object>();
+
+        if(getModuleKey() != null)
+        {
+            properties.put(ValidationModuleKey.class.getName(), getModuleKey());
+        }
+        properties.put(UIComponent.class.getName(), uiComponent);
+        return properties;
+    }
+
+    protected abstract MetaDataExtractor getComponentMetaDataExtractor(Map<String, Object> properties);
+
+    protected Object transformValueForValidation(Object convertedObject)
+    {
+        if ("".equals(convertedObject) && interpretEmptyStringValuesAsNull())
+        {
+            return null;
+        }
+
+        return convertedObject;
+    }
+
+    protected boolean validateValue(Object convertedObject)
+    {
+        if(isValueToValidateEmpty(convertedObject) && !validateEmptyFields())
+        {
+            if(this.logger.isDebugEnabled())
+            {
+                this.logger.debug("empty field validation is deactivated in the web.xml - see: " +
+                        "javax.faces.VALIDATE_EMPTY_FIELDS");
+            }
+
+            return false;
+        }
+
+        return true;
+    }
+
+    protected boolean isValueToValidateEmpty(Object convertedObject)
+    {
+        return convertedObject == null || "".equals(convertedObject);
+    }
+
+    protected boolean validateEmptyFields()
+    {
+        return ExtValUtils.validateEmptyFields();
+    }
+
+    protected boolean interpretEmptyStringValuesAsNull()
+    {
+        return ExtValUtils.interpretEmptyStringValuesAsNull();
+    }
+
+    protected abstract void processValidation(
+            FacesContext facesContext, UIComponent uiComponent, Object convertedObject);
+
+    protected boolean processComponent(UIComponent uiComponent)
+    {
+        return uiComponent instanceof EditableValueHolder && isValueBindingOfComponentValid(uiComponent);
+    }
+
+    private boolean isValueBindingOfComponentValid(UIComponent uiComponent)
+    {
+        try
+        {
+            return ExtValUtils.getELHelper().getPropertyDetailsOfValueBinding(uiComponent) != null;
+        }
+        catch (Throwable t)
+        {
+            return false;
+        }
+    }
+
+    private boolean isComponentInitializationDeactivated()
+    {
+        return "true".equalsIgnoreCase(WebXmlParameter.DEACTIVATE_COMPONENT_INITIALIZATION);
+    }
+
+    protected boolean recordProcessedInformation()
+    {
+        //override if needed
+        return false;
+    }
+
+    protected Class getModuleKey()
+    {
+        //override if needed
+        return null;
+    }
+
+    protected Map<String, Object> getInterceptorProperties(UIComponent uiComponent)
+    {
+        Map<String, Object> result = new HashMap<String, Object>();
+
+        if(getModuleKey() != null)
+        {
+            result.put(ValidationModuleKey.class.getName(), getModuleKey());
+        }
+        result.put(UIComponent.class.getName(), uiComponent);
+
+        return result;
+    }
+
+    private void setRendererInterceptorProperties(UIComponent uiComponent)
+    {
+        RendererInterceptorPropertyStorage interceptorPropertyStorage = getRendererInterceptorPropertyStorage();
+
+        Map<String, Object> properties = getInterceptorProperties(uiComponent);
+        for(String key : properties.keySet())
+        {
+            interceptorPropertyStorage.setProperty(key, properties.get(key));
+        }
+    }
+
+    private void resetRendererInterceptorProperties(UIComponent uiComponent)
+    {
+        RendererInterceptorPropertyStorage interceptorPropertyStorage = getRendererInterceptorPropertyStorage();
+
+        for(String key : getInterceptorProperties(uiComponent).keySet())
+        {
+            interceptorPropertyStorage.removeProperty(key);
+        }
+    }
+
+    private RendererInterceptorPropertyStorage getRendererInterceptorPropertyStorage()
+    {
+        return ExtValUtils.getStorage(RendererInterceptorPropertyStorage.class,
+                RendererInterceptorPropertyStorage.class.getName());
+    }
+}
diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/interceptor/ComponentInitializationAwareMetaDataExtractionInterceptor.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/interceptor/ComponentInitializationAwareMetaDataExtractionInterceptor.java
new file mode 100644
index 0000000..bdf7118
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/interceptor/ComponentInitializationAwareMetaDataExtractionInterceptor.java
@@ -0,0 +1,44 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.core.interceptor;

+

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+import org.apache.myfaces.extensions.validator.core.property.PropertyInformation;

+import org.apache.myfaces.extensions.validator.core.InvocationOrderSupport;

+import org.apache.myfaces.extensions.validator.util.JsfUtils;

+

+/**

+ * @author Gerhard Petracek

+ * @since x.x.3

+ */

+@InvocationOrderSupport

+@UsageInformation(UsageCategory.REUSE)

+public abstract class ComponentInitializationAwareMetaDataExtractionInterceptor implements MetaDataExtractionInterceptor

+{

+    public final void afterExtracting(PropertyInformation propertyInformation)

+    {

+        if(JsfUtils.isRenderResponsePhase())

+        {

+            afterExtractingForComponentInitialization(propertyInformation);

+        }

+    }

+

+    protected abstract void afterExtractingForComponentInitialization(PropertyInformation propertyInformation);

+}

diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/interceptor/FacesMessagePropertyValidationInterceptor.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/interceptor/FacesMessagePropertyValidationInterceptor.java
new file mode 100644
index 0000000..296b163
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/interceptor/FacesMessagePropertyValidationInterceptor.java
@@ -0,0 +1,61 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.core.interceptor;

+

+import org.apache.myfaces.extensions.validator.core.InvocationOrder;

+import org.apache.myfaces.extensions.validator.core.storage.FacesMessageStorage;

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+import org.apache.myfaces.extensions.validator.util.ExtValUtils;

+import org.apache.commons.logging.Log;

+import org.apache.commons.logging.LogFactory;

+

+import javax.faces.component.UIComponent;

+import javax.faces.context.FacesContext;

+import java.util.Map;

+

+/**

+ * @author Gerhard Petracek

+ * @since x.x.3

+ */

+@InvocationOrder(900)

+@UsageInformation(UsageCategory.INTERNAL)

+public class FacesMessagePropertyValidationInterceptor implements PropertyValidationInterceptor

+{

+    protected final Log logger = LogFactory.getLog(getClass());

+

+    public boolean beforeValidation(

+            FacesContext facesContext, UIComponent uiComponent, Object convertedObject, Map<String, Object> properties)

+    {

+        return true;

+    }

+

+    public void afterValidation(

+            FacesContext facesContext, UIComponent uiComponent, Object convertedObject, Map<String, Object> properties)

+    {

+        FacesMessageStorage facesMessageStorage = ExtValUtils.getStorage(

+                FacesMessageStorage.class, FacesMessageStorage.class.getName());

+

+        if(facesMessageStorage != null)

+        {

+            facesMessageStorage.addAll();

+            ExtValUtils.resetStorage(FacesMessageStorage.class, FacesMessageStorage.class.getName());

+        }

+    }

+}

diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/interceptor/HtmlCoreComponentsValidationExceptionInterceptor.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/interceptor/HtmlCoreComponentsValidationExceptionInterceptor.java
new file mode 100644
index 0000000..ed7c928
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/interceptor/HtmlCoreComponentsValidationExceptionInterceptor.java
@@ -0,0 +1,178 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.myfaces.extensions.validator.core.interceptor;
+
+import org.apache.myfaces.extensions.validator.core.metadata.MetaDataEntry;
+import org.apache.myfaces.extensions.validator.core.property.PropertyInformationKeys;
+import org.apache.myfaces.extensions.validator.core.validation.strategy.ValidationStrategy;
+import org.apache.myfaces.extensions.validator.core.validation.message.LabeledMessage;
+import org.apache.myfaces.extensions.validator.core.validation.exception.RequiredValidatorException;
+import org.apache.myfaces.extensions.validator.core.InvocationOrder;
+import org.apache.myfaces.extensions.validator.internal.UsageInformation;
+import org.apache.myfaces.extensions.validator.internal.UsageCategory;
+import org.apache.myfaces.extensions.validator.internal.ToDo;
+import org.apache.myfaces.extensions.validator.internal.Priority;
+import org.apache.myfaces.extensions.validator.util.ReflectionUtils;
+import org.apache.myfaces.extensions.validator.util.ExtValUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import javax.faces.component.UIComponent;
+import javax.faces.component.html.HtmlInputText;
+import javax.faces.component.html.HtmlInputSecret;
+import javax.faces.component.html.HtmlSelectBooleanCheckbox;
+import javax.faces.component.html.HtmlSelectOneListbox;
+import javax.faces.component.html.HtmlSelectOneMenu;
+import javax.faces.component.html.HtmlSelectOneRadio;
+import javax.faces.component.html.HtmlSelectManyCheckbox;
+import javax.faces.component.html.HtmlSelectManyListbox;
+import javax.faces.component.html.HtmlSelectManyMenu;
+import javax.faces.component.html.HtmlInputTextarea;
+import javax.faces.context.FacesContext;
+import javax.faces.validator.ValidatorException;
+import javax.faces.application.FacesMessage;
+import java.lang.annotation.Annotation;
+
+/**
+ * @author Gerhard Petracek
+ * @since 1.x.1
+ */
+@InvocationOrder(100)
+@UsageInformation(UsageCategory.INTERNAL)
+public class HtmlCoreComponentsValidationExceptionInterceptor implements ValidationExceptionInterceptor
+{
+    protected final Log logger = LogFactory.getLog(getClass());
+
+    public boolean afterThrowing(UIComponent uiComponent,
+                                 MetaDataEntry metaDataEntry,
+                                 Object convertedObject,
+                                 ValidatorException validatorException,
+                                 ValidationStrategy validatorExceptionSource)
+    {
+        if(processComponent(uiComponent))
+        {
+            FacesContext facesContext = FacesContext.getCurrentInstance();
+            FacesMessage facesMessage = ExtValUtils.convertFacesMessage(validatorException.getFacesMessage());
+
+            tryToUseInlineMessage(uiComponent, validatorException);
+
+            tryToUseLabel(facesContext, uiComponent, metaDataEntry, facesMessage);
+
+            tryToBlocksNavigation(uiComponent, metaDataEntry, facesMessage);
+        }
+        return true;
+    }
+
+    private void tryToUseInlineMessage(UIComponent uiComponent, ValidatorException validatorException)
+    {
+        FacesMessage facesMessage = validatorException.getFacesMessage();
+        String inlineMessage;
+
+        if(validatorException instanceof RequiredValidatorException)
+        {
+            inlineMessage = getInlineRequiredMessage(uiComponent);
+
+            if(inlineMessage != null)
+            {
+                facesMessage.setSummary(inlineMessage);
+                facesMessage.setDetail(inlineMessage);
+            }
+        }
+        else
+        {
+            //
+            inlineMessage = getInlineValidatorMessage(uiComponent);
+
+            if(inlineMessage != null)
+            {
+                facesMessage.setSummary(inlineMessage);
+                facesMessage.setDetail(inlineMessage);
+            }
+        }
+    }
+
+    private void tryToUseLabel(FacesContext facesContext,
+                               UIComponent uiComponent,
+                               MetaDataEntry metaDataEntry,
+                               FacesMessage facesMessage)
+    {
+        String label = (String) ReflectionUtils.tryToInvokeMethod(uiComponent,
+            ReflectionUtils.tryToGetMethod(uiComponent.getClass(), "getLabel"));
+
+        if(label == null)
+        {
+            label = uiComponent.getClientId(facesContext);
+        }
+
+        //override the label if the annotation provides a label
+        if(metaDataEntry != null && metaDataEntry.getProperty(PropertyInformationKeys.LABEL) != null)
+        {
+            label = metaDataEntry.getProperty(PropertyInformationKeys.LABEL, String.class);
+        }
+
+        if(facesMessage instanceof LabeledMessage)
+        {
+            ((LabeledMessage)facesMessage).setLabelText(label);
+        }
+        //if someone uses a normal faces message
+        else
+        {
+            for(int i = 0; i < 3; i++)
+            {
+                ExtValUtils.tryToPlaceLabel(facesMessage, label, i);
+            }
+        }
+    }
+
+    @ToDo(value = Priority.MEDIUM, description = "check if it is still required here")
+    private void tryToBlocksNavigation(UIComponent uiComponent, MetaDataEntry metaDataEntry, FacesMessage facesMessage)
+    {
+        if(metaDataEntry != null && metaDataEntry.getValue() instanceof Annotation)
+        {
+            //correct severity is e.g. provided by ViolationSeverityValidationExceptionInterceptor
+            ExtValUtils.tryToBlocksNavigationForComponent(uiComponent, facesMessage);
+        }
+    }
+
+    private String getInlineRequiredMessage(UIComponent uiComponent)
+    {
+        return (String)ReflectionUtils.tryToInvokeMethod(uiComponent,
+                ReflectionUtils.tryToGetMethod(uiComponent.getClass(), "getRequiredMessage"));
+    }
+
+    private String getInlineValidatorMessage(UIComponent uiComponent)
+    {
+        return (String)ReflectionUtils.tryToInvokeMethod(uiComponent,
+                ReflectionUtils.tryToGetMethod(uiComponent.getClass(), "getValidatorMessage"));
+    }
+
+    protected boolean processComponent(UIComponent uiComponent)
+    {
+        return uiComponent instanceof HtmlInputText ||
+                uiComponent instanceof HtmlInputSecret ||
+                uiComponent instanceof HtmlSelectBooleanCheckbox ||
+                uiComponent instanceof HtmlSelectOneListbox ||
+                uiComponent instanceof HtmlSelectOneMenu ||
+                uiComponent instanceof HtmlSelectOneRadio ||
+                uiComponent instanceof HtmlSelectManyCheckbox ||
+                uiComponent instanceof HtmlSelectManyListbox ||
+                uiComponent instanceof HtmlSelectManyMenu ||
+                uiComponent instanceof HtmlInputTextarea;
+    }
+}
diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/interceptor/MetaDataExtractionInterceptor.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/interceptor/MetaDataExtractionInterceptor.java
new file mode 100644
index 0000000..01d21de
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/interceptor/MetaDataExtractionInterceptor.java
@@ -0,0 +1,39 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.core.interceptor;

+

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+import org.apache.myfaces.extensions.validator.core.property.PropertyInformation;

+import org.apache.myfaces.extensions.validator.core.InvocationOrderSupport;

+

+/**

+ * @author Gerhard Petracek

+ * @since 1.x.2

+ */

+@InvocationOrderSupport

+@UsageInformation(UsageCategory.API)

+public interface MetaDataExtractionInterceptor

+{

+    /**

+     *

+     * @param propertyInformation the information entry which contains information about the property

+     */

+    void afterExtracting(PropertyInformation propertyInformation);

+}
\ No newline at end of file
diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/interceptor/PropertyValidationInterceptor.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/interceptor/PropertyValidationInterceptor.java
new file mode 100644
index 0000000..04cf527
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/interceptor/PropertyValidationInterceptor.java
@@ -0,0 +1,54 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.core.interceptor;

+

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+import org.apache.myfaces.extensions.validator.core.validation.parameter.ValidationParameter;

+import org.apache.myfaces.extensions.validator.core.InvocationOrderSupport;

+

+import javax.faces.context.FacesContext;

+import javax.faces.component.UIComponent;

+import java.util.Map;

+

+/**

+ * @author Gerhard Petracek

+ * @since x.x.3

+ */

+@InvocationOrderSupport

+@UsageInformation(UsageCategory.API)

+public interface PropertyValidationInterceptor extends ValidationParameter

+{

+    /**

+     * @return false if the validation process should be bypassed

+     */

+    boolean beforeValidation(FacesContext facesContext,

+                             UIComponent uiComponent,

+                             Object convertedObject,

+                             Map<String, Object> properties);

+

+    /**

+     * processed if validation was executed

+     * in contrast to ValidationExceptionInterceptor it gets executed in any case

+     */

+    void afterValidation(FacesContext facesContext,

+                         UIComponent uiComponent,

+                         Object convertedObject,

+                         Map<String, Object> properties);

+}

diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/interceptor/RendererInterceptor.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/interceptor/RendererInterceptor.java
new file mode 100644
index 0000000..431f054
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/interceptor/RendererInterceptor.java
@@ -0,0 +1,83 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.myfaces.extensions.validator.core.interceptor;
+
+import org.apache.myfaces.extensions.validator.internal.UsageCategory;
+import org.apache.myfaces.extensions.validator.internal.UsageInformation;
+import org.apache.myfaces.extensions.validator.core.renderkit.exception.SkipBeforeInterceptorsException;
+import org.apache.myfaces.extensions.validator.core.renderkit.exception.SkipRendererDelegationException;
+import org.apache.myfaces.extensions.validator.core.renderkit.exception.SkipAfterInterceptorsException;
+
+import javax.faces.context.FacesContext;
+import javax.faces.component.UIComponent;
+import javax.faces.convert.ConverterException;
+import javax.faces.render.Renderer;
+import java.io.IOException;
+
+/**
+ * Allows to intercept renderer methods.<br/>
+ * Base mechanism of extval. It allows to add custom infrastructures.
+ *
+ * @author Gerhard Petracek
+ * @since 1.x.1
+ */
+@UsageInformation(UsageCategory.API)
+public interface RendererInterceptor
+{
+    String getInterceptorId();
+
+    Object getReturnValueOnSkipRendererDelegationException(
+        SkipRendererDelegationException skipRendererDelegationException, Object currentReturnValue);
+
+    /*
+     * before
+     */
+    void beforeDecode(FacesContext facesContext, UIComponent uiComponent, Renderer renderer)
+        throws SkipBeforeInterceptorsException, SkipRendererDelegationException;
+
+    void beforeEncodeBegin(FacesContext facesContext, UIComponent uiComponent, Renderer renderer)
+        throws IOException, SkipBeforeInterceptorsException, SkipRendererDelegationException;
+
+    void beforeEncodeChildren(FacesContext facesContext, UIComponent uiComponent, Renderer renderer)
+        throws IOException, SkipBeforeInterceptorsException, SkipRendererDelegationException;
+
+    void beforeEncodeEnd(FacesContext facesContext, UIComponent uiComponent, Renderer renderer)
+        throws IOException, SkipBeforeInterceptorsException, SkipRendererDelegationException;
+
+    void beforeGetConvertedValue(FacesContext facesContext, UIComponent uiComponent, Object o, Renderer renderer)
+        throws ConverterException, SkipBeforeInterceptorsException, SkipRendererDelegationException;
+
+    /*
+     * after
+     */
+    void afterDecode(FacesContext facesContext, UIComponent uiComponent, Renderer renderer)
+        throws SkipAfterInterceptorsException;
+
+    void afterEncodeBegin(FacesContext facesContext, UIComponent uiComponent, Renderer renderer)
+        throws IOException, SkipAfterInterceptorsException;
+
+    void afterEncodeChildren(FacesContext facesContext, UIComponent uiComponent, Renderer renderer)
+        throws IOException, SkipAfterInterceptorsException;
+
+    void afterEncodeEnd(FacesContext facesContext, UIComponent uiComponent, Renderer renderer)
+        throws IOException, SkipAfterInterceptorsException;
+
+    void afterGetConvertedValue(FacesContext facesContext, UIComponent uiComponent, Object o, Renderer renderer)
+        throws ConverterException, SkipAfterInterceptorsException;
+}
\ No newline at end of file
diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/interceptor/ValidationExceptionInterceptor.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/interceptor/ValidationExceptionInterceptor.java
new file mode 100644
index 0000000..d4ec3d0
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/interceptor/ValidationExceptionInterceptor.java
@@ -0,0 +1,54 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.core.interceptor;

+

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+import org.apache.myfaces.extensions.validator.core.metadata.MetaDataEntry;

+import org.apache.myfaces.extensions.validator.core.validation.strategy.ValidationStrategy;

+import org.apache.myfaces.extensions.validator.core.InvocationOrderSupport;

+

+import javax.faces.component.UIComponent;

+import javax.faces.validator.ValidatorException;

+

+/**

+ * Allows to intercept validatior exceptions.

+ *

+ * @author Gerhard Petracek

+ * @since 1.x.1

+ */

+@InvocationOrderSupport

+@UsageInformation(UsageCategory.API)

+public interface ValidationExceptionInterceptor

+{

+    /**

+     *

+     * @param uiComponent the current component

+     * @param metaDataEntry the meta data entry which contains the meta data of the property

+     * @param convertedObject the converted user input

+     * @param validatorException the current exception

+     * @param validatorExceptionSource validation strategy which threw the exception

+     * @return false to stop throwing the exception

+     */

+    boolean afterThrowing(UIComponent uiComponent,

+                          MetaDataEntry metaDataEntry,

+                          Object convertedObject,

+                          ValidatorException validatorException,

+                          ValidationStrategy validatorExceptionSource);

+}

diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/interceptor/ValidationInterceptor.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/interceptor/ValidationInterceptor.java
new file mode 100644
index 0000000..c2e15e0
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/interceptor/ValidationInterceptor.java
@@ -0,0 +1,197 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.myfaces.extensions.validator.core.interceptor;
+
+import org.apache.myfaces.extensions.validator.internal.UsageCategory;
+import org.apache.myfaces.extensions.validator.internal.UsageInformation;
+import org.apache.myfaces.extensions.validator.core.validation.strategy.ValidationStrategy;
+import org.apache.myfaces.extensions.validator.core.validation.SkipValidationEvaluator;
+import org.apache.myfaces.extensions.validator.core.validation.NullValueAwareValidationStrategy;
+import org.apache.myfaces.extensions.validator.core.validation.EmptyValueAwareValidationStrategy;
+import org.apache.myfaces.extensions.validator.core.metadata.extractor.MetaDataExtractor;
+import org.apache.myfaces.extensions.validator.core.metadata.MetaDataEntry;
+import org.apache.myfaces.extensions.validator.core.property.PropertyInformation;
+import org.apache.myfaces.extensions.validator.core.ExtValContext;
+import org.apache.myfaces.extensions.validator.util.ExtValUtils;
+import org.apache.myfaces.extensions.validator.util.ProxyUtils;
+
+import javax.faces.context.FacesContext;
+import javax.faces.component.UIComponent;
+import java.util.Map;
+import java.lang.annotation.Annotation;
+
+/**
+ * @author Gerhard Petracek
+ * @since 1.x.1
+ */
+@UsageInformation(UsageCategory.INTERNAL)
+public class ValidationInterceptor extends AbstractValidationInterceptor
+{
+    @Override
+    protected boolean isRequiredInitializationSupported()
+    {
+        return true;
+    }
+
+    protected void initComponent(FacesContext facesContext, UIComponent uiComponent)
+    {
+        if(logger.isTraceEnabled())
+        {
+            logger.trace("start to init component " + uiComponent.getClass().getName());
+        }
+
+        Map<String, Object> metaDataResult = ExtValUtils
+                .getTransformedMetaDataFor(facesContext, uiComponent, getModuleKey());
+
+        //get component initializer for the current component and configure it
+        //also in case of skipped validation to reset e.g. the required attribute
+        if(!metaDataResult.isEmpty())
+        {
+            ExtValUtils.configureComponentWithMetaData(facesContext, uiComponent, metaDataResult);
+        }
+
+        if(logger.isTraceEnabled())
+        {
+            logger.trace("init component of " + uiComponent.getClass().getName() + " finished");
+        }
+    }
+
+    protected void processValidation(FacesContext facesContext, UIComponent uiComponent, Object convertedObject)
+    {
+        MetaDataExtractor metaDataExtractor = ExtValUtils
+                .getComponentMetaDataExtractorWith(getPropertiesForComponentMetaDataExtractor(uiComponent));
+
+        PropertyInformation propertyInformation = metaDataExtractor.extract(facesContext, uiComponent);
+
+        try
+        {
+            if(logger.isTraceEnabled())
+            {
+                logger.trace("start validation");
+            }
+
+            processFieldValidation(facesContext, uiComponent, convertedObject, propertyInformation);
+        }
+        finally
+        {
+            if(logger.isTraceEnabled())
+            {
+                logger.trace("validation finished");
+            }
+        }
+    }
+
+    protected MetaDataExtractor getComponentMetaDataExtractor(Map<String, Object> properties)
+    {
+        return ExtValUtils.getComponentMetaDataExtractorWith(properties);
+    }
+
+    protected void processFieldValidation(FacesContext facesContext,
+                                          UIComponent uiComponent,
+                                          Object convertedObject,
+                                          PropertyInformation propertyInformation)
+    {
+        ValidationStrategy validationStrategy;
+        SkipValidationEvaluator skipValidationEvaluator = ExtValContext.getContext().getSkipValidationEvaluator();
+        for (MetaDataEntry entry : propertyInformation.getMetaDataEntries())
+        {
+            validationStrategy = ExtValUtils.getValidationStrategyForMetaData(entry.getKey());
+
+            if (validationStrategy != null &&
+                    isValidationStrategyCompatibleWithValue(validationStrategy,  convertedObject))
+            {
+                if(skipValidationEvaluator.skipValidation(facesContext, uiComponent, validationStrategy, entry))
+                {
+                    if(logger.isTraceEnabled())
+                    {
+                        logger.trace("skip validation of " + entry.getValue() +
+                                " with " + validationStrategy.getClass().getName());
+                    }
+                    //don't break maybe there are constraints which don't support the skip-mechanism
+                    continue;
+                }
+
+                if(logger.isTraceEnabled())
+                {
+                    logger.trace("validate " + entry.getValue() + " with " + validationStrategy.getClass().getName());
+                }
+
+                try
+                {
+                    if(entry.getValue() instanceof Annotation)
+                    {
+                        if(!ExtValUtils.executeLocalBeforeValidationInterceptors(
+                                facesContext, uiComponent, convertedObject,
+                                PropertyInformation.class.getName(), propertyInformation,
+                                entry.getValue(Annotation.class)))
+                        {
+                            continue;
+                        }
+                    }
+
+                    /*
+                     * validation
+                     */
+                    validationStrategy.validate(facesContext, uiComponent, entry, convertedObject);
+                }
+                finally
+                {
+                    if(entry.getValue() instanceof Annotation)
+                    {
+                        ExtValUtils.executeLocalAfterValidationInterceptors(
+                                facesContext, uiComponent, convertedObject,
+                                PropertyInformation.class.getName(), propertyInformation,
+                                entry.getValue(Annotation.class));
+                    }
+                }
+            }
+            else if(validationStrategy == null && logger.isTraceEnabled())
+            {
+                logger.trace("no validation strategy found for " + entry.getValue());
+            }
+        }
+    }
+
+    protected boolean isValidationStrategyCompatibleWithValue(ValidationStrategy validationStrategy, Object value)
+    {
+        if(value == null)
+        {
+            Class validationStrategyClass = ProxyUtils.getUnproxiedClass(validationStrategy.getClass());
+            return validationStrategyClass.isAnnotationPresent(NullValueAwareValidationStrategy.class);
+        }
+
+        return !"".equals(value) || ProxyUtils.getUnproxiedClass(validationStrategy.getClass())
+                .isAnnotationPresent(EmptyValueAwareValidationStrategy.class);
+    }
+
+    @Override
+    /**
+     * to ensure backward compatibility
+     */
+    protected boolean interpretEmptyStringValuesAsNull()
+    {
+        return false;
+    }
+
+    @Override
+    protected boolean recordProcessedInformation()
+    {
+        return true;
+    }
+}
diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/interceptor/ViolationSeverityValidationExceptionInterceptor.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/interceptor/ViolationSeverityValidationExceptionInterceptor.java
new file mode 100644
index 0000000..e934c61
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/interceptor/ViolationSeverityValidationExceptionInterceptor.java
@@ -0,0 +1,74 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.core.interceptor;

+

+import org.apache.myfaces.extensions.validator.core.metadata.MetaDataEntry;

+import org.apache.myfaces.extensions.validator.core.validation.strategy.ValidationStrategy;

+import org.apache.myfaces.extensions.validator.core.validation.parameter.ViolationSeverity;

+import org.apache.myfaces.extensions.validator.core.InvocationOrder;

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+import org.apache.myfaces.extensions.validator.util.ExtValUtils;

+import org.apache.commons.logging.Log;

+import org.apache.commons.logging.LogFactory;

+

+import javax.faces.component.UIComponent;

+import javax.faces.validator.ValidatorException;

+import javax.faces.application.FacesMessage;

+import java.lang.annotation.Annotation;

+

+/**

+ * @author Gerhard Petracek

+ * @since x.x.3

+ */

+@InvocationOrder(90)

+@UsageInformation(UsageCategory.INTERNAL)

+public class ViolationSeverityValidationExceptionInterceptor implements ValidationExceptionInterceptor

+{

+    protected final Log logger = LogFactory.getLog(getClass());

+

+    public boolean afterThrowing(UIComponent uiComponent,

+                                 MetaDataEntry metaDataEntry,

+                                 Object convertedObject,

+                                 ValidatorException validatorException,

+                                 ValidationStrategy validatorExceptionSource)

+    {

+        if(isExtValMetaData(metaDataEntry))

+        {

+            tryToPlaceSeverity(validatorException, metaDataEntry.getValue(Annotation.class));

+        }

+        return true;

+    }

+

+    private boolean isExtValMetaData(MetaDataEntry metaDataEntry)

+    {

+        return metaDataEntry.getValue() instanceof Annotation;

+    }

+

+    private void tryToPlaceSeverity(ValidatorException validatorException, Annotation annotation)

+    {

+        for(FacesMessage.Severity severity : ExtValUtils.getValidationParameterExtractor()

+                .extract(annotation,

+                        ExtValUtils.getValidationParameterClassFor(ViolationSeverity.class),

+                        FacesMessage.Severity.class))

+        {

+            validatorException.getFacesMessage().setSeverity(severity);

+        }

+    }

+}

diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/mapper/AbstractCustomNameMapper.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/mapper/AbstractCustomNameMapper.java
new file mode 100644
index 0000000..47d3865
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/mapper/AbstractCustomNameMapper.java
@@ -0,0 +1,65 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.core.mapper;

+

+import org.apache.myfaces.extensions.validator.util.ClassUtils;

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+import org.apache.commons.logging.Log;

+import org.apache.commons.logging.LogFactory;

+

+/**

+ * A generic implementation. Subclasses just have to now the fully qualified name of the name mapper.

+ *

+ * NameMappers are stateless.

+ *

+ * @author Gerhard Petracek

+ * @since 1.x.1

+ */

+@UsageInformation(UsageCategory.REUSE)

+public abstract class AbstractCustomNameMapper<T> implements NameMapper<T>

+{

+    protected final Log logger = LogFactory.getLog(getClass());

+    private NameMapper<T> customNameMapper;

+

+    protected AbstractCustomNameMapper()

+    {

+        if(logger.isDebugEnabled())

+        {

+            logger.debug(getClass().getName() + " instantiated");

+        }

+    }

+

+    public String createName(T source)

+    {

+        if (customNameMapper == null)

+        {

+            String className = getCustomNameMapperClassName();

+

+            if (className != null)

+            {

+                customNameMapper = (NameMapper<T>) ClassUtils.tryToInstantiateClassForName(className);

+            }

+        }

+

+        return (customNameMapper != null) ? customNameMapper.createName(source) : null;

+    }

+

+    protected abstract String getCustomNameMapperClassName();

+}
\ No newline at end of file
diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/mapper/NameMapper.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/mapper/NameMapper.java
new file mode 100644
index 0000000..d831cb6
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/mapper/NameMapper.java
@@ -0,0 +1,38 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.core.mapper;

+

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.core.InvocationOrderSupport;

+

+/**

+ * Interface for name mappers.

+ * A name mapper calculates a name for a given source object.

+ * e.g. Meta-Data Key (e.g.: annotation class name) -> ValidationStrategy

+ *

+ * @author Gerhard Petracek

+ * @since 1.x.1

+ */

+@InvocationOrderSupport

+@UsageInformation(UsageCategory.API)

+public interface NameMapper<T>

+{

+    String createName(T source);

+}
\ No newline at end of file
diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/mapper/SubMapperAwareNameMapper.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/mapper/SubMapperAwareNameMapper.java
new file mode 100644
index 0000000..7e6ddd2
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/mapper/SubMapperAwareNameMapper.java
@@ -0,0 +1,34 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.core.mapper;

+

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+

+/**

+ * interface for name-mappers which have to delegate to other (sub-)name-mappers

+ *

+ * @author Gerhard Petracek

+ * @since x.x.3

+ */

+@UsageInformation(UsageCategory.API)

+public interface SubMapperAwareNameMapper<T> extends NameMapper<T>

+{

+    void addNameMapper(NameMapper<T> nameMapper);

+}
\ No newline at end of file
diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/metadata/CommonMetaDataKeys.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/metadata/CommonMetaDataKeys.java
new file mode 100644
index 0000000..f1ae637
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/metadata/CommonMetaDataKeys.java
@@ -0,0 +1,60 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.core.metadata;

+

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+

+/**

+ * helper for frequent meta-data keys

+ *

+ * @author Gerhard Petracek

+ * @since 1.x.1

+ */

+/*

+ * placed in core to avoid duplicated information in multiple modules (validation module and component-support module)

+ */

+@UsageInformation(UsageCategory.INTERNAL)

+public interface CommonMetaDataKeys

+{

+    static final String REQUIRED = "required";

+    static final String WEAK_REQUIRED = "weak_required";

+

+    static final String MIN_LENGTH = "min_length";

+    static final String MIN_LENGTH_DEFAULT = "min_length_default";

+

+    static final String MAX_LENGTH = "max_length";

+    static final String MAX_LENGTH_DEFAULT = "max_length_default";

+

+    static final String RANGE_MIN = "range_min";

+    static final String RANGE_MIN_DEFAULT = "range_min_default";

+

+    static final String RANGE_MAX = "range_max";

+    static final String RANGE_MAX_DEFAULT = "range_max_default";

+

+    static final String PATTERN = "pattern";

+    static final String PATTERN_VALIDATION_ERROR_MESSAGE = "pattern_validation_error_message";

+    static final String EMAIL = "email";

+

+    static final String CUSTOM = "custom";

+    static final String SKIP_VALIDATION = "skip_validation";

+    static final String DISABLE_CLIENT_SIDE_VALIDATION = "disable_client_side_validation";

+    //available for add-ons not used internally due to performance reasons

+    static final String DISABLE_SHOW_INDICATION = "disable_show_indication";

+}

diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/metadata/MetaDataEntry.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/metadata/MetaDataEntry.java
new file mode 100644
index 0000000..1e54582
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/metadata/MetaDataEntry.java
@@ -0,0 +1,103 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.myfaces.extensions.validator.core.metadata;
+
+import org.apache.myfaces.extensions.validator.internal.UsageCategory;
+import org.apache.myfaces.extensions.validator.internal.UsageInformation;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import java.util.Map;
+import java.util.HashMap;
+
+/**
+ * Data holder which stores the meta-data and some information where the meta-data was around.
+ *
+ * @author Gerhard Petracek
+ * @since 1.x.1
+ */
+@UsageInformation(UsageCategory.API)
+public class MetaDataEntry
+{
+    protected final Log logger = LogFactory.getLog(getClass());
+
+    private String key;
+    private Object value;
+    private Map<String, Object> properties = new HashMap<String, Object>();
+
+    public String getKey()
+    {
+        return key;
+    }
+
+    public void setKey(String key)
+    {
+        if(this.logger.isTraceEnabled())
+        {
+            this.logger.trace("setting meta-data key: " + key);
+        }
+
+        this.key = key;
+    }
+
+    public Object getValue()
+    {
+        return value;
+    }
+
+    public <T> T getValue(Class<T> targetClass)
+    {
+        return (T)getValue();
+    }
+
+    public void setValue(Object value)
+    {
+        if(this.logger.isTraceEnabled())
+        {
+            this.logger.trace("setting meta-data value: " + value);
+        }
+
+        this.value = value;
+    }
+
+    public void setProperties(Map<String, Object> properties)
+    {
+        this.properties = properties;
+    }
+
+    public Object getProperty(String key)
+    {
+        return this.properties.get(key);
+    }
+
+    public <T> T getProperty(String key, Class<T> targetClass)
+    {
+        return (T)getProperty(key);
+    }
+
+    public void setProperty(String key, Object value)
+    {
+        if(this.logger.isTraceEnabled())
+        {
+            this.logger.trace("new property added key: " + key + " value: " + value + " for metadata-key: " + this.key);
+        }
+
+        this.properties.put(key, value);
+    }
+}
diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/metadata/extractor/ComponentMetaDataExtractorFactory.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/metadata/extractor/ComponentMetaDataExtractorFactory.java
new file mode 100644
index 0000000..f1dc26d
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/metadata/extractor/ComponentMetaDataExtractorFactory.java
@@ -0,0 +1,38 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.myfaces.extensions.validator.core.metadata.extractor;
+
+import org.apache.myfaces.extensions.validator.internal.UsageCategory;
+import org.apache.myfaces.extensions.validator.internal.UsageInformation;
+
+import java.util.Map;
+
+/**
+ * The interface for all factories which create meta-data extractors
+ * 
+ * @author Gerhard Petracek
+ * @since 1.x.1
+ */
+@UsageInformation(UsageCategory.API)
+public interface ComponentMetaDataExtractorFactory
+{
+    MetaDataExtractor create();
+
+    MetaDataExtractor createWith(Map<String, Object> properties);
+}
diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/metadata/extractor/DefaultComponentMetaDataExtractor.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/metadata/extractor/DefaultComponentMetaDataExtractor.java
new file mode 100644
index 0000000..452876a
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/metadata/extractor/DefaultComponentMetaDataExtractor.java
@@ -0,0 +1,379 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.myfaces.extensions.validator.core.metadata.extractor;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.myfaces.extensions.validator.core.ExtValContext;
+import org.apache.myfaces.extensions.validator.core.metadata.MetaDataEntry;
+import org.apache.myfaces.extensions.validator.core.property.DefaultPropertyInformation;
+import org.apache.myfaces.extensions.validator.core.property.PropertyDetails;
+import org.apache.myfaces.extensions.validator.core.property.PropertyInformation;
+import org.apache.myfaces.extensions.validator.core.property.PropertyInformationKeys;
+import org.apache.myfaces.extensions.validator.core.storage.MetaDataStorage;
+import org.apache.myfaces.extensions.validator.core.storage.PropertyStorage;
+import org.apache.myfaces.extensions.validator.internal.Priority;
+import org.apache.myfaces.extensions.validator.internal.ToDo;
+import org.apache.myfaces.extensions.validator.internal.UsageCategory;
+import org.apache.myfaces.extensions.validator.internal.UsageInformation;
+import org.apache.myfaces.extensions.validator.util.ExtValUtils;
+import org.apache.myfaces.extensions.validator.util.ProxyUtils;
+
+import javax.faces.component.UIComponent;
+import javax.faces.context.FacesContext;
+import java.beans.BeanInfo;
+import java.beans.IntrospectionException;
+import java.beans.Introspector;
+import java.beans.PropertyDescriptor;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * Default implementation which extracts meta-data (e.g. the annotations) of the value binding of a component.
+ * It extracts the meta-data of the field and the property.
+ * (Also the annotations of super classes and interfaces.)
+ *
+ * @author Gerhard Petracek
+ * @since 1.x.1
+ */
+@UsageInformation(UsageCategory.INTERNAL)
+public class DefaultComponentMetaDataExtractor implements MetaDataExtractor
+{
+    protected final Log logger = LogFactory.getLog(getClass());
+
+    public DefaultComponentMetaDataExtractor()
+    {
+        if (logger.isDebugEnabled())
+        {
+            logger.debug(getClass().getName() + " instantiated");
+        }
+    }
+
+    @ToDo(Priority.MEDIUM)
+    public PropertyInformation extract(FacesContext facesContext, Object object)
+    {
+        PropertyInformation propertyInformation = new DefaultPropertyInformation();
+
+        //should never occur
+        if (!(object instanceof UIComponent))
+        {
+            if (this.logger.isWarnEnabled() && object != null)
+            {
+                this.logger.warn(object.getClass() + " is no valid component");
+            }
+            return propertyInformation;
+        }
+
+        UIComponent uiComponent = (UIComponent) object;
+
+        if (logger.isTraceEnabled())
+        {
+            logger.trace("start extracting meta-data of " + uiComponent.getClass().getName());
+        }
+
+        PropertyDetails propertyDetails = ExtValUtils.getELHelper().getPropertyDetailsOfValueBinding(uiComponent);
+
+        if (propertyDetails == null)
+        {
+            return propertyInformation;
+        }
+
+        /*
+         * get bean class and property name
+         */
+        Class entityClass = ProxyUtils.getUnproxiedClass(propertyDetails.getBaseObject().getClass());
+
+        //create
+        propertyInformation.setInformation(PropertyInformationKeys.PROPERTY_DETAILS, propertyDetails);
+
+        if (isCached(entityClass, propertyDetails.getProperty()))
+        {
+            for (MetaDataEntry metaDataEntry : getCachedMetaData(entityClass, propertyDetails.getProperty()))
+            {
+                propertyInformation.addMetaDataEntry(metaDataEntry);
+            }
+        }
+        else
+        {
+            extractAnnotations(propertyInformation, propertyDetails, entityClass);
+            cacheMetaData(propertyInformation);
+        }
+
+        if (logger.isTraceEnabled())
+        {
+            logger.trace("extract finished");
+        }
+
+        return propertyInformation;
+    }
+
+    private boolean isCached(Class entityClass, String property)
+    {
+        return getMetaDataStorage().containsMetaDataFor(entityClass, property);
+    }
+
+    private void cacheMetaData(PropertyInformation propertyInformation)
+    {
+        getMetaDataStorage().storeMetaDataOf(propertyInformation);
+    }
+
+    private MetaDataEntry[] getCachedMetaData(Class entityClass, String property)
+    {
+        return getMetaDataStorage().getMetaData(entityClass, property);
+    }
+
+    private MetaDataStorage getMetaDataStorage()
+    {
+        return ExtValUtils.getStorage(MetaDataStorage.class, MetaDataStorage.class.getName());
+    }
+
+    private boolean isCachedField(Class entity, String property)
+    {
+        return getPropertyStorage().containsField(entity, property);
+    }
+
+    private void tryToCachedField(Class entity, String property, Field field)
+    {
+        PropertyStorage propertyStorage = getPropertyStorage();
+        if (!propertyStorage.containsField(entity, property))
+        {
+            propertyStorage.storeField(entity, property, field);
+        }
+    }
+
+    private Field getCachedField(Class entity, String property)
+    {
+        return getPropertyStorage().getField(entity, property);
+    }
+
+    private boolean isCachedMethod(Class entity, String property)
+    {
+        return getPropertyStorage().containsMethod(entity, property);
+    }
+
+    private void tryToCachedMethod(Class entity, String property, Method method)
+    {
+        PropertyStorage propertyStorage = getPropertyStorage();
+        if (!propertyStorage.containsMethod(entity, property))
+        {
+            propertyStorage.storeMethod(entity, property, method);
+        }
+    }
+
+    private Method getCachedMethod(Class entity, String property)
+    {
+        return getPropertyStorage().getMethod(entity, property);
+    }
+
+    private PropertyStorage getPropertyStorage()
+    {
+        return ExtValUtils.getStorage(PropertyStorage.class, PropertyStorage.class.getName());
+    }
+
+    protected void extractAnnotations(
+            PropertyInformation propertyInformation, PropertyDetails propertyDetails, Class entityClass)
+    {
+        while (!Object.class.getName().equals(entityClass.getName()))
+        {
+            addPropertyAccessAnnotations(entityClass, propertyDetails.getProperty(), propertyInformation);
+            addFieldAccessAnnotations(entityClass, propertyDetails.getProperty(), propertyInformation);
+
+            processInterfaces(entityClass, propertyDetails, propertyInformation);
+
+            entityClass = entityClass.getSuperclass();
+        }
+    }
+
+    private void processInterfaces(
+            Class currentClass, PropertyDetails propertyDetails, PropertyInformation propertyInformation)
+    {
+        for (Class currentInterface : currentClass.getInterfaces())
+        {
+            addPropertyAccessAnnotations(currentInterface, propertyDetails.getProperty(), propertyInformation);
+
+            processInterfaces(currentInterface, propertyDetails, propertyInformation);
+        }
+    }
+
+    protected void addPropertyAccessAnnotations(Class entity, String property,
+                                                PropertyInformation propertyInformation)
+    {
+        Method method = tryToGetReadMethod(entity, property);
+
+        if (method == null)
+        {
+            method = tryToGetReadMethodManually(entity, property);
+        }
+
+        if (method != null)
+        {
+            tryToCachedMethod(entity, property, method);
+            addAnnotationToAnnotationEntries(Arrays.asList(method.getAnnotations()), propertyInformation);
+        }
+    }
+
+    private Method tryToGetReadMethod(Class entity, String property)
+    {
+        if (isCachedMethod(entity, property))
+        {
+            return getCachedMethod(entity, property);
+        }
+
+        if (useBeanInfo())
+        {
+            try
+            {
+                BeanInfo beanInfo = Introspector.getBeanInfo(entity);
+                for (PropertyDescriptor propertyDescriptor : beanInfo.getPropertyDescriptors())
+                {
+                    if (property.equals(propertyDescriptor.getName()) && propertyDescriptor.getReadMethod() != null)
+                    {
+                        return propertyDescriptor.getReadMethod();
+                    }
+                }
+            }
+            catch (IntrospectionException e)
+            {
+                //do nothing
+            }
+        }
+        return null;
+    }
+
+    private boolean useBeanInfo()
+    {
+        return Boolean.TRUE.equals(ExtValContext.getContext().getGlobalProperty(BeanInfo.class.getName()));
+    }
+
+    private Method tryToGetReadMethodManually(Class entity, String property)
+    {
+        property = property.substring(0, 1).toUpperCase() + property.substring(1);
+
+        try
+        {
+            //changed to official bean spec. due to caching there is no performance issue any more
+            return entity.getDeclaredMethod("is" + property);
+        }
+        catch (NoSuchMethodException e)
+        {
+            try
+            {
+                return entity.getDeclaredMethod("get" + property);
+            }
+            catch (NoSuchMethodException e1)
+            {
+                if (logger.isTraceEnabled())
+                {
+                    logger.trace("method not found - class: " + entity.getName()
+                            + " - methods: " + "get" + property + " " + "is" + property);
+                }
+
+                return null;
+            }
+        }
+    }
+
+    protected void addFieldAccessAnnotations(Class entity, String property,
+                                             PropertyInformation propertyInformation)
+    {
+        Field field;
+
+        try
+        {
+            field = getDeclaredField(entity, property);
+        }
+        catch (Exception e)
+        {
+            try
+            {
+                try
+                {
+                    field = entity.getDeclaredField("_" + property);
+                }
+                catch (Exception e1)
+                {
+                    if (property.length() > 1 &&
+                            Character.isUpperCase(property.charAt(0)) &&
+                            Character.isUpperCase(property.charAt(1)))
+                    {
+                        //don't use Introspector#decapitalize here
+                        field = entity.getDeclaredField(property.substring(0, 1).toLowerCase() + property.substring(1));
+                    }
+                    else
+                    {
+                        field = entity.getDeclaredField(Introspector.decapitalize(property));
+                    }
+                }
+            }
+            catch (NoSuchFieldException e1)
+            {
+                if (logger.isTraceEnabled())
+                {
+                    logger.trace("field " + property + " or _" + property + " not found", e1);
+                }
+
+                return;
+            }
+        }
+
+        if (field != null)
+        {
+            tryToCachedField(entity, property, field);
+            addAnnotationToAnnotationEntries(Arrays.asList(field.getAnnotations()), propertyInformation);
+        }
+    }
+
+    @ToDo(value = Priority.HIGH, description = "add support for instances wrapped with cglib")
+    private Field getDeclaredField(Class entity, String property) throws NoSuchFieldException
+    {
+        if (isCachedField(entity, property))
+        {
+            return getCachedField(entity, property);
+        }
+
+        return entity.getDeclaredField(property);
+    }
+
+    protected void addAnnotationToAnnotationEntries(
+            List<Annotation> annotations, PropertyInformation propertyInformation)
+    {
+        for (Annotation annotation : annotations)
+        {
+            propertyInformation.addMetaDataEntry(createMetaDataEntryForAnnotation(annotation));
+
+            if (logger.isTraceEnabled())
+            {
+                logger.trace(annotation.getClass().getName() + " found");
+            }
+        }
+    }
+
+    protected MetaDataEntry createMetaDataEntryForAnnotation(Annotation foundAnnotation)
+    {
+        MetaDataEntry entry = new MetaDataEntry();
+
+        entry.setKey(foundAnnotation.annotationType().getName());
+        entry.setValue(foundAnnotation);
+
+        return entry;
+    }
+}
diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/metadata/extractor/DefaultComponentMetaDataExtractorFactory.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/metadata/extractor/DefaultComponentMetaDataExtractorFactory.java
new file mode 100644
index 0000000..8f7645b
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/metadata/extractor/DefaultComponentMetaDataExtractorFactory.java
@@ -0,0 +1,102 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.myfaces.extensions.validator.core.metadata.extractor;
+
+import org.apache.myfaces.extensions.validator.core.WebXmlParameter;
+import org.apache.myfaces.extensions.validator.core.ExtValContext;
+import org.apache.myfaces.extensions.validator.core.CustomInformation;
+import org.apache.myfaces.extensions.validator.util.ClassUtils;
+import org.apache.myfaces.extensions.validator.util.ExtValUtils;
+import org.apache.myfaces.extensions.validator.internal.ToDo;
+import org.apache.myfaces.extensions.validator.internal.Priority;
+import org.apache.myfaces.extensions.validator.internal.UsageInformation;
+import org.apache.myfaces.extensions.validator.internal.UsageCategory;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * This factory creates a meta-data extractor which extracts the meta-data
+ * of the value binding of a component.
+ * <p/>
+ * order:<br/>
+ * <ol>
+ *   <li>configured meta-data extractor (web.xml)</li>
+ *   <li>configured meta-data extractor (information provider bean)</li>
+ *   <li>default implementation</li>
+ * </ol>
+ *
+ * @author Gerhard Petracek
+ * @since 1.x.1
+ */
+@UsageInformation(UsageCategory.INTERNAL)
+public class DefaultComponentMetaDataExtractorFactory implements ComponentMetaDataExtractorFactory
+{
+    private final Log logger = LogFactory.getLog(getClass());
+
+    private static MetaDataExtractor metaDataExtractor = null;
+
+    public DefaultComponentMetaDataExtractorFactory()
+    {
+        if(logger.isDebugEnabled())
+        {
+            logger.debug(getClass().getName() + " instantiated");
+        }
+    }
+
+    @ToDo(value = Priority.MEDIUM, description = "logging")
+    public MetaDataExtractor create()
+    {
+        return createWith(null);
+    }
+
+    public MetaDataExtractor createWith(Map<String, Object> properties)
+    {
+        if (metaDataExtractor == null)
+        {
+            List<String> metaDataExtractorClassNames = new ArrayList<String>();
+
+            metaDataExtractorClassNames.add(WebXmlParameter.CUSTOM_COMPONENT_META_DATA_EXTRACTOR);
+            metaDataExtractorClassNames
+                .add(ExtValContext.getContext().getInformationProviderBean()
+                    .get(CustomInformation.COMPONENT_META_DATA_EXTRACTOR));
+            metaDataExtractorClassNames.add(DefaultComponentMetaDataExtractor.class.getName());
+
+            for (String className : metaDataExtractorClassNames)
+            {
+                metaDataExtractor = (MetaDataExtractor) ClassUtils.tryToInstantiateClassForName(className);
+
+                if (metaDataExtractor != null)
+                {
+                    break;
+                }
+            }
+        }
+
+        if(logger.isTraceEnabled())
+        {
+            logger.trace(metaDataExtractor.getClass().getName() + " created");
+        }
+
+        return ExtValUtils.createInterceptedMetaDataExtractorWith(metaDataExtractor, properties);
+    }
+}
diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/metadata/extractor/MetaDataExtractor.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/metadata/extractor/MetaDataExtractor.java
new file mode 100644
index 0000000..fd4051d
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/metadata/extractor/MetaDataExtractor.java
@@ -0,0 +1,38 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.myfaces.extensions.validator.core.metadata.extractor;
+
+import org.apache.myfaces.extensions.validator.core.property.PropertyInformation;
+import org.apache.myfaces.extensions.validator.internal.UsageCategory;
+import org.apache.myfaces.extensions.validator.internal.UsageInformation;
+
+import javax.faces.context.FacesContext;
+
+/**
+ * An meta-data extractor is responsible to analyze an object
+ * and returns all available meta-data information
+ * 
+ * @author Gerhard Petracek
+ * @since 1.x.1
+ */
+@UsageInformation(UsageCategory.API)
+public interface MetaDataExtractor
+{
+    PropertyInformation extract(FacesContext facesContext, Object object);
+}
diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/metadata/transformer/BeanMetaDataTransformerAdapter.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/metadata/transformer/BeanMetaDataTransformerAdapter.java
new file mode 100644
index 0000000..569912a
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/metadata/transformer/BeanMetaDataTransformerAdapter.java
@@ -0,0 +1,40 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.core.metadata.transformer;

+

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+

+/**

+ * it's just a helper for proxies - you just need it, if you define the equivalent validation strategy as bean and

+ * e.g. spring creates a proxy for it.

+ *

+ * if there is also a proxy for the extractor you can use the className property to manually repeat the

+ * full qualified class name.

+ *

+ * @see org.apache.myfaces.extensions.validator.core.validation.strategy.BeanValidationStrategyAdapter

+ *

+ * @author Gerhard Petracek

+ * @since 1.x.1

+ */

+@UsageInformation({UsageCategory.REUSE})

+public interface BeanMetaDataTransformerAdapter extends MetaDataTransformer

+{

+    String getMetaDataTransformerClassName();

+}
\ No newline at end of file
diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/metadata/transformer/BeanMetaDataTransformerAdapterImpl.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/metadata/transformer/BeanMetaDataTransformerAdapterImpl.java
new file mode 100644
index 0000000..10ea819
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/metadata/transformer/BeanMetaDataTransformerAdapterImpl.java
@@ -0,0 +1,85 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.core.metadata.transformer;

+

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.core.metadata.MetaDataEntry;

+import org.apache.commons.logging.Log;

+import org.apache.commons.logging.LogFactory;

+

+import java.util.Map;

+

+/**

+ * it's just a helper for proxies - you just need it, if you define the equivalent validation strategy as bean and

+ * e.g. spring creates a proxy for it.

+ *

+ * if there is also a proxy for the transformer you can use the className property to manually repeat the

+ * full qualified class name.

+ *

+ * @see org.apache.myfaces.extensions.validator.core.validation.strategy.BeanValidationStrategyAdapter

+ *

+ * @author Gerhard Petracek

+ * @since 1.x.1

+ */

+@UsageInformation({UsageCategory.REUSE})

+public class BeanMetaDataTransformerAdapterImpl implements MetaDataTransformer, BeanMetaDataTransformerAdapter

+{

+    protected final Log logger = LogFactory.getLog(getClass());

+

+    private MetaDataTransformer metaDataTransformer;

+    private String metaDataTransformerClassName;

+

+    public Map<String, Object> convertMetaData(MetaDataEntry metaDataEntry)

+    {

+        return this.metaDataTransformer.convertMetaData(metaDataEntry);

+    }

+

+    public String getMetaDataTransformerClassName()

+    {

+        if(metaDataTransformerClassName != null)

+        {

+            return metaDataTransformerClassName;

+        }

+        if(metaDataTransformer.getClass().getPackage() != null)

+        {

+            metaDataTransformer.getClass();

+        }

+

+        return null;

+    }

+

+    /*

+     * generated

+     */

+    public void setMetaDataTransformerClassName(String metaDataTransformerClassName)

+    {

+        this.metaDataTransformerClassName = metaDataTransformerClassName;

+    }

+

+    public MetaDataTransformer getMetaDataTransformer()

+    {

+        return metaDataTransformer;

+    }

+

+    public void setMetaDataTransformer(MetaDataTransformer metaDataTransformer)

+    {

+        this.metaDataTransformer = metaDataTransformer;

+    }

+}

diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/metadata/transformer/DefaultMetaDataTransformerFactory.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/metadata/transformer/DefaultMetaDataTransformerFactory.java
new file mode 100644
index 0000000..32c3aee
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/metadata/transformer/DefaultMetaDataTransformerFactory.java
@@ -0,0 +1,266 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.core.metadata.transformer;

+

+import org.apache.myfaces.extensions.validator.core.factory.ClassMappingFactory;

+import org.apache.myfaces.extensions.validator.core.factory.AbstractNameMapperAwareFactory;

+import org.apache.myfaces.extensions.validator.core.validation.strategy.ValidationStrategy;

+import org.apache.myfaces.extensions.validator.core.validation.strategy.BeanValidationStrategyAdapter;

+import org.apache.myfaces.extensions.validator.core.validation.strategy.IdentifiableValidationStrategy;

+import org.apache.myfaces.extensions.validator.core.mapper.NameMapper;

+import org.apache.myfaces.extensions.validator.core.mapper.SubMapperAwareNameMapper;

+import org.apache.myfaces.extensions.validator.core.Nested;

+import org.apache.myfaces.extensions.validator.core.initializer.configuration.StaticConfiguration;

+import org.apache.myfaces.extensions.validator.core.initializer.configuration.StaticConfigurationNames;

+import org.apache.myfaces.extensions.validator.core.initializer.configuration.StaticConfigurationEntry;

+import org.apache.myfaces.extensions.validator.core.ExtValContext;

+import org.apache.myfaces.extensions.validator.core.metadata.transformer.mapper.

+        ValidationStrategyToMetaDataTransformerSubMapperAwareNameMapper;

+import org.apache.myfaces.extensions.validator.util.ClassUtils;

+import org.apache.myfaces.extensions.validator.util.ProxyUtils;

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+import org.apache.commons.logging.Log;

+import org.apache.commons.logging.LogFactory;

+

+import java.util.ArrayList;

+import java.util.HashMap;

+import java.util.List;

+import java.util.Map;

+

+

+/**

+ * Factory which creates the MetaDataTransformer for a given ValidationStrategy

+ *

+ * @author Gerhard Petracek

+ * @since 1.x.1

+ */

+/*

+ * ValidationStrategy -> MetaDataTransformer instead of Meta-Data -> MetaDataTransformer

+ * to avoid a second static mapping e.g. for jpa annotations

+ */

+@UsageInformation({UsageCategory.INTERNAL, UsageCategory.CUSTOMIZABLE})

+public class DefaultMetaDataTransformerFactory extends AbstractNameMapperAwareFactory<ValidationStrategy>

+        implements ClassMappingFactory<ValidationStrategy, MetaDataTransformer>

+{

+    protected final Log logger = LogFactory.getLog(getClass());

+

+    private Map<String, String> validationStrategyToMetaDataTransformerMapping;

+    private List<NameMapper<ValidationStrategy>> nameMapperList = new ArrayList<NameMapper<ValidationStrategy>>();

+    private List<NameMapper<ValidationStrategy>> subNameMapperList =

+            new ArrayList<NameMapper<ValidationStrategy>>();

+

+    public DefaultMetaDataTransformerFactory()

+    {

+        if(logger.isDebugEnabled())

+        {

+            logger.debug(getClass().getName() + " instantiated");

+        }

+

+        //since there is no guarantee that the startup listener of the core gets executed first

+        register(new ValidationStrategyToMetaDataTransformerSubMapperAwareNameMapper());

+    }

+

+    public MetaDataTransformer create(ValidationStrategy validationStrategy)

+    {

+        String validationStrategyName = createValidationStrategyName(validationStrategy);

+

+        tryToInitStaticMappings();

+

+        MetaDataTransformer metaDataTransformer =

+                tryToResolveCachedMetaDataTransformer(validationStrategy, validationStrategyName);

+

+        if(metaDataTransformer != null)

+        {

+            return metaDataTransformer;

+        }

+

+        return createAndCacheMetaDataTransformer(validationStrategy, validationStrategyName);

+    }

+

+    private String createValidationStrategyName(ValidationStrategy validationStrategy)

+    {

+        boolean isProxyDetected = isProxy(validationStrategy);

+        //in case of a proxy and the usage of a BeanValidationStrategyAdapter

+        if (isProxyDetected && validationStrategy instanceof BeanValidationStrategyAdapter)

+        {

+            return ((BeanValidationStrategyAdapter)validationStrategy)

+                                        .getValidationStrategyClassName();

+        }

+

+        return !isProxyDetected ? ProxyUtils.getClassName(validationStrategy.getClass()) : null;

+    }

+

+    private void tryToInitStaticMappings()

+    {

+        if (validationStrategyToMetaDataTransformerMapping == null)

+        {

+            initStaticMappings();

+        }

+    }

+

+    private boolean isProxy(ValidationStrategy validationStrategy)

+    {

+        return validationStrategy.getClass().getPackage() == null;

+    }

+

+    private MetaDataTransformer createAndCacheMetaDataTransformer(

+            ValidationStrategy validationStrategy, String validationStrategyName)

+    {

+        MetaDataTransformer metaDataTransformer;

+        String transformerName;

+        //null -> use name mappers

+        for (NameMapper<ValidationStrategy> nameMapper : nameMapperList)

+        {

+            transformerName = nameMapper.createName(validationStrategy);

+

+            if (transformerName == null)

+            {

+                continue;

+            }

+

+            metaDataTransformer = tryToCreateAndCacheMetaDataTransformer(

+                    validationStrategy, validationStrategyName, transformerName);

+

+            if(metaDataTransformer != null)

+            {

+                return metaDataTransformer;

+            }

+        }

+

+        return null;

+    }

+

+    private MetaDataTransformer tryToResolveCachedMetaDataTransformer(

+            ValidationStrategy validationStrategy, String validationStrategyName)

+    {

+        if (validationStrategyToMetaDataTransformerMapping.containsKey(validationStrategyName))

+        {

+            return (MetaDataTransformer)ClassUtils.tryToInstantiateClassForName(

+                validationStrategyToMetaDataTransformerMapping.get(validationStrategyName));

+        }

+

+        if(validationStrategy instanceof IdentifiableValidationStrategy)

+        {

+            String newValidationStrategyName = validationStrategyName + IdentifiableValidationStrategy.ID_PREFIX +

+                    ((IdentifiableValidationStrategy)validationStrategy).getId();

+

+            if (validationStrategyToMetaDataTransformerMapping.containsKey(newValidationStrategyName))

+            {

+                return (MetaDataTransformer)ClassUtils.tryToInstantiateClassForName(

+                    validationStrategyToMetaDataTransformerMapping.get(newValidationStrategyName));

+            }

+        }

+

+        return null;

+    }

+

+    private MetaDataTransformer tryToCreateAndCacheMetaDataTransformer(

+            ValidationStrategy validationStrategy, String validationStrategyName, String transformerName)

+    {

+        MetaDataTransformer metaDataTransformer = (MetaDataTransformer)

+                ClassUtils.tryToInstantiateClassForName(transformerName);

+

+        if (metaDataTransformer != null)

+        {

+            if(validationStrategyName != null)

+            {

+                if(validationStrategy instanceof IdentifiableValidationStrategy)

+                {

+                    validationStrategyName += IdentifiableValidationStrategy.ID_PREFIX +

+                            ((IdentifiableValidationStrategy)validationStrategy).getId();

+                }

+                addMapping(validationStrategyName, transformerName);

+            }

+            return metaDataTransformer;

+        }

+

+        return null;

+    }

+

+    private synchronized void initStaticMappings()

+    {

+        validationStrategyToMetaDataTransformerMapping = new HashMap<String, String>();

+

+        //setup internal static mappings

+        for (StaticConfiguration<String, String> staticConfig :

+            ExtValContext.getContext().getStaticConfiguration(

+                StaticConfigurationNames.VALIDATION_STRATEGY_TO_META_DATA_TRANSFORMER_CONFIG))

+        {

+            setupMappings(staticConfig.getMapping());

+        }

+    }

+

+    private void setupMappings(List<StaticConfigurationEntry<String, String>> mappings)

+    {

+        for(StaticConfigurationEntry<String, String> mapping : mappings)

+        {

+            addMapping(mapping.getSource(), mapping.getTarget());

+        }

+    }

+

+    private synchronized void addMapping(String validationStrategyName, String transformerName)

+    {

+        if(logger.isTraceEnabled())

+        {

+            logger.trace("adding validation strategy to meta-data transformer mapping: "

+                + validationStrategyName + " -> " + transformerName);

+        }

+

+        validationStrategyToMetaDataTransformerMapping.put(validationStrategyName, transformerName);

+    }

+

+    protected List<NameMapper<ValidationStrategy>> getNameMapperList()

+    {

+        return new SortedNameMapperList<NameMapper<ValidationStrategy>>(this.nameMapperList, this.subNameMapperList);

+    }

+

+    @Override

+    public void register(NameMapper<ValidationStrategy> validationStrategyNameMapper)

+    {

+        tryToInitNameMapperWithExistingSubMappers(validationStrategyNameMapper);

+        super.register(validationStrategyNameMapper);

+    }

+

+    /**

+     * it's a very special case due to the missing order in the execution of startup-listeners (phase listeners)

+     * packaged in faces-config.xml files of jars

+     *

+     * normally the default SubMapperAwareNameMapper should be enough

+     * anyway, if a module adds a new SubMapperAwareNameMapper,

+     * all previous added SubNameMappers have to be added to avoid confusion in special cases.

+     * if a SubMapperAwareNameMapper should be considered as final extend the interface and filter it in addNameMapper

+     * 

+     * @param validationStrategyNameMapper which has to be added

+     */

+    private void tryToInitNameMapperWithExistingSubMappers(NameMapper<ValidationStrategy> validationStrategyNameMapper)

+    {

+        if(validationStrategyNameMapper instanceof SubMapperAwareNameMapper)

+        {

+            for(NameMapper<ValidationStrategy> nameMapper : this.subNameMapperList)

+            {

+                if(nameMapper.getClass().isAnnotationPresent(Nested.class))

+                {

+                    ((SubMapperAwareNameMapper<ValidationStrategy>)validationStrategyNameMapper)

+                            .addNameMapper(nameMapper);

+                }

+            }

+        }

+    }

+}

diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/metadata/transformer/MetaDataTransformer.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/metadata/transformer/MetaDataTransformer.java
new file mode 100644
index 0000000..9e504b2
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/metadata/transformer/MetaDataTransformer.java
@@ -0,0 +1,39 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.core.metadata.transformer;

+

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+import org.apache.myfaces.extensions.validator.core.metadata.MetaDataEntry;

+

+import java.util.Map;

+

+/**

+ * Allows to transform concrete meta-data to a more abstract form.<br/>

+ * e.g.: @Required, @Column(nullable = false,...), @Length(minimum = 1), ... -> required = true

+ * 

+ * @author Gerhard Petracek

+ * @since 1.x.1

+ */

+@UsageInformation(UsageCategory.API)

+//*Transformer instead of *Converter to avoid naming confusion 

+public interface MetaDataTransformer

+{

+    Map<String, Object> convertMetaData(MetaDataEntry metaData);

+}

diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/metadata/transformer/SortedNameMapperList.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/metadata/transformer/SortedNameMapperList.java
new file mode 100644
index 0000000..3bcbb48
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/metadata/transformer/SortedNameMapperList.java
@@ -0,0 +1,214 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.core.metadata.transformer;

+

+import org.apache.myfaces.extensions.validator.core.mapper.NameMapper;

+import org.apache.myfaces.extensions.validator.core.mapper.SubMapperAwareNameMapper;

+import org.apache.myfaces.extensions.validator.core.Nested;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+

+import java.util.List;

+import java.util.Collections;

+import java.util.Collection;

+import java.util.Comparator;

+import java.util.Iterator;

+import java.util.ListIterator;

+

+

+/**

+ * @author Gerhard Petracek

+ * @since x.x.3

+ */

+@UsageInformation({UsageCategory.INTERNAL})

+class SortedNameMapperList<T extends NameMapper> implements List<T>

+{

+    private List<T> wrapped;

+    private List<T> globalSubNameMapperList;

+

+    SortedNameMapperList(List<T> wrapped, List<T> subNameMapperList)

+    {

+        this.wrapped = wrapped;

+        this.globalSubNameMapperList = subNameMapperList;

+    }

+

+    public boolean add(T t)

+    {

+        if (t != null && t.getClass().isAnnotationPresent(Nested.class))

+        {

+            return addSubNameMapper(t);

+        }

+        else

+        {

+            boolean result = wrapped.add(t);

+

+            Collections.sort(wrapped, new Comparator<T>()

+            {

+                public int compare(T nm1, T nm2)

+                {

+                    if (nm1 instanceof SubMapperAwareNameMapper && nm2 instanceof SubMapperAwareNameMapper)

+                    {

+                        return 0;

+                    }

+                    return nm1 instanceof SubMapperAwareNameMapper ? 1 : -1;

+                }

+            });

+            return result;

+        }

+    }

+

+    @SuppressWarnings({"unchecked"})

+    private boolean addSubNameMapper(T subNameMapper)

+    {

+        boolean result = false;

+        for (NameMapper nameMapper : this.wrapped)

+        {

+            if (nameMapper instanceof SubMapperAwareNameMapper)

+            {

+                ((SubMapperAwareNameMapper) nameMapper).addNameMapper(subNameMapper);

+                result = true;

+            }

+        }

+

+        tryToAddMapperAsGlobalSubNameMapper(subNameMapper);

+        return result;

+    }

+

+    private void tryToAddMapperAsGlobalSubNameMapper(T subNameMapper)

+    {

+        if(!this.globalSubNameMapperList.contains(subNameMapper))

+        {

+            this.globalSubNameMapperList.add(subNameMapper);

+        }

+    }

+

+    /*

+     * generated

+     */

+    public int size()

+    {

+        return wrapped.size();

+    }

+

+    public boolean isEmpty()

+    {

+        return wrapped.isEmpty();

+    }

+

+    public boolean contains(Object o)

+    {

+        return wrapped.contains(o);

+    }

+

+    public Iterator<T> iterator()

+    {

+        return wrapped.iterator();

+    }

+

+    public Object[] toArray()

+    {

+        return wrapped.toArray();

+    }

+

+    @SuppressWarnings({"SuspiciousToArrayCall"})

+    public <T> T[] toArray(T[] a)

+    {

+        return wrapped.toArray(a);

+    }

+

+    public boolean remove(Object o)

+    {

+        return wrapped.remove(o);

+    }

+

+    public boolean containsAll(Collection<?> c)

+    {

+        return wrapped.containsAll(c);

+    }

+

+    public boolean addAll(Collection<? extends T> c)

+    {

+        return wrapped.addAll(c);

+    }

+

+    public boolean addAll(int index, Collection<? extends T> c)

+    {

+        return wrapped.addAll(index, c);

+    }

+

+    public boolean removeAll(Collection<?> c)

+    {

+        return wrapped.removeAll(c);

+    }

+

+    public boolean retainAll(Collection<?> c)

+    {

+        return wrapped.retainAll(c);

+    }

+

+    public void clear()

+    {

+        wrapped.clear();

+    }

+

+    public T get(int index)

+    {

+        return wrapped.get(index);

+    }

+

+    public T set(int index, T element)

+    {

+        return wrapped.set(index, element);

+    }

+

+    public void add(int index, T element)

+    {

+        wrapped.add(index, element);

+    }

+

+    public T remove(int index)

+    {

+        return wrapped.remove(index);

+    }

+

+    public int indexOf(Object o)

+    {

+        return wrapped.indexOf(o);

+    }

+

+    public int lastIndexOf(Object o)

+    {

+        return wrapped.lastIndexOf(o);

+    }

+

+    public ListIterator<T> listIterator()

+    {

+        return wrapped.listIterator();

+    }

+

+    public ListIterator<T> listIterator(int index)

+    {

+        return wrapped.listIterator(index);

+    }

+

+    public List<T> subList(int fromIndex, int toIndex)

+    {

+        return wrapped.subList(fromIndex, toIndex);

+    }

+}
\ No newline at end of file
diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/metadata/transformer/mapper/AbstractValidationStrategyToMetaDataTransformerNameMapper.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/metadata/transformer/mapper/AbstractValidationStrategyToMetaDataTransformerNameMapper.java
new file mode 100644
index 0000000..2dadc16
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/metadata/transformer/mapper/AbstractValidationStrategyToMetaDataTransformerNameMapper.java
@@ -0,0 +1,45 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.core.metadata.transformer.mapper;

+

+import org.apache.myfaces.extensions.validator.core.mapper.NameMapper;

+import org.apache.myfaces.extensions.validator.core.validation.strategy.ValidationStrategy;

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+import org.apache.commons.logging.Log;

+import org.apache.commons.logging.LogFactory;

+

+/**

+ * @author Gerhard Petracek

+ * @since 1.x.1

+ */

+@UsageInformation({UsageCategory.INTERNAL})

+public abstract class AbstractValidationStrategyToMetaDataTransformerNameMapper

+    implements NameMapper<ValidationStrategy>

+{

+    protected final Log logger = LogFactory.getLog(getClass());

+

+    public AbstractValidationStrategyToMetaDataTransformerNameMapper()

+    {

+        if(logger.isDebugEnabled())

+        {

+            logger.debug(getClass().getName() + " instantiated");

+        }

+    }

+}
\ No newline at end of file
diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/metadata/transformer/mapper/BeanValidationStrategyToMetaDataTransformerNameMapper.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/metadata/transformer/mapper/BeanValidationStrategyToMetaDataTransformerNameMapper.java
new file mode 100644
index 0000000..e8894d1
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/metadata/transformer/mapper/BeanValidationStrategyToMetaDataTransformerNameMapper.java
@@ -0,0 +1,46 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.core.metadata.transformer.mapper;

+

+import org.apache.myfaces.extensions.validator.core.validation.strategy.ValidationStrategy;

+import org.apache.myfaces.extensions.validator.core.validation.strategy.BeanValidationStrategyAdapter;

+import org.apache.myfaces.extensions.validator.core.InvocationOrder;

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+

+/**

+ * It's an alternative Mapper - if there is a proxy around the validation strategy.

+ *

+ * @author Gerhard Petracek

+ * @since 1.x.1

+ */

+@InvocationOrder(500)

+@UsageInformation({UsageCategory.INTERNAL})

+public class BeanValidationStrategyToMetaDataTransformerNameMapper extends

+    AbstractValidationStrategyToMetaDataTransformerNameMapper

+{

+    public String createName(ValidationStrategy validationStrategy)

+    {

+        if(validationStrategy instanceof BeanValidationStrategyAdapter)

+        {

+            return ((BeanValidationStrategyAdapter)validationStrategy).getMetaDataTransformerClassName();

+        }

+        return null;

+    }

+}
\ No newline at end of file
diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/metadata/transformer/mapper/CustomConfiguredValidationStrategyToMetaDataTransformerNameMapper.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/metadata/transformer/mapper/CustomConfiguredValidationStrategyToMetaDataTransformerNameMapper.java
new file mode 100644
index 0000000..e21aaf9
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/metadata/transformer/mapper/CustomConfiguredValidationStrategyToMetaDataTransformerNameMapper.java
@@ -0,0 +1,44 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.core.metadata.transformer.mapper;

+

+import org.apache.myfaces.extensions.validator.core.WebXmlParameter;

+import org.apache.myfaces.extensions.validator.core.InvocationOrder;

+import org.apache.myfaces.extensions.validator.core.validation.strategy.ValidationStrategy;

+import org.apache.myfaces.extensions.validator.core.mapper.AbstractCustomNameMapper;

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+

+/**

+ * To provide a custom NameMapper to map ValidationStrategies to MetaDataTransformers.

+ * (configured via web.xml)

+ *

+ * @author Gerhard Petracek

+ * @since 1.x.1

+ */

+@InvocationOrder(100)

+@UsageInformation({UsageCategory.INTERNAL, UsageCategory.CUSTOMIZABLE})

+public class CustomConfiguredValidationStrategyToMetaDataTransformerNameMapper extends

+    AbstractCustomNameMapper<ValidationStrategy>

+{

+    protected String getCustomNameMapperClassName()

+    {

+        return WebXmlParameter.CUSTOM_VALIDATION_STRATEGY_TO_META_DATA_TRANSFORMER_NAME_MAPPER;

+    }

+}
\ No newline at end of file
diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/metadata/transformer/mapper/CustomConventionValidationStrategyToMetaDataTransformerNameMapper.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/metadata/transformer/mapper/CustomConventionValidationStrategyToMetaDataTransformerNameMapper.java
new file mode 100644
index 0000000..cfd080f
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/metadata/transformer/mapper/CustomConventionValidationStrategyToMetaDataTransformerNameMapper.java
@@ -0,0 +1,48 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.core.metadata.transformer.mapper;

+

+import org.apache.myfaces.extensions.validator.core.mapper.AbstractCustomNameMapper;

+import org.apache.myfaces.extensions.validator.core.validation.strategy.ValidationStrategy;

+import org.apache.myfaces.extensions.validator.core.ExtValContext;

+import org.apache.myfaces.extensions.validator.core.CustomInformation;

+import org.apache.myfaces.extensions.validator.core.InvocationOrder;

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+

+/**

+ * To provide a custom NameMapper to map ValidationStrategies to MetaDataTransformers.

+ * (configured via information provider bean)

+ * The bean provides the default name (convention).

+ * It's possible to provide a custom full qualified name. (= customizable convention)

+ *

+ * @author Gerhard Petracek

+ * @since 1.x.1

+ */

+@InvocationOrder(200)

+@UsageInformation({UsageCategory.INTERNAL, UsageCategory.CUSTOMIZABLE})

+public class CustomConventionValidationStrategyToMetaDataTransformerNameMapper extends

+    AbstractCustomNameMapper<ValidationStrategy>

+{

+    protected String getCustomNameMapperClassName()

+    {

+        return ExtValContext.getContext().getInformationProviderBean()

+            .get(CustomInformation.VALIDATION_STRATEGY_TO_META_DATA_TRANSFORMER_NAME_MAPPER);

+    }

+}
\ No newline at end of file
diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/metadata/transformer/mapper/DefaultValidationStrategyToMetaDataTransformerNameMapper.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/metadata/transformer/mapper/DefaultValidationStrategyToMetaDataTransformerNameMapper.java
new file mode 100644
index 0000000..80e850d
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/metadata/transformer/mapper/DefaultValidationStrategyToMetaDataTransformerNameMapper.java
@@ -0,0 +1,53 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.core.metadata.transformer.mapper;

+

+import org.apache.myfaces.extensions.validator.core.validation.strategy.ValidationStrategy;

+import org.apache.myfaces.extensions.validator.core.InternalConventionProvider;

+import org.apache.myfaces.extensions.validator.core.InvocationOrder;

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+import org.apache.myfaces.extensions.validator.util.ProxyUtils;

+

+/**

+ * Default implementation which maps ExtVal ValidationStrategies to MetaDataTransformers.

+ *

+ * @author Gerhard Petracek

+ * @since 1.x.1

+ */

+@InvocationOrder(300)

+@UsageInformation(UsageCategory.INTERNAL)

+public class DefaultValidationStrategyToMetaDataTransformerNameMapper extends

+    AbstractValidationStrategyToMetaDataTransformerNameMapper

+{

+    public String createName(ValidationStrategy validationStrategy)

+    {

+        Class<? extends ValidationStrategy> validationStrategyClass =

+                ProxyUtils.getUnproxiedClass(validationStrategy.getClass(), ValidationStrategy.class);

+

+        return InternalConventionProvider.getMetaDataTransformerClassName(

+                validationStrategyClass,

+                getClassName(validationStrategyClass.getSimpleName()));

+    }

+

+    protected String getClassName(String validationStrategyClassName)

+    {

+        return InternalConventionProvider.getMetaDataTransformerClassName(validationStrategyClassName);

+    }

+}

diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/metadata/transformer/mapper/SimpleValidationStrategyToMetaDataTransformerNameMapper.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/metadata/transformer/mapper/SimpleValidationStrategyToMetaDataTransformerNameMapper.java
new file mode 100644
index 0000000..4ef175c
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/metadata/transformer/mapper/SimpleValidationStrategyToMetaDataTransformerNameMapper.java
@@ -0,0 +1,73 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.core.metadata.transformer.mapper;

+

+import org.apache.myfaces.extensions.validator.core.validation.strategy.ValidationStrategy;

+import org.apache.myfaces.extensions.validator.core.ExtValContext;

+import org.apache.myfaces.extensions.validator.core.CustomInformation;

+import org.apache.myfaces.extensions.validator.core.InvocationOrder;

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+import org.apache.myfaces.extensions.validator.util.ProxyUtils;

+

+/**

+ * It's an alternative Mapper to place ValidationStrategies and MetaDataTransformers in the same package.

+ *

+ * @author Gerhard Petracek

+ * @since 1.x.1

+ */

+@InvocationOrder(400)

+@UsageInformation({UsageCategory.INTERNAL})

+public class SimpleValidationStrategyToMetaDataTransformerNameMapper extends

+    AbstractValidationStrategyToMetaDataTransformerNameMapper

+{

+    public String createName(ValidationStrategy validationStrategy)

+    {

+        Class<? extends ValidationStrategy> validationStrategyClass =

+                ProxyUtils.getUnproxiedClass(validationStrategy.getClass(), ValidationStrategy.class);

+

+        if(validationStrategyClass.getPackage() == null)

+        {

+            return null;

+        }

+        return getSimpleMetaDataTransformerName(validationStrategyClass.getPackage().getName() + ".",

+                                                validationStrategyClass.getSimpleName());

+    }

+

+    public String getSimpleMetaDataTransformerName(String validationStrategyPackageName,

+                                                 String validationStrategyClassName)

+    {

+        String postfix = ExtValContext.getContext().getInformationProviderBean()

+            .get(CustomInformation.META_DATA_TRANSFORMER_POSTFIX);

+

+        if(validationStrategyClassName.endsWith("ValidationStrategy") ||

+           validationStrategyClassName.endsWith("Strategy"))

+        {

+            return validationStrategyPackageName + validationStrategyClassName

+                    .replace(ExtValContext.getContext().getInformationProviderBean()

+                        .get(CustomInformation.VALIDATION_STRATEGY_POSTFIX) ,postfix)

+                    .replace("ValidationStrategy", postfix)

+                    .replace("Strategy", postfix);

+        }

+

+        //in case of a static validation strategy mapping

+        return validationStrategyPackageName + validationStrategyClassName + postfix;

+    }

+

+}

diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/metadata/transformer/mapper/ValidationStrategyToMetaDataTransformerSubMapperAwareNameMapper.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/metadata/transformer/mapper/ValidationStrategyToMetaDataTransformerSubMapperAwareNameMapper.java
new file mode 100644
index 0000000..56a583b
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/metadata/transformer/mapper/ValidationStrategyToMetaDataTransformerSubMapperAwareNameMapper.java
@@ -0,0 +1,75 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.core.metadata.transformer.mapper;

+

+import org.apache.myfaces.extensions.validator.core.mapper.NameMapper;

+import org.apache.myfaces.extensions.validator.core.mapper.SubMapperAwareNameMapper;

+import org.apache.myfaces.extensions.validator.core.Nested;

+import org.apache.myfaces.extensions.validator.core.InvocationOrderComparator;

+import org.apache.myfaces.extensions.validator.core.InvocationOrder;

+import org.apache.myfaces.extensions.validator.core.validation.strategy.ValidationStrategy;

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+

+import java.util.List;

+import java.util.ArrayList;

+import java.util.Collections;

+

+/**

+ * @author Gerhard Petracek

+ * @since x.x.3

+ */

+@InvocationOrder(100)

+@UsageInformation({UsageCategory.INTERNAL})

+public class ValidationStrategyToMetaDataTransformerSubMapperAwareNameMapper

+    extends AbstractValidationStrategyToMetaDataTransformerNameMapper

+    implements SubMapperAwareNameMapper<ValidationStrategy>

+{

+    private List<NameMapper<ValidationStrategy>> subNameMappers = new ArrayList<NameMapper<ValidationStrategy>>();

+

+    public void addNameMapper(NameMapper<ValidationStrategy> nameMapper)

+    {

+        if(!this.subNameMappers.contains(nameMapper) && nameMapper.getClass().isAnnotationPresent(Nested.class))

+        {

+            this.subNameMappers.add(nameMapper);

+            sortSubNameMappers();

+        }

+    }

+

+    private void sortSubNameMappers()

+    {

+        Collections.sort(this.subNameMappers, new InvocationOrderComparator<NameMapper<ValidationStrategy>>());

+    }

+

+    public String createName(ValidationStrategy source)

+    {

+        String result = null;

+

+        for(NameMapper<ValidationStrategy> mapper : this.subNameMappers)

+        {

+            result = mapper.createName(source);

+

+            if(result != null)

+            {

+                return result;

+            }

+        }

+        return result;

+    }

+}
\ No newline at end of file
diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/property/DefaultPropertyInformation.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/property/DefaultPropertyInformation.java
new file mode 100644
index 0000000..e45f528
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/property/DefaultPropertyInformation.java
@@ -0,0 +1,89 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.myfaces.extensions.validator.core.property;
+
+import org.apache.myfaces.extensions.validator.internal.UsageCategory;
+import org.apache.myfaces.extensions.validator.internal.UsageInformation;
+import org.apache.myfaces.extensions.validator.core.metadata.MetaDataEntry;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Map;
+
+/**
+ * @author Gerhard Petracek
+ * @since 1.x.1
+ */
+@UsageInformation(UsageCategory.INTERNAL)
+public class DefaultPropertyInformation implements PropertyInformation
+{
+    protected final Log logger = LogFactory.getLog(getClass());
+
+    private Map<String, Object> informationMap = new HashMap<String, Object>();
+    private List<MetaDataEntry> metaDataList = new ArrayList<MetaDataEntry>();
+
+    public boolean containsInformation(String key)
+    {
+        return informationMap.containsKey(key);
+    }
+
+    public Object getInformation(String key)
+    {
+        return informationMap.get(key);
+    }
+
+    public <T> T getInformation(String key, Class<T> targetClass)
+    {
+        return (T) getInformation(key);
+    }
+
+    public void setInformation(String key, Object value)
+    {
+        if(this.logger.isTraceEnabled())
+        {
+            this.logger.trace("new information added key: " + key + " value: " + value);
+        }
+
+        informationMap.put(key, value);
+    }
+
+    public MetaDataEntry[] getMetaDataEntries()
+    {
+        return metaDataList.toArray(new MetaDataEntry[metaDataList.size()]);
+    }
+
+    public void addMetaDataEntry(MetaDataEntry metaDataEntry)
+    {
+        metaDataEntry.setProperties(this.informationMap);
+        this.metaDataList.add(metaDataEntry);
+    }
+
+    public void resetMetaDataEntries()
+    {
+        if(this.logger.isTraceEnabled())
+        {
+            this.logger.trace("resetting meta-data entries");
+        }
+
+        this.metaDataList.clear();
+    }
+}
diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/property/PropertyDetails.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/property/PropertyDetails.java
new file mode 100644
index 0000000..79037cf
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/property/PropertyDetails.java
@@ -0,0 +1,68 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.myfaces.extensions.validator.core.property;
+
+/**
+ * @author Gerhard Petracek
+ * @since 1.x.1
+ */
+public class PropertyDetails
+{
+    //forms the id for cross-validation within complex components
+    private String key;
+    private Object baseObject;
+    private String property;
+
+    public PropertyDetails(String key, Object baseObject, String property)
+    {
+        this.key = key;
+        this.baseObject = baseObject;
+        this.property = property;
+    }
+
+    public String getKey()
+    {
+        return key;
+    }
+
+    public void setKey(String key)
+    {
+        this.key = key;
+    }
+
+    public Object getBaseObject()
+    {
+        return baseObject;
+    }
+
+    public void setBaseObject(Object baseObject)
+    {
+        this.baseObject = baseObject;
+    }
+
+    public String getProperty()
+    {
+        return property;
+    }
+
+    public void setProperty(String property)
+    {
+        this.property = property;
+    }
+}
diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/property/PropertyInformation.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/property/PropertyInformation.java
new file mode 100644
index 0000000..ad9284f
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/property/PropertyInformation.java
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.myfaces.extensions.validator.core.property;
+
+import org.apache.myfaces.extensions.validator.internal.UsageCategory;
+import org.apache.myfaces.extensions.validator.internal.UsageInformation;
+import org.apache.myfaces.extensions.validator.core.metadata.MetaDataEntry;
+
+/**
+ * @author Gerhard Petracek
+ * @since 1.x.1
+ */
+@UsageInformation(UsageCategory.API)
+public interface PropertyInformation
+{
+    boolean containsInformation(String key);
+    Object getInformation(String key);
+    <T> T getInformation(String key, Class<T> targetClass);
+    void setInformation(String key, Object value);
+
+    MetaDataEntry[] getMetaDataEntries();
+    void addMetaDataEntry(MetaDataEntry metaDataEntry);
+    void resetMetaDataEntries();
+}
diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/property/PropertyInformationKeys.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/property/PropertyInformationKeys.java
new file mode 100644
index 0000000..2fef430
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/property/PropertyInformationKeys.java
@@ -0,0 +1,35 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.myfaces.extensions.validator.core.property;
+
+import org.apache.myfaces.extensions.validator.internal.UsageCategory;
+import org.apache.myfaces.extensions.validator.internal.UsageInformation;
+
+/**
+ * @author Gerhard Petracek
+ * @since 1.x.1
+ */
+@UsageInformation(UsageCategory.INTERNAL)
+public interface PropertyInformationKeys
+{
+    static final String PROPERTY_DETAILS = "property_details";
+    static final String SKIP_VALIDATION = "skip_validation";
+    static final String LABEL = "label";
+    static final String CUSTOM_PROPERTIES = "custom_properties";
+}
diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/proxy/DefaultProxyHelper.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/proxy/DefaultProxyHelper.java
new file mode 100644
index 0000000..5785b96
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/proxy/DefaultProxyHelper.java
@@ -0,0 +1,86 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.core.proxy;

+

+import org.apache.commons.logging.Log;

+import org.apache.commons.logging.LogFactory;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+

+/**

+ * @author Gerhard Petracek

+ * @since x.x.3

+ */

+@UsageInformation(UsageCategory.INTERNAL)

+public class DefaultProxyHelper implements ProxyHelper

+{

+    protected final Log logger = LogFactory.getLog(getClass());

+

+    public DefaultProxyHelper()

+    {

+        if (logger.isDebugEnabled())

+        {

+            logger.debug(getClass().getName() + " instantiated");

+        }

+    }

+

+    public <T> Class<T> getUnproxiedClass(Class currentClass, Class<T> targetType)

+    {

+        return (Class<T>)getUnproxiedClass(currentClass);

+    }

+

+    public Class getUnproxiedClass(Class currentClass)

+    {

+        if(isProxiedClass(currentClass))

+        {

+            return currentClass.getSuperclass();

+        }

+        return currentClass;

+    }

+

+    public String getNameOfClass(Class currentClass)

+    {

+        if (isProxiedClass(currentClass))

+        {

+            return currentClass.getSuperclass().getName();

+        }

+        return currentClass.getName();

+    }

+

+    public String getClassNameOfObject(Object object)

+    {

+        if(object != null)

+        {

+            return getNameOfClass(object.getClass());

+        }

+        return null;

+    }

+

+    public boolean isProxiedClass(Class currentClass)

+    {

+        return currentClass.getName().contains("$$EnhancerByCGLIB$$") ||

+            currentClass.getName().contains("$$FastClassByCGLIB$$") ||

+            currentClass.getName().contains("_$$_javassist");

+    }

+

+    public boolean isProxiedObject(Object proxiedObject)

+    {

+        return proxiedObject != null && isProxiedClass(proxiedObject.getClass());

+    }

+}

diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/proxy/ProxyHelper.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/proxy/ProxyHelper.java
new file mode 100644
index 0000000..0ce7e4a
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/proxy/ProxyHelper.java
@@ -0,0 +1,42 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.core.proxy;

+

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+

+/**

+ * @author Gerhard Petracek

+ * @since x.x.3

+ */

+@UsageInformation(UsageCategory.API)

+public interface ProxyHelper

+{

+    Class getUnproxiedClass(Class currentClass);

+

+    <T> Class<T> getUnproxiedClass(Class currentClass, Class<T> targetType);

+

+    String getNameOfClass(Class proxiedClass);

+

+    String getClassNameOfObject(Object proxiedObject);

+

+    boolean isProxiedClass(Class currentClass);

+

+    boolean isProxiedObject(Object proxiedObject);

+}

diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/recorder/ProcessedInformationRecorder.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/recorder/ProcessedInformationRecorder.java
new file mode 100644
index 0000000..270f23f
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/recorder/ProcessedInformationRecorder.java
@@ -0,0 +1,36 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.myfaces.extensions.validator.core.recorder;
+
+import org.apache.myfaces.extensions.validator.internal.UsageInformation;
+import org.apache.myfaces.extensions.validator.internal.UsageCategory;
+
+import javax.faces.component.UIComponent;
+
+/**
+ * Allows to capture converted values.
+ *
+ * @author Gerhard Petracek
+ * @since 1.x.1
+ */
+@UsageInformation(UsageCategory.API)
+public interface ProcessedInformationRecorder
+{
+    void recordUserInput(UIComponent uiComponent, Object value);
+}
diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/renderkit/AbstractRenderKitWrapperFactory.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/renderkit/AbstractRenderKitWrapperFactory.java
new file mode 100644
index 0000000..ac5920c
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/renderkit/AbstractRenderKitWrapperFactory.java
@@ -0,0 +1,117 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.myfaces.extensions.validator.core.renderkit;
+
+import org.apache.myfaces.extensions.validator.internal.UsageCategory;
+import org.apache.myfaces.extensions.validator.internal.UsageInformation;
+import org.apache.myfaces.extensions.validator.core.factory.ClassMappingFactory;
+import org.apache.myfaces.extensions.validator.util.JsfUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import javax.faces.render.RenderKit;
+
+/**
+ * Base for all RenderKitWrapperFactories to force a specific behaviour
+ *
+ * @author Gerhard Petracek
+ * @since 1.x.1
+ */
+@UsageInformation(UsageCategory.API)
+public abstract class AbstractRenderKitWrapperFactory implements ClassMappingFactory<RenderKit, RenderKit>
+{
+    protected final Log logger = LogFactory.getLog(getClass());
+
+    protected AbstractRenderKitWrapperFactory wrapped;
+    private boolean deactivated = false;
+
+    protected AbstractRenderKitWrapperFactory()
+    {
+        if(logger.isDebugEnabled())
+        {
+            logger.debug(getClass().getName() + " instantiated");
+        }
+    }
+
+    public void addRenderKitWrapperFactory(AbstractRenderKitWrapperFactory renderKitWrapperFactory)
+    {
+        if(logger.isTraceEnabled())
+        {
+            logger.trace(renderKitWrapperFactory.getClass().getName() + " added");
+        }
+
+        if(this.wrapped != null)
+        {
+            this.wrapped.addRenderKitWrapperFactory(renderKitWrapperFactory);
+            return;
+        }
+
+        this.wrapped = renderKitWrapperFactory;
+    }
+
+    public void deactivate()
+    {
+        if(logger.isTraceEnabled())
+        {
+            logger.trace(getClass().getName() + " deactivated");
+        }
+
+        this.deactivated = true;
+    }
+
+    public boolean isDeactivated()
+    {
+        return deactivated;
+    }
+
+    public final RenderKit create(RenderKit renderKit)
+    {
+        if(isDeactivated())
+        {
+            return null;
+        }
+
+        RenderKit result = null;
+
+        if(this.wrapped != null)
+        {
+            result = this.wrapped.create(renderKit);
+        }
+
+        if(result == null)
+        {
+            return createWrapper(renderKit);
+        }
+
+        return result;
+    }
+
+    protected abstract RenderKit createWrapper(RenderKit renderKit);
+
+    /**
+     * simple test for early config in case of mojarra (incl. the combination with trinidad).
+     * use a custom extval context impl. (see EXTVAL-58) to optimize this check for the target runtime.
+     * this check works for all current implementations since the jsf internals are autom. ready during a request
+     * @return true if the jsf impl. is initialized and it's possible to use it as expected
+     */
+    protected boolean isApplicationInitialized()
+    {
+        return JsfUtils.isApplicationInitialized();
+    }
+}
diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/renderkit/DefaultRenderKitWrapperFactory.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/renderkit/DefaultRenderKitWrapperFactory.java
new file mode 100644
index 0000000..3f26b72
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/renderkit/DefaultRenderKitWrapperFactory.java
@@ -0,0 +1,66 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.myfaces.extensions.validator.core.renderkit;
+
+import org.apache.myfaces.extensions.validator.internal.UsageCategory;
+import org.apache.myfaces.extensions.validator.internal.UsageInformation;
+import org.apache.myfaces.extensions.validator.util.ClassUtils;
+
+import javax.faces.render.RenderKit;
+
+/**
+ * @author Gerhard Petracek
+ * @since 1.x.1
+ */
+@UsageInformation(UsageCategory.INTERNAL)
+public class DefaultRenderKitWrapperFactory extends AbstractRenderKitWrapperFactory
+{
+    private RenderKit renderKit;
+    private static final String GENERIC_RENDER_KIT_WRAPPER_FACTORY =
+            "org.apache.myfaces.extensions.validator.generic.renderkit.GenericRenderKitWrapperFactory";
+    private static Boolean useGenericRenderKitWrapperFactory = null;
+
+    protected RenderKit createWrapper(RenderKit renderKit)
+    {
+        if(logger.isTraceEnabled())
+        {
+            logger.trace("extval renderkit wrapper created for " + renderKit.getClass().getName());
+        }
+
+        //workaround for mojarra (EXTVAL-38)
+        if(useGenericRenderKitWrapperFactory == null)
+        {
+            Class genericFactory = ClassUtils.tryToLoadClassForName(GENERIC_RENDER_KIT_WRAPPER_FACTORY);
+            useGenericRenderKitWrapperFactory = genericFactory != null;
+        }
+
+        if(useGenericRenderKitWrapperFactory)
+        {
+            AbstractRenderKitWrapperFactory renderKitWrapperFactory = (AbstractRenderKitWrapperFactory)ClassUtils
+                    .tryToInstantiateClassForName(GENERIC_RENDER_KIT_WRAPPER_FACTORY);
+            return renderKitWrapperFactory.createWrapper(renderKit);
+        }
+
+        if(this.renderKit == null)
+        {
+            this.renderKit = new ExtValRenderKit(renderKit);
+        }
+        return this.renderKit;
+    }
+}
\ No newline at end of file
diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/renderkit/ExtValLazyRendererProxy.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/renderkit/ExtValLazyRendererProxy.java
new file mode 100644
index 0000000..cb36287
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/renderkit/ExtValLazyRendererProxy.java
@@ -0,0 +1,141 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.myfaces.extensions.validator.core.renderkit;
+
+import org.apache.myfaces.extensions.validator.internal.UsageCategory;
+import org.apache.myfaces.extensions.validator.internal.UsageInformation;
+import org.apache.myfaces.extensions.validator.core.ExtValContext;
+import org.apache.myfaces.extensions.validator.util.ClassUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import javax.faces.context.FacesContext;
+import javax.faces.render.Renderer;
+import javax.faces.component.UIComponent;
+import javax.faces.convert.ConverterException;
+import java.io.IOException;
+import java.lang.reflect.Constructor;
+
+/**
+ * to support a custom proxy
+ *
+ * @author Gerhard Petracek
+ * @since 1.x.1
+ */
+@UsageInformation(UsageCategory.INTERNAL)
+class ExtValLazyRendererProxy extends Renderer
+{
+    protected final Log logger = LogFactory.getLog(getClass());
+
+    private Renderer wrapped;
+
+    public ExtValLazyRendererProxy(Renderer renderer)
+    {
+        this.wrapped = renderer;
+
+        if(logger.isTraceEnabled())
+        {
+            logger.trace("simple proxy created for " + renderer.getClass().getName());
+        }
+    }
+
+    @Override
+    public void decode(FacesContext facesContext, UIComponent uiComponent)
+    {
+        getLazyRenderer().decode(facesContext, uiComponent);
+    }
+
+    @Override
+    public void encodeBegin(FacesContext facesContext, UIComponent uiComponent)
+        throws IOException
+    {
+        getLazyRenderer().encodeBegin(facesContext, uiComponent);
+    }
+
+    @Override
+    public void encodeChildren(FacesContext facesContext, UIComponent uiComponent)
+        throws IOException
+    {
+        getLazyRenderer().encodeChildren(facesContext, uiComponent);
+    }
+
+    @Override
+    public void encodeEnd(FacesContext facesContext, UIComponent uiComponent)
+        throws IOException
+    {
+        getLazyRenderer().encodeEnd(facesContext, uiComponent);
+    }
+
+    @Override
+    public String convertClientId(FacesContext facesContext, String s)
+    {
+        return getLazyRenderer().convertClientId(facesContext, s);
+    }
+
+    @Override
+    public boolean getRendersChildren()
+    {
+        return getLazyRenderer().getRendersChildren();
+    }
+
+    @Override
+    public Object getConvertedValue(FacesContext facesContext, UIComponent uiComponent, Object o)
+        throws ConverterException
+    {
+        return getLazyRenderer().getConvertedValue(facesContext, uiComponent, o);
+    }
+
+    private Renderer getLazyRenderer()
+    {
+        String proxyClassName = (String) ExtValContext.getContext().getGlobalProperty(ExtValRendererProxy.KEY);
+
+        if(proxyClassName != null && !proxyClassName.endsWith(getClass().getName()))
+        {
+            Class targetClass = ClassUtils.tryToLoadClassForName(proxyClassName);
+
+            if(targetClass == null)
+            {
+                throw new IllegalStateException("a custom invalid renderer proxy is configured: " + proxyClassName);
+            }
+
+            Class[] argClasses = new Class[1];
+            argClasses[0] = Renderer.class;
+
+            try
+            {
+                Constructor constructor = targetClass.getConstructor(argClasses);
+                return (Renderer)constructor.newInstance(this.wrapped);
+            }
+            catch (Throwable t)
+            {
+                if(logger.isWarnEnabled())
+                {
+                    logger.warn("couldn't create: " + targetClass.getName());
+                }
+
+                return this.wrapped;
+            }
+        }
+        else
+        {
+            return this.wrapped;
+        }
+    }
+
+}
\ No newline at end of file
diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/renderkit/ExtValRenderKit.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/renderkit/ExtValRenderKit.java
new file mode 100644
index 0000000..547e6f4
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/renderkit/ExtValRenderKit.java
@@ -0,0 +1,131 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.myfaces.extensions.validator.core.renderkit;
+
+import org.apache.myfaces.extensions.validator.internal.UsageCategory;
+import org.apache.myfaces.extensions.validator.internal.UsageInformation;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import javax.faces.context.ResponseStream;
+import javax.faces.context.ResponseWriter;
+import javax.faces.render.RenderKit;
+import javax.faces.render.Renderer;
+import javax.faces.render.ResponseStateManager;
+import javax.faces.render.ClientBehaviorRenderer;
+import java.io.OutputStream;
+import java.io.Writer;
+import java.util.Iterator;
+
+/**
+ * @author Gerhard Petracek
+ * @since 1.x.1
+ */
+@UsageInformation(UsageCategory.INTERNAL)
+public class ExtValRenderKit extends RenderKit
+{
+    protected final Log logger = LogFactory.getLog(getClass());
+    protected RenderKit wrapped;
+
+    public ExtValRenderKit(RenderKit wrapped)
+    {
+        this.wrapped = wrapped;
+
+        if(logger.isDebugEnabled())
+        {
+            logger.debug(getClass().getName() + " instantiated");
+        }
+    }
+
+    public void addRenderer(String family, String rendererType, Renderer renderer)
+    {
+        if (renderer instanceof ExtValRendererWrapper)
+        {
+            wrapped.addRenderer(family, rendererType, renderer);
+        }
+        else
+        {
+            wrapped.addRenderer(family, rendererType, createWrapper(renderer));
+        }
+    }
+
+    public Renderer getRenderer(String family, String rendererType)
+    {
+        Renderer renderer = wrapped.getRenderer(family, rendererType);
+
+        if(renderer != null)
+        {
+            return renderer instanceof ExtValRendererWrapper ? renderer : createWrapper(renderer);
+        }
+
+        if(this.logger.isWarnEnabled())
+        {
+            this.logger.warn("no renderer found for family " + family + " and type " + rendererType);
+        }
+
+        return renderer;
+    }
+
+    public ResponseStateManager getResponseStateManager()
+    {
+        return wrapped.getResponseStateManager();
+    }
+
+    public ResponseWriter createResponseWriter(Writer writer, String s, String s1)
+    {
+        return wrapped.createResponseWriter(writer, s, s1);
+    }
+
+    public ResponseStream createResponseStream(OutputStream outputStream)
+    {
+        return wrapped.createResponseStream(outputStream);
+    }
+
+    public Iterator<String> getComponentFamilies()
+    {
+        return wrapped.getComponentFamilies();
+    }
+
+    public Iterator<String> getRendererTypes(String s)
+    {
+        return wrapped.getRendererTypes(s);
+    }
+
+    public void addClientBehaviorRenderer(String s, ClientBehaviorRenderer clientBehaviorRenderer)
+    {
+        wrapped.addClientBehaviorRenderer(s, clientBehaviorRenderer);
+    }
+
+    public ClientBehaviorRenderer getClientBehaviorRenderer(String s)
+    {
+        return wrapped.getClientBehaviorRenderer(s);
+    }
+
+    public Iterator<String> getClientBehaviorRendererTypes()
+    {
+        return wrapped.getClientBehaviorRendererTypes();
+    }
+
+    @UsageInformation(UsageCategory.REUSE)
+    protected Renderer createWrapper(Renderer renderer)
+    {
+        return new ExtValRendererWrapper(renderer);
+    }
+
+}
diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/renderkit/ExtValRenderKitFactory.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/renderkit/ExtValRenderKitFactory.java
new file mode 100644
index 0000000..7376b98
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/renderkit/ExtValRenderKitFactory.java
@@ -0,0 +1,167 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.myfaces.extensions.validator.core.renderkit;
+
+import org.apache.myfaces.extensions.validator.internal.UsageCategory;
+import org.apache.myfaces.extensions.validator.internal.UsageInformation;
+import org.apache.myfaces.extensions.validator.core.ExtValContext;
+import org.apache.myfaces.extensions.validator.core.WebXmlParameter;
+import org.apache.myfaces.extensions.validator.core.factory.FactoryNames;
+import org.apache.myfaces.extensions.validator.util.ClassUtils;
+import org.apache.myfaces.extensions.validator.util.ExtValUtils;
+import org.apache.myfaces.extensions.validator.ExtValInformation;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import javax.faces.render.RenderKitFactory;
+import javax.faces.render.RenderKit;
+import javax.faces.context.FacesContext;
+import java.util.Iterator;
+
+/**
+ * central mechanism which is responsible to create a wrapper for a renderer - starting point of extval.
+ *
+ * @author Gerhard Petracek
+ * @since 1.x.1
+ */
+@UsageInformation(UsageCategory.INTERNAL)
+public class ExtValRenderKitFactory extends RenderKitFactory
+{
+    protected final Log logger = LogFactory.getLog(getClass());
+    private RenderKitFactory wrapped;
+    private AbstractRenderKitWrapperFactory defaultRenderKitWrapperFactory;
+    private Boolean isDeactivated;
+
+    public ExtValRenderKitFactory(RenderKitFactory renderKitFactory)
+    {
+        this.wrapped = renderKitFactory;
+
+        if(logger.isDebugEnabled())
+        {
+            logger.debug(getClass().getName() + " instantiated");
+        }
+    }
+
+    public void addRenderKit(String s, RenderKit renderKit)
+    {
+        this.wrapped.addRenderKit(s, renderKit);
+    }
+
+    public RenderKit getRenderKit(FacesContext facesContext, String s)
+    {
+        RenderKit renderKit = this.wrapped.getRenderKit(facesContext, s);
+
+        //for mojarra + trinidad
+        if(renderKit == null)
+        {
+            return null;
+        }
+
+        tryToInitDefaultRenderKitWrapperFactory();
+
+        checkRenderKitFactoryDeactivation();
+
+        if(this.isDeactivated)
+        {
+            return renderKit;
+        }
+
+        //test early config in case of mojarra
+        if(!this.defaultRenderKitWrapperFactory.isApplicationInitialized())
+        {
+            return this.defaultRenderKitWrapperFactory.createWrapper(renderKit);
+        }
+
+        return tryToCreateWrapperWithWrapperFactory(renderKit);
+    }
+
+    private void checkRenderKitFactoryDeactivation()
+    {
+        if(this.isDeactivated == null)
+        {
+            if(ExtValUtils.isExtValDeactivated())
+            {
+                this.isDeactivated = true;
+                return;
+            }
+
+            if(this.defaultRenderKitWrapperFactory.isApplicationInitialized())
+            {
+                this.isDeactivated = isRenderKitFactoryDeactivatedViaWebXml();
+            }
+            else
+            {
+                this.isDeactivated = isRenderKitFactoryDeactivatedViaVMParameter();
+            }
+        }
+    }
+
+    private synchronized void tryToInitDefaultRenderKitWrapperFactory()
+    {
+        if(this.defaultRenderKitWrapperFactory == null)
+        {
+            //workaround for mojarra to allow a custom factory during the early config phase
+            //just create the factory with the given name
+            //+it should extend your custom implementation which you register as usual
+            Object customFactory = ClassUtils.tryToInstantiateClassForName(
+                    ExtValInformation.EXTENSIONS_VALIDATOR_BASE_PACKAGE_NAME + ".custom.RenderKitWrapperFactory");
+
+            if(customFactory instanceof AbstractRenderKitWrapperFactory)
+            {
+                this.defaultRenderKitWrapperFactory = (AbstractRenderKitWrapperFactory)customFactory;
+            }
+            else
+            {
+                this.defaultRenderKitWrapperFactory = new DefaultRenderKitWrapperFactory();
+            }
+        }
+    }
+
+    private RenderKit tryToCreateWrapperWithWrapperFactory(RenderKit renderKit)
+    {
+        AbstractRenderKitWrapperFactory wrapperFactory = ExtValContext.getContext().getFactoryFinder()
+            .getFactory(FactoryNames.RENDERKIT_WRAPPER_FACTORY, AbstractRenderKitWrapperFactory.class);
+
+        //some component libs e.g. myfaces-trinidad aren't compatible with this clean approach
+        //example see TrinidadModuleStartupListener
+        if(wrapperFactory.isDeactivated())
+        {
+            return renderKit;
+        }
+
+        return wrapperFactory.create(renderKit);
+    }
+
+    public Iterator<String> getRenderKitIds()
+    {
+        return this.wrapped.getRenderKitIds();
+    }
+
+    private boolean isRenderKitFactoryDeactivatedViaWebXml()
+    {
+        return "true".equalsIgnoreCase(WebXmlParameter.DEACTIVATE_RENDER_KIT_FACTORY);
+    }
+
+    private boolean isRenderKitFactoryDeactivatedViaVMParameter()
+    {
+        return "true".equalsIgnoreCase(System
+                .getProperty(ExtValInformation.EXTENSIONS_VALIDATOR_BASE_PACKAGE_NAME +
+                    ".DEACTIVATE_RENDER_KIT_FACTORY", "false"));
+    }
+}
diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/renderkit/ExtValRendererProxy.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/renderkit/ExtValRendererProxy.java
new file mode 100644
index 0000000..ca3613c
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/renderkit/ExtValRendererProxy.java
@@ -0,0 +1,290 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.myfaces.extensions.validator.core.renderkit;
+
+import org.apache.myfaces.extensions.validator.internal.UsageCategory;
+import org.apache.myfaces.extensions.validator.internal.UsageInformation;
+import org.apache.myfaces.extensions.validator.core.storage.RendererProxyStorageEntry;
+import org.apache.myfaces.extensions.validator.core.storage.RendererProxyStorage;
+import org.apache.myfaces.extensions.validator.core.JsfProjectStage;
+import org.apache.myfaces.extensions.validator.util.ExtValUtils;
+import org.apache.myfaces.extensions.validator.util.ProxyUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import javax.faces.context.FacesContext;
+import javax.faces.render.Renderer;
+import javax.faces.component.UIComponent;
+import javax.faces.convert.ConverterException;
+import javax.faces.application.FacesMessage;
+import java.io.IOException;
+
+/**
+ * to avoid multiple calls of renderer methods within renderer interceptors (e.g. for encode, decode,...)
+ *
+ * @author Gerhard Petracek
+ * @since 1.x.1
+ */
+@UsageInformation(UsageCategory.INTERNAL)
+public class ExtValRendererProxy extends Renderer
+{
+    public static final String KEY = ExtValRendererProxy.class.getName() + ":KEY";
+    protected final Log logger = LogFactory.getLog(getClass());
+    
+    protected Renderer wrapped;
+
+    public ExtValRendererProxy(Renderer renderer)
+    {
+        this.wrapped = renderer;
+
+        if(logger.isTraceEnabled())
+        {
+            logger.trace("proxy created for " + renderer.getClass().getName());
+        }
+    }
+
+    @Override
+    public void decode(FacesContext facesContext, UIComponent uiComponent)
+    {
+        RendererProxyStorageEntry entry = getRendererEntry(facesContext, uiComponent);
+
+        if (!entry.isDecodeCalled())
+        {
+            entry.setDecodeCalled(true);
+
+            try
+            {
+                this.wrapped.decode(facesContext, uiComponent);
+            }
+            catch (RuntimeException r)
+            {
+                resetComponentProxyMapping();
+                throw r;
+            }
+        }
+        else
+        {
+            tryToCreateMessage("decode");
+        }
+    }
+
+    @Override
+    public void encodeBegin(FacesContext facesContext, UIComponent uiComponent)
+        throws IOException
+    {
+        RendererProxyStorageEntry entry = getRendererEntry(facesContext, uiComponent);
+
+        if (!entry.isEncodeBeginCalled())
+        {
+            entry.setEncodeBeginCalled(true);
+            try
+            {
+                this.wrapped.encodeBegin(facesContext, uiComponent);
+            }
+            catch (IOException e)
+            {
+                resetComponentProxyMapping();
+                throw e;
+            }
+            catch (RuntimeException r)
+            {
+                resetComponentProxyMapping();
+                throw r;
+            }
+        }
+        else
+        {
+            tryToCreateMessage("encodeBegin");
+        }
+    }
+
+    @Override
+    public void encodeChildren(FacesContext facesContext, UIComponent uiComponent)
+        throws IOException
+    {
+        RendererProxyStorageEntry entry = getRendererEntry(facesContext, uiComponent);
+
+        if (!entry.isEncodeChildrenCalled())
+        {
+            entry.setEncodeChildrenCalled(true);
+
+            try
+            {
+                this.wrapped.encodeChildren(facesContext, uiComponent);
+            }
+            catch (IOException e)
+            {
+                resetComponentProxyMapping();
+                throw e;
+            }
+            catch (RuntimeException r)
+            {
+                resetComponentProxyMapping();
+                throw r;
+            }
+        }
+        else
+        {
+            tryToCreateMessage("encodeChildren");
+        }
+    }
+
+    @Override
+    public void encodeEnd(FacesContext facesContext, UIComponent uiComponent)
+        throws IOException
+    {
+        RendererProxyStorageEntry entry = getRendererEntry(facesContext, uiComponent);
+
+        if (!entry.isEncodeEndCalled())
+        {
+            entry.setEncodeEndCalled(true);
+
+            try
+            {
+                this.wrapped.encodeEnd(facesContext, uiComponent);
+            }
+            catch (IOException e)
+            {
+                resetComponentProxyMapping();
+                throw e;
+            }
+            catch (RuntimeException r)
+            {
+                resetComponentProxyMapping();
+                throw r;
+            }
+        }
+        else
+        {
+            tryToCreateMessage("encodeEnd");
+        }
+    }
+
+    @Override
+    public String convertClientId(FacesContext facesContext, String s)
+    {
+        try
+        {
+            return wrapped.convertClientId(facesContext, s);
+        }
+        catch (RuntimeException r)
+        {
+            resetComponentProxyMapping();
+            throw r;
+        }
+    }
+
+    @Override
+    public boolean getRendersChildren()
+    {
+        try
+        {
+            return wrapped.getRendersChildren();
+        }
+        catch (RuntimeException t)
+        {
+            resetComponentProxyMapping();
+            throw t;
+        }
+    }
+
+    @Override
+    public Object getConvertedValue(FacesContext facesContext, UIComponent uiComponent, Object o)
+        throws ConverterException
+    {
+        RendererProxyStorageEntry entry = getRendererEntry(facesContext, uiComponent);
+
+        if (entry.getConvertedValue() == null)
+        {
+            try
+            {
+                entry.setConvertedValue(wrapped.getConvertedValue(facesContext, uiComponent, o));
+            }
+            catch (RuntimeException r)
+            {
+                resetComponentProxyMapping();
+                throw r;
+            }
+        }
+        else
+        {
+            tryToCreateMessage("getConvertedValue");
+        }
+        return entry.getConvertedValue();
+    }
+
+    protected RendererProxyStorageEntry getRendererEntry(FacesContext facesContext, UIComponent uiComponent)
+    {
+        String key = uiComponent.getClientId(facesContext);
+
+        key += getOptionalKey(facesContext, uiComponent);
+
+        if (!getRendererStorage().containsEntry(getRendererKey(), key))
+        {
+            getRendererStorage().setEntry(getRendererKey(), key, new RendererProxyStorageEntry());
+        }
+        return getRendererStorage().getEntry(getRendererKey(), key);
+    }
+
+    protected String getOptionalKey(FacesContext facesContext, UIComponent uiComponent)
+    {
+        return "";
+    }
+
+    protected String getRendererKey()
+    {
+        return ProxyUtils.getClassName(this.wrapped.getClass());
+    }
+
+    private RendererProxyStorage getRendererStorage()
+    {
+        return ExtValUtils.getStorage(RendererProxyStorage.class, RendererProxyStorage.class.getName());
+    }
+
+    private void resetComponentProxyMapping()
+    {
+        //reset component proxy mapping
+        ExtValUtils.resetStorage(RendererProxyStorage.class, RendererProxyStorage.class.getName());
+    }
+
+    private void tryToCreateMessage(String methodName)
+    {
+        if(JsfProjectStage.is(JsfProjectStage.Development))
+        {
+            String message = "double call of " + this.wrapped.getClass().getName() + "#" + methodName + " filtered. " +
+                    "this optimization might lead to incompatibilities with some component libs. " +
+                    "in such a case use the support module for the component lib or use: " +
+                    "ExtValContext.getContext().addGlobalProperty(ExtValRendererProxy.KEY, null); " +
+                    "in a startup listener";
+
+            FacesContext.getCurrentInstance()
+                    .addMessage(null, ExtValUtils.createFacesMessage(FacesMessage.SEVERITY_WARN, message, message));
+
+            if(logger.isWarnEnabled())
+            {
+                logger.warn(message);
+            }
+        }
+
+        if(logger.isDebugEnabled())
+        {
+            logger.debug("turn on the development mode for further information, if something is displayed wrong.");
+        }
+    }
+}
diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/renderkit/ExtValRendererWrapper.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/renderkit/ExtValRendererWrapper.java
new file mode 100644
index 0000000..b7c305e
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/renderkit/ExtValRendererWrapper.java
@@ -0,0 +1,537 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.myfaces.extensions.validator.core.renderkit;
+
+import org.apache.myfaces.extensions.validator.internal.UsageCategory;
+import org.apache.myfaces.extensions.validator.internal.UsageInformation;
+import org.apache.myfaces.extensions.validator.core.interceptor.RendererInterceptor;
+import org.apache.myfaces.extensions.validator.core.ExtValContext;
+import org.apache.myfaces.extensions.validator.core.renderkit.exception.SkipBeforeInterceptorsException;
+import org.apache.myfaces.extensions.validator.core.renderkit.exception.SkipAfterInterceptorsException;
+import org.apache.myfaces.extensions.validator.core.renderkit.exception.SkipRendererDelegationException;
+import org.apache.myfaces.extensions.validator.util.ClassUtils;
+import org.apache.commons.logging.LogFactory;
+import org.apache.commons.logging.Log;
+
+import javax.faces.component.UIComponent;
+import javax.faces.context.FacesContext;
+import javax.faces.convert.ConverterException;
+import javax.faces.render.Renderer;
+import java.io.IOException;
+import java.lang.reflect.Constructor;
+
+/**
+ * Default approach to avoid proxies for converters and the adapter fallback.
+ * It requires that components delegate getConvertedValue to a renderer.<br/>
+ * If it isn't the case for your component lib use:
+ * org.apache.myfaces.extensions.validator.core.proxy.ExtValApplicationFactory<br/>
+ * and<br/>
+ * org.apache.myfaces.extensions.validator.core.proxy.ProxyMappingPhaseListener
+ * <p/>
+ * This wrapper will also implement client-side validation behaviour
+ *
+ * @author Gerhard Petracek
+ * @since 1.x.1
+ */
+@UsageInformation(UsageCategory.INTERNAL)
+public class ExtValRendererWrapper extends Renderer
+{
+    protected final Log logger = LogFactory.getLog(getClass());
+
+    protected Renderer wrapped;
+    protected ExtValContext extValContext = ExtValContext.getContext();
+
+    public ExtValRendererWrapper(Renderer renderer)
+    {
+        String proxyClassName = (String)ExtValContext.getContext().getGlobalProperty(ExtValRendererProxy.KEY);
+
+        if(proxyClassName == null)
+        {
+            if(logger.isTraceEnabled())
+            {
+                logger.trace("no extval renderer proxy configured");
+            }
+
+            this.wrapped = new ExtValLazyRendererProxy(renderer);
+            return;
+        }
+
+        Class targetClass = ClassUtils.tryToLoadClassForName(proxyClassName);
+
+        if(targetClass == null)
+        {
+            if(logger.isTraceEnabled())
+            {
+                logger.trace("no extval renderer proxy configured");
+            }
+
+            this.wrapped = new ExtValLazyRendererProxy(renderer);
+            return;
+        }
+
+        Class[] argClasses = new Class[1];
+        argClasses[0] = Renderer.class;
+
+        try
+        {
+            Constructor constructor = targetClass.getConstructor(argClasses);
+            this.wrapped = (Renderer)constructor.newInstance(renderer);
+        }
+        catch (Throwable e)
+        {
+            if(logger.isWarnEnabled())
+            {
+                logger.warn("no extval renderer proxy created for " + renderer.getClass().getName());
+            }
+        }
+
+        if(logger.isTraceEnabled())
+        {
+            logger.trace("extval renderer wrapper created for " + renderer.getClass().getName());
+        }
+    }
+
+    @Override
+    public final void decode(FacesContext facesContext, UIComponent uiComponent)
+    {
+        boolean delegateToWrappedRenderer = true;
+
+        try
+        {
+            for(RendererInterceptor rendererInterceptor : extValContext.getRendererInterceptors())
+            {
+                if(logger.isTraceEnabled())
+                {
+                    logger.trace("start beforeDecode of " + rendererInterceptor.getClass().getName());
+                }
+
+                try
+                {
+                    rendererInterceptor.beforeDecode(facesContext, uiComponent, this.wrapped);
+                }
+                catch (SkipRendererDelegationException e)
+                {
+                    if(logger.isTraceEnabled())
+                    {
+                        logger.trace("decode delegation canceled", e);
+                    }
+
+                    delegateToWrappedRenderer = false;
+
+                    if(e.isSkipOtherInterceptors())
+                    {
+                        break;
+                    }
+                }
+
+                if(logger.isTraceEnabled())
+                {
+                    logger.trace("beforeDecode of " + rendererInterceptor.getClass().getName() + " finished");
+                }
+            }
+        }
+        catch(SkipBeforeInterceptorsException e)
+        {
+            if(logger.isTraceEnabled())
+            {
+                logger.trace("beforeDecode interceptors canceled", e);
+            }
+        }
+
+        /*
+         * delegate
+         */
+        if(delegateToWrappedRenderer)
+        {
+            wrapped.decode(facesContext, uiComponent);
+        }
+
+        try
+        {
+            for(RendererInterceptor rendererInterceptor : extValContext.getRendererInterceptors())
+            {
+                if(logger.isTraceEnabled())
+                {
+                    logger.trace("start afterDecode of " + rendererInterceptor.getClass().getName());
+                }
+
+                rendererInterceptor.afterDecode(facesContext, uiComponent, this.wrapped);
+
+                if(logger.isTraceEnabled())
+                {
+                    logger.trace("afterDecode of " + rendererInterceptor.getClass().getName() + " finished");
+                }
+            }
+        }
+        catch (SkipAfterInterceptorsException e)
+        {
+            if(logger.isTraceEnabled())
+            {
+                logger.trace("afterDecode interceptors canceled", e);
+            }
+        }
+    }
+
+    @Override
+    public final void encodeBegin(FacesContext facesContext, UIComponent uiComponent)
+        throws IOException
+    {
+        boolean delegateToWrappedRenderer = true;
+
+        try
+        {
+            for(RendererInterceptor rendererInterceptor : extValContext.getRendererInterceptors())
+            {
+                if(logger.isTraceEnabled())
+                {
+                    logger.trace("start beforeEncodeBegin of " + rendererInterceptor.getClass().getName());
+                }
+
+                try
+                {
+                    rendererInterceptor.beforeEncodeBegin(facesContext, uiComponent, this.wrapped);
+                }
+                catch (SkipRendererDelegationException e)
+                {
+                    if(logger.isTraceEnabled())
+                    {
+                        logger.trace("encodeBegin delegation canceled", e);
+                    }
+
+                    delegateToWrappedRenderer = false;
+
+                    if(e.isSkipOtherInterceptors())
+                    {
+                        break;
+                    }
+                }
+
+                if(logger.isTraceEnabled())
+                {
+                    logger.trace("beforeEncodeBegin of " + rendererInterceptor.getClass().getName() + " finished");
+                }
+            }
+        }
+        catch (SkipBeforeInterceptorsException e)
+        {
+            if(logger.isTraceEnabled())
+            {
+                logger.trace("beforeEncodeBegin interceptors canceled", e);
+            }
+        }
+
+        /*
+         * delegate
+         */
+        if(delegateToWrappedRenderer)
+        {
+            wrapped.encodeBegin(facesContext, uiComponent);
+        }
+
+        try
+        {
+            for(RendererInterceptor rendererInterceptor : extValContext.getRendererInterceptors())
+            {
+                if(logger.isTraceEnabled())
+                {
+                    logger.trace("start afterEncodeBegin of " + rendererInterceptor.getClass().getName());
+                }
+
+                    rendererInterceptor.afterEncodeBegin(facesContext, uiComponent, this.wrapped);
+
+                if(logger.isTraceEnabled())
+                {
+                    logger.trace("afterEncodeBegin of " + rendererInterceptor.getClass().getName() + " finished");
+                }
+            }
+        }
+        catch (SkipAfterInterceptorsException e)
+        {
+            if(logger.isTraceEnabled())
+            {
+                logger.trace("afterEncodeBegin interceptors canceled", e);
+            }
+        }
+    }
+
+    @Override
+    public final void encodeChildren(FacesContext facesContext, UIComponent uiComponent)
+        throws IOException
+    {
+        boolean delegateToWrappedRenderer = true;
+
+        try
+        {
+            for(RendererInterceptor rendererInterceptor : extValContext.getRendererInterceptors())
+            {
+                if(logger.isTraceEnabled())
+                {
+                    logger.trace("start beforeEncodeChildren of " + rendererInterceptor.getClass().getName());
+                }
+
+                try
+                {
+                    rendererInterceptor.beforeEncodeChildren(facesContext, uiComponent, this.wrapped);
+                }
+                catch (SkipRendererDelegationException e)
+                {
+                    if(logger.isTraceEnabled())
+                    {
+                        logger.trace("encodeChildren delegation canceled", e);
+                    }
+
+                    delegateToWrappedRenderer = false;
+
+                    if(e.isSkipOtherInterceptors())
+                    {
+                        break;
+                    }
+                }
+
+                if(logger.isTraceEnabled())
+                {
+                    logger.trace("beforeEncodeChildren of " +
+                        rendererInterceptor.getClass().getName() + " finished");
+                }
+            }
+        }
+        catch (SkipBeforeInterceptorsException e)
+        {
+            if(logger.isTraceEnabled())
+            {
+                logger.trace("beforeEncodeChildren interceptors canceled", e);
+            }
+        }
+
+        /*
+         * delegate
+         */
+        if(delegateToWrappedRenderer)
+        {
+            wrapped.encodeChildren(facesContext, uiComponent);
+        }
+
+        try
+        {
+            for(RendererInterceptor rendererInterceptor : extValContext.getRendererInterceptors())
+            {
+                if(logger.isTraceEnabled())
+                {
+                    logger.trace("start afterEncodeChildren of " + rendererInterceptor.getClass().getName());
+                }
+
+                rendererInterceptor.afterEncodeChildren(facesContext, uiComponent, this.wrapped);
+
+                if(logger.isTraceEnabled())
+                {
+                    logger.trace("afterEncodeChildren of " + rendererInterceptor.getClass().getName() + " finished");
+                }
+            }
+        }
+        catch (SkipAfterInterceptorsException e)
+        {
+            if(logger.isTraceEnabled())
+            {
+                logger.trace("afterEncodeChildren interceptors canceled", e);
+            }
+        }
+    }
+
+    @Override
+    public final void encodeEnd(FacesContext facesContext, UIComponent uiComponent)
+        throws IOException
+    {
+        boolean delegateToWrappedRenderer = true;
+
+        try
+        {
+            for(RendererInterceptor rendererInterceptor : extValContext.getRendererInterceptors())
+            {
+                if(logger.isTraceEnabled())
+                {
+                    logger.trace("start beforeEncodeEnd of " + rendererInterceptor.getClass().getName());
+                }
+
+                try
+                {
+                    rendererInterceptor.beforeEncodeEnd(facesContext, uiComponent, this.wrapped);
+                }
+                catch (SkipRendererDelegationException e)
+                {
+                    if(logger.isTraceEnabled())
+                    {
+                        logger.trace("encodeEnd delegation canceled", e);
+                    }
+
+                    delegateToWrappedRenderer = false;
+
+                    if(e.isSkipOtherInterceptors())
+                    {
+                        break;
+                    }
+                }
+
+                if(logger.isTraceEnabled())
+                {
+                    logger.trace("beforeEncodeEnd of " + rendererInterceptor.getClass().getName() + " finished");
+                }
+            }
+        }
+        catch (SkipBeforeInterceptorsException e)
+        {
+            if(logger.isTraceEnabled())
+            {
+                logger.trace("beforeEncodeEnd interceptors canceled", e);
+            }
+        }
+
+        /*
+         * delegate
+         */
+        if(delegateToWrappedRenderer)
+        {
+            wrapped.encodeEnd(facesContext, uiComponent);
+        }
+
+        try
+        {
+            for(RendererInterceptor rendererInterceptor : extValContext.getRendererInterceptors())
+            {
+                if(logger.isTraceEnabled())
+                {
+                    logger.trace("start afterEncodeEnd of " + rendererInterceptor.getClass().getName());
+                }
+
+                rendererInterceptor.afterEncodeEnd(facesContext, uiComponent, this.wrapped);
+
+                if(logger.isTraceEnabled())
+                {
+                    logger.trace("afterEncodeEnd of " + rendererInterceptor.getClass().getName() + " finished");
+                }
+            }
+        }
+        catch (SkipAfterInterceptorsException e)
+        {
+            if(logger.isTraceEnabled())
+            {
+                logger.trace("afterEncodeEnd interceptors canceled", e);
+            }
+        }
+    }
+
+    @Override
+    public final String convertClientId(FacesContext facesContext, String s)
+    {
+        return wrapped.convertClientId(facesContext, s);
+    }
+
+    @Override
+    public final boolean getRendersChildren()
+    {
+        return wrapped.getRendersChildren();
+    }
+
+    @Override
+    public final Object getConvertedValue(FacesContext facesContext, UIComponent uiComponent, Object o)
+        throws ConverterException
+    {
+        boolean delegateToWrappedRenderer = true;
+        Object convertedObject = null;
+
+        try
+        {
+            for(RendererInterceptor rendererInterceptor : extValContext.getRendererInterceptors())
+            {
+                if(logger.isTraceEnabled())
+                {
+                    logger.trace("start beforeGetConvertedValue of " + rendererInterceptor.getClass().getName());
+                }
+
+                try
+                {
+                    rendererInterceptor.beforeGetConvertedValue(facesContext, uiComponent, o, this.wrapped);
+                }
+                catch (SkipRendererDelegationException e)
+                {
+                    convertedObject = e.getReturnValueOnException(convertedObject);
+
+                    if(logger.isTraceEnabled())
+                    {
+                        logger.trace("getConvertedValue delegation canceled", e);
+                    }
+
+                    delegateToWrappedRenderer = false;
+
+                    if(e.isSkipOtherInterceptors())
+                    {
+                        break;
+                    }
+                }
+
+                if(logger.isTraceEnabled())
+                {
+                    logger.trace("beforeGetConvertedValue of " +
+                        rendererInterceptor.getClass().getName() + " finished");
+                }
+            }
+        }
+        catch (SkipBeforeInterceptorsException e)
+        {
+            if(logger.isTraceEnabled())
+            {
+                logger.trace("beforeGetConvertedValue interceptors canceled", e);
+            }
+        }
+
+        /*
+         * delegate
+         */
+        if(delegateToWrappedRenderer)
+        {
+            convertedObject = wrapped.getConvertedValue(facesContext, uiComponent, o);
+        }
+
+        try
+        {
+            for(RendererInterceptor rendererInterceptor : extValContext.getRendererInterceptors())
+            {
+                if(logger.isTraceEnabled())
+                {
+                    logger.trace("start afterGetConvertedValue of " + rendererInterceptor.getClass().getName());
+                }
+
+                rendererInterceptor.afterGetConvertedValue(facesContext, uiComponent, o, this.wrapped);
+
+                if(logger.isTraceEnabled())
+                {
+                    logger.trace("afterGetConvertedValue of " + rendererInterceptor.getClass().getName() + " finished");
+                }
+            }
+        }
+        catch (SkipAfterInterceptorsException e)
+        {
+            if(logger.isTraceEnabled())
+            {
+                logger.trace("afterGetConvertedValue interceptors canceled", e);
+            }
+        }
+
+        return convertedObject;
+    }
+}
diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/renderkit/exception/SkipAfterInterceptorsException.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/renderkit/exception/SkipAfterInterceptorsException.java
new file mode 100644
index 0000000..722ffda
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/renderkit/exception/SkipAfterInterceptorsException.java
@@ -0,0 +1,32 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.myfaces.extensions.validator.core.renderkit.exception;
+
+import org.apache.myfaces.extensions.validator.internal.UsageCategory;
+import org.apache.myfaces.extensions.validator.internal.UsageInformation;
+
+/**
+ * @author Gerhard Petracek
+ * @since 1.x.1
+ */
+@UsageInformation(UsageCategory.API)
+public class SkipAfterInterceptorsException extends Exception
+{
+    private static final long serialVersionUID = -1472790498766251346L;
+}
\ No newline at end of file
diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/renderkit/exception/SkipBeforeInterceptorsException.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/renderkit/exception/SkipBeforeInterceptorsException.java
new file mode 100644
index 0000000..58c20a7
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/renderkit/exception/SkipBeforeInterceptorsException.java
@@ -0,0 +1,32 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.myfaces.extensions.validator.core.renderkit.exception;
+
+import org.apache.myfaces.extensions.validator.internal.UsageCategory;
+import org.apache.myfaces.extensions.validator.internal.UsageInformation;
+
+/**
+ * @author Gerhard Petracek
+ * @since 1.x.1
+ */
+@UsageInformation(UsageCategory.API)
+public class SkipBeforeInterceptorsException extends Exception
+{
+    private static final long serialVersionUID = -418424051464814888L;
+}
\ No newline at end of file
diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/renderkit/exception/SkipRendererDelegationException.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/renderkit/exception/SkipRendererDelegationException.java
new file mode 100644
index 0000000..b920fbe
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/renderkit/exception/SkipRendererDelegationException.java
@@ -0,0 +1,75 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.myfaces.extensions.validator.core.renderkit.exception;
+
+import org.apache.myfaces.extensions.validator.core.interceptor.RendererInterceptor;
+import org.apache.myfaces.extensions.validator.internal.UsageCategory;
+import org.apache.myfaces.extensions.validator.internal.UsageInformation;
+
+/**
+ * @author Gerhard Petracek
+ * @since 1.x.1
+ */
+@UsageInformation(UsageCategory.API)
+public class SkipRendererDelegationException extends Exception
+{
+    protected RendererInterceptor exceptionSource;
+    protected Object information;
+    boolean skipOtherInterceptors = false;
+    private static final long serialVersionUID = 2343074077532915722L;
+
+    public SkipRendererDelegationException()
+    {
+    }
+
+    public SkipRendererDelegationException(boolean skipOtherInterceptors)
+    {
+        this.skipOtherInterceptors = skipOtherInterceptors;
+    }
+
+    public SkipRendererDelegationException(boolean skipOtherInterceptors, RendererInterceptor rendererInterceptor)
+    {
+        this(skipOtherInterceptors);
+        this.exceptionSource = rendererInterceptor;
+    }
+
+    public void setInformation(Object information)
+    {
+        this.information = information;
+    }
+
+    public Object getInformation()
+    {
+        return information;
+    }
+
+    public boolean isSkipOtherInterceptors()
+    {
+        return skipOtherInterceptors;
+    }
+
+    public Object getReturnValueOnException(Object currentReturnValue)
+    {
+        if (this.exceptionSource != null)
+        {
+            return this.exceptionSource.getReturnValueOnSkipRendererDelegationException(this, currentReturnValue);
+        }
+        return currentReturnValue;
+    }
+}
\ No newline at end of file
diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/startup/AbstractStartupListener.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/startup/AbstractStartupListener.java
new file mode 100644
index 0000000..e070a6a
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/startup/AbstractStartupListener.java
@@ -0,0 +1,153 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.core.startup;

+

+import org.apache.myfaces.extensions.validator.util.JsfUtils;

+import org.apache.myfaces.extensions.validator.util.WebXmlUtils;

+import org.apache.myfaces.extensions.validator.util.ExtValUtils;

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+import org.apache.myfaces.extensions.validator.core.ExtValContext;

+import org.apache.myfaces.extensions.validator.core.ProjectStageResolver;

+import org.apache.myfaces.extensions.validator.core.DefaultProjectStageResolver;

+import org.apache.commons.logging.LogFactory;

+import org.apache.commons.logging.Log;

+

+import javax.faces.event.PhaseEvent;

+import javax.faces.event.PhaseId;

+import javax.faces.event.PhaseListener;

+import java.util.ArrayList;

+import java.util.List;

+

+/**

+ * In order to execute logic just once.

+ * e.g. register artifacts via api

+ *

+ * @author Gerhard Petracek

+ * @since 1.x.1

+ */

+@UsageInformation(UsageCategory.REUSE)

+public abstract class AbstractStartupListener implements PhaseListener

+{

+    protected final Log logger = LogFactory.getLog(getClass());

+

+    //don't remove - it's a fallback if there is a problem with deregistration

+    //target: don't process init logic more than once

+    private static List<Class> initializedListeners = new ArrayList<Class>();

+

+    private static boolean defaultProjectStageResolverInitialized = false;

+

+    protected AbstractStartupListener()

+    {

+        if(logger.isDebugEnabled())

+        {

+            logger.debug(getClass().getName() + " instantiated");

+        }

+    }

+

+    public void afterPhase(PhaseEvent event)

+    {

+    }

+

+    public void beforePhase(PhaseEvent event)

+    {

+        synchronized (AbstractStartupListener.class)

+        {

+            if (!initializedListeners.contains(getClass()))

+            {

+                try

+                {

+                    if(logger.isInfoEnabled())

+                    {

+                        logger.info("start init of " + getClass().getName());

+                    }

+

+                    try

+                    {

+                        if(!isStartupListenerDeactivated())

+                        {

+                            initProjectStageResolver();

+

+                            init();

+                        }

+                        else

+                        {

+                            if(logger.isInfoEnabled())

+                            {

+                                logger.info("init of " + getClass().getName() + " deactivated");

+                            }

+                        }

+

+                        if(logger.isInfoEnabled())

+                        {

+                            logger.info("init of " + getClass().getName() + " finished");

+                        }

+                    }

+                    finally

+                    {

+                        JsfUtils.deregisterPhaseListener(this);

+                    }

+                }

+                catch (Throwable t)

+                {

+                    if(logger.isWarnEnabled())

+                    {

+                        logger.warn("an exception occurred while deregistering the phase-listener"

+                                + getClass().getName()

+                                + " -> there is just a little overhead,"

+                                + " but everything else works correctly."

+                                + " however, please inform the community about your configuration", t);

+                    }

+                }

+                finally

+                {

+                    initializedListeners.add(getClass());

+                }

+            }

+        }

+    }

+

+    public PhaseId getPhaseId()

+    {

+        return PhaseId.RESTORE_VIEW;

+    }

+

+    protected boolean isStartupListenerDeactivated()

+    {

+        return ExtValUtils.isExtValDeactivated() ||

+                "true".equalsIgnoreCase(WebXmlUtils.getInitParameter(null, getClass().getName() + ":DEACTIVATED"));

+    }

+

+    protected void initProjectStageResolver()

+    {

+        if(!defaultProjectStageResolverInitialized)

+        {

+            ExtValContext.getContext()

+                    .addGlobalProperty(ProjectStageResolver.class.getName(), getProjectStageResolver(), false);

+            defaultProjectStageResolverInitialized = true;

+        }

+    }

+

+    protected ProjectStageResolver getProjectStageResolver()

+    {

+        return new DefaultProjectStageResolver();

+    }

+

+    protected abstract void init();

+}

diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/startup/ExtValStartupListener.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/startup/ExtValStartupListener.java
new file mode 100644
index 0000000..6ed3281
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/startup/ExtValStartupListener.java
@@ -0,0 +1,245 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.myfaces.extensions.validator.core.startup;
+
+import org.apache.myfaces.extensions.validator.internal.UsageCategory;
+import org.apache.myfaces.extensions.validator.internal.UsageInformation;
+import org.apache.myfaces.extensions.validator.core.interceptor.ValidationInterceptor;
+import org.apache.myfaces.extensions.validator.core.interceptor.HtmlCoreComponentsValidationExceptionInterceptor;
+import org.apache.myfaces.extensions.validator.core.interceptor.ViolationSeverityValidationExceptionInterceptor;
+import org.apache.myfaces.extensions.validator.core.interceptor.FacesMessagePropertyValidationInterceptor;
+import org.apache.myfaces.extensions.validator.core.ExtValContext;
+import org.apache.myfaces.extensions.validator.core.CustomInformation;
+import org.apache.myfaces.extensions.validator.core.WebXmlParameter;
+import org.apache.myfaces.extensions.validator.core.PhaseIdRecordingPhaseListener;
+import org.apache.myfaces.extensions.validator.core.metadata.transformer.mapper
+        .BeanValidationStrategyToMetaDataTransformerNameMapper;
+import org.apache.myfaces.extensions.validator.core.metadata.transformer.mapper
+        .SimpleValidationStrategyToMetaDataTransformerNameMapper;
+import org.apache.myfaces.extensions.validator.core.metadata.transformer.mapper
+        .DefaultValidationStrategyToMetaDataTransformerNameMapper;
+import org.apache.myfaces.extensions.validator.core.metadata.transformer.mapper
+        .CustomConventionValidationStrategyToMetaDataTransformerNameMapper;
+import org.apache.myfaces.extensions.validator.core.metadata.transformer.mapper
+        .CustomConfiguredValidationStrategyToMetaDataTransformerNameMapper;
+import org.apache.myfaces.extensions.validator.core.validation.strategy.mapper
+        .CustomConventionAnnotationToValidationStrategyNameMapper;
+import org.apache.myfaces.extensions.validator.core.validation.strategy.mapper
+        .DefaultAnnotationToValidationStrategyNameMapper;
+import org.apache.myfaces.extensions.validator.core.validation.strategy.mapper
+        .CustomConfiguredAnnotationToValidationStrategyNameMapper;
+import org.apache.myfaces.extensions.validator.core.validation.strategy.mapper
+        .SimpleAnnotationToValidationStrategyNameMapper;
+import org.apache.myfaces.extensions.validator.core.validation.strategy.mapper
+        .AnnotationToValidationStrategyBeanNameMapper;
+import org.apache.myfaces.extensions.validator.core.validation.message.resolver.mapper
+        .CustomConfiguredValidationStrategyToMsgResolverNameMapper;
+import org.apache.myfaces.extensions.validator.core.validation.message.resolver.mapper
+        .CustomConventionValidationStrategyToMsgResolverNameMapper;
+import org.apache.myfaces.extensions.validator.core.validation.message.resolver.mapper
+        .DefaultValidationStrategyToMsgResolverNameMapper;
+import org.apache.myfaces.extensions.validator.core.validation.message.resolver.mapper
+        .DefaultModuleValidationStrategyToMsgResolverNameMapper;
+import org.apache.myfaces.extensions.validator.core.validation.message.resolver.mapper
+        .SimpleValidationStrategyToMsgResolverNameMapper;
+import org.apache.myfaces.extensions.validator.core.validation.parameter.DefaultViolationSeverityInterpreter;
+import org.apache.myfaces.extensions.validator.core.validation.parameter.ViolationSeverity;
+import org.apache.myfaces.extensions.validator.core.validation.parameter.DisableClientSideValidation;
+import org.apache.myfaces.extensions.validator.core.renderkit.ExtValRendererProxy;
+import org.apache.myfaces.extensions.validator.util.ClassUtils;
+import org.apache.myfaces.extensions.validator.util.ExtValUtils;
+import org.apache.myfaces.extensions.validator.util.JsfUtils;
+import org.apache.myfaces.extensions.validator.ExtValInformation;
+
+/**
+ * @author Gerhard Petracek
+ * @since 1.x.1
+ */
+@UsageInformation(UsageCategory.INTERNAL)
+public class ExtValStartupListener extends AbstractStartupListener
+{
+    private static final long serialVersionUID = -2504826421086572012L;
+
+    protected void init()
+    {
+        if(logger.isInfoEnabled())
+        {
+            if(ExtValInformation.VERSION != null)
+            {
+                logger.info("starting up MyFaces Extensions Validator v" + ExtValInformation.VERSION);
+            }
+            else
+            {
+                logger.info("starting up MyFaces Extensions Validator");
+            }
+        }
+
+        ExtValContext.getContext().registerRendererInterceptor(new ValidationInterceptor());
+
+        ExtValContext.getContext()
+                .addGlobalProperty(ExtValRendererProxy.KEY, ExtValRendererProxy.class.getName(), false);
+
+        initNameMappers();
+        initValidationExceptionInterceptors();
+        initViolationSeverityInterpreter();
+        initPropertyValidationInterceptors();
+        initPhaseListeners();
+        initViolationSeverityKey();
+        initDisableClientSideValidationKey();
+        initRequiredInitialization();
+        executeCustomStartupListener();
+    }
+
+    private void initNameMappers()
+    {
+        String deactivateDefaultNameMappers = WebXmlParameter.DEACTIVATE_DEFAULT_NAME_MAPPERS;
+        if ((deactivateDefaultNameMappers != null && deactivateDefaultNameMappers.equalsIgnoreCase("true")))
+        {
+            return;
+        }
+
+        //register metadata to validation strategy name mapper
+        ExtValUtils.registerMetaDataToValidationStrategyNameMapper(
+                new CustomConfiguredAnnotationToValidationStrategyNameMapper());
+        ExtValUtils.registerMetaDataToValidationStrategyNameMapper(
+                new CustomConventionAnnotationToValidationStrategyNameMapper());
+        ExtValUtils.registerMetaDataToValidationStrategyNameMapper(
+                new DefaultAnnotationToValidationStrategyNameMapper());
+        ExtValUtils.registerMetaDataToValidationStrategyNameMapper(
+                new SimpleAnnotationToValidationStrategyNameMapper());
+
+        ExtValUtils.registerMetaDataToValidationStrategyNameMapper(
+                new AnnotationToValidationStrategyBeanNameMapper(
+                        new CustomConfiguredAnnotationToValidationStrategyNameMapper()));
+        ExtValUtils.registerMetaDataToValidationStrategyNameMapper(
+                new AnnotationToValidationStrategyBeanNameMapper(
+                        new CustomConventionAnnotationToValidationStrategyNameMapper()));
+        ExtValUtils.registerMetaDataToValidationStrategyNameMapper(
+                new AnnotationToValidationStrategyBeanNameMapper(
+                        new DefaultAnnotationToValidationStrategyNameMapper()));
+        ExtValUtils.registerMetaDataToValidationStrategyNameMapper(
+                new AnnotationToValidationStrategyBeanNameMapper(
+                        new SimpleAnnotationToValidationStrategyNameMapper()));
+
+        //register validation strategy to message resolver name mapper
+        ExtValUtils.registerValidationStrategyToMessageResolverNameMapper(
+                new CustomConfiguredValidationStrategyToMsgResolverNameMapper());
+        ExtValUtils.registerValidationStrategyToMessageResolverNameMapper(
+                new CustomConventionValidationStrategyToMsgResolverNameMapper());
+        ExtValUtils.registerValidationStrategyToMessageResolverNameMapper(
+                new DefaultValidationStrategyToMsgResolverNameMapper());
+        ExtValUtils.registerValidationStrategyToMessageResolverNameMapper(
+                new DefaultModuleValidationStrategyToMsgResolverNameMapper());
+        ExtValUtils.registerValidationStrategyToMessageResolverNameMapper(
+                new SimpleValidationStrategyToMsgResolverNameMapper());
+
+        //register validation strategy to metadata transformer name mapper
+        ExtValUtils.registerValidationStrategyToMetaDataTransformerNameMapper(
+                new CustomConfiguredValidationStrategyToMetaDataTransformerNameMapper());
+        ExtValUtils.registerValidationStrategyToMetaDataTransformerNameMapper(
+                new CustomConventionValidationStrategyToMetaDataTransformerNameMapper());
+        ExtValUtils.registerValidationStrategyToMetaDataTransformerNameMapper(
+                new DefaultValidationStrategyToMetaDataTransformerNameMapper());
+        ExtValUtils.registerValidationStrategyToMetaDataTransformerNameMapper(
+                new SimpleValidationStrategyToMetaDataTransformerNameMapper());
+        ExtValUtils.registerValidationStrategyToMetaDataTransformerNameMapper(
+                new BeanValidationStrategyToMetaDataTransformerNameMapper());
+    }
+
+    private void executeCustomStartupListener()
+    {
+        String customStartupListenerName = ExtValContext.getContext().getInformationProviderBean()
+            .get(CustomInformation.STARTUP_LISTENER);
+        AbstractStartupListener customStartupListener =
+            (AbstractStartupListener)ClassUtils.tryToInstantiateClassForName(customStartupListenerName);
+
+        if(customStartupListener != null)
+        {
+            if(logger.isInfoEnabled())
+            {
+                logger.info("start init of " + customStartupListener.getClass().getName());
+            }
+
+            customStartupListener.init();
+
+            if(logger.isInfoEnabled())
+            {
+                logger.info("init of " + customStartupListener.getClass().getName() + " finished");
+            }
+        }
+    }
+
+    private void initValidationExceptionInterceptors()
+    {
+        ExtValContext.getContext().addValidationExceptionInterceptor(
+                new HtmlCoreComponentsValidationExceptionInterceptor());
+        ExtValContext.getContext().addValidationExceptionInterceptor(
+                new ViolationSeverityValidationExceptionInterceptor());
+    }
+
+    private void initViolationSeverityInterpreter()
+    {
+        ExtValContext.getContext().setViolationSeverityInterpreter(new DefaultViolationSeverityInterpreter(), false);
+    }
+
+    private void initPropertyValidationInterceptors()
+    {
+        ExtValContext.getContext().addPropertyValidationInterceptor(new FacesMessagePropertyValidationInterceptor());
+    }
+
+    private void initPhaseListeners()
+    {
+        JsfUtils.registerPhaseListener(new PhaseIdRecordingPhaseListener());
+    }
+
+    private void initViolationSeverityKey()
+    {
+        ExtValContext.getContext().addGlobalProperty(ViolationSeverity.class.getName(), ViolationSeverity.class, false);
+    }
+
+    private void initDisableClientSideValidationKey()
+    {
+        ExtValContext.getContext().addGlobalProperty(
+                DisableClientSideValidation.class.getName(), DisableClientSideValidation.class, false);
+    }
+
+    private void initRequiredInitialization()
+    {
+        if(WebXmlParameter.ACTIVATE_REQUIRED_INITIALIZATION != null)
+        {
+            boolean requiredInitialization = "true".equalsIgnoreCase(WebXmlParameter.ACTIVATE_REQUIRED_INITIALIZATION);
+
+            ExtValContext.getContext().addGlobalProperty("mode:init:required", requiredInitialization, false);
+
+            if(requiredInitialization)
+            {
+                deactivateRequiredAttributeSupport();
+            }
+        }
+    }
+
+    /**
+     * if it's configured that required init should happen,
+     * it's required to deactivate the support for the required attribute
+     */
+    private void deactivateRequiredAttributeSupport()
+    {
+        ExtValContext.getContext().addGlobalProperty("mode:reset:required", Boolean.TRUE, false);
+    }
+}
diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/storage/AbstractApplicationScopeAwareStorageManager.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/storage/AbstractApplicationScopeAwareStorageManager.java
new file mode 100644
index 0000000..1238bdf
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/storage/AbstractApplicationScopeAwareStorageManager.java
@@ -0,0 +1,50 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.core.storage;

+

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import static org.apache.myfaces.extensions.validator.internal.UsageCategory.REUSE;

+

+import javax.faces.context.FacesContext;

+import java.util.Map;

+import java.util.HashMap;

+

+/**

+ * generic storage manager implementation which stores the storage implementations in the application scope

+ *

+ * @author Gerhard Petracek

+ * @since x.x.3

+ */

+@UsageInformation(REUSE)

+public abstract class AbstractApplicationScopeAwareStorageManager<T> extends AbstractStorageManager<T>

+{

+    protected Map<String, T> resolveStorageMap()

+    {

+        Map applicationMap = FacesContext.getCurrentInstance().getExternalContext().getApplicationMap();

+        Map<String, T> storageMap;

+

+        if(!applicationMap.containsKey(getStorageManagerKey()))

+        {

+            storageMap = new HashMap<String, T>();

+            applicationMap.put(getStorageManagerKey(), storageMap);

+        }

+

+        return (Map<String, T>)applicationMap.get(getStorageManagerKey());

+    }

+}

diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/storage/AbstractRequestScopeAwareStorageManager.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/storage/AbstractRequestScopeAwareStorageManager.java
new file mode 100644
index 0000000..ff6614e
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/storage/AbstractRequestScopeAwareStorageManager.java
@@ -0,0 +1,50 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.core.storage;

+

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import static org.apache.myfaces.extensions.validator.internal.UsageCategory.REUSE;

+

+import javax.faces.context.FacesContext;

+import java.util.Map;

+import java.util.HashMap;

+

+/**

+ * generic storage manager implementation which stores the storage implementations in the request scope

+ *

+ * @author Gerhard Petracek

+ * @since x.x.3

+ */

+@UsageInformation(REUSE)

+public abstract class AbstractRequestScopeAwareStorageManager<T> extends AbstractStorageManager<T>

+{

+    protected Map<String, T> resolveStorageMap()

+    {

+        Map requestMap = FacesContext.getCurrentInstance().getExternalContext().getRequestMap();

+        Map<String, T> storageMap;

+

+        if(!requestMap.containsKey(getStorageManagerKey()))

+        {

+            storageMap = new HashMap<String, T>();

+            requestMap.put(getStorageManagerKey(), storageMap);

+        }

+

+        return (Map<String, T>)requestMap.get(getStorageManagerKey());

+    }

+}
\ No newline at end of file
diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/storage/AbstractStorageManager.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/storage/AbstractStorageManager.java
new file mode 100644
index 0000000..5898b97
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/storage/AbstractStorageManager.java
@@ -0,0 +1,110 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.core.storage;

+

+import org.apache.myfaces.extensions.validator.core.factory.AbstractNameMapperAwareFactory;

+import org.apache.myfaces.extensions.validator.core.mapper.NameMapper;

+import org.apache.myfaces.extensions.validator.util.ClassUtils;

+import org.apache.myfaces.extensions.validator.util.ProxyUtils;

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import static org.apache.myfaces.extensions.validator.internal.UsageCategory.REUSE;

+import org.apache.commons.logging.Log;

+import org.apache.commons.logging.LogFactory;

+

+import java.util.List;

+import java.util.ArrayList;

+import java.util.Map;

+

+/**

+ * generic storage manager implementation

+ *

+ * @author Gerhard Petracek

+ * @since x.x.3

+ */

+@UsageInformation(REUSE)

+public abstract class AbstractStorageManager<T> extends AbstractNameMapperAwareFactory<String>

+        implements StorageManager<T>

+{

+    protected final Log logger = LogFactory.getLog(getClass());

+

+    private List<NameMapper<String>> nameMapperList = new ArrayList<NameMapper<String>>();

+

+    public AbstractStorageManager()

+    {

+        if(logger.isDebugEnabled())

+        {

+            logger.debug(getClass().getName() + " instantiated");

+        }

+    }

+

+    public T create(String storageName)

+    {

+        T storageManager;

+        String storageClassName;

+        //null -> use name mappers

+        for (NameMapper<String> nameMapper : this.nameMapperList)

+        {

+            storageClassName = nameMapper.createName(storageName);

+

+            if (storageClassName == null)

+            {

+                continue;

+            }

+

+            storageManager = resolveStorage(storageName, storageClassName);

+

+            if (storageManager != null)

+            {

+                return storageManager;

+            }

+        }

+        return null;

+    }

+

+    protected T resolveStorage(String storageKey, String storageClassName)

+    {

+        Map<String, T> storageMap = resolveStorageMap();

+

+        if(!storageMap.containsKey(storageKey))

+        {

+            storageMap.put(storageKey, (T)ClassUtils.tryToInstantiateClassForName(storageClassName));

+        }

+        return storageMap.get(storageKey);

+    }

+

+    protected abstract Map<String, T> resolveStorageMap();

+

+    public void reset(String storageKey)

+    {

+        Map<String, T> storageMap = resolveStorageMap();

+

+        if(storageMap != null && storageMap.containsKey(storageKey))

+        {

+            Class storageClass = ProxyUtils.getUnproxiedClass(storageMap.get(storageKey).getClass());

+            storageMap.put(storageKey, (T)ClassUtils.tryToInstantiateClass(storageClass));

+        }

+    }

+

+    protected List<NameMapper<String>> getNameMapperList()

+    {

+        return this.nameMapperList;

+    }

+

+    public abstract String getStorageManagerKey();

+}

diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/storage/DefaultFacesInformationStorage.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/storage/DefaultFacesInformationStorage.java
new file mode 100644
index 0000000..47af031
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/storage/DefaultFacesInformationStorage.java
@@ -0,0 +1,44 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.core.storage;

+

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+

+import javax.faces.event.PhaseId;

+

+/**

+ * @author Gerhard Petracek

+ * @since x.x.3

+ */

+@UsageInformation(UsageCategory.INTERNAL)

+public class DefaultFacesInformationStorage implements FacesInformationStorage

+{

+    private PhaseId currentPhaseId;

+

+    public void setCurrentPhaseId(PhaseId phaseId)

+    {

+        this.currentPhaseId = phaseId;

+    }

+

+    public PhaseId getCurrentPhaseId()

+    {

+        return this.currentPhaseId;

+    }

+}

diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/storage/DefaultFacesInformationStorageManager.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/storage/DefaultFacesInformationStorageManager.java
new file mode 100644
index 0000000..da13bdf
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/storage/DefaultFacesInformationStorageManager.java
@@ -0,0 +1,44 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.core.storage;

+

+import org.apache.myfaces.extensions.validator.core.storage.mapper.DefaultFacesInformationStorageNameMapper;

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+

+/**

+ * default storage-manager for jsf information not available via jsf-api

+ *

+ * @author Gerhard Petracek

+ * @since x.x.3

+ */

+@UsageInformation(UsageCategory.INTERNAL)

+class DefaultFacesInformationStorageManager extends

+        AbstractRequestScopeAwareStorageManager<FacesInformationStorage>

+{

+    DefaultFacesInformationStorageManager()

+    {

+        register(new DefaultFacesInformationStorageNameMapper());

+    }

+

+    public String getStorageManagerKey()

+    {

+        return StorageManager.class.getName() + "_FOR_FACES_INFORMATION_STORAGE:KEY";

+    }

+}

diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/storage/DefaultFacesMessageStorage.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/storage/DefaultFacesMessageStorage.java
new file mode 100644
index 0000000..abd6b7c
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/storage/DefaultFacesMessageStorage.java
@@ -0,0 +1,153 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.core.storage;

+

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+import org.apache.myfaces.extensions.validator.internal.ToDo;

+import org.apache.myfaces.extensions.validator.internal.Priority;

+import org.apache.myfaces.extensions.validator.core.validation.message.FacesMessageHolder;

+

+import javax.faces.application.FacesMessage;

+import javax.faces.context.FacesContext;

+import java.util.List;

+import java.util.Map;

+import java.util.HashMap;

+import java.util.ArrayList;

+import java.util.Collections;

+import java.util.Comparator;

+

+/**

+ * @author Gerhard Petracek

+ * @since x.x.3

+ */

+@ToDo(value = Priority.LOW, description = "optional parameter to deactivate sorting")

+@UsageInformation(UsageCategory.INTERNAL)

+public class DefaultFacesMessageStorage implements FacesMessageStorage

+{

+    Map<String, ValidationResult> results = new HashMap<String, ValidationResult>();

+

+    public void addFacesMessage(String clientId, FacesMessage facesMessage)

+    {

+        if(clientId == null)

+        {

+            clientId = "*";

+        }

+

+        if(!this.results.containsKey(clientId))

+        {

+            this.results.put(clientId, new ValidationResult());

+        }

+

+        this.results.get(clientId).addFacesMessageHolder(new FacesMessageHolder(facesMessage, clientId));

+    }

+

+    public List<FacesMessageHolder> getFacesMessages()

+    {

+        List<FacesMessageHolder> result = new ArrayList<FacesMessageHolder>();

+

+        for(ValidationResult validationResult : this.results.values())

+        {

+            result.addAll(validationResult.getFacesMessageHolderList());

+        }

+        return result;

+    }

+

+    public void addAll()

+    {

+        FacesContext facesContext = FacesContext.getCurrentInstance();

+        List<FacesMessageHolder> facesMessageHolderList;

+

+        for(ValidationResult validationResult : this.results.values())

+        {

+            facesMessageHolderList = validationResult.getFacesMessageHolderList();

+            sortFacesMessageHolderList(facesMessageHolderList);

+

+            for(FacesMessageHolder facesMessageHolder : facesMessageHolderList)

+            {

+                facesContext.addMessage(facesMessageHolder.getClientId(), facesMessageHolder.getFacesMessage());

+            }

+        }

+    }

+

+    private void sortFacesMessageHolderList(List<FacesMessageHolder> facesMessageHolderList)

+    {

+        Collections.sort(facesMessageHolderList, getFacesMessageComparator());

+    }

+

+    protected Comparator<FacesMessageHolder> getFacesMessageComparator()

+    {

+        return new Comparator<FacesMessageHolder>() {

+            public int compare(FacesMessageHolder holder1, FacesMessageHolder holder2)

+            {

+                if(holder1.getFacesMessage().getSeverity() == null)

+                {

+                    return 1;

+                }

+                if(isSameSeverity(holder1, holder2))

+                {

+                    return compareMessageText(holder1.getFacesMessage(), holder2.getFacesMessage());

+                }

+

+                if(holder1.getFacesMessage().getSeverity().getOrdinal() >

+                        holder2.getFacesMessage().getSeverity().getOrdinal())

+                {

+                    return -1;

+                }

+                else

+                {

+                    return 1;

+                }

+            }

+

+            private int compareMessageText(FacesMessage facesMessage1, FacesMessage facesMessage2)

+            {

+                String text1 = facesMessage1.getDetail();

+                String text2 = facesMessage2.getDetail();

+

+                if(text1 == null)

+                {

+                    text1 = facesMessage1.getSummary();

+                }

+

+                if(text2 == null)

+                {

+                    text2 = facesMessage2.getSummary();

+                }

+

+                if(text1 == null)

+                {

+                    return 1;

+                }

+

+                if(text2 == null)

+                {

+                    return -1;

+                }

+

+                return text1.compareToIgnoreCase(text2);

+            }

+        };

+    }

+

+    private boolean isSameSeverity(FacesMessageHolder holder1, FacesMessageHolder holder2)

+    {

+        return holder1.getFacesMessage().getSeverity().equals(holder2.getFacesMessage().getSeverity());

+    }

+}

diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/storage/DefaultFacesMessageStorageManager.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/storage/DefaultFacesMessageStorageManager.java
new file mode 100644
index 0000000..312326f
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/storage/DefaultFacesMessageStorageManager.java
@@ -0,0 +1,43 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.core.storage;

+

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import static org.apache.myfaces.extensions.validator.internal.UsageCategory.INTERNAL;

+import org.apache.myfaces.extensions.validator.core.storage.mapper.DefaultFacesMessageStorageNameMapper;

+

+/**

+ * default storage-manager for faces messages

+ *

+ * @author Gerhard Petracek

+ * @since x.x.3

+ */

+@UsageInformation(INTERNAL)

+class DefaultFacesMessageStorageManager extends AbstractRequestScopeAwareStorageManager<FacesMessageStorage>

+{

+    DefaultFacesMessageStorageManager()

+    {

+        register(new DefaultFacesMessageStorageNameMapper());

+    }

+

+    public String getStorageManagerKey()

+    {

+        return StorageManager.class.getName() + "_FOR_FACES_MESSAGES:KEY";

+    }

+}

diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/storage/DefaultGroupStorage.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/storage/DefaultGroupStorage.java
new file mode 100644
index 0000000..16b4d61
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/storage/DefaultGroupStorage.java
@@ -0,0 +1,146 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.core.storage;

+

+import org.apache.myfaces.extensions.validator.util.GroupUtils;

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import static org.apache.myfaces.extensions.validator.internal.UsageCategory.INTERNAL;

+import org.apache.commons.logging.Log;

+import org.apache.commons.logging.LogFactory;

+

+import java.util.List;

+import java.util.Map;

+import java.util.HashMap;

+import java.util.ArrayList;

+

+/**

+ * default storage implementation for groups

+ *

+ * @author Gerhard Petracek

+ * @since x.x.3

+ */

+@UsageInformation(INTERNAL)

+public class DefaultGroupStorage implements GroupStorage

+{

+    protected final Log logger = LogFactory.getLog(getClass());

+

+    private Map<String, List<Class>> addedGroups = new HashMap<String, List<Class>>();

+

+    private Map<String, List<Class>> restrictedGroups = new HashMap<String, List<Class>>();

+

+    public void addGroup(Class groupClass, String viewId, String clientId)

+    {

+        addGroupToGroupStorage(groupClass, viewId, clientId, this.addedGroups);

+    }

+

+    public void restrictGroup(Class groupClass, String viewId, String clientId)

+    {

+        addGroupToGroupStorage(groupClass, viewId, clientId, this.restrictedGroups);

+    }

+

+    public Class[] getGroups(String viewId, String clientId)

+    {

+        if(this.addedGroups.size() < 1)

+        {

+            return null;

+        }

+

+        //add found groups

+        String key = GroupUtils.getGroupKey(viewId, null);

+        List<Class> resultListForPage = buildGroupList(key, this.addedGroups);

+

+        key = GroupUtils.getGroupKey(viewId, clientId);

+        List<Class> resultListForComponent = buildGroupList(key, this.addedGroups);

+

+        //remove restricted groups

+        Class[] resultsForPage =

+                filterGroupList(GroupUtils.getGroupKey(viewId, null), resultListForPage);

+        Class[] resultsForComponent =

+                filterGroupList(GroupUtils.getGroupKey(viewId, clientId), resultListForComponent);

+

+        if(resultsForPage.length == 0)

+        {

+            if(resultsForComponent.length == 0)

+            {

+                if(this.logger.isDebugEnabled())

+                {

+                    this.logger.debug("no groups for group-validation available." +

+                            "maybe you restricted all groups or you aren't using groups." +

+                            "bean validation will use the default group for validation");

+                }

+            }

+            return resultsForComponent;

+        }

+        else if(resultsForComponent.length == 0)

+        {

+            return resultsForPage;

+        }

+

+        return mergeResults(resultsForPage, resultsForComponent);

+    }

+

+    private void addGroupToGroupStorage(Class groupClass, String viewId, String clientId,

+                                        Map<String, List<Class>> groupStorage)

+    {

+        List<Class> groupList = groupStorage.get(GroupUtils.getGroupKey(viewId, clientId));

+

+        if(groupList == null)

+        {

+            groupList = new ArrayList<Class>();

+            groupStorage.put(GroupUtils.getGroupKey(viewId, clientId), groupList);

+        }

+

+        if(!groupList.contains(groupClass))

+        {

+            groupList.add(groupClass);

+        }

+    }

+

+    private List<Class> buildGroupList(String key, Map<String, List<Class>> groupStorage)

+    {

+        List<Class> list = groupStorage.get(key);

+        return (list != null) ? list : new ArrayList<Class>();

+    }

+

+    private Class[] filterGroupList(String key, List<Class> addedGroups)

+    {

+        List<Class> restrictedGroups = buildGroupList(key, this.restrictedGroups);

+        List<Class> results = new ArrayList<Class>();

+

+        for(Class currentGroup : addedGroups)

+        {

+            if(!restrictedGroups.contains(currentGroup))

+            {

+                results.add(currentGroup);

+            }

+        }

+

+        return results.toArray(new Class[results.size()]);

+    }

+

+    private Class[] mergeResults(Class[] resultsForPage, Class[] resultsForComponent)

+    {

+        Class[] mergedResult = new Class[resultsForPage.length + resultsForComponent.length];

+

+        System.arraycopy(resultsForPage, 0, mergedResult, 0, resultsForPage.length);

+        System.arraycopy(resultsForComponent, 0, mergedResult, resultsForPage.length, resultsForComponent.length);

+

+        return mergedResult;

+    }

+}

diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/storage/DefaultGroupStorageManager.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/storage/DefaultGroupStorageManager.java
new file mode 100644
index 0000000..916b5bc
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/storage/DefaultGroupStorageManager.java
@@ -0,0 +1,37 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.core.storage;

+

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import static org.apache.myfaces.extensions.validator.internal.UsageCategory.INTERNAL;

+

+/**

+ * default storage-manager for groups

+ *

+ * @author Gerhard Petracek

+ * @since x.x.3

+ */

+@UsageInformation(INTERNAL)

+class DefaultGroupStorageManager extends AbstractRequestScopeAwareStorageManager<GroupStorage>

+{

+    public String getStorageManagerKey()

+    {

+        return StorageManager.class.getName() + "_FOR_GROUPS:KEY";

+    }

+}

diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/storage/DefaultMetaDataStorage.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/storage/DefaultMetaDataStorage.java
new file mode 100644
index 0000000..26d7b58
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/storage/DefaultMetaDataStorage.java
@@ -0,0 +1,229 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.core.storage;

+

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.ToDo;

+import org.apache.myfaces.extensions.validator.internal.Priority;

+import static org.apache.myfaces.extensions.validator.internal.UsageCategory.INTERNAL;

+import org.apache.myfaces.extensions.validator.core.property.PropertyInformation;

+import org.apache.myfaces.extensions.validator.core.property.PropertyDetails;

+import org.apache.myfaces.extensions.validator.core.property.PropertyInformationKeys;

+import org.apache.myfaces.extensions.validator.core.property.DefaultPropertyInformation;

+import org.apache.myfaces.extensions.validator.core.metadata.MetaDataEntry;

+import org.apache.myfaces.extensions.validator.core.WebXmlParameter;

+import org.apache.myfaces.extensions.validator.core.CustomInformation;

+import org.apache.myfaces.extensions.validator.core.ExtValContext;

+import org.apache.myfaces.extensions.validator.util.ClassUtils;

+import org.apache.myfaces.extensions.validator.util.ProxyUtils;

+import org.apache.commons.logging.Log;

+import org.apache.commons.logging.LogFactory;

+

+import java.util.Map;

+import java.util.HashMap;

+import java.util.List;

+import java.util.ArrayList;

+

+/**

+ * @author Gerhard Petracek

+ * @since x.x.3

+ */

+@UsageInformation(INTERNAL)

+public class DefaultMetaDataStorage implements MetaDataStorage

+{

+    protected final Log logger = LogFactory.getLog(getClass());

+

+    private Map<String, Map<String, PropertyInformation>> cachedPropertyInformation =

+            new HashMap<String, Map<String, PropertyInformation>>();

+

+    private List<MetaDataStorageFilter> metaDataStorageFilters = new ArrayList<MetaDataStorageFilter>();

+    private List<Class<? extends MetaDataStorageFilter>> deniedMetaDataFilters =

+            new ArrayList<Class<? extends MetaDataStorageFilter>>();

+

+    public DefaultMetaDataStorage()

+    {

+        initFilters();

+    }

+

+    private void initFilters()

+    {

+        List<String> metaDataStorageFilterClassNames = new ArrayList<String>();

+

+        metaDataStorageFilterClassNames

+            .add(WebXmlParameter.CUSTOM_META_DATA_STORAGE_FILTER);

+        metaDataStorageFilterClassNames

+            .add(ExtValContext.getContext().getInformationProviderBean().get(

+                    CustomInformation.META_DATA_STORAGE_FILTER));

+

+        MetaDataStorageFilter metaDataStorageFilter;

+        for (String validationExceptionInterceptorName : metaDataStorageFilterClassNames)

+        {

+            metaDataStorageFilter =

+                (MetaDataStorageFilter)ClassUtils.tryToInstantiateClassForName(validationExceptionInterceptorName);

+

+            if (metaDataStorageFilter != null)

+            {

+                this.metaDataStorageFilters.add(metaDataStorageFilter);

+

+                logAddedFilter(metaDataStorageFilter.getClass());

+            }

+        }

+    }

+

+    public void storeMetaDataOf(PropertyInformation propertyInformation)

+    {

+        invokeFilters(propertyInformation);

+

+        PropertyInformation propertyInformationToStore = new DefaultPropertyInformation();

+

+        PropertyDetails propertyDetails = propertyInformation

+                .getInformation(PropertyInformationKeys.PROPERTY_DETAILS, PropertyDetails.class);

+

+        copyMetaData(propertyInformation, propertyInformationToStore);

+

+        getMapForClass(ProxyUtils.getUnproxiedClass(propertyDetails.getBaseObject().getClass()))

+                .put(propertyDetails.getProperty(), propertyInformationToStore);

+    }

+

+    private void invokeFilters(PropertyInformation propertyInformation)

+    {

+        for(MetaDataStorageFilter filter : this.metaDataStorageFilters)

+        {

+            filter.filter(propertyInformation);

+        }

+    }

+

+    public MetaDataEntry[] getMetaData(Class targetClass, String targetProperty)

+    {

+        PropertyInformation propertyInformation = getMapForClass(targetClass).get(targetProperty);

+

+        PropertyInformation clonedPropertyInformation = new DefaultPropertyInformation();

+        copyMetaData(propertyInformation, clonedPropertyInformation);

+

+        return clonedPropertyInformation.getMetaDataEntries();

+    }

+

+    public boolean containsMetaDataFor(Class targetClass, String targetProperty)

+    {

+        return getMapForClass(targetClass).containsKey(targetProperty);

+    }

+

+    public void registerFilter(MetaDataStorageFilter storageFilter)

+    {

+        synchronized (this)

+        {

+            if(!isFilterDenied(storageFilter) && !isFilterAlreadyRegistered(storageFilter))

+            {

+                this.metaDataStorageFilters.add(storageFilter);

+                logAddedFilter(storageFilter.getClass());

+            }

+        }

+    }

+

+    private boolean isFilterDenied(MetaDataStorageFilter storageFilter)

+    {

+        return this.deniedMetaDataFilters.contains(getStorageFilterClass(storageFilter));

+    }

+

+    private boolean isFilterAlreadyRegistered(MetaDataStorageFilter storageFilter)

+    {

+        for(MetaDataStorageFilter filter : this.metaDataStorageFilters)

+        {

+            if(filter.getClass().equals(getStorageFilterClass(storageFilter)))

+            {

+                return true;

+            }

+        }

+        return false;

+    }

+

+    public void deregisterFilter(Class<? extends MetaDataStorageFilter> filterClass)

+    {

+        MetaDataStorageFilter storageFilter = ClassUtils.tryToInstantiateClass(filterClass);

+

+        synchronized (this)

+        {

+            this.metaDataStorageFilters.remove(storageFilter);

+        }

+

+        logRemovedFilter(storageFilter.getClass());

+    }

+

+    public void denyFilter(Class<? extends MetaDataStorageFilter> filterClass)

+    {

+        synchronized (this)

+        {

+            for(Class<? extends MetaDataStorageFilter> filterId : this.deniedMetaDataFilters)

+            {

+                if(filterId.equals(filterClass))

+                {

+                    return;

+                }

+            }

+            this.deniedMetaDataFilters.add(filterClass);

+        }

+

+        deregisterFilter(filterClass);

+    }

+

+    @ToDo(Priority.MEDIUM)

+    private void copyMetaData(PropertyInformation source, PropertyInformation target)

+    {

+        MetaDataEntry newMetaDataEntry;

+        for(MetaDataEntry metaDataEntry : source.getMetaDataEntries())

+        {

+            newMetaDataEntry = new MetaDataEntry();

+            newMetaDataEntry.setKey(metaDataEntry.getKey());

+            newMetaDataEntry.setValue(metaDataEntry.getValue());

+

+            target.addMetaDataEntry(newMetaDataEntry);

+        }

+    }

+

+    private void logAddedFilter(Class<? extends MetaDataStorageFilter> filterClass)

+    {

+        if(this.logger.isInfoEnabled())

+        {

+            this.logger.info(filterClass.getName() + " added");

+        }

+    }

+

+    private void logRemovedFilter(Class<? extends MetaDataStorageFilter> filterClass)

+    {

+        if(this.logger.isInfoEnabled())

+        {

+            this.logger.info(filterClass.getName() + " removed");

+        }

+    }

+

+    private Map<String, PropertyInformation> getMapForClass(Class target)

+    {

+        String key = ProxyUtils.getClassName(target);

+        if(!this.cachedPropertyInformation.containsKey(key))

+        {

+            this.cachedPropertyInformation.put(key, new HashMap<String, PropertyInformation>());

+        }

+        return this.cachedPropertyInformation.get(key);

+    }

+

+    private Class<? extends MetaDataStorageFilter> getStorageFilterClass(MetaDataStorageFilter storageFilter)

+    {

+        return ProxyUtils.getUnproxiedClass(storageFilter.getClass(), MetaDataStorageFilter.class);

+    }

+}

diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/storage/DefaultMetaDataStorageManager.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/storage/DefaultMetaDataStorageManager.java
new file mode 100644
index 0000000..ecc69be
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/storage/DefaultMetaDataStorageManager.java
@@ -0,0 +1,43 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.core.storage;

+

+import org.apache.myfaces.extensions.validator.core.storage.mapper.DefaultMetaDataStorageNameMapper;

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+

+/**

+ * default storage-manager for property information entries

+ *

+ * @author Gerhard Petracek

+ * @since x.x.3

+ */

+@UsageInformation(UsageCategory.INTERNAL)

+class DefaultMetaDataStorageManager extends AbstractApplicationScopeAwareStorageManager<MetaDataStorage>

+{

+    DefaultMetaDataStorageManager()

+    {

+        register(new DefaultMetaDataStorageNameMapper());

+    }

+

+    public String getStorageManagerKey()

+    {

+        return StorageManager.class.getName() + "_FOR_META_DATA_CACHE:KEY";

+    }

+}

diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/storage/DefaultPropertyStorage.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/storage/DefaultPropertyStorage.java
new file mode 100644
index 0000000..c10a7f0
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/storage/DefaultPropertyStorage.java
@@ -0,0 +1,93 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.core.storage;

+

+import org.apache.commons.logging.Log;

+import org.apache.commons.logging.LogFactory;

+import static org.apache.myfaces.extensions.validator.internal.UsageCategory.INTERNAL;

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.util.ProxyUtils;

+

+import java.lang.reflect.Field;

+import java.lang.reflect.Method;

+import java.util.HashMap;

+import java.util.Map;

+

+/**

+ * @author Gerhard Petracek

+ * @since x.x.3

+ */

+@UsageInformation(INTERNAL)

+public class DefaultPropertyStorage implements PropertyStorage

+{

+    protected final Log logger = LogFactory.getLog(getClass());

+

+    private Map<String, Map<String, Field>> fieldMap = new HashMap<String, Map<String, Field>>();

+    private Map<String, Map<String, Method>> methodMap = new HashMap<String, Map<String, Method>>();

+

+    public void storeField(Class targetClass, String property, Field field)

+    {

+        getFieldMapForClass(targetClass).put(property, field);

+    }

+

+    public void storeMethod(Class targetClass, String property, Method method)

+    {

+        getMethodMapForClass(targetClass).put(property,  method);

+    }

+

+    public Field getField(Class targetClass, String property)

+    {

+        return getFieldMapForClass(targetClass).get(property);

+    }

+

+    public Method getMethod(Class targetClass, String property)

+    {

+        return getMethodMapForClass(targetClass).get(property);

+    }

+

+    public boolean containsField(Class targetClass, String property)

+    {

+        return getFieldMapForClass(targetClass).containsKey(property);

+    }

+

+    public boolean containsMethod(Class targetClass, String property)

+    {

+        return getMethodMapForClass(targetClass).containsKey(property);

+    }

+

+    private Map<String, Field> getFieldMapForClass(Class target)

+    {

+        String key = ProxyUtils.getClassName(target);

+        if (!this.fieldMap.containsKey(key))

+        {

+            this.fieldMap.put(key, new HashMap<String, Field>());

+        }

+        return this.fieldMap.get(key);

+    }

+

+    private Map<String, Method> getMethodMapForClass(Class target)

+    {

+        String key = ProxyUtils.getClassName(target);

+        if (!this.methodMap.containsKey(key))

+        {

+            this.methodMap.put(key, new HashMap<String, Method>());

+        }

+        return this.methodMap.get(key);

+    }

+}

diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/storage/DefaultPropertyStorageManager.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/storage/DefaultPropertyStorageManager.java
new file mode 100644
index 0000000..9b3010a
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/storage/DefaultPropertyStorageManager.java
@@ -0,0 +1,43 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.core.storage;

+

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import static org.apache.myfaces.extensions.validator.internal.UsageCategory.INTERNAL;

+import org.apache.myfaces.extensions.validator.core.storage.mapper.DefaultPropertyStorageNameMapper;

+

+/**

+ * default storage-manager for property information

+ *

+ * @author Gerhard Petracek

+ * @since x.x.3

+ */

+@UsageInformation(INTERNAL)

+class DefaultPropertyStorageManager extends AbstractApplicationScopeAwareStorageManager<PropertyStorage>

+{

+    DefaultPropertyStorageManager()

+    {

+        register(new DefaultPropertyStorageNameMapper());

+    }

+

+    public String getStorageManagerKey()

+    {

+        return StorageManager.class.getName() + "_FOR_PROPERTY:KEY";

+    }

+}

diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/storage/DefaultRendererInterceptorPropertyStorage.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/storage/DefaultRendererInterceptorPropertyStorage.java
new file mode 100644
index 0000000..ee79c62
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/storage/DefaultRendererInterceptorPropertyStorage.java
@@ -0,0 +1,59 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.core.storage;

+

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import static org.apache.myfaces.extensions.validator.internal.UsageCategory.INTERNAL;

+import org.apache.commons.logging.Log;

+import org.apache.commons.logging.LogFactory;

+

+import java.util.Map;

+import java.util.HashMap;

+

+/**

+ * @author Gerhard Petracek

+ * @since x.x.3

+ */

+@UsageInformation(INTERNAL)

+public class DefaultRendererInterceptorPropertyStorage implements RendererInterceptorPropertyStorage

+{

+    protected final Log logger = LogFactory.getLog(getClass());

+

+    private Map<String, Object> properties = new HashMap<String, Object>();

+

+    public void setProperty(String key, Object value)

+    {

+        this.properties.put(key, value);

+    }

+

+    public Object getProperty(String key)

+    {

+        return this.properties.get(key);

+    }

+

+    public <T> T getProperty(String key, Class<T> targetClass)

+    {

+        return (T)this.properties.get(key);

+    }

+

+    public void removeProperty(String key)

+    {

+        this.properties.remove(key);

+    }

+}

diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/storage/DefaultRendererInterceptorPropertyStorageManager.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/storage/DefaultRendererInterceptorPropertyStorageManager.java
new file mode 100644
index 0000000..761b10a
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/storage/DefaultRendererInterceptorPropertyStorageManager.java
@@ -0,0 +1,44 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.core.storage;

+

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import static org.apache.myfaces.extensions.validator.internal.UsageCategory.INTERNAL;

+import org.apache.myfaces.extensions.validator.core.storage.mapper.DefaultRendererInterceptorPropertyStorageNameMapper;

+

+/**

+ * default storage-manager for renderer interceptor properties

+ *

+ * @author Gerhard Petracek

+ * @since x.x.3

+ */

+@UsageInformation(INTERNAL)

+class DefaultRendererInterceptorPropertyStorageManager

+        extends AbstractRequestScopeAwareStorageManager<RendererInterceptorPropertyStorage>

+{

+    DefaultRendererInterceptorPropertyStorageManager()

+    {

+        register(new DefaultRendererInterceptorPropertyStorageNameMapper());

+    }

+

+    public String getStorageManagerKey()

+    {

+        return StorageManager.class.getName() + "_FOR_RENDERER_INTERCEPTOR_PROPERTY:KEY";

+    }

+}

diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/storage/DefaultRendererProxyStorage.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/storage/DefaultRendererProxyStorage.java
new file mode 100644
index 0000000..dd27ef8
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/storage/DefaultRendererProxyStorage.java
@@ -0,0 +1,63 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.core.storage;

+

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import static org.apache.myfaces.extensions.validator.internal.UsageCategory.INTERNAL;

+

+import java.util.Map;

+import java.util.HashMap;

+

+/**

+ * default storage implementation for groups

+ *

+ * @author Gerhard Petracek

+ * @since x.x.3

+ */

+@UsageInformation(INTERNAL)

+public class DefaultRendererProxyStorage implements RendererProxyStorage

+{

+    Map<String, Map<String, RendererProxyStorageEntry>> proxyStorage =

+        new HashMap<String, Map<String, RendererProxyStorageEntry>>();

+

+    public void setEntry(String rendererKey, String clientId, RendererProxyStorageEntry entry)

+    {

+        getRendererStorage(rendererKey).put(clientId, entry);

+    }

+

+    public boolean containsEntry(String rendererKey, String clientId)

+    {

+        return getRendererStorage(rendererKey).containsKey(clientId);

+    }

+

+    public RendererProxyStorageEntry getEntry(String rendererKey, String clientId)

+    {

+        return getRendererStorage(rendererKey).get(clientId);

+    }

+

+    private Map<String, RendererProxyStorageEntry> getRendererStorage(String rendererKey)

+    {

+        if(!proxyStorage.containsKey(rendererKey))

+        {

+            proxyStorage.put(rendererKey, new HashMap<String, RendererProxyStorageEntry>());

+        }

+

+        return proxyStorage.get(rendererKey);

+    }

+}
\ No newline at end of file
diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/storage/DefaultRendererProxyStorageManager.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/storage/DefaultRendererProxyStorageManager.java
new file mode 100644
index 0000000..cd81196
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/storage/DefaultRendererProxyStorageManager.java
@@ -0,0 +1,46 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.core.storage;

+

+import org.apache.myfaces.extensions.validator.core.renderkit.ExtValRendererProxy;

+import org.apache.myfaces.extensions.validator.core.storage.mapper.DefaultRendererProxyStorageNameMapper;

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+

+/**

+ * default storage-manager for renderer proxy entries

+ *

+ * @author Gerhard Petracek

+ * @since x.x.3

+ */

+@UsageInformation(UsageCategory.INTERNAL)

+class DefaultRendererProxyStorageManager

+    extends AbstractRequestScopeAwareStorageManager<RendererProxyStorage>

+{

+    DefaultRendererProxyStorageManager()

+    {

+        register(new DefaultRendererProxyStorageNameMapper());

+    }

+

+    public String getStorageManagerKey()

+    {

+        //for better backward compatibility

+        return ExtValRendererProxy.class.getName() + ":STORAGE";

+    }

+}

diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/storage/DefaultStorageManagerFactory.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/storage/DefaultStorageManagerFactory.java
new file mode 100644
index 0000000..05566de
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/storage/DefaultStorageManagerFactory.java
@@ -0,0 +1,187 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.core.storage;

+

+import org.apache.myfaces.extensions.validator.core.factory.ClassMappingFactory;

+import org.apache.myfaces.extensions.validator.core.factory.AbstractNameMapperAwareFactory;

+import org.apache.myfaces.extensions.validator.core.mapper.NameMapper;

+import org.apache.myfaces.extensions.validator.core.initializer.configuration.StaticConfigurationNames;

+import org.apache.myfaces.extensions.validator.core.initializer.configuration.StaticConfiguration;

+import org.apache.myfaces.extensions.validator.core.initializer.configuration.StaticConfigurationEntry;

+import org.apache.myfaces.extensions.validator.core.ExtValContext;

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.util.ClassUtils;

+import org.apache.commons.logging.Log;

+import org.apache.commons.logging.LogFactory;

+import static org.apache.myfaces.extensions.validator.internal.UsageCategory.INTERNAL;

+

+import java.util.List;

+import java.util.ArrayList;

+import java.util.Map;

+import java.util.HashMap;

+

+/**

+ * default implementation for storage-manager creation and caching

+ *

+ * @author Gerhard Petracek

+ * @since x.x.3

+ */

+@UsageInformation(INTERNAL)

+public class DefaultStorageManagerFactory extends AbstractNameMapperAwareFactory<Class>

+        implements ClassMappingFactory<Class, StorageManager>, StorageManagerHolder

+{

+    protected final Log logger = LogFactory.getLog(getClass());

+

+    private boolean lazyStaticMappingApplied = false;

+    private List<NameMapper<Class>> nameMapperList = new ArrayList<NameMapper<Class>>();

+    private Map<Class, StorageManager> storageTypeToStorageManagerMap = new HashMap<Class, StorageManager>();

+

+    public DefaultStorageManagerFactory()

+    {

+        if(logger.isDebugEnabled())

+        {

+            logger.debug(getClass().getName() + " instantiated");

+        }

+

+        setStorageManager(RendererProxyStorage.class,

+                new DefaultRendererProxyStorageManager(), false);

+        setStorageManager(GroupStorage.class,

+                new DefaultGroupStorageManager(), false);

+        setStorageManager(MetaDataStorage.class,

+                new DefaultMetaDataStorageManager(), false);

+        setStorageManager(FacesMessageStorage.class,

+                new DefaultFacesMessageStorageManager(), false);

+        setStorageManager(PropertyStorage.class,

+                new DefaultPropertyStorageManager(), false);

+        setStorageManager(RendererInterceptorPropertyStorage.class,

+                new DefaultRendererInterceptorPropertyStorageManager(), false);

+        setStorageManager(ViolationSeverityInterpreterStorage.class,

+                new DefaultViolationSeverityInterpreterStorageManager(), false);

+

+        setStorageManager(FacesInformationStorage.class,

+                new DefaultFacesInformationStorageManager(), false);

+    }

+

+    public StorageManager create(Class storageType)

+    {

+        if (!this.lazyStaticMappingApplied)

+        {

+            initStaticMappings();

+        }

+

+        StorageManager storageManager;

+        String storageManagerName;

+        //null -> use name mappers

+        for (NameMapper<Class> nameMapper : this.nameMapperList)

+        {

+            storageManagerName = nameMapper.createName(storageType);

+

+            if (storageManagerName == null)

+            {

+                continue;

+            }

+

+            storageManager = (StorageManager)ClassUtils.tryToInstantiateClassForName(storageManagerName);

+

+            if (storageManager != null)

+            {

+                addMapping(storageType, storageManager);

+                return storageManager;

+            }

+        }

+        return getStorageManager(storageType);

+    }

+

+    private synchronized void addMapping(Class storageType, StorageManager storageManager)

+    {

+        boolean isValidEntry = true;

+        if(storageType == null)

+        {

+            isValidEntry = false;

+            if(this.logger.isErrorEnabled())

+            {

+                this.logger.error("you tried to add an invalid storage type");

+            }

+        }

+

+        if(storageManager == null)

+        {

+            isValidEntry = false;

+            if(this.logger.isErrorEnabled())

+            {

+                this.logger.error("you tried to add an invalid storage manager");

+            }

+        }

+

+        if(!isValidEntry)

+        {

+            return;

+        }

+

+        setStorageManager(storageType, storageManager, true);

+    }

+

+    private void initStaticMappings()

+    {

+        this.lazyStaticMappingApplied = true;

+

+        //setup internal static mappings

+        for (StaticConfiguration<String, String> staticConfig :

+            ExtValContext.getContext().getStaticConfiguration(

+                StaticConfigurationNames.STORAGE_TYPE_TO_STORAGE_MANAGER_CONFIG))

+        {

+            setupMappings(staticConfig.getMapping());

+        }

+    }

+

+    private void setupMappings(List<StaticConfigurationEntry<String, String>> mappings)

+    {

+        for(StaticConfigurationEntry<String, String> mapping : mappings)

+        {

+            addMapping(ClassUtils.tryToLoadClassForName(mapping.getSource()),

+                    (StorageManager)ClassUtils.tryToInstantiateClassForName(mapping.getTarget()));

+        }

+    }

+

+    protected List<NameMapper<Class>> getNameMapperList()

+    {

+        return this.nameMapperList;

+    }

+

+    public void setStorageManager(Class storageType, StorageManager storageManager, boolean override)

+    {

+        if(!this.storageTypeToStorageManagerMap.containsKey(storageType) ||

+                (this.storageTypeToStorageManagerMap.containsKey(storageType) && override))

+        {

+

+            if(logger.isTraceEnabled())

+            {

+                logger.trace("adding type to storage-manager mapping: "

+                    + storageType.getName() + " -> " + storageManager.getClass().getName());

+            }

+

+            this.storageTypeToStorageManagerMap.put(storageType, storageManager);

+        }

+    }

+

+    public StorageManager getStorageManager(Class type)

+    {

+        return this.storageTypeToStorageManagerMap.get(type);

+    }

+}

diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/storage/DefaultViolationSeverityInterpreterStorage.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/storage/DefaultViolationSeverityInterpreterStorage.java
new file mode 100644
index 0000000..007bc3d
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/storage/DefaultViolationSeverityInterpreterStorage.java
@@ -0,0 +1,47 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.core.storage;

+

+import org.apache.commons.logging.Log;

+import org.apache.commons.logging.LogFactory;

+import org.apache.myfaces.extensions.validator.core.validation.parameter.ViolationSeverityInterpreter;

+import static org.apache.myfaces.extensions.validator.internal.UsageCategory.INTERNAL;

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+

+/**

+ * @author Gerhard Petracek

+ * @since x.x.3

+ */

+@UsageInformation(INTERNAL)

+public class DefaultViolationSeverityInterpreterStorage implements ViolationSeverityInterpreterStorage

+{

+    protected final Log logger = LogFactory.getLog(getClass());

+

+    private ViolationSeverityInterpreter violationSeverityInterpreter;

+

+    public void setViolationSeverityInterpreter(ViolationSeverityInterpreter violationSeverityInterpreter)

+    {

+        this.violationSeverityInterpreter = violationSeverityInterpreter;

+    }

+

+    public ViolationSeverityInterpreter getViolationSeverityInterpreter()

+    {

+        return this.violationSeverityInterpreter;

+    }

+}

diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/storage/DefaultViolationSeverityInterpreterStorageManager.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/storage/DefaultViolationSeverityInterpreterStorageManager.java
new file mode 100644
index 0000000..5008b53
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/storage/DefaultViolationSeverityInterpreterStorageManager.java
@@ -0,0 +1,44 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.core.storage;

+

+import org.apache.myfaces.extensions.validator.core.storage.mapper.DefaultViolationSeverityInterpreterStorageNameMapper;

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+

+/**

+ * default storage-manager for a custom ViolationSeverityInterpreter

+ *

+ * @author Gerhard Petracek

+ * @since x.x.3

+ */

+@UsageInformation(UsageCategory.INTERNAL)

+class DefaultViolationSeverityInterpreterStorageManager extends

+        AbstractRequestScopeAwareStorageManager<ViolationSeverityInterpreterStorage>

+{

+    DefaultViolationSeverityInterpreterStorageManager()

+    {

+        register(new DefaultViolationSeverityInterpreterStorageNameMapper());

+    }

+

+    public String getStorageManagerKey()

+    {

+        return StorageManager.class.getName() + "_FOR_VIOLATIONSEVERITY_INTERPRETER:KEY";

+    }

+}

diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/storage/FacesInformationStorage.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/storage/FacesInformationStorage.java
new file mode 100644
index 0000000..6601834
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/storage/FacesInformationStorage.java
@@ -0,0 +1,39 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.core.storage;

+

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+

+import javax.faces.event.PhaseId;

+

+/**

+ * storage for additional information about the current faces request

+ * for now it just contains information about the current phase of the lifecycle

+ *

+ * @author Gerhard Petracek

+ * @since x.x.3

+ */

+@UsageInformation(UsageCategory.INTERNAL)

+public interface FacesInformationStorage

+{

+    void setCurrentPhaseId(PhaseId phaseId);

+

+    PhaseId getCurrentPhaseId();

+}

diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/storage/FacesMessageStorage.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/storage/FacesMessageStorage.java
new file mode 100644
index 0000000..7a50f4f
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/storage/FacesMessageStorage.java
@@ -0,0 +1,40 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.core.storage;

+

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+import org.apache.myfaces.extensions.validator.core.validation.message.FacesMessageHolder;

+

+import javax.faces.application.FacesMessage;

+import java.util.List;

+

+/**

+ * @author Gerhard Petracek

+ * @since x.x.3

+ */

+@UsageInformation(UsageCategory.INTERNAL)

+public interface FacesMessageStorage

+{

+    void addFacesMessage(String clientId, FacesMessage facesMessage);

+

+    List<FacesMessageHolder> getFacesMessages();

+

+    void addAll();

+}

diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/storage/GroupStorage.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/storage/GroupStorage.java
new file mode 100644
index 0000000..4bc014b
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/storage/GroupStorage.java
@@ -0,0 +1,41 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.core.storage;

+

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+

+/**

+ * suggested interface for a group storage

+ * used by the bvi module and add-ons

+ * <p/>

+ * it allows to manage groups for the current request

+ * 

+ * @author Gerhard Petracek

+ * @since x.x.3

+ */

+@UsageInformation(UsageCategory.API)

+public interface GroupStorage

+{

+    void addGroup(Class groupClass, String viewId, String clientId);

+

+    void restrictGroup(Class groupClass, String viewId, String clientId);

+

+    Class[] getGroups(String viewId, String clientId);

+}

diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/storage/MetaDataStorage.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/storage/MetaDataStorage.java
new file mode 100644
index 0000000..b9ecebd
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/storage/MetaDataStorage.java
@@ -0,0 +1,44 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.core.storage;

+

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+import org.apache.myfaces.extensions.validator.core.property.PropertyInformation;

+import org.apache.myfaces.extensions.validator.core.metadata.MetaDataEntry;

+

+/**

+ * @author Gerhard Petracek

+ * @since x.x.3

+ */

+@UsageInformation(UsageCategory.API)

+public interface MetaDataStorage

+{

+    void storeMetaDataOf(PropertyInformation propertyInformation);

+

+    MetaDataEntry[] getMetaData(Class targetClass, String targetProperty);

+

+    boolean containsMetaDataFor(Class targetClass, String targetProperty);

+

+    void registerFilter(MetaDataStorageFilter storageFilter);

+

+    void deregisterFilter(Class<? extends MetaDataStorageFilter> filterClass);

+

+    void denyFilter(Class<? extends MetaDataStorageFilter> filterClass);

+}

diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/storage/MetaDataStorageFilter.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/storage/MetaDataStorageFilter.java
new file mode 100644
index 0000000..eb2fdb6
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/storage/MetaDataStorageFilter.java
@@ -0,0 +1,33 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.core.storage;

+

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+import org.apache.myfaces.extensions.validator.core.property.PropertyInformation;

+

+/**

+ * @author Gerhard Petracek

+ * @since x.x.3

+ */

+@UsageInformation(UsageCategory.API)

+public interface MetaDataStorageFilter

+{

+    void filter(PropertyInformation propertyInformation);

+}
\ No newline at end of file
diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/storage/PropertyStorage.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/storage/PropertyStorage.java
new file mode 100644
index 0000000..99bed26
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/storage/PropertyStorage.java
@@ -0,0 +1,45 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.core.storage;

+

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+

+import java.lang.reflect.Method;

+import java.lang.reflect.Field;

+

+/**

+ * @author Gerhard Petracek

+ * @since x.x.3

+ */

+@UsageInformation(UsageCategory.INTERNAL)

+public interface PropertyStorage

+{

+    void storeField(Class targetClass, String property, Field field);

+

+    void storeMethod(Class targetClass, String property, Method method);

+

+    Field getField(Class targetClass, String property);

+

+    Method getMethod(Class targetClass, String property);

+

+    boolean containsField(Class targetClass, String property);

+

+    boolean containsMethod(Class targetClass, String property);

+}

diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/storage/RendererInterceptorPropertyStorage.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/storage/RendererInterceptorPropertyStorage.java
new file mode 100644
index 0000000..6cc8c1d
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/storage/RendererInterceptorPropertyStorage.java
@@ -0,0 +1,42 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.core.storage;

+

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+

+/**

+ * a storage which isn't used internally. it's for add-ons to easily store properties of interceptors.

+ * without braking backward compatibility, it's possible to use these properties in custom artifacts.

+ * rendering interception is an internal concept. so properties,... of it won't get into the api.

+ *

+ * @author Gerhard Petracek

+ * @since x.x.3

+ */

+@UsageInformation(UsageCategory.INTERNAL)

+public interface RendererInterceptorPropertyStorage

+{

+    void setProperty(String key, Object value);

+

+    Object getProperty(String key);

+

+    <T> T getProperty(String key, Class<T> targetClass);

+

+    void removeProperty(String key);

+}

diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/storage/RendererProxyStorage.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/storage/RendererProxyStorage.java
new file mode 100644
index 0000000..d71a75b
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/storage/RendererProxyStorage.java
@@ -0,0 +1,36 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.core.storage;

+

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import static org.apache.myfaces.extensions.validator.internal.UsageCategory.INTERNAL;

+

+/**

+ * @author Gerhard Petracek

+ * @since x.x.3

+ */

+@UsageInformation(INTERNAL)

+public interface RendererProxyStorage

+{

+    void setEntry(String rendererKey, String clientId, RendererProxyStorageEntry entry);

+

+    boolean containsEntry(String rendererKey, String clientId);

+

+    RendererProxyStorageEntry getEntry(String rendererKey, String clientId);

+}

diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/storage/RendererProxyStorageEntry.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/storage/RendererProxyStorageEntry.java
new file mode 100644
index 0000000..d934778
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/storage/RendererProxyStorageEntry.java
@@ -0,0 +1,87 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.myfaces.extensions.validator.core.storage;
+
+import org.apache.myfaces.extensions.validator.internal.UsageCategory;
+import org.apache.myfaces.extensions.validator.internal.UsageInformation;
+
+/**
+ * @author Gerhard Petracek
+ * @since 1.x.1
+ */
+@UsageInformation(UsageCategory.INTERNAL)
+public class RendererProxyStorageEntry
+{
+    private boolean decodeCalled = false;
+    private boolean encodeBeginCalled = false;
+    private boolean encodeChildrenCalled = false;
+    private boolean encodeEndCalled = false;
+
+    private Object convertedValue = null;
+
+    public boolean isDecodeCalled()
+    {
+        return decodeCalled;
+    }
+
+    public void setDecodeCalled(boolean decodeCalled)
+    {
+        this.decodeCalled = decodeCalled;
+    }
+
+    public boolean isEncodeBeginCalled()
+    {
+        return encodeBeginCalled;
+    }
+
+    public void setEncodeBeginCalled(boolean encodeBeginCalled)
+    {
+        this.encodeBeginCalled = encodeBeginCalled;
+    }
+
+    public boolean isEncodeChildrenCalled()
+    {
+        return encodeChildrenCalled;
+    }
+
+    public void setEncodeChildrenCalled(boolean encodeChildrenCalled)
+    {
+        this.encodeChildrenCalled = encodeChildrenCalled;
+    }
+
+    public boolean isEncodeEndCalled()
+    {
+        return encodeEndCalled;
+    }
+
+    public void setEncodeEndCalled(boolean encodeEndCalled)
+    {
+        this.encodeEndCalled = encodeEndCalled;
+    }
+
+    public Object getConvertedValue()
+    {
+        return convertedValue;
+    }
+
+    public void setConvertedValue(Object convertedValue)
+    {
+        this.convertedValue = convertedValue;
+    }
+}
\ No newline at end of file
diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/storage/StorageManager.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/storage/StorageManager.java
new file mode 100644
index 0000000..50c8397
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/storage/StorageManager.java
@@ -0,0 +1,35 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.core.storage;

+

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import static org.apache.myfaces.extensions.validator.internal.UsageCategory.API;

+

+/**

+ * manager to create and reset specific storage implementations

+ *

+ * @author Gerhard Petracek

+ * @since x.x.3

+ */

+@UsageInformation(API)

+public interface StorageManager<T>

+{

+    T create(String key);

+    void reset(String key);

+}
\ No newline at end of file
diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/storage/StorageManagerHolder.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/storage/StorageManagerHolder.java
new file mode 100644
index 0000000..fdf9538
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/storage/StorageManagerHolder.java
@@ -0,0 +1,35 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.core.storage;

+

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import static org.apache.myfaces.extensions.validator.internal.UsageCategory.API;

+

+/**

+ * interface to manage storage-manager instances

+ * 

+ * @author Gerhard Petracek

+ * @since x.x.3

+ */

+@UsageInformation(API)

+public interface StorageManagerHolder

+{

+    void setStorageManager(Class type, StorageManager storageManager, boolean override);

+    StorageManager getStorageManager(Class type);

+}
\ No newline at end of file
diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/storage/ValidationResult.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/storage/ValidationResult.java
new file mode 100644
index 0000000..f79327c
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/storage/ValidationResult.java
@@ -0,0 +1,49 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.core.storage;

+

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+import org.apache.myfaces.extensions.validator.internal.ToDo;

+import org.apache.myfaces.extensions.validator.internal.Priority;

+import org.apache.myfaces.extensions.validator.core.validation.message.FacesMessageHolder;

+

+import java.util.List;

+import java.util.ArrayList;

+

+/**

+ * @author Gerhard Petracek

+ * @since x.x.3

+ */

+@ToDo(value = Priority.LOW, description = "refactor it")

+@UsageInformation(UsageCategory.INTERNAL)

+class ValidationResult

+{

+    private List<FacesMessageHolder> facesMessageHolderList = new ArrayList<FacesMessageHolder>();

+

+    public void addFacesMessageHolder(FacesMessageHolder facesMessageHolder)

+    {

+        this.facesMessageHolderList.add(facesMessageHolder);

+    }

+

+    public List<FacesMessageHolder> getFacesMessageHolderList()

+    {

+        return facesMessageHolderList;

+    }

+}

diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/storage/ViolationSeverityInterpreterStorage.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/storage/ViolationSeverityInterpreterStorage.java
new file mode 100644
index 0000000..31669ec
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/storage/ViolationSeverityInterpreterStorage.java
@@ -0,0 +1,38 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.core.storage;

+

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+import org.apache.myfaces.extensions.validator.core.validation.parameter.ViolationSeverityInterpreter;

+

+/**

+ * suggested interface for a violation-severity-interpreter storage

+ * used by add-ons to change the interpreter for the current request

+ * 

+ * @author Gerhard Petracek

+ * @since x.x.3

+ */

+@UsageInformation(UsageCategory.API)

+public interface ViolationSeverityInterpreterStorage

+{

+    void setViolationSeverityInterpreter(ViolationSeverityInterpreter violationSeverityInterpreter);

+

+    ViolationSeverityInterpreter getViolationSeverityInterpreter();

+}

diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/storage/mapper/DefaultFacesInformationStorageNameMapper.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/storage/mapper/DefaultFacesInformationStorageNameMapper.java
new file mode 100644
index 0000000..1a10296
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/storage/mapper/DefaultFacesInformationStorageNameMapper.java
@@ -0,0 +1,43 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.core.storage.mapper;

+

+import org.apache.myfaces.extensions.validator.core.mapper.NameMapper;

+import org.apache.myfaces.extensions.validator.core.storage.FacesInformationStorage;

+import org.apache.myfaces.extensions.validator.core.storage.DefaultFacesInformationStorage;

+import org.apache.myfaces.extensions.validator.core.InvocationOrder;

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+

+/**

+ * use a public class to allow optional deregistration

+ *

+ * @author Gerhard Petracek

+ * @since x.x.3

+ */

+@InvocationOrder(100)

+@UsageInformation(UsageCategory.INTERNAL)

+public class DefaultFacesInformationStorageNameMapper implements NameMapper<String>

+{

+    public String createName(String source)

+    {

+        return (FacesInformationStorage.class.getName().equals(source)) ?

+                DefaultFacesInformationStorage.class.getName() : null;

+    }

+}

diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/storage/mapper/DefaultFacesMessageStorageNameMapper.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/storage/mapper/DefaultFacesMessageStorageNameMapper.java
new file mode 100644
index 0000000..b8e97f2
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/storage/mapper/DefaultFacesMessageStorageNameMapper.java
@@ -0,0 +1,43 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.core.storage.mapper;

+

+import org.apache.myfaces.extensions.validator.core.mapper.NameMapper;

+import org.apache.myfaces.extensions.validator.core.storage.DefaultFacesMessageStorage;

+import org.apache.myfaces.extensions.validator.core.storage.FacesMessageStorage;

+import org.apache.myfaces.extensions.validator.core.InvocationOrder;

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+

+/**

+ * use a public class to allow optional deregistration

+ *

+ * @author Gerhard Petracek

+ * @since x.x.3

+ */

+@InvocationOrder(100)

+@UsageInformation(UsageCategory.INTERNAL)

+public class DefaultFacesMessageStorageNameMapper implements NameMapper<String>

+{

+    public String createName(String source)

+    {

+        return (FacesMessageStorage.class.getName().equals(source)) ?

+                DefaultFacesMessageStorage.class.getName() : null;

+    }

+}

diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/storage/mapper/DefaultMetaDataStorageNameMapper.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/storage/mapper/DefaultMetaDataStorageNameMapper.java
new file mode 100644
index 0000000..45bfe97
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/storage/mapper/DefaultMetaDataStorageNameMapper.java
@@ -0,0 +1,43 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.core.storage.mapper;

+

+import org.apache.myfaces.extensions.validator.core.mapper.NameMapper;

+import org.apache.myfaces.extensions.validator.core.storage.MetaDataStorage;

+import org.apache.myfaces.extensions.validator.core.storage.DefaultMetaDataStorage;

+import org.apache.myfaces.extensions.validator.core.InvocationOrder;

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+

+/**

+ * use a public class to allow optional deregistration

+ *

+ * @author Gerhard Petracek

+ * @since x.x.3

+ */

+@InvocationOrder(100)

+@UsageInformation(UsageCategory.INTERNAL)

+public class DefaultMetaDataStorageNameMapper implements NameMapper<String>

+{

+    public String createName(String source)

+    {

+        return (MetaDataStorage.class.getName().equals(source)) ?

+                DefaultMetaDataStorage.class.getName() : null;

+    }

+}

diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/storage/mapper/DefaultPropertyStorageNameMapper.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/storage/mapper/DefaultPropertyStorageNameMapper.java
new file mode 100644
index 0000000..27f8623
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/storage/mapper/DefaultPropertyStorageNameMapper.java
@@ -0,0 +1,43 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.core.storage.mapper;

+

+import org.apache.myfaces.extensions.validator.core.mapper.NameMapper;

+import org.apache.myfaces.extensions.validator.core.storage.DefaultPropertyStorage;

+import org.apache.myfaces.extensions.validator.core.storage.PropertyStorage;

+import org.apache.myfaces.extensions.validator.core.InvocationOrder;

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+

+/**

+ * use a public class to allow optional deregistration

+ *

+ * @author Gerhard Petracek

+ * @since x.x.3

+ */

+@InvocationOrder(100)

+@UsageInformation(UsageCategory.INTERNAL)

+public class DefaultPropertyStorageNameMapper implements NameMapper<String>

+{

+    public String createName(String source)

+    {

+        return (PropertyStorage.class.getName().equals(source)) ?

+                DefaultPropertyStorage.class.getName() : null;

+    }

+}

diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/storage/mapper/DefaultRendererInterceptorPropertyStorageNameMapper.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/storage/mapper/DefaultRendererInterceptorPropertyStorageNameMapper.java
new file mode 100644
index 0000000..696841d
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/storage/mapper/DefaultRendererInterceptorPropertyStorageNameMapper.java
@@ -0,0 +1,43 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.core.storage.mapper;

+

+import org.apache.myfaces.extensions.validator.core.mapper.NameMapper;

+import org.apache.myfaces.extensions.validator.core.storage.RendererInterceptorPropertyStorage;

+import org.apache.myfaces.extensions.validator.core.storage.DefaultRendererInterceptorPropertyStorage;

+import org.apache.myfaces.extensions.validator.core.InvocationOrder;

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+

+/**

+ * use a public class to allow optional deregistration

+ *

+ * @author Gerhard Petracek

+ * @since x.x.3

+ */

+@InvocationOrder(100)

+@UsageInformation(UsageCategory.INTERNAL)

+public class DefaultRendererInterceptorPropertyStorageNameMapper implements NameMapper<String>

+{

+    public String createName(String source)

+    {

+        return (RendererInterceptorPropertyStorage.class.getName().equals(source)) ?

+                DefaultRendererInterceptorPropertyStorage.class.getName() : null;

+    }

+}

diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/storage/mapper/DefaultRendererProxyStorageNameMapper.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/storage/mapper/DefaultRendererProxyStorageNameMapper.java
new file mode 100644
index 0000000..c8e9de9
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/storage/mapper/DefaultRendererProxyStorageNameMapper.java
@@ -0,0 +1,44 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.core.storage.mapper;

+

+import org.apache.myfaces.extensions.validator.core.mapper.NameMapper;

+import org.apache.myfaces.extensions.validator.core.storage.DefaultRendererProxyStorage;

+import org.apache.myfaces.extensions.validator.core.storage.RendererProxyStorage;

+import org.apache.myfaces.extensions.validator.core.InvocationOrder;

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+

+/**

+ * use a public class to allow optional deregistration

+ *

+ * @author Gerhard Petracek

+ * @since x.x.3

+ */

+@InvocationOrder(100)

+@UsageInformation(UsageCategory.INTERNAL)

+public class DefaultRendererProxyStorageNameMapper implements NameMapper<String>

+{

+

+    public String createName(String source)

+    {

+        return (RendererProxyStorage.class.getName().equals(source)) ?

+                DefaultRendererProxyStorage.class.getName() : null;

+    }

+}

diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/storage/mapper/DefaultViolationSeverityInterpreterStorageNameMapper.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/storage/mapper/DefaultViolationSeverityInterpreterStorageNameMapper.java
new file mode 100644
index 0000000..19496d7
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/storage/mapper/DefaultViolationSeverityInterpreterStorageNameMapper.java
@@ -0,0 +1,43 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.core.storage.mapper;

+

+import org.apache.myfaces.extensions.validator.core.InvocationOrder;

+import org.apache.myfaces.extensions.validator.core.mapper.NameMapper;

+import org.apache.myfaces.extensions.validator.core.storage.DefaultViolationSeverityInterpreterStorage;

+import org.apache.myfaces.extensions.validator.core.storage.ViolationSeverityInterpreterStorage;

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+

+/**

+ * use a public class to allow optional deregistration

+ *

+ * @author Gerhard Petracek

+ * @since x.x.3

+ */

+@InvocationOrder(100)

+@UsageInformation(UsageCategory.INTERNAL)

+public class DefaultViolationSeverityInterpreterStorageNameMapper implements NameMapper<String>

+{

+    public String createName(String source)

+    {

+        return (ViolationSeverityInterpreterStorage.class.getName().equals(source)) ?

+                DefaultViolationSeverityInterpreterStorage.class.getName() : null;

+    }

+}

diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/validation/EmptyValueAwareValidationStrategy.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/validation/EmptyValueAwareValidationStrategy.java
new file mode 100644
index 0000000..cafbf65
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/validation/EmptyValueAwareValidationStrategy.java
@@ -0,0 +1,40 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.core.validation;

+

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+

+import static java.lang.annotation.ElementType.TYPE;

+import java.lang.annotation.Target;

+import java.lang.annotation.Retention;

+import java.lang.annotation.Documented;

+import static java.lang.annotation.RetentionPolicy.RUNTIME;

+

+/**

+ * @author Gerhard Petracek

+ * @since x.x.3

+ */

+@Target(TYPE)

+@Retention(RUNTIME)

+@Documented

+@UsageInformation(UsageCategory.API)

+public @interface EmptyValueAwareValidationStrategy

+{

+}

diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/validation/NullValueAwareValidationStrategy.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/validation/NullValueAwareValidationStrategy.java
new file mode 100644
index 0000000..cb750eb
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/validation/NullValueAwareValidationStrategy.java
@@ -0,0 +1,40 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.core.validation;

+

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+

+import static java.lang.annotation.ElementType.TYPE;

+import java.lang.annotation.Target;

+import java.lang.annotation.Retention;

+import java.lang.annotation.Documented;

+import static java.lang.annotation.RetentionPolicy.RUNTIME;

+

+/**

+ * @author Gerhard Petracek

+ * @since x.x.3

+ */

+@Target(TYPE)

+@Retention(RUNTIME)

+@Documented

+@UsageInformation(UsageCategory.API)

+public @interface NullValueAwareValidationStrategy

+{

+}
\ No newline at end of file
diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/validation/SkipValidationEvaluator.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/validation/SkipValidationEvaluator.java
new file mode 100644
index 0000000..9b4caa4
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/validation/SkipValidationEvaluator.java
@@ -0,0 +1,38 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.core.validation;

+

+import org.apache.myfaces.extensions.validator.core.validation.strategy.ValidationStrategy;

+import org.apache.myfaces.extensions.validator.core.metadata.MetaDataEntry;

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+

+import javax.faces.context.FacesContext;

+import javax.faces.component.UIComponent;

+

+/**

+ * @author Gerhard Petracek

+ * @since x.x.3

+ */

+@UsageInformation(UsageCategory.API)

+public interface SkipValidationEvaluator

+{

+    boolean skipValidation(FacesContext facesContext, UIComponent uiComponent,

+                           ValidationStrategy validationStrategy, MetaDataEntry entry);

+}

diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/validation/exception/RequiredValidatorException.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/validation/exception/RequiredValidatorException.java
new file mode 100644
index 0000000..5fb2bb0
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/validation/exception/RequiredValidatorException.java
@@ -0,0 +1,47 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.core.validation.exception;

+

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+

+import javax.faces.validator.ValidatorException;

+import javax.faces.application.FacesMessage;

+

+/**

+ * to handle special cases in ValidationExceptionInterceptors

+ *

+ * @author Gerhard Petracek

+ * @since x.x.3

+ */

+@UsageInformation(UsageCategory.API)

+public class RequiredValidatorException extends ValidatorException

+{

+    private static final long serialVersionUID = -4646331736428495884L;

+

+    public RequiredValidatorException(FacesMessage facesMessage)

+    {

+        super(facesMessage);

+    }

+

+    public RequiredValidatorException(FacesMessage facesMessage, Throwable throwable)

+    {

+        super(facesMessage, throwable);

+    }

+}

diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/validation/message/DefaultFacesMessageFactory.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/validation/message/DefaultFacesMessageFactory.java
new file mode 100644
index 0000000..a62510c
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/validation/message/DefaultFacesMessageFactory.java
@@ -0,0 +1,53 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.core.validation.message;

+

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+import org.apache.myfaces.extensions.validator.core.factory.FacesMessageFactory;

+

+import javax.faces.application.FacesMessage;

+

+/**

+ * @author Gerhard Petracek

+ * @since 1.x.2

+ */

+@UsageInformation(UsageCategory.INTERNAL)

+public class DefaultFacesMessageFactory implements FacesMessageFactory

+{

+    public FacesMessage convert(FacesMessage facesMessage)

+    {

+        if(isLabeledFacesMessage(facesMessage))

+        {

+            return facesMessage;

+        }

+        return create(facesMessage.getSeverity(), facesMessage.getSummary(), facesMessage.getDetail());

+    }

+

+    public FacesMessage create(FacesMessage.Severity severity, String summary, String detail)

+    {

+        return new ViolationMessage(severity, summary, detail);

+    }

+

+    protected boolean isLabeledFacesMessage(FacesMessage facesMessage)

+    {

+        //don't use the interface here

+        return facesMessage instanceof ViolationMessage;

+    }

+}

diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/validation/message/FacesMessageHolder.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/validation/message/FacesMessageHolder.java
new file mode 100644
index 0000000..a31c367
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/validation/message/FacesMessageHolder.java
@@ -0,0 +1,64 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.core.validation.message;

+

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+

+import javax.faces.application.FacesMessage;

+

+/**

+ * @author Gerhard Petracek

+ * @since x.x.3

+ */

+@UsageInformation(UsageCategory.INTERNAL)

+public class FacesMessageHolder

+{

+    private FacesMessage facesMessage;

+    private String clientId;

+

+    public FacesMessageHolder(FacesMessage facesMessage)

+    {

+        this.facesMessage = facesMessage;

+    }

+

+    public FacesMessageHolder(FacesMessage facesMessage, String clientId)

+    {

+        this.facesMessage = facesMessage;

+        setClientId(clientId);

+    }

+

+    public FacesMessage getFacesMessage()

+    {

+        return facesMessage;

+    }

+

+    public String getClientId()

+    {

+        return clientId;

+    }

+

+    public void setClientId(String clientId)

+    {

+        if(!"*".equals(clientId))

+        {

+            this.clientId = clientId;

+        }

+    }

+}

diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/validation/message/LabeledMessage.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/validation/message/LabeledMessage.java
new file mode 100644
index 0000000..3df7ae7
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/validation/message/LabeledMessage.java
@@ -0,0 +1,35 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.core.validation.message;

+

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+

+/**

+ * don't remove *Text - it would lead to an overlap with trinidad

+ * 

+ * @author Gerhard Petracek

+ * @since 1.x.2

+ */

+@UsageInformation(UsageCategory.API)

+public interface LabeledMessage

+{

+    String getLabelText();

+    void setLabelText(String label);

+}

diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/validation/message/ViolationMessage.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/validation/message/ViolationMessage.java
new file mode 100644
index 0000000..6944c76
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/validation/message/ViolationMessage.java
@@ -0,0 +1,108 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.core.validation.message;

+

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+

+import javax.faces.application.FacesMessage;

+

+/**

+ * @author Gerhard Petracek

+ * @since 1.x.2

+ */

+@UsageInformation(UsageCategory.INTERNAL)

+class ViolationMessage extends FacesMessage implements LabeledMessage

+{

+    private static final long serialVersionUID = 6903958942987711231L;

+    private String label;

+    private boolean summaryLabelReplaced = false;

+    private boolean detailLabelReplaced = false;

+

+    public ViolationMessage(String summary, String detail)

+    {

+        this(SEVERITY_ERROR, summary, detail);

+    }

+

+    public ViolationMessage(Severity severity, String summary, String detail)

+    {

+        setSeverity(severity);

+        setSummary(summary);

+        setDetail(detail);

+    }

+

+    public String getLabelText()

+    {

+        return label;

+    }

+

+    public void setLabelText(String label)

+    {

+        this.label = label;

+    }

+

+    @Override

+    public String getSummary()

+    {

+        if(label != null && !this.summaryLabelReplaced)

+        {

+            setSummary(getLabeledMesssage(super.getSummary(), getLabelText()));

+            this.summaryLabelReplaced = true;

+        }

+        return super.getSummary();

+    }

+

+    @Override

+    public String getDetail()

+    {

+        if(label != null && !this.detailLabelReplaced)

+        {

+            setDetail(getLabeledMesssage(super.getDetail(), getLabelText()));

+            this.detailLabelReplaced = true;

+        }

+        return super.getDetail();

+    }

+

+    private String getLabeledMesssage(String message, String label)

+    {

+        for(int i = 0; i < 3; i++)

+        {

+            if(message != null && message.contains("{" + i + "}"))

+            {

+                message = message.replace("{" + i + "}", label);

+            }

+        }

+

+        return message;

+    }

+

+    @Override

+    public void setSummary(String s)

+    {

+        super.setSummary(s);

+        this.summaryLabelReplaced = false;

+    }

+

+    @Override

+    public void setDetail(String s)

+    {

+        super.setDetail(s);

+        this.detailLabelReplaced = false;

+    }

+}

diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/validation/message/resolver/AbstractValidationErrorMessageResolver.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/validation/message/resolver/AbstractValidationErrorMessageResolver.java
new file mode 100644
index 0000000..56396d4
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/validation/message/resolver/AbstractValidationErrorMessageResolver.java
@@ -0,0 +1,267 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.core.validation.message.resolver;

+

+import org.apache.myfaces.extensions.validator.core.WebXmlParameter;

+import org.apache.myfaces.extensions.validator.core.ExtValContext;

+import org.apache.myfaces.extensions.validator.core.CustomInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+import org.apache.myfaces.extensions.validator.util.ExtValUtils;

+import org.apache.commons.logging.LogFactory;

+import org.apache.commons.logging.Log;

+

+import java.util.Locale;

+import java.util.MissingResourceException;

+import java.util.ResourceBundle;

+

+/**

+ * MessageResolver which uses property files.

+ * Subclasses just have to provide the package to look at.

+ * An implementation can also provide a custom name which is e.g. configured via web.xml.

+ *

+ * @author Gerhard Petracek

+ * @since 1.x.1

+ */

+@UsageInformation({UsageCategory.INTERNAL, UsageCategory.CUSTOMIZABLE})

+public abstract class AbstractValidationErrorMessageResolver implements MessageResolver

+{

+    public static final String MISSING_RESOURCE_MARKER = "???";

+

+    protected final Log logger = LogFactory.getLog(getClass());

+

+    private static String deactivateDefaultConvention = WebXmlParameter.DEACTIVATE_DEFAULT_CONVENTION;

+    private static ResourceBundle defaultBundle = null;

+    private String messageBundleBaseName;

+    //with jsf 1.1 only available if there is a custom bean

+    private String messageBundleVarName;

+

+    protected AbstractValidationErrorMessageResolver()

+    {

+        if(logger.isDebugEnabled())

+        {

+            logger.debug(getClass().getName() + " instantiated");

+        }

+    }

+

+    public String getMessage(String key, Locale locale)

+    {

+        if (key == null || key.equals(""))

+        {

+            return null;

+        }

+

+        if(key.contains(" "))

+        {

+            if(key.endsWith("_detail"))

+            {

+                key = key.substring(0, key.length() - 7);

+            }

+            return key;

+        }

+

+        String customMessage = null;

+

+        try

+        {

+            customMessage = tryToFindCustomMessage(key, locale);

+        }

+        catch (Throwable t)

+        {

+            //do nothing

+        }

+

+        if (customMessage != null)

+        {

+            return customMessage;

+        }

+

+        /*

+         * try to use the convention for the message bundle

+         */

+        try

+        {

+            customMessage = tryToUseMessageBundleConvention(key, locale);

+        }

+        catch (Throwable t)

+        {

+            //do nothing

+        }

+

+        if (customMessage != null)

+        {

+            return customMessage;

+        }

+

+        /*

+         * no message bundle or message found (with the convention)?

+         */

+

+        //try to load custom messages

+        try

+        {

+            customMessage = tryToFindCustomMessageInCustomResourceBundle(key, locale);

+        }

+        catch (Throwable t)

+        {

+            //do nothing - it was just a try

+        }

+

+        return determineMessage(key, locale, customMessage);

+    }

+

+    private String tryToFindCustomMessage(String key, Locale locale)

+    {

+        ResourceBundle resourceBundle;

+        String customMessage = null;

+

+        //only in case of a ValidationErrorMessageResolver which is configured as bean

+        if (this.messageBundleBaseName != null)

+        {

+            resourceBundle = ResourceBundle.getBundle(this.messageBundleBaseName, locale);

+            if (resourceBundle != null)

+            {

+                customMessage = resourceBundle.getString(key);

+            }

+            else

+            {

+                if(logger.isWarnEnabled())

+                {

+                    logger.warn("message bundle " + this.messageBundleBaseName + " not found");

+                }

+            }

+        }

+

+        //only in case of a ValidationErrorMessageResolver which is configured as bean

+        if (this.messageBundleVarName != null && customMessage == null)

+        {

+            resourceBundle = (ResourceBundle) ExtValUtils.getELHelper().getBean(messageBundleVarName);

+

+            if (resourceBundle != null)

+            {

+                customMessage = resourceBundle.getString(key);

+            }

+            else

+            {

+                if(logger.isWarnEnabled())

+                {

+                    logger.warn("message bundle var name " + this.messageBundleVarName + " not found");

+                }

+            }

+        }

+

+        return customMessage;

+    }

+

+    private String tryToUseMessageBundleConvention(String key, Locale locale)

+    {

+        if ((deactivateDefaultConvention == null || !deactivateDefaultConvention.equalsIgnoreCase("true"))

+            && isDefaultMessageBundleConventionActive())

+        {

+            if (defaultBundle == null)

+            {

+                try

+                {

+                    defaultBundle = ResourceBundle.getBundle(ExtValContext.getContext().getInformationProviderBean()

+                        .get(CustomInformation.MESSAGE_BUNDLE_NAME), locale);

+                }

+                catch (Throwable t)

+                {

+                    //do nothing

+                    deactivateDefaultConvention = "true";

+                }

+            }

+

+            if (defaultBundle != null)

+            {

+                return defaultBundle.getString(key);

+            }

+        }

+

+        return null;

+    }

+

+    private String tryToFindCustomMessageInCustomResourceBundle(String key, Locale locale)

+    {

+        ResourceBundle resourceBundle = tryToLoadCustomResourceBundle(locale);

+

+        if (resourceBundle != null)

+        {

+            try

+            {

+                return resourceBundle.getString(key);

+            }

+            catch (MissingResourceException e)

+            {

+                if(logger.isTraceEnabled())

+                {

+                    logger.trace("no custom message for " + key + " within " + getCustomBaseName(), e);

+                }

+            }

+        }

+        return null;

+    }

+

+    private ResourceBundle tryToLoadCustomResourceBundle(Locale locale)

+    {

+        String customBaseName = getCustomBaseName();

+

+        if(customBaseName != null)

+        {

+            return ResourceBundle.getBundle(customBaseName, locale);

+        }

+        return null;

+    }

+

+    private String determineMessage(String key, Locale locale, String customMessage)

+    {

+        //use custom name (if possible) otherwise: fallback to default message (if possible)

+        try

+        {

+            return (customMessage != null) ? customMessage

+                    : (getBaseName() != null) ? ResourceBundle.getBundle(getBaseName(), locale).getString(key) : null;

+        }

+        catch (MissingResourceException e)

+        {

+            return MISSING_RESOURCE_MARKER + key + MISSING_RESOURCE_MARKER;

+        }

+    }

+

+    protected boolean isDefaultMessageBundleConventionActive()

+    {

+        return true;

+    }

+

+    protected abstract String getBaseName();

+

+    protected String getCustomBaseName()

+    {

+        return null;

+    }

+

+    public void setMessageBundleBaseName(String messageBundleBaseName)

+    {

+        this.messageBundleBaseName = messageBundleBaseName;

+    }

+

+    public void setMessageBundleVarName(String messageBundleVarName)

+    {

+        this.messageBundleVarName = messageBundleVarName;

+    }

+}

diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/validation/message/resolver/DefaultMessageResolverFactory.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/validation/message/resolver/DefaultMessageResolverFactory.java
new file mode 100644
index 0000000..1818037
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/validation/message/resolver/DefaultMessageResolverFactory.java
@@ -0,0 +1,151 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.core.validation.message.resolver;

+

+import org.apache.myfaces.extensions.validator.core.factory.ClassMappingFactory;

+import org.apache.myfaces.extensions.validator.core.factory.AbstractNameMapperAwareFactory;

+import org.apache.myfaces.extensions.validator.core.mapper.NameMapper;

+import org.apache.myfaces.extensions.validator.core.validation.strategy.ValidationStrategy;

+import org.apache.myfaces.extensions.validator.core.initializer.configuration.StaticConfiguration;

+import org.apache.myfaces.extensions.validator.core.initializer.configuration.StaticConfigurationEntry;

+import org.apache.myfaces.extensions.validator.core.initializer.configuration.StaticConfigurationNames;

+import org.apache.myfaces.extensions.validator.core.ExtValContext;

+import org.apache.myfaces.extensions.validator.util.ClassUtils;

+import org.apache.myfaces.extensions.validator.util.ProxyUtils;

+import org.apache.myfaces.extensions.validator.internal.ToDo;

+import org.apache.myfaces.extensions.validator.internal.Priority;

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+import org.apache.commons.logging.Log;

+import org.apache.commons.logging.LogFactory;

+

+import java.util.ArrayList;

+import java.util.HashMap;

+import java.util.List;

+import java.util.Map;

+

+/**

+ * Factory which creates a MessageResolver for a given ValidationStrategy

+ *

+ * @author Gerhard Petracek

+ * @since 1.x.1

+ */

+@ToDo(value = Priority.MEDIUM, description = "add generic java api (de-/register mapping)")

+@UsageInformation({UsageCategory.INTERNAL, UsageCategory.CUSTOMIZABLE})

+public class DefaultMessageResolverFactory extends AbstractNameMapperAwareFactory<ValidationStrategy>

+        implements ClassMappingFactory<ValidationStrategy, MessageResolver>

+{

+    protected final Log logger = LogFactory.getLog(getClass());

+

+    private Map<String, String> strategyMessageResolverMapping;

+    private List<NameMapper<ValidationStrategy>> nameMapperList = new ArrayList<NameMapper<ValidationStrategy>>();

+

+    public DefaultMessageResolverFactory()

+    {

+        if(logger.isDebugEnabled())

+        {

+            logger.debug(getClass().getName() + " instantiated");

+        }

+    }

+

+    public MessageResolver create(ValidationStrategy validationStrategy)

+    {

+        String strategyName = ProxyUtils.getClassName(validationStrategy.getClass());

+

+        if (strategyMessageResolverMapping == null)

+        {

+            initStaticMappings();

+        }

+

+        if (strategyMessageResolverMapping.containsKey(strategyName))

+        {

+            return (MessageResolver) ClassUtils

+                .tryToInstantiateClassForName(strategyMessageResolverMapping.get(strategyName));

+        }

+

+        MessageResolver messageResolver;

+        String resolverName;

+        for (NameMapper<ValidationStrategy> nameMapper : nameMapperList)

+        {

+            //build convention (ValidationErrorMessageResolver)

+            resolverName = nameMapper.createName(validationStrategy);

+

+            //name wasn't mapped

+            if (resolverName == null || ProxyUtils.getClassName(validationStrategy.getClass()).equals(resolverName))

+            {

+                continue;

+            }

+

+            messageResolver = (MessageResolver) ClassUtils.tryToInstantiateClassForName(resolverName);

+

+            if (messageResolver != null)

+            {

+                addMapping(strategyName, resolverName);

+

+                if(logger.isTraceEnabled())

+                {

+                    logger.trace(resolverName + " used for " + strategyName);

+                }

+

+                return messageResolver;

+            }

+        }

+

+        addMapping(strategyName, DefaultValidationErrorMessageResolver.class.getName());

+        return new DefaultValidationErrorMessageResolver();

+    }

+

+    private synchronized void initStaticMappings()

+    {

+        strategyMessageResolverMapping = new HashMap<String, String>();

+

+        //setup internal static mappings

+        for (StaticConfiguration<String, String> staticConfig :

+            ExtValContext.getContext().getStaticConfiguration(

+                StaticConfigurationNames.VALIDATION_STRATEGY_TO_MESSAGE_RESOLVER_CONFIG))

+        {

+            setupMappings(staticConfig.getMapping());

+        }

+    }

+

+    private void setupMappings(List<StaticConfigurationEntry<String,String>> mappings)

+    {

+        for(StaticConfigurationEntry<String, String> mapping : mappings)

+        {

+            addMapping(mapping.getSource(), mapping.getTarget());

+        }

+    }

+

+    @ToDo(value = Priority.MEDIUM, description = "logging")

+    private synchronized void addMapping(String validationStrategyName, String messageResolverName)

+    {

+        if(logger.isTraceEnabled())

+        {

+            logger.trace("adding static validation strategy to message resolver mapping: "

+                + validationStrategyName + " -> " + messageResolverName);

+        }

+

+        strategyMessageResolverMapping.put(validationStrategyName, messageResolverName);

+    }

+

+    protected List<NameMapper<ValidationStrategy>> getNameMapperList()

+    {

+        return nameMapperList;

+    }

+}

diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/validation/message/resolver/DefaultValidationErrorMessageResolver.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/validation/message/resolver/DefaultValidationErrorMessageResolver.java
new file mode 100644
index 0000000..079edc6
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/validation/message/resolver/DefaultValidationErrorMessageResolver.java
@@ -0,0 +1,48 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.core.validation.message.resolver;

+

+import org.apache.myfaces.extensions.validator.core.WebXmlParameter;

+import org.apache.myfaces.extensions.validator.core.InternalConventionProvider;

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+

+/**

+ * Default MessageResolver which uses the default convention for the message bundle.

+ * It's possible to provide a custom message bundle via web.xml

+ *

+ * @author Gerhard Petracek

+ * @since 1.x.1

+ */

+@UsageInformation({UsageCategory.INTERNAL, UsageCategory.CUSTOMIZABLE})

+public class DefaultValidationErrorMessageResolver extends AbstractValidationErrorMessageResolver

+{

+    private static final String CUSTOM_BUNDLE = WebXmlParameter.CUSTOM_MESSAGE_BUNDLE;

+

+    //not used at the moment - just for a convention

+    protected String getBaseName()

+    {

+        return InternalConventionProvider.getModuleMessageBundleName(getClass().getPackage().getName());

+    }

+

+    protected String getCustomBaseName()

+    {

+        return CUSTOM_BUNDLE;

+    }

+}
\ No newline at end of file
diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/validation/message/resolver/MessageResolver.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/validation/message/resolver/MessageResolver.java
new file mode 100644
index 0000000..dcca1c1
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/validation/message/resolver/MessageResolver.java
@@ -0,0 +1,36 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.core.validation.message.resolver;

+

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+

+import java.util.Locale;

+

+/**

+ * Interface for MessageResolvers independent of the message source.

+ *

+ * @author Gerhard Petracek

+ * @since 1.x.1

+ */

+@UsageInformation(UsageCategory.API)

+public interface MessageResolver

+{

+    String getMessage(String key, Locale locale);

+}
\ No newline at end of file
diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/validation/message/resolver/mapper/AbstractValidationStrategyToMsgResolverNameMapper.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/validation/message/resolver/mapper/AbstractValidationStrategyToMsgResolverNameMapper.java
new file mode 100644
index 0000000..10d40b6
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/validation/message/resolver/mapper/AbstractValidationStrategyToMsgResolverNameMapper.java
@@ -0,0 +1,44 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.core.validation.message.resolver.mapper;

+

+import org.apache.myfaces.extensions.validator.core.mapper.NameMapper;

+import org.apache.myfaces.extensions.validator.core.validation.strategy.ValidationStrategy;

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+import org.apache.commons.logging.Log;

+import org.apache.commons.logging.LogFactory;

+

+/**

+ * @author Gerhard Petracek

+ * @since 1.x.1

+ */

+@UsageInformation(UsageCategory.INTERNAL)

+public abstract class AbstractValidationStrategyToMsgResolverNameMapper implements NameMapper<ValidationStrategy>

+{

+    protected final Log logger = LogFactory.getLog(getClass());

+

+    public AbstractValidationStrategyToMsgResolverNameMapper()

+    {

+        if(logger.isDebugEnabled())

+        {

+            logger.debug(getClass().getName() + " instantiated");

+        }

+    }

+}
\ No newline at end of file
diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/validation/message/resolver/mapper/CustomConfiguredValidationStrategyToMsgResolverNameMapper.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/validation/message/resolver/mapper/CustomConfiguredValidationStrategyToMsgResolverNameMapper.java
new file mode 100644
index 0000000..76c08e8
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/validation/message/resolver/mapper/CustomConfiguredValidationStrategyToMsgResolverNameMapper.java
@@ -0,0 +1,45 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.core.validation.message.resolver.mapper;

+

+import org.apache.myfaces.extensions.validator.core.WebXmlParameter;

+import org.apache.myfaces.extensions.validator.core.InvocationOrder;

+import org.apache.myfaces.extensions.validator.core.mapper.AbstractCustomNameMapper;

+import org.apache.myfaces.extensions.validator.core.validation.strategy.ValidationStrategy;

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+

+/**

+ * To provide a custom NameMapper to map ValidationStrategies to MessageResolvers.

+ * (configured via web.xml)

+ *

+ * @author Gerhard Petracek

+ * @since 1.x.1

+ */

+@InvocationOrder(100)

+@UsageInformation({UsageCategory.INTERNAL, UsageCategory.CUSTOMIZABLE})

+public class CustomConfiguredValidationStrategyToMsgResolverNameMapper extends

+    AbstractCustomNameMapper<ValidationStrategy>

+{

+

+    protected String getCustomNameMapperClassName()

+    {

+        return WebXmlParameter.CUSTOM_VALIDATION_STRATEGY_TO_MESSAGE_RESOLVER_NAME_MAPPER;

+    }

+}
\ No newline at end of file
diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/validation/message/resolver/mapper/CustomConventionValidationStrategyToMsgResolverNameMapper.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/validation/message/resolver/mapper/CustomConventionValidationStrategyToMsgResolverNameMapper.java
new file mode 100644
index 0000000..343c013
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/validation/message/resolver/mapper/CustomConventionValidationStrategyToMsgResolverNameMapper.java
@@ -0,0 +1,49 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.core.validation.message.resolver.mapper;

+

+import org.apache.myfaces.extensions.validator.core.mapper.AbstractCustomNameMapper;

+import org.apache.myfaces.extensions.validator.core.validation.strategy.ValidationStrategy;

+import org.apache.myfaces.extensions.validator.core.ExtValContext;

+import org.apache.myfaces.extensions.validator.core.CustomInformation;

+import org.apache.myfaces.extensions.validator.core.InvocationOrder;

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+

+/**

+ * To provide a custom NameMapper to map ValidationStrategy to MessageResolver.

+ * (configured via information provider bean)

+ * The bean provides the default name (convention).

+ * It's possible to provide a custom full qualified name. (= customizable convention)

+ *

+ * @author Gerhard Petracek

+ * @since 1.x.1

+ */

+@InvocationOrder(200)

+@UsageInformation({UsageCategory.INTERNAL, UsageCategory.CUSTOMIZABLE})

+public class CustomConventionValidationStrategyToMsgResolverNameMapper extends

+    AbstractCustomNameMapper<ValidationStrategy>

+{

+

+    protected String getCustomNameMapperClassName()

+    {

+        return ExtValContext.getContext().getInformationProviderBean()

+            .get(CustomInformation.VALIDATION_STRATEGY_TO_MSG_RESOLVER_NAME_MAPPER);

+    }

+}
\ No newline at end of file
diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/validation/message/resolver/mapper/DefaultModuleValidationStrategyToMsgResolverNameMapper.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/validation/message/resolver/mapper/DefaultModuleValidationStrategyToMsgResolverNameMapper.java
new file mode 100644
index 0000000..0ebb4d6
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/validation/message/resolver/mapper/DefaultModuleValidationStrategyToMsgResolverNameMapper.java
@@ -0,0 +1,42 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.core.validation.message.resolver.mapper;

+

+import org.apache.myfaces.extensions.validator.core.validation.message.resolver.DefaultValidationErrorMessageResolver;

+import org.apache.myfaces.extensions.validator.core.InvocationOrder;

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+

+/**

+ * In order to provide a NameMapper per validation module.

+ *

+ * @author Gerhard Petracek

+ * @since 1.x.1

+ */

+@InvocationOrder(310)

+@UsageInformation({UsageCategory.INTERNAL, UsageCategory.CUSTOMIZABLE})

+public class DefaultModuleValidationStrategyToMsgResolverNameMapper extends

+    DefaultValidationStrategyToMsgResolverNameMapper

+{

+    @Override

+    protected String getClassName(String strategyClassName)

+    {

+        return DefaultValidationErrorMessageResolver.class.getSimpleName();

+    }

+}
\ No newline at end of file
diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/validation/message/resolver/mapper/DefaultValidationStrategyToMsgResolverNameMapper.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/validation/message/resolver/mapper/DefaultValidationStrategyToMsgResolverNameMapper.java
new file mode 100644
index 0000000..3da477b
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/validation/message/resolver/mapper/DefaultValidationStrategyToMsgResolverNameMapper.java
@@ -0,0 +1,51 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.core.validation.message.resolver.mapper;

+

+import org.apache.myfaces.extensions.validator.core.validation.strategy.ValidationStrategy;

+import org.apache.myfaces.extensions.validator.core.InternalConventionProvider;

+import org.apache.myfaces.extensions.validator.core.InvocationOrder;

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+import org.apache.myfaces.extensions.validator.util.ProxyUtils;

+

+/**

+ * Default implementation which maps ExtVal ValidationStrategies to ExtVal MessageResolvers.

+ *

+ * @author Gerhard Petracek

+ * @since 1.x.1

+ */

+@InvocationOrder(300)

+@UsageInformation(UsageCategory.INTERNAL)

+public class DefaultValidationStrategyToMsgResolverNameMapper extends

+    AbstractValidationStrategyToMsgResolverNameMapper

+{

+    public String createName(ValidationStrategy validationStrategy)

+    {

+        Class<? extends ValidationStrategy> validationStrategyClass = ProxyUtils

+                .getUnproxiedClass(validationStrategy.getClass(), ValidationStrategy.class);

+        return InternalConventionProvider.getMessageResolverClassName(validationStrategyClass,

+                                                     getClassName(validationStrategyClass.getSimpleName()));

+    }

+

+    protected String getClassName(String strategyClassName)

+    {

+        return InternalConventionProvider.getMessageResolverClassName(strategyClassName);

+    }

+}

diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/validation/message/resolver/mapper/SimpleValidationStrategyToMsgResolverNameMapper.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/validation/message/resolver/mapper/SimpleValidationStrategyToMsgResolverNameMapper.java
new file mode 100644
index 0000000..d63d970
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/validation/message/resolver/mapper/SimpleValidationStrategyToMsgResolverNameMapper.java
@@ -0,0 +1,45 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.core.validation.message.resolver.mapper;

+

+import org.apache.myfaces.extensions.validator.core.ExtValContext;

+import org.apache.myfaces.extensions.validator.core.CustomInformation;

+import org.apache.myfaces.extensions.validator.core.InternalConventionProvider;

+import org.apache.myfaces.extensions.validator.core.InvocationOrder;

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+

+/**

+ * It's an alternative Mapper to place ValidationStrategies and MessageResolvers in the same package.

+ *

+ * @author Gerhard Petracek

+ * @since 1.x.1

+ */

+@InvocationOrder(400)

+@UsageInformation({UsageCategory.INTERNAL})

+public class SimpleValidationStrategyToMsgResolverNameMapper extends

+    DefaultValidationStrategyToMsgResolverNameMapper

+{

+    protected String getClassName(String strategyClassName)

+    {

+        String customPostfix = ExtValContext.getContext().getInformationProviderBean()

+            .get(CustomInformation.VALIDATION_ERROR_MESSAGE_RESOLVER_POSTFIX);

+        return InternalConventionProvider.getValidationStrategyBasedName(strategyClassName, customPostfix);

+    }

+}
\ No newline at end of file
diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/validation/parameter/DefaultValidationParameterExtractor.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/validation/parameter/DefaultValidationParameterExtractor.java
new file mode 100644
index 0000000..5d38f54
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/validation/parameter/DefaultValidationParameterExtractor.java
@@ -0,0 +1,400 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.core.validation.parameter;

+

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+import org.apache.myfaces.extensions.validator.internal.ToDo;

+import org.apache.myfaces.extensions.validator.internal.Priority;

+import org.apache.commons.logging.Log;

+import org.apache.commons.logging.LogFactory;

+

+import java.util.Map;

+import java.util.List;

+import java.util.HashMap;

+import java.util.ArrayList;

+import java.lang.annotation.Annotation;

+import java.lang.reflect.Field;

+import java.lang.reflect.Method;

+import java.lang.reflect.Type;

+import java.lang.reflect.ParameterizedType;

+import java.lang.reflect.GenericArrayType;

+import java.lang.reflect.WildcardType;

+import java.lang.reflect.Modifier;

+

+/**

+ * @author Gerhard Petracek

+ * @since x.x.3

+ */

+@UsageInformation(UsageCategory.INTERNAL)

+public class DefaultValidationParameterExtractor implements ValidationParameterExtractor

+{

+    protected final Log logger = LogFactory.getLog(getClass());

+

+    public Map<Object, List<Object>> extract(Annotation annotation)

+    {

+        return extractById(annotation, null);

+    }

+

+    public List<Object> extract(Annotation annotation, Object key)

+    {

+        return extractById(annotation, key, null);

+    }

+

+    public <T> List<T> extract(Annotation annotation, Object key, Class<T> valueType)

+    {

+        return extractById(annotation, key, valueType, null);

+    }

+

+    public <T> T extract(Annotation annotation, Object key, Class<T> valueType, Class valueId)

+    {

+        List<T> results = extractById(annotation, key, valueType, valueId);

+

+        if(results.iterator().hasNext())

+        {

+            return results.iterator().next();

+        }

+

+        return null;

+    }

+

+    @SuppressWarnings({"unchecked"})

+    public <T> List<T> extractById(Annotation annotation, Object key, Class<T> valueType, Class valueId)

+    {

+        List<Object> result = new ArrayList<Object>();

+

+        for(Object entry : extractById(annotation, key, valueId))

+        {

+            if(valueType.isAssignableFrom(entry.getClass()))

+            {

+                result.add(entry);

+            }

+        }

+

+        return (List<T>)result;

+    }

+

+    public List<Object> extractById(Annotation annotation, Object key, Class valueId)

+    {

+        Map<Object, List<Object>> fullResult = extractById(annotation, valueId);

+

+        if(fullResult.containsKey(key))

+        {

+            return fullResult.get(key);

+        }

+

+        return new ArrayList<Object>();

+    }

+

+    @ToDo(value = Priority.MEDIUM, description = "add web.xml parameter for performance tuning to deactivate the scan")

+    public Map<Object, List<Object>> extractById(Annotation annotation, Class valueId)

+    {

+        Map<Object, List<Object>> result = new HashMap<Object, List<Object>>();

+

+        for(Method currentAnnotationAttribute : annotation.annotationType().getDeclaredMethods())

+        {

+            try

+            {

+                if(!isValidationParameter(currentAnnotationAttribute.getGenericReturnType()))

+                {

+                    continue;

+                }

+

+                Object parameterValue = currentAnnotationAttribute.invoke(annotation);

+

+                if(parameterValue instanceof Class[])

+                {

+                    for(Class currentParameterValue : (Class[])parameterValue)

+                    {

+                        //keep check so that following is true:

+                        //if at least one parameter is found which tells that it isn't a blocking error, let it pass

+                        processParameterValue(annotation, currentParameterValue, result, valueId);

+                    }

+                }

+                else if(parameterValue instanceof Class)

+                {

+                    //keep check so that following is true:

+                    //if at least one parameter is found which tells that it isn't a blocking error, let it pass

+                    processParameterValue(annotation, (Class)parameterValue, result, valueId);

+                }

+            }

+            catch (Throwable e)

+            {

+                if(this.logger.isWarnEnabled())

+                {

+                    this.logger.warn(e);

+                }

+            }

+        }

+

+        return result;

+    }

+

+    /*

+     * don't use the Introspector in this case

+     * if you have a better solution which supports all supported parameter styles (see extval wiki),

+     * you can impl. it and use it (exchange the impls. via the ExtValContext).

+     * furthermore, you can provide the fix for the community

+     */

+    private void processParameterValue(

+            Annotation annotation, Class paramClass, Map<Object, List<Object>> result, Class valueId) throws Exception

+    {

+        Object key = null;

+        List<Object> parameterValues = new ArrayList<Object>();

+

+        if(ValidationParameter.class.isAssignableFrom(paramClass))

+        {

+            List<Field> processedFields = new ArrayList<Field>();

+            List<Method> processedMethods = new ArrayList<Method>();

+

+            Class currentParamClass = paramClass;

+            while (currentParamClass != null && !Object.class.getName().equals(currentParamClass.getName()))

+            {

+                /*

+                 * process class

+                 */

+                //support pure interface approach e.g. ViolationSeverity.Warn.class

+                for(Field currentField : currentParamClass.getDeclaredFields())

+                {

+                    if(!processedFields.contains(currentField))

+                    {

+                        key = processFoundField(annotation, currentField, parameterValues, key, valueId);

+                        processedFields.add(currentField);

+                    }

+                }

+

+                //inspect the other methods of the implementing class

+                for(Method currentMethod : currentParamClass.getDeclaredMethods())

+                {

+                    if(!processedMethods.contains(currentMethod))

+                    {

+                        key = processFoundMethod(currentParamClass, currentMethod, parameterValues, key, valueId);

+                        processedMethods.add(currentMethod);

+                    }

+                }

+

+                /*

+                 * process interfaces

+                 */

+                for(Class currentInterface : currentParamClass.getInterfaces())

+                {

+                    if(!ValidationParameter.class.isAssignableFrom(currentInterface))

+                    {

+                        continue;

+                    }

+

+                    //support interface + impl. approach e.g. MyParamImpl.class

+                    //(MyParamImpl implements MyParam

+                    //MyParam extends ValidationParameter

+                    //methods in the interface have to be marked with @ParameterValue and @ParameterKey

+                    for(Method currentMethod : currentInterface.getDeclaredMethods())

+                    {

+                        if(!processedMethods.contains(currentMethod))

+                        {

+                            key = processFoundMethod(currentParamClass, currentMethod, parameterValues, key, valueId);

+                            processedMethods.add(currentMethod);

+                        }

+                    }

+

+                    for(Field currentField : currentInterface.getDeclaredFields())

+                    {

+                        if(!processedFields.contains(currentField))

+                        {

+                            key = processFoundField(annotation, currentField, parameterValues, key, valueId);

+                            processedFields.add(currentField);

+                        }

+                    }

+                }

+

+                currentParamClass = currentParamClass.getSuperclass();

+            }

+        }

+

+        key = createDefaultKey(key, paramClass);

+

+        if(parameterValues.isEmpty())

+        {

+            //@ParameterValue is optional as well

+            parameterValues.add(key);

+        }

+

+        if(result.containsKey(key))

+        {

+            result.get(key).addAll(parameterValues);

+        }

+        else

+        {

+            result.put(key, parameterValues);

+        }

+    }

+

+    private Object createDefaultKey(Object key, Class currentClass)

+    {

+        if(key == null)

+        {

+            //check for super-interface (exclude ValidationParameter itself)

+            for(Class interfaceClass : currentClass.getInterfaces())

+            {

+                if(ValidationParameter.class.isAssignableFrom(interfaceClass) &&

+                        (!interfaceClass.getName().equals(ValidationParameter.class.getName())))

+                {

+                    key = interfaceClass;

+                    break;

+                }

+            }

+        }

+

+        if(key == null)

+        {

+            key = currentClass;

+        }

+

+        return key;

+    }

+

+    private Object processFoundField(

+            Object instance, Field currentField, List<Object> paramValues, Object key, Class valueId)

+    {

+        Object newKey = null;

+        if(key == null && currentField.isAnnotationPresent(ParameterKey.class))

+        {

+            try

+            {

+                newKey = currentField.get(instance);

+            }

+            catch (Throwable e)

+            {

+                if(this.logger.isWarnEnabled())

+                {

+                    this.logger.warn(e);

+                }

+            }

+        }

+        //no "else if" to allow both at one field

+        if(currentField.isAnnotationPresent(ParameterValue.class))

+        {

+            if(valueId == null || valueId.equals(currentField.getAnnotation(ParameterValue.class).id()))

+            {

+                currentField.setAccessible(true);

+                try

+                {

+                    paramValues.add(currentField.get(instance));

+                }

+                catch (Throwable e)

+                {

+                    if(this.logger.isWarnEnabled())

+                    {

+                        this.logger.warn(e);

+                    }

+                }

+            }

+        }

+

+        return newKey != null ? newKey : key;

+    }

+

+    private Object processFoundMethod(

+            Class paramClass, Method currentMethod, List<Object> parameterValues, Object key, Class valueId)

+    {

+        Object newKey = null;

+        if(key == null && currentMethod.isAnnotationPresent(ParameterKey.class))

+        {

+            try

+            {

+                if(!(Modifier.isAbstract(paramClass.getModifiers()) || Modifier.isInterface(paramClass.getModifiers())))

+                {

+                    newKey = currentMethod.invoke(paramClass.newInstance());

+                }

+            }

+            catch (Throwable e)

+            {

+                if(this.logger.isWarnEnabled())

+                {

+                    this.logger.warn(e);

+                }

+            }

+        }

+        //no "else if" to allow both at one field

+        if(currentMethod.isAnnotationPresent(ParameterValue.class))

+        {

+            if(valueId == null || valueId.equals(currentMethod.getAnnotation(ParameterValue.class).id()))

+            {

+                currentMethod.setAccessible(true);

+                try

+                {

+                    parameterValues.add(currentMethod.invoke(paramClass.newInstance()));

+                }

+                catch (Throwable e)

+                {

+                    //check if it's a none-static inner class -> return this class

+                    if(paramClass.getEnclosingClass() != null)

+                    {

+                        parameterValues.add(paramClass);

+                    }

+                    else if(this.logger.isWarnEnabled())

+                    {

+                        this.logger.warn(e);

+                    }

+                }

+            }

+        }

+

+        return newKey != null ? newKey : key;

+    }

+

+    private boolean isValidationParameter(Type genericReturnType)

+    {

+        if(genericReturnType instanceof GenericArrayType)

+        {

+            if(((GenericArrayType)genericReturnType).getGenericComponentType() instanceof ParameterizedType)

+            {

+                return analyzeParameterizedType(

+                        (ParameterizedType)((GenericArrayType)genericReturnType).getGenericComponentType());

+            }

+        }

+        else if(genericReturnType instanceof ParameterizedType)

+        {

+            return analyzeParameterizedType(

+                    (ParameterizedType)genericReturnType);

+        }

+

+        return false;

+    }

+

+    private boolean analyzeParameterizedType(ParameterizedType parameterizedType)

+    {

+        for(Type type : parameterizedType.getActualTypeArguments())

+        {

+            if(type instanceof WildcardType)

+            {

+                for(Type upperBounds : ((WildcardType)type).getUpperBounds())

+                {

+                    if(upperBounds instanceof Class &&

+                            //for attributes like: Class<? extends InheritedFromValidationParameter> value();

+                            ValidationParameter.class.isAssignableFrom((Class)upperBounds))

+                    {

+                        return true;

+                    }

+                }

+            }

+        }

+

+        return false;

+    }

+}
\ No newline at end of file
diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/validation/parameter/DefaultValidationParameterExtractorFactory.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/validation/parameter/DefaultValidationParameterExtractorFactory.java
new file mode 100644
index 0000000..da2a73c
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/validation/parameter/DefaultValidationParameterExtractorFactory.java
@@ -0,0 +1,83 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.core.validation.parameter;

+

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+import org.apache.myfaces.extensions.validator.core.WebXmlParameter;

+import org.apache.myfaces.extensions.validator.core.ExtValContext;

+import org.apache.myfaces.extensions.validator.core.CustomInformation;

+import org.apache.myfaces.extensions.validator.util.ClassUtils;

+import org.apache.commons.logging.Log;

+import org.apache.commons.logging.LogFactory;

+

+import java.util.ArrayList;

+import java.util.List;

+

+/**

+ * @author Gerhard Petracek

+ * @since x.x.3

+ */

+@UsageInformation(UsageCategory.INTERNAL)

+public class DefaultValidationParameterExtractorFactory implements ValidationParameterExtractorFactory

+{

+    private final Log logger = LogFactory.getLog(getClass());

+

+    private static ValidationParameterExtractor validationParameterExtractor = null;

+

+    public DefaultValidationParameterExtractorFactory()

+    {

+        if(logger.isDebugEnabled())

+        {

+            logger.debug(getClass().getName() + " instantiated");

+        }

+    }

+

+    public ValidationParameterExtractor create()

+    {

+        if (validationParameterExtractor == null)

+        {

+            List<String> validationParameterExtractorClassNames = new ArrayList<String>();

+

+            validationParameterExtractorClassNames.add(WebXmlParameter.CUSTOM_VALIDATION_PARAMETER_EXTRACTOR);

+            validationParameterExtractorClassNames

+                .add(ExtValContext.getContext().getInformationProviderBean()

+                    .get(CustomInformation.VALIDATION_PARAMETER_EXTRACTOR));

+            validationParameterExtractorClassNames.add(DefaultValidationParameterExtractor.class.getName());

+

+            for (String className : validationParameterExtractorClassNames)

+            {

+                validationParameterExtractor = (ValidationParameterExtractor)

+                        ClassUtils.tryToInstantiateClassForName(className);

+

+                if (validationParameterExtractor != null)

+                {

+                    break;

+                }

+            }

+        }

+

+        if(logger.isTraceEnabled())

+        {

+            logger.trace(validationParameterExtractor.getClass().getName() + " created");

+        }

+

+        return validationParameterExtractor;

+    }

+}
\ No newline at end of file
diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/validation/parameter/DefaultValidationParameterFactory.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/validation/parameter/DefaultValidationParameterFactory.java
new file mode 100644
index 0000000..3d5c8fe
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/validation/parameter/DefaultValidationParameterFactory.java
@@ -0,0 +1,123 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.core.validation.parameter;

+

+import org.apache.myfaces.extensions.validator.core.ExtValContext;

+import org.apache.myfaces.extensions.validator.core.factory.ClassMappingFactory;

+import org.apache.myfaces.extensions.validator.core.initializer.configuration.StaticConfiguration;

+import org.apache.myfaces.extensions.validator.core.initializer.configuration.StaticConfigurationEntry;

+import org.apache.myfaces.extensions.validator.core.initializer.configuration.StaticConfigurationNames;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.util.ClassUtils;

+

+import java.util.HashMap;

+import java.util.List;

+import java.util.Map;

+

+/**

+ * maps internal parameters to optionally available custom parameters

+ *

+ * @author Gerhard Petracek

+ * @since x.x.3

+ */

+@UsageInformation(UsageCategory.INTERNAL)

+public class DefaultValidationParameterFactory implements ClassMappingFactory<Class, Class>

+{

+    private Map<Class, Class> parameterMapping = new HashMap<Class, Class>();

+

+    public Class create(Class source)

+    {

+        if (this.parameterMapping.containsKey(source))

+        {

+            return this.parameterMapping.get(source);

+        }

+

+        Class result;

+

+        //it's important to look for the static configs first - global parameters are used internally

+        result = tryToFindStaticConfig(source);

+

+        if (result == null)

+        {

+            result = tryToFindGlobalParameter(source);

+        }

+

+        if (result == null)

+        {

+            result = source;

+        }

+

+        cacheMapping(source, result);

+        return result;

+    }

+

+    private Class tryToFindGlobalParameter(Class source)

+    {

+        Object target = ExtValContext.getContext().getGlobalProperty(source.getName());

+

+        if (target instanceof Class)

+        {

+            return (Class) target;

+        }

+        return null;

+    }

+

+    private Class tryToFindStaticConfig(Class source)

+    {

+        Class result = null;

+        for (StaticConfiguration<String, String> config : ExtValContext.getContext()

+                .getStaticConfiguration(StaticConfigurationNames.VALIDATION_PARAMETER_CONFIG))

+        {

+            result = tryToMap(source, config.getMapping());

+

+            if (result != null)

+            {

+                break;

+            }

+        }

+

+        return result;

+    }

+

+    private Class tryToMap(Class source, List<StaticConfigurationEntry<String, String>> mapping)

+    {

+        Class target = null;

+

+        for (StaticConfigurationEntry<String, String> entry : mapping)

+        {

+            if (source.getName().equals(entry.getSource()))

+            {

+                target = ClassUtils.tryToLoadClassForName(entry.getTarget());

+

+                if (target != null)

+                {

+                    break;

+                }

+            }

+        }

+

+        return target;

+    }

+

+    private void cacheMapping(Class source, Class target)

+    {

+        this.parameterMapping.put(source, target);

+    }

+}

diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/validation/parameter/DefaultViolationSeverityInterpreter.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/validation/parameter/DefaultViolationSeverityInterpreter.java
new file mode 100644
index 0000000..f26c7f1
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/validation/parameter/DefaultViolationSeverityInterpreter.java
@@ -0,0 +1,66 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.core.validation.parameter;

+

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+

+import javax.faces.context.FacesContext;

+import javax.faces.component.UIComponent;

+import javax.faces.application.FacesMessage;

+

+/**

+ * mechanism to change the default behavior of extval

+ *

+ * @author Gerhard Petracek

+ * @since x.x.3

+ */

+@UsageInformation(UsageCategory.INTERNAL)

+public class DefaultViolationSeverityInterpreter implements ViolationSeverityInterpreter

+{

+    public boolean severityBlocksNavigation(

+            FacesContext facesContext, UIComponent uiComponent, FacesMessage.Severity severity)

+    {

+        return FacesMessage.SEVERITY_ERROR.equals(severity) || FacesMessage.SEVERITY_FATAL.equals(severity);

+    }

+

+    public boolean severityCausesValidatorException(

+            FacesContext facesContext, UIComponent uiComponent, FacesMessage.Severity severity)

+    {

+        return FacesMessage.SEVERITY_ERROR.equals(severity) || FacesMessage.SEVERITY_FATAL.equals(severity);

+    }

+

+    public boolean severityCausesViolationMessage(

+            FacesContext facesContext, UIComponent uiComponent, FacesMessage.Severity severity)

+    {

+        return true;

+    }

+

+    public boolean severityBlocksSubmit(

+            FacesContext facesContext, UIComponent uiComponent, FacesMessage.Severity severity)

+    {

+        return FacesMessage.SEVERITY_ERROR.equals(severity) || FacesMessage.SEVERITY_FATAL.equals(severity);

+    }

+

+    public boolean severityShowsIndication(

+            FacesContext facesContext, UIComponent uiComponent, FacesMessage.Severity severity)

+    {

+        return FacesMessage.SEVERITY_ERROR.equals(severity) || FacesMessage.SEVERITY_FATAL.equals(severity);

+    }

+}

diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/validation/parameter/DisableClientSideValidation.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/validation/parameter/DisableClientSideValidation.java
new file mode 100644
index 0000000..4c0086b
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/validation/parameter/DisableClientSideValidation.java
@@ -0,0 +1,31 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.core.validation.parameter;

+

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+

+/**

+ * @author Gerhard Petracek

+ * @since x.x.3

+ */

+@UsageInformation(UsageCategory.API)

+public interface DisableClientSideValidation extends ValidationParameter

+{

+}
\ No newline at end of file
diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/validation/parameter/ParameterKey.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/validation/parameter/ParameterKey.java
new file mode 100644
index 0000000..c302bba
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/validation/parameter/ParameterKey.java
@@ -0,0 +1,39 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.core.validation.parameter;

+

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+

+import java.lang.annotation.Target;

+import java.lang.annotation.Retention;

+import static java.lang.annotation.RetentionPolicy.RUNTIME;

+import static java.lang.annotation.ElementType.FIELD;

+import static java.lang.annotation.ElementType.METHOD;

+

+/**

+ * @author Gerhard Petracek

+ * @since x.x.3

+ */

+@Target({FIELD, METHOD})

+@Retention(RUNTIME)

+@UsageInformation(UsageCategory.API)

+public @interface ParameterKey

+{

+}
\ No newline at end of file
diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/validation/parameter/ParameterValue.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/validation/parameter/ParameterValue.java
new file mode 100644
index 0000000..3fdc8f3
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/validation/parameter/ParameterValue.java
@@ -0,0 +1,40 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.core.validation.parameter;

+

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+

+import java.lang.annotation.Target;

+import java.lang.annotation.Retention;

+import static java.lang.annotation.RetentionPolicy.RUNTIME;

+import static java.lang.annotation.ElementType.FIELD;

+import static java.lang.annotation.ElementType.METHOD;

+

+/**

+ * @author Gerhard Petracek

+ * @since x.x.3

+ */

+@Target({FIELD, METHOD})

+@Retention(RUNTIME)

+@UsageInformation(UsageCategory.API)

+public @interface ParameterValue

+{

+    Class id() default ParameterValue.class;

+}

diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/validation/parameter/ValidationParameter.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/validation/parameter/ValidationParameter.java
new file mode 100644
index 0000000..b159c76
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/validation/parameter/ValidationParameter.java
@@ -0,0 +1,31 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.core.validation.parameter;

+

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+

+/**

+ * @author Gerhard Petracek

+ * @since x.x.3

+ */

+@UsageInformation(UsageCategory.API)

+public interface ValidationParameter

+{

+}

diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/validation/parameter/ValidationParameterExtractor.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/validation/parameter/ValidationParameterExtractor.java
new file mode 100644
index 0000000..9209902
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/validation/parameter/ValidationParameterExtractor.java
@@ -0,0 +1,39 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.core.validation.parameter;

+

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+

+import java.util.Map;

+import java.util.List;

+import java.lang.annotation.Annotation;

+

+/**

+ * @author Gerhard Petracek

+ * @since x.x.3

+ */

+@UsageInformation(UsageCategory.API)

+public interface ValidationParameterExtractor

+{

+    Map<Object, List<Object>> extract(Annotation annotation);

+    List<Object> extract(Annotation annotation, Object key);

+    <T> List<T> extract(Annotation annotation, Object key, Class<T> valueType);

+    <T> T extract(Annotation annotation, Object key, Class<T> valueType, Class valueId);

+}
\ No newline at end of file
diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/validation/parameter/ValidationParameterExtractorFactory.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/validation/parameter/ValidationParameterExtractorFactory.java
new file mode 100644
index 0000000..0dcddd2
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/validation/parameter/ValidationParameterExtractorFactory.java
@@ -0,0 +1,32 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.core.validation.parameter;

+

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+

+/**

+ * @author Gerhard Petracek

+ * @since x.x.3

+ */

+@UsageInformation(UsageCategory.API)

+public interface ValidationParameterExtractorFactory

+{

+    ValidationParameterExtractor create();

+}

diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/validation/parameter/ViolationSeverity.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/validation/parameter/ViolationSeverity.java
new file mode 100644
index 0000000..532887c
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/validation/parameter/ViolationSeverity.java
@@ -0,0 +1,80 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.core.validation.parameter;

+

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+

+import javax.faces.application.FacesMessage;

+

+/**

+ * @author Gerhard Petracek

+ * @since x.x.3

+ */

+@UsageInformation(UsageCategory.API)

+public interface ViolationSeverity

+{

+    interface Info extends ValidationParameter

+    {

+        @ParameterKey

+        public Class KEY = ViolationSeverity.class;

+                

+        @ParameterValue

+        public FacesMessage.Severity SEVERITY = FacesMessage.SEVERITY_INFO;

+

+        //@ParameterValue

+        //MessageType postfix = MessageType.INFO;

+    }

+

+    interface Warn extends ValidationParameter

+    {

+        @ParameterKey

+        public Class KEY = ViolationSeverity.class;

+

+        @ParameterValue

+        FacesMessage.Severity SEVERITY = FacesMessage.SEVERITY_WARN;

+

+        //@ParameterValue

+        //MessageType postfix = MessageType.WARN;

+    }

+

+    interface Error extends ValidationParameter

+    {

+        @ParameterKey

+        public Class KEY = ViolationSeverity.class;

+

+        @ParameterValue

+        FacesMessage.Severity SEVERITY = FacesMessage.SEVERITY_ERROR;

+

+        //@ParameterValue

+        //MessageType postfix = MessageType.ERROR;

+    }

+

+    interface Fatal extends ValidationParameter

+    {

+        @ParameterKey

+        public Class KEY = ViolationSeverity.class;

+

+        @ParameterValue

+        FacesMessage.Severity SEVERITY = FacesMessage.SEVERITY_FATAL;

+

+        //@ParameterValue

+        //MessageType postfix = MessageType.FATAL;

+    }

+}
\ No newline at end of file
diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/validation/parameter/ViolationSeverityInterpreter.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/validation/parameter/ViolationSeverityInterpreter.java
new file mode 100644
index 0000000..b76bd94
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/validation/parameter/ViolationSeverityInterpreter.java
@@ -0,0 +1,89 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.core.validation.parameter;

+

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+

+import javax.faces.context.FacesContext;

+import javax.faces.component.UIComponent;

+import javax.faces.application.FacesMessage;

+

+/**

+ * mechanism to change the default behavior of extval

+ * 

+ * @author Gerhard Petracek

+ * @since x.x.3

+ */

+@UsageInformation(UsageCategory.API)

+public interface ViolationSeverityInterpreter

+{

+    /**

+     * @param facesContext current faces context

+     * @param uiComponent current component

+     * @param severity jsf severity for faces messages

+     * @return true if the given severity should block the navigation

+     * if #severityCausesValidatorException returns falls validation will be continued for the current property

+     * all messages which don't lead to an exception should be stored in an storage and

+     * added after the first message which gets thrown as exception

+     * a global PropertyValidationInterceptor add the messages of the storage as faces message

+     */

+    boolean severityBlocksNavigation(

+            FacesContext facesContext, UIComponent uiComponent, FacesMessage.Severity severity);

+

+    /**

+     * @param facesContext current faces context

+     * @param uiComponent current component

+     * @param severity jsf severity for faces messages

+     * @return true if the given severity should cause a validator exception

+     */

+    boolean severityCausesValidatorException(

+            FacesContext facesContext, UIComponent uiComponent, FacesMessage.Severity severity);

+

+    /**

+     *

+     * @param facesContext current faces context

+     * @param uiComponent current component

+     * @param severity jsf severity for faces messages

+     * @return true if a violation message leads to a faces message

+     */

+    boolean severityCausesViolationMessage(

+            FacesContext facesContext, UIComponent uiComponent, FacesMessage.Severity severity);

+

+    /**

+     * @param facesContext current faces context

+     * @param uiComponent current component

+     * @param severity jsf severity for faces messages

+     * @return true if the constraint with the given severity should be validated on the client side (if supported)

+     */

+    boolean severityBlocksSubmit(

+            FacesContext facesContext, UIComponent uiComponent, FacesMessage.Severity severity);

+

+    /**

+     * available for add-ons - not used internally due to performance reasons

+     *

+     * @param facesContext current faces context

+     * @param uiComponent current component

+     * @param severity jsf severity for faces messages

+     * @return true if the constraint with the given severity

+     * should cause e.g. a required marker independent of client-side validation (if supported)

+     */

+    boolean severityShowsIndication(

+            FacesContext facesContext, UIComponent uiComponent, FacesMessage.Severity severity);

+}

diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/validation/strategy/AbstractAnnotationValidationStrategy.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/validation/strategy/AbstractAnnotationValidationStrategy.java
new file mode 100644
index 0000000..159c934
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/validation/strategy/AbstractAnnotationValidationStrategy.java
@@ -0,0 +1,110 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.myfaces.extensions.validator.core.validation.strategy;
+
+import org.apache.myfaces.extensions.validator.core.validation.message.resolver.MessageResolver;
+import org.apache.myfaces.extensions.validator.core.metadata.MetaDataEntry;
+import org.apache.myfaces.extensions.validator.core.property.PropertyInformationKeys;
+import org.apache.myfaces.extensions.validator.internal.UsageInformation;
+import org.apache.myfaces.extensions.validator.internal.UsageCategory;
+import org.apache.myfaces.extensions.validator.util.ExtValUtils;
+
+import javax.faces.application.FacesMessage;
+import javax.faces.context.FacesContext;
+import javax.faces.component.UIComponent;
+import javax.faces.validator.ValidatorException;
+import java.lang.annotation.Annotation;
+import java.util.Locale;
+import java.util.MissingResourceException;
+
+/**
+ * Provides the ability of message resolving to ValidationStrategies
+ *
+ * @author Gerhard Petracek
+ * @since 1.x.1
+ */
+@UsageInformation({UsageCategory.INTERNAL, UsageCategory.REUSE})
+public abstract class AbstractAnnotationValidationStrategy<A extends Annotation> extends AbstractValidationStrategy
+{
+    protected static final String DETAIL_MESSAGE_KEY_POSTFIX = "_detail";
+    //e.g. for injecting a message resolver via spring
+    private MessageResolver messageResolver;
+
+    protected String resolveMessage(String key)
+    {
+        Locale locale = FacesContext.getCurrentInstance().getViewRoot().getLocale();
+
+        return this.messageResolver != null ? this.messageResolver.getMessage(key, locale) :
+            ExtValUtils.getMessageResolverForValidationStrategy(this).getMessage(key, locale);
+    }
+
+    protected String getErrorMessageSummary(A annotation)
+    {
+        return resolveMessage(getValidationErrorMsgKey(annotation));
+    }
+
+    protected String getErrorMessageDetail(A annotation)
+    {
+        try
+        {
+            String key = getValidationErrorMsgKey(annotation);
+            return (key != null) ? resolveMessage(key + DETAIL_MESSAGE_KEY_POSTFIX) : null;
+        }
+        catch (MissingResourceException e)
+        {
+            if(logger.isWarnEnabled())
+            {
+                logger.warn("couldn't find key " + getValidationErrorMsgKey(annotation) + DETAIL_MESSAGE_KEY_POSTFIX,
+                        e);
+            }
+        }
+        return null;
+    }
+
+    protected FacesMessage getValidationErrorFacesMessage(A annotation)
+    {
+        return ExtValUtils.createFacesMessage(getErrorMessageSummary(annotation), getErrorMessageDetail(annotation));
+    }
+
+    protected abstract String getValidationErrorMsgKey(A annotation);
+
+    public void setMessageResolver(MessageResolver messageResolver)
+    {
+        this.messageResolver = messageResolver;
+    }
+
+    @Override
+    protected boolean processAfterValidatorException(FacesContext facesContext,
+                                                     UIComponent uiComponent,
+                                                     MetaDataEntry metaDataEntry,
+                                                     Object convertedObject,
+                                                     ValidatorException validatorException)
+    {
+        metaDataEntry.setProperty(PropertyInformationKeys.LABEL, getLabel(facesContext, uiComponent, metaDataEntry));
+
+        return super.processAfterValidatorException(
+                facesContext, uiComponent, metaDataEntry, convertedObject, validatorException);
+    }
+
+    //e.g. for custom annotations - override if needed
+    protected String getLabel(FacesContext facesContext, UIComponent uiComponent, MetaDataEntry metaDataEntry)
+    {
+        return null;
+    }
+}
diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/validation/strategy/AbstractValidationStrategy.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/validation/strategy/AbstractValidationStrategy.java
new file mode 100644
index 0000000..d01f3ed
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/validation/strategy/AbstractValidationStrategy.java
@@ -0,0 +1,147 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.core.validation.strategy;

+

+import org.apache.myfaces.extensions.validator.core.metadata.MetaDataEntry;

+import org.apache.myfaces.extensions.validator.core.validation.exception.RequiredValidatorException;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.util.ExtValUtils;

+import org.apache.commons.logging.Log;

+import org.apache.commons.logging.LogFactory;

+

+import javax.faces.component.UIComponent;

+import javax.faces.context.FacesContext;

+import javax.faces.validator.ValidatorException;

+

+/**

+ * Provides the ability to use ValidatorException (as expected by the user) instead of ConverterException.

+ * Furthermore it provides:<br/>

+ * initValidation<br/>

+ * processAfterValidatorException

+ *

+ * @author Gerhard Petracek

+ * @since 1.x.1

+ */

+@UsageInformation({UsageCategory.INTERNAL, UsageCategory.REUSE})

+public abstract class AbstractValidationStrategy implements ValidationStrategy

+{

+    protected final Log logger = LogFactory.getLog(getClass());

+

+    protected AbstractValidationStrategy()

+    {

+        if(logger.isDebugEnabled())

+        {

+            logger.debug(getClass().getName() + " instantiated");

+        }

+    }

+

+    public void validate(FacesContext facesContext, UIComponent uiComponent,

+                         MetaDataEntry metaDataEntry, Object convertedObject)

+    {

+        if(logger.isTraceEnabled())

+        {

+            logger.trace("start initValidation of " + getClass().getName());

+        }

+

+        initValidation(facesContext, uiComponent, metaDataEntry, convertedObject);

+

+        if(logger.isTraceEnabled())

+        {

+            logger.trace("initValidation of " + getClass().getName() + " finished");

+        }

+

+        try

+        {

+            if(logger.isTraceEnabled())

+            {

+                logger.trace("start processValidation of " + getClass().getName());

+            }

+

+            processValidation(facesContext, uiComponent, metaDataEntry, convertedObject);

+

+            if(logger.isTraceEnabled())

+            {

+                logger.trace("processValidation of " + getClass().getName() + " finished");

+            }

+        }

+        catch (ValidatorException e)

+        {

+            if(logger.isTraceEnabled())

+            {

+                logger.trace("start processAfterValidatorException of " + getClass().getName());

+            }

+

+            ValidatorException validatorException;

+

+            if(e instanceof RequiredValidatorException)

+            {

+                validatorException = new RequiredValidatorException(

+                        ExtValUtils.convertFacesMessage(e.getFacesMessage()), e.getCause());

+            }

+            else

+            {

+                validatorException = new ValidatorException(

+                        ExtValUtils.convertFacesMessage(e.getFacesMessage()), e.getCause());

+            }

+            

+            if (processAfterValidatorException(

+                    facesContext, uiComponent, metaDataEntry, convertedObject, validatorException))

+            {

+                if(logger.isTraceEnabled())

+                {

+                    logger.trace(getClass().getName() +

+                        ": throw original exception after processAfterValidatorException");

+                }

+

+                ExtValUtils.tryToThrowValidatorExceptionForComponent(

+                        uiComponent, validatorException.getFacesMessage(), validatorException);

+            }

+

+            if(logger.isTraceEnabled())

+            {

+                logger.trace(getClass().getName() +

+                    ": original exception after processAfterValidatorException not thrown");

+            }

+        }

+    }

+

+    protected void initValidation(FacesContext facesContext,

+                                  UIComponent uiComponent,

+                                  MetaDataEntry metaDataEntry,

+                                  Object convertedObject)

+    {

+        //override if needed

+    }

+

+    //override if needed

+    protected boolean processAfterValidatorException(FacesContext facesContext,

+                                                     UIComponent uiComponent,

+                                                     MetaDataEntry metaDataEntry,

+                                                     Object convertedObject,

+                                                     ValidatorException validatorException)

+    {

+        return ExtValUtils.executeAfterThrowingInterceptors(

+                uiComponent, metaDataEntry, convertedObject, validatorException, this);

+    }

+

+    protected abstract void processValidation(FacesContext facesContext,

+                                              UIComponent uiComponent, MetaDataEntry metaDataEntry,

+                                              Object convertedObject) throws ValidatorException;

+}

diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/validation/strategy/AbstractVirtualValidationStrategy.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/validation/strategy/AbstractVirtualValidationStrategy.java
new file mode 100644
index 0000000..26a8cfe
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/validation/strategy/AbstractVirtualValidationStrategy.java
@@ -0,0 +1,42 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.core.validation.strategy;

+

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.core.metadata.MetaDataEntry;

+

+import javax.faces.context.FacesContext;

+import javax.faces.component.UIComponent;

+

+/**

+ * to map constraints directly to a meta-data transformer if there is no validation strategy (required by jsr 303)

+ *

+ * @author Gerhard Petracek

+ * @since x.x.3

+ */

+@UsageInformation(UsageCategory.REUSE)

+public abstract class AbstractVirtualValidationStrategy implements IdentifiableValidationStrategy

+{

+    public final void validate(

+            FacesContext facesContext, UIComponent uiComponent, MetaDataEntry metaDataEntry, Object convertedObject)

+    {

+        throw new UnsupportedOperationException("this is just an adapter e.g. for component initialization");

+    }

+}
\ No newline at end of file
diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/validation/strategy/BeanValidationStrategyAdapter.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/validation/strategy/BeanValidationStrategyAdapter.java
new file mode 100644
index 0000000..6c25e04
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/validation/strategy/BeanValidationStrategyAdapter.java
@@ -0,0 +1,43 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.core.validation.strategy;

+

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+

+/**

+ * it isn't linked to jsr 303

+ *

+ * it's just a helper for proxies - you just need it, if you define the validation strategy as bean and

+ * e.g. spring creates a proxy for it.

+

+ * adapter to connect validation strategies with meta-data transformers,

+ * if the validation strategy is defined as bean and e.g. spring creates a proxy

+ *

+ * @author Gerhard Petracek

+ * @since 1.x.1

+ */

+@UsageInformation({UsageCategory.REUSE})

+public interface BeanValidationStrategyAdapter extends ValidationStrategy

+{

+    //to get back the internal cashing

+    String getValidationStrategyClassName();

+

+    String getMetaDataTransformerClassName();

+}

diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/validation/strategy/BeanValidationStrategyAdapterImpl.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/validation/strategy/BeanValidationStrategyAdapterImpl.java
new file mode 100644
index 0000000..4c116f2
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/validation/strategy/BeanValidationStrategyAdapterImpl.java
@@ -0,0 +1,125 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.core.validation.strategy;

+

+import org.apache.myfaces.extensions.validator.core.metadata.MetaDataEntry;

+import org.apache.myfaces.extensions.validator.core.metadata.transformer.MetaDataTransformer;

+import org.apache.myfaces.extensions.validator.core.metadata.transformer.BeanMetaDataTransformerAdapter;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.commons.logging.Log;

+import org.apache.commons.logging.LogFactory;

+

+import javax.faces.component.UIComponent;

+import javax.faces.context.FacesContext;

+

+/**

+ * it isn't linked to jsr 303

+ *

+ * it's just a helper for proxies - you just need it, if you define the validation strategy as bean and

+ * e.g. spring creates a proxy for it.

+

+ * adapter to connect validation strategies with meta-data transformers,

+ * if the validation strategy is defined as bean and e.g. spring creates a proxy

+ *

+ * @author Gerhard Petracek

+ * @since 1.x.1

+ */

+@UsageInformation({UsageCategory.REUSE})

+public class BeanValidationStrategyAdapterImpl implements BeanValidationStrategyAdapter

+{

+    protected final Log logger = LogFactory.getLog(getClass());

+

+    private MetaDataTransformer metaDataTransformer;

+    private ValidationStrategy validationStrategy;

+    //optional fallback for internal cashing

+    private String validationStrategyClassName;

+

+    public BeanValidationStrategyAdapterImpl()

+    {

+        if(logger.isDebugEnabled())

+        {

+            logger.debug(getClass().getName() + " instantiated");

+        }

+    }

+

+    public void validate(FacesContext facesContext,

+                         UIComponent uiComponent,

+                         MetaDataEntry metaDataEntry,

+                         Object convertedObject)

+    {

+        this.validationStrategy.validate(facesContext, uiComponent, metaDataEntry, convertedObject);

+    }

+

+    public String getValidationStrategyClassName()

+    {

+        if(validationStrategy.getClass().getPackage() != null)

+        {

+            return validationStrategy.getClass().getName();

+        }

+        return validationStrategyClassName;

+    }

+

+    public String getMetaDataTransformerClassName()

+    {

+        if(metaDataTransformer != null)

+        {

+            if(metaDataTransformer.getClass().getPackage() != null)

+            {

+                return metaDataTransformer.getClass().getName();

+            }

+            else

+            {

+                if(metaDataTransformer instanceof BeanMetaDataTransformerAdapter)

+                {

+                    return ((BeanMetaDataTransformerAdapter) metaDataTransformer ).getMetaDataTransformerClassName();

+                }

+            }

+        }

+        return null;

+    }

+

+    /*

+     * generated

+     */

+    public MetaDataTransformer getMetaDataTransformer()

+    {

+        return metaDataTransformer;

+    }

+

+    public void setMetaDataTransformer(MetaDataTransformer metaDataTransformer)

+    {

+        this.metaDataTransformer = metaDataTransformer;

+    }

+

+    public ValidationStrategy getValidationStrategy()

+    {

+        return validationStrategy;

+    }

+

+    public void setValidationStrategy(ValidationStrategy validationStrategy)

+    {

+        this.validationStrategy = validationStrategy;

+    }

+

+    public void setValidationStrategyClassName(String validationStrategyClassName)

+    {

+        this.validationStrategyClassName = validationStrategyClassName;

+    }

+}

diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/validation/strategy/DefaultValidationStrategyFactory.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/validation/strategy/DefaultValidationStrategyFactory.java
new file mode 100644
index 0000000..210a11d
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/validation/strategy/DefaultValidationStrategyFactory.java
@@ -0,0 +1,189 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.core.validation.strategy;

+

+import org.apache.myfaces.extensions.validator.core.factory.ClassMappingFactory;

+import org.apache.myfaces.extensions.validator.core.factory.AbstractNameMapperAwareFactory;

+import org.apache.myfaces.extensions.validator.core.WebXmlParameter;

+import org.apache.myfaces.extensions.validator.core.ExtValContext;

+import org.apache.myfaces.extensions.validator.core.CustomInformation;

+import org.apache.myfaces.extensions.validator.core.mapper.NameMapper;

+import org.apache.myfaces.extensions.validator.core.initializer.configuration.StaticConfiguration;

+import org.apache.myfaces.extensions.validator.core.initializer.configuration.StaticConfigurationEntry;

+import org.apache.myfaces.extensions.validator.core.initializer.configuration.StaticConfigurationNames;

+import org.apache.myfaces.extensions.validator.core.initializer.configuration.StaticResourceBundleConfiguration;

+import org.apache.myfaces.extensions.validator.core.validation.strategy.mapper

+    .AnnotationToValidationStrategyBeanNameMapper;

+import org.apache.myfaces.extensions.validator.util.ClassUtils;

+import org.apache.myfaces.extensions.validator.util.ExtValUtils;

+import org.apache.myfaces.extensions.validator.internal.ToDo;

+import org.apache.myfaces.extensions.validator.internal.Priority;

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+import org.apache.commons.logging.Log;

+import org.apache.commons.logging.LogFactory;

+

+import java.util.ArrayList;

+import java.util.HashMap;

+import java.util.List;

+import java.util.Map;

+import java.util.MissingResourceException;

+

+

+/**

+ * Factory which creates the ValidationStrategy for a given Meta-Data Key

+ *

+ * @author Gerhard Petracek

+ * @since 1.x.1

+ */

+@UsageInformation({UsageCategory.INTERNAL, UsageCategory.CUSTOMIZABLE})

+public class DefaultValidationStrategyFactory extends AbstractNameMapperAwareFactory<String>

+        implements ClassMappingFactory<String, ValidationStrategy>

+{

+    protected final Log logger = LogFactory.getLog(getClass());

+

+    private Map<String, String> metaDataKeyToValidationStrategyMapping = null;

+    private List<NameMapper<String>> nameMapperList = new ArrayList<NameMapper<String>>();

+

+    public DefaultValidationStrategyFactory()

+    {

+        if(logger.isDebugEnabled())

+        {

+            logger.debug(getClass().getName() + " instantiated");

+        }

+    }

+

+    public ValidationStrategy create(String metaDataKey)

+    {

+        if (metaDataKeyToValidationStrategyMapping == null)

+        {

+            initStaticMappings();

+        }

+

+        if (metaDataKeyToValidationStrategyMapping.containsKey(metaDataKey))

+        {

+            return getValidationStrategyInstance(metaDataKeyToValidationStrategyMapping.get(metaDataKey));

+        }

+

+        ValidationStrategy validationStrategy;

+        String strategyName;

+        //null -> use name mappers

+        for (NameMapper<String> nameMapper : nameMapperList)

+        {

+            strategyName = nameMapper.createName(metaDataKey);

+

+            if (strategyName == null)

+            {

+                continue;

+            }

+

+            validationStrategy = getValidationStrategyInstance(strategyName);

+

+            if (validationStrategy != null)

+            {

+                addMapping(metaDataKey, strategyName);

+                return validationStrategy;

+            }

+        }

+        return null;

+    }

+

+    private ValidationStrategy getValidationStrategyInstance(String validationStrategyName)

+    {

+        if (validationStrategyName

+            .startsWith(AnnotationToValidationStrategyBeanNameMapper.PREFIX_FOR_BEAN_MAPPING))

+        {

+            return (ValidationStrategy) ExtValUtils.getELHelper().getBean(validationStrategyName

+                    .substring(AnnotationToValidationStrategyBeanNameMapper.PREFIX_FOR_BEAN_MAPPING.length()));

+        }

+        else

+        {

+            return (ValidationStrategy) ClassUtils.tryToInstantiateClassForName(validationStrategyName);

+        }

+    }

+

+    private synchronized void addMapping(String metaDataKey, String validationStrategyName)

+    {

+        if(logger.isTraceEnabled())

+        {

+            logger.trace("adding meta-data key to validation strategy mapping: "

+                + metaDataKey + " -> " + validationStrategyName);

+        }

+

+        metaDataKeyToValidationStrategyMapping.put(metaDataKey, validationStrategyName);

+    }

+

+    @ToDo(value = Priority.MEDIUM, description = "logging")

+    private synchronized void initStaticMappings()

+    {

+        metaDataKeyToValidationStrategyMapping = new HashMap<String, String>();

+

+        //setup internal static mappings

+        for (StaticConfiguration<String, String> staticConfig :

+            ExtValContext.getContext().getStaticConfiguration(

+                StaticConfigurationNames.META_DATA_TO_VALIDATION_STRATEGY_CONFIG))

+        {

+            setupStrategyMappings(staticConfig.getMapping());

+        }

+

+        StaticConfiguration<String, String> staticConfig = new StaticResourceBundleConfiguration();

+        //try to setup mapping with base name by convention - overrides default mapping

+        try

+        {

+            //build convention (strategy mapping)

+            staticConfig.setSourceOfMapping(ExtValContext.getContext().getInformationProviderBean()

+                .get(CustomInformation.STATIC_STRATEGY_MAPPING_SOURCE));

+

+            setupStrategyMappings(staticConfig.getMapping());

+        }

+        catch (Throwable t)

+        {

+            //do nothing - it was just a try

+        }

+

+        //setup custom mapping - overrides all other mappings

+        String customMappingBaseName = WebXmlParameter.CUSTOM_STATIC_VALIDATION_STRATEGY_MAPPING;

+        if (customMappingBaseName != null)

+        {

+            try

+            {

+                staticConfig = new StaticResourceBundleConfiguration();

+                staticConfig.setSourceOfMapping(customMappingBaseName);

+                setupStrategyMappings(staticConfig.getMapping());

+            }

+            catch (MissingResourceException e)

+            {

+                e.printStackTrace();

+            }

+        }

+    }

+

+    private void setupStrategyMappings(List<StaticConfigurationEntry<String,String>> mappings)

+    {

+        for(StaticConfigurationEntry<String, String> mapping : mappings)

+        {

+            addMapping(mapping.getSource(), mapping.getTarget());

+        }

+    }

+

+    protected List<NameMapper<String>> getNameMapperList()

+    {

+        return this.nameMapperList;

+    }

+}

diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/validation/strategy/IdentifiableValidationStrategy.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/validation/strategy/IdentifiableValidationStrategy.java
new file mode 100644
index 0000000..bf3a2ab
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/validation/strategy/IdentifiableValidationStrategy.java
@@ -0,0 +1,36 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.core.validation.strategy;

+

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+

+/**

+ * if an adapter is used for several constraints, this interface allows to identify instances

+ *

+ * @author Gerhard Petracek

+ * @since x.x.3

+ */

+@UsageInformation(UsageCategory.API)

+public interface IdentifiableValidationStrategy extends ValidationStrategy

+{

+    String ID_PREFIX = ":";

+

+    String getId();

+}
\ No newline at end of file
diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/validation/strategy/ValidationStrategy.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/validation/strategy/ValidationStrategy.java
new file mode 100644
index 0000000..b55523d
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/validation/strategy/ValidationStrategy.java
@@ -0,0 +1,40 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.core.validation.strategy;

+

+import org.apache.myfaces.extensions.validator.core.metadata.MetaDataEntry;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+

+import javax.faces.component.UIComponent;

+import javax.faces.context.FacesContext;

+

+/**

+ * Base interface for ValidationStrategies

+ *

+ * @author Gerhard Petracek

+ * @since 1.x.1

+ */

+@UsageInformation(UsageCategory.API)

+//*ValidationStrategy instead of *Validator to avoid naming confusion 

+public interface ValidationStrategy

+{

+    void validate(FacesContext facesContext, UIComponent uiComponent,

+                  MetaDataEntry metaDataEntry, Object convertedObject);

+}

diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/validation/strategy/mapper/AbstractMetaDataToValidationStrategyNameMapper.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/validation/strategy/mapper/AbstractMetaDataToValidationStrategyNameMapper.java
new file mode 100644
index 0000000..b9b3f0d
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/validation/strategy/mapper/AbstractMetaDataToValidationStrategyNameMapper.java
@@ -0,0 +1,43 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.core.validation.strategy.mapper;

+

+import org.apache.myfaces.extensions.validator.core.mapper.NameMapper;

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+import org.apache.commons.logging.Log;

+import org.apache.commons.logging.LogFactory;

+

+/**

+ * @author Gerhard Petracek

+ * @since 1.x.1

+ */

+@UsageInformation(UsageCategory.INTERNAL)

+public abstract class AbstractMetaDataToValidationStrategyNameMapper implements NameMapper<String>

+{

+    protected final Log logger = LogFactory.getLog(getClass());

+

+    public AbstractMetaDataToValidationStrategyNameMapper()

+    {

+        if(logger.isDebugEnabled())

+        {

+            logger.debug(getClass().getName() + " instantiated");

+        }

+    }

+}

diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/validation/strategy/mapper/AnnotationToValidationStrategyBeanNameMapper.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/validation/strategy/mapper/AnnotationToValidationStrategyBeanNameMapper.java
new file mode 100644
index 0000000..d8d94f7
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/validation/strategy/mapper/AnnotationToValidationStrategyBeanNameMapper.java
@@ -0,0 +1,65 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.core.validation.strategy.mapper;

+

+import org.apache.myfaces.extensions.validator.core.mapper.NameMapper;

+import org.apache.myfaces.extensions.validator.core.InvocationOrder;

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+

+import java.beans.Introspector;

+

+/**

+ * Name Mapper which delegates the name mapping, extract the name and convert it to a bean name + prefix

+ * target: configure a validation strategy via a managed bean facility -> allows to inject other beans

+ * instead of api calls + hardcoded bean names

+ * <p/>

+ * allowed bean scopes:

+ * the validation strategy is stateless: application/singleton

+ * the validation strategy is stateful: none/prototype

+ * don't use the session or a conversation scope

+ *

+ * @author Gerhard Petracek

+ * @since 1.x.1

+ */

+@InvocationOrder(500)

+@UsageInformation(UsageCategory.INTERNAL)

+public class AnnotationToValidationStrategyBeanNameMapper extends AbstractMetaDataToValidationStrategyNameMapper

+{

+    public static final String PREFIX_FOR_BEAN_MAPPING = "bean:";

+    private NameMapper<String> wrapped;

+

+    public AnnotationToValidationStrategyBeanNameMapper(NameMapper<String> nameMapper)

+    {

+        this.wrapped = nameMapper;

+    }

+

+    public String createName(String source)

+    {

+        String name = wrapped.createName(source);

+

+        if (name == null)

+        {

+            return null;

+        }

+

+        name = name.substring(name.lastIndexOf(".") + 1);

+        return PREFIX_FOR_BEAN_MAPPING + Introspector.decapitalize(name);

+    }

+}

diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/validation/strategy/mapper/CustomConfiguredAnnotationToValidationStrategyNameMapper.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/validation/strategy/mapper/CustomConfiguredAnnotationToValidationStrategyNameMapper.java
new file mode 100644
index 0000000..fd03206
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/validation/strategy/mapper/CustomConfiguredAnnotationToValidationStrategyNameMapper.java
@@ -0,0 +1,43 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.core.validation.strategy.mapper;

+

+import org.apache.myfaces.extensions.validator.core.WebXmlParameter;

+import org.apache.myfaces.extensions.validator.core.InvocationOrder;

+import org.apache.myfaces.extensions.validator.core.mapper.AbstractCustomNameMapper;

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+

+/**

+ * To provide a custom NameMapper to map Annotations to ValidationStrategies.

+ * (configured via web.xml)

+ *

+ * @author Gerhard Petracek

+ * @since 1.x.1

+ */

+@InvocationOrder(100)

+@UsageInformation({UsageCategory.INTERNAL, UsageCategory.CUSTOMIZABLE})

+public class CustomConfiguredAnnotationToValidationStrategyNameMapper extends

+    AbstractCustomNameMapper<String>

+{

+    protected String getCustomNameMapperClassName()

+    {

+        return WebXmlParameter.CUSTOM_META_DATA_TO_VALIDATION_STRATEGY_NAME_MAPPER;

+    }

+}

diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/validation/strategy/mapper/CustomConventionAnnotationToValidationStrategyNameMapper.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/validation/strategy/mapper/CustomConventionAnnotationToValidationStrategyNameMapper.java
new file mode 100644
index 0000000..d1e8302
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/validation/strategy/mapper/CustomConventionAnnotationToValidationStrategyNameMapper.java
@@ -0,0 +1,47 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.core.validation.strategy.mapper;

+

+import org.apache.myfaces.extensions.validator.core.mapper.AbstractCustomNameMapper;

+import org.apache.myfaces.extensions.validator.core.ExtValContext;

+import org.apache.myfaces.extensions.validator.core.CustomInformation;

+import org.apache.myfaces.extensions.validator.core.InvocationOrder;

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+

+/**

+ * To provide a custom NameMapper to map Annotations to ValidationStrategies.

+ * (configured via information provider bean)

+ * The bean provides the default name (convention).

+ * It's possible to provide a custom full qualified name. (= customizable convention)

+ *

+ * @author Gerhard Petracek

+ * @since 1.x.1

+ */

+@InvocationOrder(200)

+@UsageInformation({UsageCategory.INTERNAL, UsageCategory.CUSTOMIZABLE})

+public class CustomConventionAnnotationToValidationStrategyNameMapper extends

+    AbstractCustomNameMapper<String>

+{

+    protected String getCustomNameMapperClassName()

+    {

+        return ExtValContext.getContext().getInformationProviderBean()

+            .get(CustomInformation.META_DATA_TO_VALIDATION_STRATEGY_NAME_MAPPER);

+    }

+}

diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/validation/strategy/mapper/DefaultAnnotationToValidationStrategyNameMapper.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/validation/strategy/mapper/DefaultAnnotationToValidationStrategyNameMapper.java
new file mode 100644
index 0000000..6c38d8f
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/validation/strategy/mapper/DefaultAnnotationToValidationStrategyNameMapper.java
@@ -0,0 +1,40 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.core.validation.strategy.mapper;

+

+import org.apache.myfaces.extensions.validator.core.InternalConventionProvider;

+import org.apache.myfaces.extensions.validator.core.InvocationOrder;

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+

+/**

+ * Default implementation which maps ExtVal Annotations to ExtVal ValidationStrategies.

+ *

+ * @author Gerhard Petracek

+ * @since 1.x.1

+ */

+@InvocationOrder(300)

+@UsageInformation(UsageCategory.INTERNAL)

+public class DefaultAnnotationToValidationStrategyNameMapper extends AbstractMetaDataToValidationStrategyNameMapper

+{

+    public String createName(String metaDataKey)

+    {

+        return InternalConventionProvider.getValidationStrategyClassName(metaDataKey);

+    }

+}

diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/validation/strategy/mapper/SimpleAnnotationToValidationStrategyNameMapper.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/validation/strategy/mapper/SimpleAnnotationToValidationStrategyNameMapper.java
new file mode 100644
index 0000000..9382053
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/core/validation/strategy/mapper/SimpleAnnotationToValidationStrategyNameMapper.java
@@ -0,0 +1,42 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.core.validation.strategy.mapper;

+

+import org.apache.myfaces.extensions.validator.core.ExtValContext;

+import org.apache.myfaces.extensions.validator.core.CustomInformation;

+import org.apache.myfaces.extensions.validator.core.InvocationOrder;

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+

+/**

+ * It's an alternative Mapper to place Annotations and ValidationStrategies in the same package.

+ *

+ * @author Gerhard Petracek

+ * @since 1.x.1

+ */

+@InvocationOrder(400)

+@UsageInformation({UsageCategory.INTERNAL})

+public class SimpleAnnotationToValidationStrategyNameMapper extends AbstractMetaDataToValidationStrategyNameMapper

+{

+    public String createName(String metaDataKey)

+    {

+        return metaDataKey +

+            ExtValContext.getContext().getInformationProviderBean().get(CustomInformation.VALIDATION_STRATEGY_POSTFIX);

+    }

+}

diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/internal/Priority.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/internal/Priority.java
new file mode 100644
index 0000000..111aa33
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/internal/Priority.java
@@ -0,0 +1,31 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.myfaces.extensions.validator.internal;
+
+/**
+ * @author Gerhard Petracek
+ * @since 1.x.1
+ */
+public enum Priority
+{
+    BLOCKING,
+    HIGH,
+    MEDIUM,
+    LOW
+}
\ No newline at end of file
diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/internal/ToDo.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/internal/ToDo.java
new file mode 100644
index 0000000..9d25a0a
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/internal/ToDo.java
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.myfaces.extensions.validator.internal;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.TYPE;
+import static java.lang.annotation.ElementType.CONSTRUCTOR;
+import java.lang.annotation.Target;
+
+/**
+ * @author Gerhard Petracek
+ * @since 1.x.1
+ */
+@Target({TYPE, METHOD, FIELD, CONSTRUCTOR})
+public @interface ToDo
+{
+    Priority value();
+    String description() default "";
+
+    @Target({TYPE, METHOD, FIELD})
+    @interface List
+    {
+        ToDo[] value();
+    }
+}
\ No newline at end of file
diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/internal/UsageCategory.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/internal/UsageCategory.java
new file mode 100644
index 0000000..547b385
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/internal/UsageCategory.java
@@ -0,0 +1,48 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.myfaces.extensions.validator.internal;
+
+/**
+ * API:<br/>
+ * parts you might need for custom implementations and which are quite stable in view of changes
+ * <p/>
+ * INTERNAL:<br/>
+ * if you think about referencing an artifact which is marked as internal, ask for support.
+ * there should be a better solution
+ * <p/>
+ * CUSTOMIZABLE:<br/>
+ * a planned extension point which contains logic to customize the framework.
+ * if it isn't also marked as API it might change in future releases.
+ * however, we try to keep it as stable as possible and reasonable.
+ * <p/>
+ * REUSE:<br/>
+ * an artifact which you can reuse for a custom implementation.
+ * if it isn't marked as API it might change in future releases.
+ * however, we try to keep it as stable as possible and reasonable.
+ *
+ * @author Gerhard Petracek
+ * @since 1.x.1
+ */
+public enum UsageCategory
+{
+    API,
+    INTERNAL,
+    CUSTOMIZABLE,
+    REUSE
+}
diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/internal/UsageInformation.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/internal/UsageInformation.java
new file mode 100644
index 0000000..f937ebc
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/internal/UsageInformation.java
@@ -0,0 +1,37 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.myfaces.extensions.validator.internal;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.TYPE;
+import java.lang.annotation.Target;
+
+/**
+ * it's an internal annotation to provide some information concerning usage-categories
+ *
+ * @author Gerhard Petracek
+ * @since 1.x.1
+ * @see org.apache.myfaces.extensions.validator.internal.UsageCategory
+ */
+@Target({TYPE, METHOD, FIELD})
+public @interface UsageInformation
+{
+    UsageCategory[] value();
+}
diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/util/ClassUtils.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/util/ClassUtils.java
new file mode 100644
index 0000000..c3e2056
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/util/ClassUtils.java
@@ -0,0 +1,123 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.util;

+

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+import org.apache.commons.logging.Log;

+import org.apache.commons.logging.LogFactory;

+

+import java.util.jar.Manifest;

+import java.util.jar.Attributes;

+import java.net.URL;

+

+/**

+ * @author Gerhard Petracek

+ * @since 1.x.1

+ */

+@UsageInformation(UsageCategory.INTERNAL)

+public class ClassUtils

+{

+    private static final Log LOG = LogFactory.getLog(ClassUtils.class);

+

+    public static Class tryToLoadClassForName(String name)

+    {

+        try

+        {

+            return loadClassForName(name);

+        }

+        catch (ClassNotFoundException e)

+        {

+            //do nothing - it's just a try

+            return null;

+        }

+    }

+    

+    public static Class loadClassForName(String name) throws ClassNotFoundException

+    {

+        try

+        {

+            // Try WebApp ClassLoader first

+            return Class.forName(name, false, // do not initialize for faster startup

+                Thread.currentThread().getContextClassLoader());

+        }

+        catch (ClassNotFoundException ignore)

+        {

+            // fallback: Try ClassLoader for ClassUtils (i.e. the myfaces.jar lib)

+            return Class.forName(name, false, // do not initialize for faster startup

+                ClassUtils.class.getClassLoader());

+        }

+    }

+

+    public static <T> T tryToInstantiateClass(Class<T> targetClass)

+    {

+        try

+        {

+            return targetClass.newInstance();

+        }

+        catch (Throwable t)

+        {

+            //do nothing - it was just a try

+        }

+        return null;

+    }

+

+    public static Object tryToInstantiateClassForName(String className)

+    {

+        try

+        {

+            return instantiateClassForName(className);

+        }

+        catch (Throwable t)

+        {

+            //do nothing - it was just a try

+        }

+        return null;

+    }

+

+    public static Object instantiateClassForName(String className)

+        throws ClassNotFoundException, IllegalAccessException, InstantiationException

+    {

+        return loadClassForName(className).newInstance();

+    }

+

+    public static String getJarVersion(Class targetClass)

+    {

+        String classFilePath = targetClass.getCanonicalName().replace('.', '/') + ".class";

+        String manifestFilePath = "/META-INF/MANIFEST.MF";

+

+        String classLocation = targetClass.getResource(targetClass.getSimpleName() + ".class").toString();

+        String manifestFileLocation = classLocation

+                .substring(0, classLocation.indexOf(classFilePath) - 1) + manifestFilePath;

+

+        try

+        {

+            return new Manifest(new URL(manifestFileLocation).openStream())

+                    .getMainAttributes().getValue(Attributes.Name.IMPLEMENTATION_VERSION);

+        }

+        catch (Throwable t)

+        {

+            if (LOG.isTraceEnabled())

+            {

+                LOG.trace("couldn't load version of jar file which contains " + targetClass.getName(), t);

+            }

+            return null;

+        }

+    }

+}

diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/util/DefaultProjectName.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/util/DefaultProjectName.java
new file mode 100644
index 0000000..4fd6399
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/util/DefaultProjectName.java
@@ -0,0 +1,81 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.util;

+

+import org.apache.myfaces.extensions.validator.core.ProjectStageName;

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+

+/**

+ * @author Gerhard Petracek

+ */

+@UsageInformation(UsageCategory.INTERNAL)

+class DefaultProjectName implements ProjectStageName

+{

+    private final String name;

+

+    @SuppressWarnings({"UnusedDeclaration"})

+    private DefaultProjectName()

+    {

+        this.name = null;

+    }

+

+    private DefaultProjectName(String name)

+    {

+        this.name = name;

+    }

+

+    static ProjectStageName createProjectStageName(String name)

+    {

+        return new DefaultProjectName(name);

+    }

+

+    public String getName()

+    {

+        return this.name;

+    }

+

+    @Override

+    public boolean equals(Object o)

+    {

+        if (this == o)

+        {

+            return true;

+        }

+        if (!(o instanceof DefaultProjectName))

+        {

+            return false;

+        }

+

+        DefaultProjectName that = (DefaultProjectName) o;

+

+        if (!name.equals(that.name))

+        {

+            return false;

+        }

+

+        return true;

+    }

+

+    @Override

+    public int hashCode()

+    {

+        return name.hashCode();

+    }

+}

diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/util/ExtValUtils.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/util/ExtValUtils.java
new file mode 100644
index 0000000..42ee3da
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/util/ExtValUtils.java
@@ -0,0 +1,964 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.util;

+

+import org.apache.commons.logging.Log;

+import org.apache.commons.logging.LogFactory;

+import org.apache.myfaces.extensions.validator.core.ExtValContext;

+import org.apache.myfaces.extensions.validator.core.WebXmlParameter;

+import org.apache.myfaces.extensions.validator.core.ValidationModuleKey;

+import org.apache.myfaces.extensions.validator.core.ProjectStageName;

+import org.apache.myfaces.extensions.validator.core.el.AbstractELHelperFactory;

+import org.apache.myfaces.extensions.validator.core.el.ELHelper;

+import org.apache.myfaces.extensions.validator.core.el.ValueBindingExpression;

+import org.apache.myfaces.extensions.validator.core.factory.ClassMappingFactory;

+import org.apache.myfaces.extensions.validator.core.factory.FacesMessageFactory;

+import org.apache.myfaces.extensions.validator.core.factory.FactoryNames;

+import org.apache.myfaces.extensions.validator.core.factory.NameMapperAwareFactory;

+import org.apache.myfaces.extensions.validator.core.initializer.component.ComponentInitializer;

+import org.apache.myfaces.extensions.validator.core.initializer.configuration.StaticConfiguration;

+import org.apache.myfaces.extensions.validator.core.initializer.configuration.StaticConfigurationEntry;

+import org.apache.myfaces.extensions.validator.core.initializer.configuration.StaticConfigurationNames;

+import org.apache.myfaces.extensions.validator.core.interceptor.MetaDataExtractionInterceptor;

+import org.apache.myfaces.extensions.validator.core.interceptor.PropertyValidationInterceptor;

+import org.apache.myfaces.extensions.validator.core.interceptor.ValidationExceptionInterceptor;

+import org.apache.myfaces.extensions.validator.core.mapper.NameMapper;

+import org.apache.myfaces.extensions.validator.core.metadata.MetaDataEntry;

+import org.apache.myfaces.extensions.validator.core.metadata.extractor.ComponentMetaDataExtractorFactory;

+import org.apache.myfaces.extensions.validator.core.metadata.extractor.MetaDataExtractor;

+import org.apache.myfaces.extensions.validator.core.metadata.transformer.MetaDataTransformer;

+import org.apache.myfaces.extensions.validator.core.property.PropertyDetails;

+import org.apache.myfaces.extensions.validator.core.property.PropertyInformation;

+import org.apache.myfaces.extensions.validator.core.property.PropertyInformationKeys;

+import org.apache.myfaces.extensions.validator.core.storage.FacesMessageStorage;

+import org.apache.myfaces.extensions.validator.core.storage.StorageManager;

+import org.apache.myfaces.extensions.validator.core.validation.SkipValidationEvaluator;

+import org.apache.myfaces.extensions.validator.core.validation.message.resolver.MessageResolver;

+import org.apache.myfaces.extensions.validator.core.validation.parameter.ValidationParameterExtractor;

+import org.apache.myfaces.extensions.validator.core.validation.parameter.ValidationParameterExtractorFactory;

+import org.apache.myfaces.extensions.validator.core.validation.parameter.ViolationSeverityInterpreter;

+import org.apache.myfaces.extensions.validator.core.validation.strategy.ValidationStrategy;

+import org.apache.myfaces.extensions.validator.internal.Priority;

+import org.apache.myfaces.extensions.validator.internal.ToDo;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.ExtValInformation;

+

+import javax.faces.application.FacesMessage;

+import javax.faces.component.UIComponent;

+import javax.faces.context.FacesContext;

+import javax.faces.validator.ValidatorException;

+import java.util.Map;

+import java.util.HashMap;

+import java.util.MissingResourceException;

+import java.util.List;

+import java.util.ArrayList;

+import java.lang.annotation.Annotation;

+

+/**

+ * @author Gerhard Petracek

+ * @since 1.x.1

+ */

+@SuppressWarnings({"unchecked"})

+@UsageInformation(UsageCategory.INTERNAL)

+public class ExtValUtils

+{

+    private static final Log LOGGER = LogFactory.getLog(ExtValUtils.class);

+

+    private static final String JAVAX_FACES_REQUIRED = "javax.faces.component.UIInput.REQUIRED";

+    private static final String JAVAX_FACES_REQUIRED_DETAIL = "javax.faces.component.UIInput.REQUIRED_detail";

+

+    private static final String JAVAX_FACES_MAXIMUM = "javax.faces.validator.LengthValidator.MAXIMUM";

+    private static final String JAVAX_FACES_MAXIMUM_DETAIL = "javax.faces.validator.LengthValidator.MAXIMUM_detail";

+

+    public static ValidationStrategy getValidationStrategyForMetaData(String metaDataKey)

+    {

+        return ((ClassMappingFactory<String, ValidationStrategy>) ExtValContext.getContext()

+                .getFactoryFinder()

+                .getFactory(FactoryNames.VALIDATION_STRATEGY_FACTORY, ClassMappingFactory.class))

+                .create(metaDataKey);

+    }

+

+    public static void registerMetaDataToValidationStrategyNameMapper(

+            NameMapper<String> metaDataToValidationStrategyNameMapper)

+    {

+        (ExtValContext.getContext()

+                .getFactoryFinder()

+                .getFactory(FactoryNames.VALIDATION_STRATEGY_FACTORY, NameMapperAwareFactory.class))

+                .register(metaDataToValidationStrategyNameMapper);

+    }

+

+    public static void deregisterMetaDataToValidationStrategyNameMapper(

+            Class<? extends NameMapper> metaDataToValidationStrategyNameMapperClass)

+    {

+        (ExtValContext.getContext()

+                .getFactoryFinder()

+                .getFactory(FactoryNames.VALIDATION_STRATEGY_FACTORY, NameMapperAwareFactory.class))

+                .deregister(metaDataToValidationStrategyNameMapperClass);

+    }

+

+    public static void denyMetaDataToValidationStrategyNameMapper(

+            Class<? extends NameMapper> metaDataToValidationStrategyNameMapperClass)

+    {

+        (ExtValContext.getContext()

+                .getFactoryFinder()

+                .getFactory(FactoryNames.VALIDATION_STRATEGY_FACTORY, NameMapperAwareFactory.class))

+                .deny(metaDataToValidationStrategyNameMapperClass);

+    }

+

+    public static MetaDataTransformer getMetaDataTransformerForValidationStrategy(ValidationStrategy validationStrategy)

+    {

+        return ((ClassMappingFactory<ValidationStrategy, MetaDataTransformer>) ExtValContext

+                .getContext().getFactoryFinder()

+                .getFactory(FactoryNames.META_DATA_TRANSFORMER_FACTORY, ClassMappingFactory.class))

+                .create(validationStrategy);

+    }

+

+    public static void registerValidationStrategyToMetaDataTransformerNameMapper(

+            NameMapper<ValidationStrategy> validationStrategyToMetaDataTransformerNameMapper)

+    {

+        (ExtValContext.getContext()

+                .getFactoryFinder()

+                .getFactory(FactoryNames.META_DATA_TRANSFORMER_FACTORY, NameMapperAwareFactory.class))

+                .register(validationStrategyToMetaDataTransformerNameMapper);

+    }

+

+    public static void deregisterValidationStrategyToMetaDataTransformerNameMapper(

+            Class<? extends NameMapper> validationStrategyToMetaDataTransformerNameMapperClass)

+    {

+        (ExtValContext.getContext()

+                .getFactoryFinder()

+                .getFactory(FactoryNames.META_DATA_TRANSFORMER_FACTORY, NameMapperAwareFactory.class))

+                .deregister(validationStrategyToMetaDataTransformerNameMapperClass);

+    }

+

+    public static void denyValidationStrategyToMetaDataTransformerNameMapper(

+            Class<? extends NameMapper> validationStrategyToMetaDataTransformerNameMapperClass)

+    {

+        (ExtValContext.getContext()

+                .getFactoryFinder()

+                .getFactory(FactoryNames.META_DATA_TRANSFORMER_FACTORY, NameMapperAwareFactory.class))

+                .deny(validationStrategyToMetaDataTransformerNameMapperClass);

+    }

+

+    public static MetaDataExtractor getComponentMetaDataExtractor()

+    {

+        return ExtValContext.getContext().getFactoryFinder()

+                .getFactory(FactoryNames.COMPONENT_META_DATA_EXTRACTOR_FACTORY, ComponentMetaDataExtractorFactory.class)

+                .create();

+    }

+

+    public static MetaDataExtractor getComponentMetaDataExtractorWith(Map<String, Object> properties)

+    {

+        return ExtValContext.getContext().getFactoryFinder()

+                .getFactory(FactoryNames.COMPONENT_META_DATA_EXTRACTOR_FACTORY, ComponentMetaDataExtractorFactory.class)

+                .createWith(properties);

+    }

+

+    public static void configureComponentWithMetaData(FacesContext facesContext,

+                                                      UIComponent uiComponent,

+                                                      Map<String, Object> metaData)

+    {

+        for (ComponentInitializer componentInitializer : ExtValContext.getContext().getComponentInitializers())

+        {

+            componentInitializer.configureComponent(facesContext, uiComponent, metaData);

+        }

+    }

+

+    public static boolean executeAfterThrowingInterceptors(UIComponent uiComponent,

+                                                           MetaDataEntry metaDataEntry,

+                                                           Object convertedObject,

+                                                           ValidatorException validatorException,

+                                                           ValidationStrategy validatorExceptionSource)

+    {

+        boolean result = true;

+

+        if (metaDataEntry == null)

+        {

+            metaDataEntry = new MetaDataEntry();

+        }

+

+        for (ValidationExceptionInterceptor validationExceptionInterceptor : ExtValContext.getContext()

+                .getValidationExceptionInterceptors())

+        {

+            if (!validationExceptionInterceptor.afterThrowing(

+                    uiComponent, metaDataEntry, convertedObject, validatorException, validatorExceptionSource))

+            {

+                result = false;

+            }

+        }

+

+        return result;

+    }

+

+    public static MetaDataExtractor createInterceptedMetaDataExtractor(final MetaDataExtractor metaDataExtractor)

+    {

+        return createInterceptedMetaDataExtractorWith(metaDataExtractor, null);

+    }

+

+    public static MetaDataExtractor createInterceptedMetaDataExtractorFor(

+            final MetaDataExtractor metaDataExtractor, Class moduleKey)

+    {

+        Map<String, Object> properties = new HashMap<String, Object>();

+

+        if(moduleKey != null)

+        {

+            properties.put(ValidationModuleKey.class.getName(), moduleKey);

+        }

+        return createInterceptedMetaDataExtractorWith(metaDataExtractor, properties);

+    }

+

+    public static MetaDataExtractor createInterceptedMetaDataExtractorWith(

+            final MetaDataExtractor metaDataExtractor, final Map<String, Object> properties)

+    {

+        return new MetaDataExtractor()

+        {

+            public PropertyInformation extract(FacesContext facesContext, Object object)

+            {

+                PropertyInformation result = metaDataExtractor.extract(facesContext, object);

+

+                addProperties(result, properties);

+                invokeMetaDataExtractionInterceptors(result, properties);

+

+                return result;

+            }

+        };

+    }

+

+    private static void addProperties(PropertyInformation result, Map<String, Object> properties)

+    {

+        if(properties != null)

+        {

+            Map<String, Object> customProperties = getCustomProperties(result);

+            customProperties.putAll(properties);

+        }

+    }

+

+    private static Map<String, Object> getCustomProperties(PropertyInformation propertyInformation)

+    {

+        if(!propertyInformation.containsInformation(PropertyInformationKeys.CUSTOM_PROPERTIES))

+        {

+            propertyInformation.setInformation(

+                    PropertyInformationKeys.CUSTOM_PROPERTIES, new HashMap<String, Object>());

+        }

+

+        return (Map<String, Object>) propertyInformation.getInformation(PropertyInformationKeys.CUSTOM_PROPERTIES);

+    }

+

+    private static void invokeMetaDataExtractionInterceptors(PropertyInformation result, Map<String, Object> properties)

+    {

+        for (MetaDataExtractionInterceptor metaDataExtractionInterceptor :

+                ExtValContext.getContext().getMetaDataExtractionInterceptorsWith(properties))

+        {

+            metaDataExtractionInterceptor.afterExtracting(result);

+        }

+    }

+

+    public static MessageResolver getMessageResolverForValidationStrategy(ValidationStrategy validationStrategy)

+    {

+        return ((ClassMappingFactory<ValidationStrategy, MessageResolver>) ExtValContext.getContext()

+                .getFactoryFinder()

+                .getFactory(FactoryNames.MESSAGE_RESOLVER_FACTORY, ClassMappingFactory.class))

+                .create(validationStrategy);

+    }

+

+    public static void registerValidationStrategyToMessageResolverNameMapper(

+            NameMapper<ValidationStrategy> validationStrategyToMsgResolverNameMapper)

+    {

+        (ExtValContext.getContext()

+                .getFactoryFinder()

+                .getFactory(FactoryNames.MESSAGE_RESOLVER_FACTORY, NameMapperAwareFactory.class))

+                .register(validationStrategyToMsgResolverNameMapper);

+    }

+

+    public static void deregisterValidationStrategyToMessageResolverNameMapper(

+            Class<? extends NameMapper> validationStrategyToMessageResolverNameMapperClass)

+    {

+        (ExtValContext.getContext()

+                .getFactoryFinder()

+                .getFactory(FactoryNames.MESSAGE_RESOLVER_FACTORY, NameMapperAwareFactory.class))

+                .deregister(validationStrategyToMessageResolverNameMapperClass);

+    }

+

+    public static void denyValidationStrategyToMessageResolverNameMapper(

+            Class<? extends NameMapper> validationStrategyToMessageResolverNameMapperClass)

+    {

+        (ExtValContext.getContext()

+                .getFactoryFinder()

+                .getFactory(FactoryNames.MESSAGE_RESOLVER_FACTORY, NameMapperAwareFactory.class))

+                .deny(validationStrategyToMessageResolverNameMapperClass);

+    }

+

+    public static ELHelper getELHelper()

+    {

+        return ExtValContext.getContext().getFactoryFinder()

+                .getFactory(FactoryNames.EL_HELPER_FACTORY, AbstractELHelperFactory.class).create();

+    }

+

+    public static FacesMessage createFacesMessage(String summary, String detail)

+    {

+        return createFacesMessage(FacesMessage.SEVERITY_ERROR, summary, detail);

+    }

+

+    public static FacesMessage createFacesMessage(FacesMessage.Severity severity, String summary, String detail)

+    {

+        return ExtValContext.getContext().getFactoryFinder()

+                .getFactory(FactoryNames.FACES_MESSAGE_FACTORY, FacesMessageFactory.class)

+                .create(severity, summary, detail);

+    }

+

+    public static FacesMessage convertFacesMessage(FacesMessage facesMessage)

+    {

+        return ExtValContext.getContext().getFactoryFinder()

+                .getFactory(FactoryNames.FACES_MESSAGE_FACTORY, FacesMessageFactory.class)

+                .convert(facesMessage);

+    }

+

+    public static PropertyDetails createPropertyDetailsForNewTarget(MetaDataEntry metaDataEntry,

+                                                                    String targetExpression)

+    {

+        Object baseObject;

+        if (getELHelper().isELTermWellFormed(targetExpression))

+        {

+            ValueBindingExpression vbe = new ValueBindingExpression(targetExpression);

+

+            String expression = vbe.getExpressionString();

+            baseObject = getELHelper().getValueOfExpression(FacesContext.getCurrentInstance(), vbe.getBaseExpression());

+            return new PropertyDetails(

+                    expression.substring(2, expression.length() - 1), baseObject, vbe.getProperty());

+        }

+

+        PropertyDetails original = metaDataEntry.getProperty(

+                PropertyInformationKeys.PROPERTY_DETAILS, PropertyDetails.class);

+

+        String newBaseKey = original.getKey().substring(0, original.getKey().lastIndexOf(".") + 1);

+        String newKey = newBaseKey + targetExpression;

+

+        baseObject = ReflectionUtils.getBaseOfPropertyChain(original.getBaseObject(), targetExpression);

+        return new PropertyDetails(

+                newKey, baseObject, targetExpression.substring(targetExpression.lastIndexOf(".") + 1,

+                        targetExpression.length()));

+    }

+

+    @UsageInformation(UsageCategory.INTERNAL)

+    public static void tryToPlaceLabel(FacesMessage facesMessage, String label, int index)

+    {

+        if (facesMessage.getSummary() != null && facesMessage.getSummary().contains("{" + index + "}"))

+        {

+            facesMessage.setSummary(facesMessage.getSummary().replace("{" + index + "}", label));

+        }

+

+        if (facesMessage.getDetail() != null && facesMessage.getDetail().contains("{" + index + "}"))

+        {

+            facesMessage.setDetail(facesMessage.getDetail().replace("{" + index + "}", label));

+        }

+    }

+

+    @UsageInformation(UsageCategory.INTERNAL)

+    public static void replaceWithDefaultMaximumMessage(FacesMessage facesMessage, int maxLength)

+    {

+        String facesRequiredMessage = JsfUtils.getMessageFromApplicationMessageBundle(JAVAX_FACES_MAXIMUM);

+        String facesRequiredMessageDetail = facesRequiredMessage;

+

+        //use try/catch for easier sync between trunk/branch

+        try

+        {

+            if (JsfUtils.getMessageFromApplicationMessageBundle(JAVAX_FACES_MAXIMUM_DETAIL) != null)

+            {

+                facesRequiredMessageDetail = JsfUtils

+                        .getMessageFromApplicationMessageBundle(JAVAX_FACES_MAXIMUM_DETAIL);

+            }

+        }

+        catch (MissingResourceException missingResourceException)

+        {

+            //jsf 1.2 doesn't have a detail message

+        }

+

+        facesRequiredMessage = facesRequiredMessage.replace("{0}", "" + maxLength);

+        facesRequiredMessageDetail = facesRequiredMessageDetail.replace("{0}", "" + maxLength);

+

+        facesMessage.setSummary(facesRequiredMessage);

+        facesMessage.setDetail(facesRequiredMessageDetail);

+    }

+

+    @UsageInformation(UsageCategory.INTERNAL)

+    public static void replaceWithDefaultRequiredMessage(FacesMessage facesMessage)

+    {

+        String facesRequiredMessage = JsfUtils.getMessageFromApplicationMessageBundle(JAVAX_FACES_REQUIRED);

+        String facesRequiredMessageDetail = facesRequiredMessage;

+

+        //use try/catch for easier sync between trunk/branch

+        try

+        {

+            if (JsfUtils.getMessageFromApplicationMessageBundle(JAVAX_FACES_REQUIRED_DETAIL) != null)

+            {

+                facesRequiredMessageDetail = JsfUtils

+                        .getMessageFromApplicationMessageBundle(JAVAX_FACES_REQUIRED_DETAIL);

+            }

+        }

+        catch (MissingResourceException missingResourceException)

+        {

+            //jsf 1.2 doesn't have a detail message

+        }

+

+        facesMessage.setSummary(facesRequiredMessage);

+        facesMessage.setDetail(facesRequiredMessageDetail);

+    }

+

+    public static boolean isSkipableValidationStrategy(Class<? extends ValidationStrategy> targetClass)

+    {

+        for (Class currentClass : getSkipValidationSupportClassList())

+        {

+            if (isSkipValidationSupported(currentClass, targetClass))

+            {

+                return true;

+            }

+        }

+

+        return false;

+    }

+

+    public static boolean processMetaDataEntryAfterSkipValidation(

+            Class<? extends ValidationStrategy> targetClass, MetaDataEntry entry)

+    {

+        return isSkipableValidationStrategy(targetClass) &&

+                Boolean.TRUE.equals(entry.getProperty(PropertyInformationKeys.SKIP_VALIDATION, Boolean.class));

+    }

+

+    public static List<Class> getSkipValidationSupportClassList()

+    {

+        List<StaticConfiguration<String, String>> staticConfigurationList = ExtValContext.getContext()

+                .getStaticConfiguration(StaticConfigurationNames.SKIP_VALIDATION_SUPPORT_CONFIG);

+

+        List<Class> markerList = new ArrayList<Class>();

+

+        Class currentClass;

+        for (StaticConfiguration<String, String> currentEntry : staticConfigurationList)

+        {

+            for (StaticConfigurationEntry<String, String> currentConfigurationEntry : currentEntry.getMapping())

+            {

+                currentClass = ClassUtils.tryToLoadClassForName(currentConfigurationEntry.getTarget());

+

+                if (currentClass != null)

+                {

+                    markerList.add(currentClass);

+                }

+                else

+                {

+                    if (LOGGER.isWarnEnabled())

+                    {

+                        LOGGER.warn("configuration entry provides an invalid entry: "

+                                + currentConfigurationEntry.getTarget());

+                    }

+                }

+            }

+        }

+

+        return markerList;

+    }

+

+    @SuppressWarnings({"unchecked"})

+    public static boolean isSkipValidationSupported(Class currentClass, Class targetClass)

+    {

+        if (currentClass.isAnnotation())

+        {

+            if (targetClass.isAnnotationPresent(currentClass))

+            {

+                return true;

+            }

+        }

+        else

+        {

+            if (currentClass.isAssignableFrom(targetClass))

+            {

+                return true;

+            }

+        }

+

+        return false;

+    }

+

+    public static ValidationParameterExtractor getValidationParameterExtractor()

+    {

+        if(isValidationParameterExtractionDeactivated())

+        {

+            return new ValidationParameterExtractor() {

+

+                public Map<Object, List<Object>> extract(Annotation annotation)

+                {

+                    return new HashMap<Object, List<Object>>();

+                }

+

+                public List<Object> extract(Annotation annotation, Object key)

+                {

+                    return new ArrayList<Object>();

+                }

+

+                public <T> List<T> extract(Annotation annotation, Object key, Class<T> valueType)

+                {

+                    return new ArrayList<T>();

+                }

+

+                public <T> T extract(Annotation annotation, Object key, Class<T> valueType, Class valueId)

+                {

+                    return null;

+                }

+            };

+        }

+        return ExtValContext.getContext().getFactoryFinder().getFactory(

+                FactoryNames.VALIDATION_PARAMETER_EXTRACTOR_FACTORY, ValidationParameterExtractorFactory.class)

+                .create();

+    }

+

+    public static Class getValidationParameterClassFor(Class source)

+    {

+         ClassMappingFactory<Class, Class> validationParameterFactory = ExtValContext.getContext().getFactoryFinder()

+                 .getFactory(FactoryNames.VALIDATION_PARAMETER_FACTORY, ClassMappingFactory.class);

+

+        return validationParameterFactory.create(source);

+    }

+

+    private static boolean isValidationParameterExtractionDeactivated()

+    {

+        return "true".equalsIgnoreCase(WebXmlParameter.DEACTIVATE_VALIDATION_PARAMETERS);

+    }

+

+    public static boolean executeLocalBeforeValidationInterceptors(FacesContext facesContext,

+                                                                   UIComponent uiComponent,

+                                                                   Object convertedObject,

+                                                                   String propertyKey,

+                                                                   Object properties,

+                                                                   Annotation annotation)

+    {

+        Map<String, Object> propertyMap = new HashMap<String, Object>();

+        List<PropertyValidationInterceptor> propertyValidationInterceptors = getValidationParameterExtractor().extract(

+                annotation, PropertyValidationInterceptor.class, PropertyValidationInterceptor.class);

+        boolean result = true;

+

+        if (properties != null)

+        {

+            propertyMap.put(propertyKey, properties);

+        }

+        propertyMap.put(Annotation.class.getName(), annotation);

+

+        for (PropertyValidationInterceptor propertyValidationInterceptor : propertyValidationInterceptors)

+        {

+            if (!propertyValidationInterceptor

+                    .beforeValidation(facesContext, uiComponent, convertedObject, propertyMap))

+            {

+                result = false;

+            }

+        }

+

+        return result;

+    }

+

+    public static void executeLocalAfterValidationInterceptors(FacesContext facesContext,

+                                                               UIComponent uiComponent,

+                                                               Object convertedObject,

+                                                               String propertyKey,

+                                                               Object properties,

+                                                               Annotation annotation)

+    {

+        Map<String, Object> propertyMap = new HashMap<String, Object>();

+        List<PropertyValidationInterceptor> propertyValidationInterceptors = getValidationParameterExtractor().extract(

+                annotation, PropertyValidationInterceptor.class, PropertyValidationInterceptor.class);

+

+        if (properties != null)

+        {

+            propertyMap.put(propertyKey, properties);

+            propertyMap.put(Annotation.class.getName(), annotation);

+        }

+

+        for (PropertyValidationInterceptor propertyValidationInterceptor : propertyValidationInterceptors)

+        {

+            propertyValidationInterceptor.afterValidation(facesContext, uiComponent, convertedObject, propertyMap);

+        }

+    }

+

+    @ToDo(value = Priority.MEDIUM, description = "is renaming ok?")

+    public static boolean executeGlobalBeforeValidationInterceptors(FacesContext facesContext,

+                                                                    UIComponent uiComponent,

+                                                                    Object convertedObject,

+                                                                    String propertyKey,

+                                                                    Object properties,

+                                                                    Class moduleKey)

+    {

+        Map<String, Object> propertyMap = new HashMap<String, Object>();

+        boolean result = true;

+

+        if (properties != null)

+        {

+            propertyMap.put(propertyKey, properties);

+        }

+

+        List<PropertyValidationInterceptor> propertyValidationInterceptors =

+                ExtValContext.getContext().getPropertyValidationInterceptorsFor(moduleKey);

+

+        for (PropertyValidationInterceptor propertyValidationInterceptor : propertyValidationInterceptors)

+        {

+            if (!propertyValidationInterceptor

+                    .beforeValidation(facesContext, uiComponent, convertedObject, propertyMap))

+            {

+                result = false;

+            }

+        }

+

+        return result;

+    }

+

+    @ToDo(value = Priority.MEDIUM, description = "is renaming ok?")

+    public static void executeGlobalAfterValidationInterceptors(FacesContext facesContext,

+                                                                UIComponent uiComponent,

+                                                                Object convertedObject,

+                                                                String propertyKey,

+                                                                Object properties,

+                                                                Class moduleKey)

+    {

+        Map<String, Object> propertyMap = new HashMap<String, Object>();

+

+        if (properties != null)

+        {

+            propertyMap.put(propertyKey, properties);

+        }

+

+        List<PropertyValidationInterceptor> propertyValidationInterceptors =

+                ExtValContext.getContext().getPropertyValidationInterceptorsFor(moduleKey);

+

+        for (PropertyValidationInterceptor propertyValidationInterceptor : propertyValidationInterceptors)

+        {

+            propertyValidationInterceptor.afterValidation(facesContext, uiComponent, convertedObject, propertyMap);

+        }

+    }

+

+    public static <T> T getStorage(Class<T> storageType, String storageName)

+    {

+        return (T) getStorageManagerFactory().create(storageType).create(storageName);

+    }

+

+    public static void resetStorage(Class storageType, String storageName)

+    {

+        getStorageManagerFactory().create(storageType).reset(storageName);

+    }

+

+    private static ClassMappingFactory<Class, StorageManager> getStorageManagerFactory()

+    {

+        return (ExtValContext.getContext()

+                .getFactoryFinder()

+                .getFactory(FactoryNames.STORAGE_MANAGER_FACTORY, ClassMappingFactory.class));

+    }

+

+    public static Map<String, Object> getTransformedMetaData(FacesContext facesContext, UIComponent uiComponent)

+    {

+        return getTransformedMetaDataFor(facesContext, uiComponent, null);

+    }

+

+    public static Map<String, Object> getTransformedMetaDataFor(

+            FacesContext facesContext, UIComponent uiComponent, Class moduleKey)

+    {

+        Map<String, Object> properties = new HashMap<String, Object>();

+

+        if(moduleKey != null)

+        {

+            properties.put(ValidationModuleKey.class.getName(), moduleKey);

+        }

+

+        return getTransformedMetaDataWith(facesContext, uiComponent, properties);

+    }

+

+    public static Map<String, Object> getTransformedMetaDataWith(

+            FacesContext facesContext, UIComponent uiComponent, Map<String, Object> properties)

+    {

+        ValidationStrategy validationStrategy;

+

+        SkipValidationEvaluator skipValidationEvaluator = ExtValContext.getContext().getSkipValidationEvaluator();

+        MetaDataExtractor metaDataExtractor = getComponentMetaDataExtractorWith(properties);

+

+        Map<String, Object> metaData;

+        Map<String, Object> metaDataResult = new HashMap<String, Object>();

+

+        for (MetaDataEntry entry : metaDataExtractor.extract(facesContext, uiComponent).getMetaDataEntries())

+        {

+            metaData = new HashMap<String, Object>();

+            validationStrategy = getValidationStrategyForMetaData(entry.getKey());

+

+            if (validationStrategy != null)

+            {

+                metaData = transformMetaData(

+                        facesContext, uiComponent, validationStrategy, skipValidationEvaluator, metaData, entry);

+

+                if (!isComponentInitializationSkipped(metaData, entry, validationStrategy))

+                {

+                    //don't break maybe there are constraints which don't support the skip-mechanism

+                    metaDataResult.putAll(metaData);

+                }

+            }

+        }

+

+        return metaDataResult;

+    }

+

+    private static Map<String, Object> transformMetaData(FacesContext facesContext,

+                                                         UIComponent uiComponent,

+                                                         ValidationStrategy validationStrategy,

+                                                         SkipValidationEvaluator skipValidationEvaluator,

+                                                         Map<String, Object> metaData, MetaDataEntry entry)

+    {

+        if (!skipValidationEvaluator.skipValidation(facesContext, uiComponent, validationStrategy, entry))

+        {

+            MetaDataTransformer metaDataTransformer = getMetaDataTransformerForValidationStrategy(validationStrategy);

+

+            if (metaDataTransformer != null)

+            {

+                if (LOGGER.isDebugEnabled())

+                {

+                    LOGGER.debug(metaDataTransformer.getClass().getName() + " instantiated");

+                }

+

+                metaData = metaDataTransformer.convertMetaData(entry);

+            }

+            else

+            {

+                metaData = null;

+            }

+

+            if (metaData == null)

+            {

+                return new HashMap<String, Object>();

+            }

+        }

+        return metaData;

+    }

+

+    private static boolean isComponentInitializationSkipped(Map<String, Object> metaData, MetaDataEntry entry,

+                                                            ValidationStrategy validationStrategy)

+    {

+        return metaData.isEmpty() ||

+                (Boolean.TRUE.equals(entry.getProperty(PropertyInformationKeys.SKIP_VALIDATION, Boolean.class)) &&

+                        isSkipableValidationStrategy(ProxyUtils.getUnproxiedClass(

+                                validationStrategy.getClass(), ValidationStrategy.class)));

+    }

+

+    public static boolean interpretEmptyStringValuesAsNull()

+    {

+        //to deactivate: the parameter has to be explicitly false

+        return !"false".equalsIgnoreCase(WebXmlParameter.INTERPRET_EMPTY_STRING_SUBMITTED_VALUES_AS_NULL);

+    }

+

+    public static boolean validateEmptyFields()

+    {

+        return !"false".equalsIgnoreCase(WebXmlParameter.VALIDATE_EMPTY_FIELDS);

+    }

+

+    public static PropertyDetails getPropertyDetails(PropertyInformation propertyInformation)

+    {

+        return propertyInformation.getInformation(PropertyInformationKeys.PROPERTY_DETAILS, PropertyDetails.class);

+    }

+

+    public static void tryToThrowValidatorExceptionForComponentId(

+            String clientId, FacesMessage facesMessage, Throwable throwable)

+    {

+        UIComponent targetComponent = findComponent(clientId);

+

+        tryToThrowValidatorExceptionForComponent(targetComponent, facesMessage, throwable);

+    }

+

+    public static void tryToThrowValidatorExceptionForComponent(

+            UIComponent uiComponent, FacesMessage facesMessage, Throwable throwable)

+    {

+        ViolationSeverityInterpreter interpreter =

+                ExtValContext.getContext().getViolationSeverityInterpreter();

+

+        FacesContext facesContext = FacesContext.getCurrentInstance();

+

+        if (interpreter.severityCausesValidatorException(facesContext, uiComponent, facesMessage.getSeverity()))

+        {

+            if (throwable == null)

+            {

+                throw new ValidatorException(facesMessage);

+            }

+            else

+            {

+                throw new ValidatorException(facesMessage, throwable);

+            }

+        }

+        else

+        {

+            tryToAddViolationMessageForComponent(uiComponent, facesMessage);

+        }

+    }

+

+    public static void tryToAddViolationMessageForComponentId(String clientId, FacesMessage facesMessage)

+    {

+        UIComponent targetComponent = findComponent(clientId);

+

+        if (targetComponent == null && clientId != null)

+        {

+            tryToAddViolationMessageForTestClientId(clientId, facesMessage);

+            return;

+        }

+        tryToAddViolationMessageForComponent(targetComponent, facesMessage);

+    }

+

+    @ToDo(value = Priority.MEDIUM, description = "required for test frameworks - goal: remove it")

+    private static void tryToAddViolationMessageForTestClientId(String clientId, FacesMessage facesMessage)

+    {

+        ViolationSeverityInterpreter interpreter =

+                ExtValContext.getContext().getViolationSeverityInterpreter();

+

+        FacesContext facesContext = FacesContext.getCurrentInstance();

+

+        if (interpreter.severityCausesViolationMessage(facesContext, null, facesMessage.getSeverity()))

+        {

+            addFacesMessage(clientId, facesMessage);

+        }

+        tryToBlocksNavigationForComponent(null, facesMessage);

+    }

+

+    public static void tryToAddViolationMessageForComponent(UIComponent uiComponent, FacesMessage facesMessage)

+    {

+        ViolationSeverityInterpreter interpreter =

+                ExtValContext.getContext().getViolationSeverityInterpreter();

+

+        FacesContext facesContext = FacesContext.getCurrentInstance();

+

+        if (interpreter.severityCausesViolationMessage(facesContext, uiComponent, facesMessage.getSeverity()))

+        {

+            if (uiComponent != null)

+            {

+                addFacesMessage(uiComponent.getClientId(facesContext), facesMessage);

+            }

+            else

+            {

+                addFacesMessage(null, facesMessage);

+            }

+        }

+        tryToBlocksNavigationForComponent(uiComponent, facesMessage);

+    }

+

+    public static void addFacesMessage(FacesMessage facesMessage)

+    {

+        addFacesMessage(null, facesMessage);

+    }

+

+    public static void addFacesMessage(String clientId, FacesMessage facesMessage)

+    {

+        FacesMessageStorage storage = getStorage(FacesMessageStorage.class, FacesMessageStorage.class.getName());

+

+        if (storage != null)

+        {

+            storage.addFacesMessage(clientId, facesMessage);

+        }

+        else

+        {

+            FacesContext.getCurrentInstance().addMessage(clientId, facesMessage);

+        }

+    }

+

+    public static void tryToBlocksNavigationForComponentId(String clientId, FacesMessage facesMessage)

+    {

+        UIComponent targetComponent = findComponent(clientId);

+

+        tryToBlocksNavigationForComponent(targetComponent, facesMessage);

+    }

+

+    public static void tryToBlocksNavigationForComponent(UIComponent uiComponent, FacesMessage facesMessage)

+    {

+        ViolationSeverityInterpreter interpreter =

+                ExtValContext.getContext().getViolationSeverityInterpreter();

+

+        FacesContext facesContext = FacesContext.getCurrentInstance();

+

+        if (interpreter.severityBlocksNavigation(facesContext, uiComponent, facesMessage.getSeverity()))

+        {

+            FacesContext.getCurrentInstance().renderResponse();

+        }

+    }

+

+    public static boolean severityBlocksSubmitForComponentId(String clientId, FacesMessage facesMessage)

+    {

+        ViolationSeverityInterpreter interpreter =

+                ExtValContext.getContext().getViolationSeverityInterpreter();

+

+        FacesContext facesContext = FacesContext.getCurrentInstance();

+        UIComponent targetComponent = findComponent(clientId);

+

+        return interpreter.severityBlocksSubmit(facesContext, targetComponent, facesMessage.getSeverity());

+    }

+

+    //available for add-ons - not used internally due to performance reasons

+    public static boolean severityShowsIndicationForComponentId(String clientId, FacesMessage facesMessage)

+    {

+        ViolationSeverityInterpreter interpreter =

+                ExtValContext.getContext().getViolationSeverityInterpreter();

+

+        FacesContext facesContext = FacesContext.getCurrentInstance();

+        UIComponent targetComponent = findComponent(clientId);

+

+        return interpreter.severityShowsIndication(facesContext, targetComponent, facesMessage.getSeverity());

+    }

+

+    private static UIComponent findComponent(String clientId)

+    {

+        UIComponent targetComponent = null;

+

+        if (clientId != null)

+        {

+            targetComponent = FacesContext.getCurrentInstance().getViewRoot().findComponent(clientId);

+        }

+        return targetComponent;

+    }

+

+    /**

+     * @return true if component initialization for required validation is activated

+     */

+    public static boolean isRequiredInitializationActive()

+    {

+        return Boolean.TRUE.equals(ExtValContext.getContext().getGlobalProperty("mode:init:required"));

+    }

+

+    /**

+     * needed for some component libs - if required initialization is used e.g. for visual indicators

+     * but features like severity aware validation aren't used.

+     * in such a case it's possible to use the required attribute.

+     * 

+     * @return false to deactivate the final reset of the value of the required attribute

+     */

+    public static boolean isRequiredResetActivated()

+    {

+        return Boolean.TRUE.equals(ExtValContext.getContext().getGlobalProperty("mode:reset:required"));

+    }

+

+    public static ProjectStageName getDefaultStageName()

+    {

+        return createProjectStageName("Production");

+    }

+

+    public static ProjectStageName createProjectStageName(String name)

+    {

+        return DefaultProjectName.createProjectStageName(name);

+    }

+

+    public static boolean isExtValDeactivated()

+    {

+        return "true".equalsIgnoreCase(System

+                .getProperty(ExtValInformation.EXTENSIONS_VALIDATOR_BASE_PACKAGE_NAME +

+                    ".DEACTIVATE_ALL", "false"));

+    }

+}

diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/util/GroupUtils.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/util/GroupUtils.java
new file mode 100644
index 0000000..585eab3
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/util/GroupUtils.java
@@ -0,0 +1,35 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.util;

+

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+

+/**

+ * @author Gerhard Petracek

+ * @since x.x.3

+ */

+@UsageInformation(UsageCategory.INTERNAL)

+public class GroupUtils

+{

+    public static String getGroupKey(String viewId, String clientId)

+    {

+        return clientId == null ? viewId : viewId + "@" + clientId;

+    }

+}

diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/util/JsfUtils.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/util/JsfUtils.java
new file mode 100644
index 0000000..5e76eca
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/util/JsfUtils.java
@@ -0,0 +1,138 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.util;

+

+import org.apache.myfaces.extensions.validator.core.storage.FacesInformationStorage;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+

+import javax.faces.FactoryFinder;

+import javax.faces.application.FacesMessage;

+import javax.faces.context.FacesContext;

+import javax.faces.event.PhaseId;

+import javax.faces.event.PhaseListener;

+import javax.faces.lifecycle.Lifecycle;

+import javax.faces.lifecycle.LifecycleFactory;

+import java.util.Iterator;

+import java.util.MissingResourceException;

+import java.util.ResourceBundle;

+

+

+/**

+ * @author Gerhard Petracek

+ * @since 1.x.1

+ */

+@UsageInformation(UsageCategory.INTERNAL)

+public class JsfUtils

+{

+    public static void deregisterPhaseListener(PhaseListener phaseListener)

+    {

+        LifecycleFactory lifecycleFactory = (LifecycleFactory)FactoryFinder.getFactory(FactoryFinder.LIFECYCLE_FACTORY);

+

+        String currentId;

+        Lifecycle currentLifecycle;

+        Iterator lifecycleIds = lifecycleFactory.getLifecycleIds();

+        while (lifecycleIds.hasNext())

+        {

+            currentId = (String) lifecycleIds.next();

+            currentLifecycle = lifecycleFactory.getLifecycle(currentId);

+            currentLifecycle.removePhaseListener(phaseListener);

+        }

+    }

+

+    public static void registerPhaseListener(PhaseListener phaseListener)

+    {

+        LifecycleFactory lifecycleFactory = (LifecycleFactory)FactoryFinder.getFactory(FactoryFinder.LIFECYCLE_FACTORY);

+

+        String currentId;

+        Lifecycle currentLifecycle;

+        Iterator lifecycleIds = lifecycleFactory.getLifecycleIds();

+        while (lifecycleIds.hasNext())

+        {

+            currentId = (String) lifecycleIds.next();

+            currentLifecycle = lifecycleFactory.getLifecycle(currentId);

+            currentLifecycle.addPhaseListener(phaseListener);

+        }

+    }

+

+    public static ResourceBundle getDefaultFacesMessageBundle()

+    {

+        FacesContext facesContext = FacesContext.getCurrentInstance();

+

+        return ResourceBundle.getBundle(FacesMessage.FACES_MESSAGES, facesContext.getViewRoot().getLocale());

+    }

+

+    public static ResourceBundle getCustomFacesMessageBundle()

+    {

+        FacesContext facesContext = FacesContext.getCurrentInstance();

+        String bundleName = facesContext.getApplication().getMessageBundle();

+

+        if (bundleName == null)

+        {

+            return null;

+        }

+

+        return ResourceBundle.getBundle(bundleName, facesContext.getViewRoot().getLocale());

+    }

+

+    public static String getMessageFromApplicationMessageBundle(String messageKey)

+    {

+        ResourceBundle customResourceBundle = getCustomFacesMessageBundle();

+

+        try

+        {

+            if (customResourceBundle != null)

+            {

+                return customResourceBundle.getString(messageKey);

+            }

+        }

+        catch (MissingResourceException e)

+        {

+            //no custom message is available - do nothing

+        }

+

+        return getDefaultFacesMessageBundle().getString(messageKey);

+    }

+

+    public static boolean isRenderResponsePhase()

+    {

+        return PhaseId.RENDER_RESPONSE.equals(getFacesInformationStorage().getCurrentPhaseId());

+    }

+

+    public static PhaseId getCurrentPhaseId()

+    {

+        return getFacesInformationStorage().getCurrentPhaseId();

+    }

+

+    /**

+     * simple test for early config in case of mojarra

+     * @return true if the jsf impl. is initialized and it's possible to use it as expected

+     */

+    public static boolean isApplicationInitialized()

+    {

+        return FacesContext.getCurrentInstance().getClass().getName().startsWith("org.apache.myfaces") ||

+                FacesContext.getCurrentInstance().getExternalContext().getRequestMap() != null &&

+                        !FacesContext.getCurrentInstance().getExternalContext().getRequestMap().isEmpty();

+    }

+

+    private static FacesInformationStorage getFacesInformationStorage()

+    {

+        return ExtValUtils.getStorage(FacesInformationStorage.class, FacesInformationStorage.class.getName());

+    }

+}

diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/util/ProxyUtils.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/util/ProxyUtils.java
new file mode 100644
index 0000000..c75c23e
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/util/ProxyUtils.java
@@ -0,0 +1,98 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.util;

+

+import org.apache.myfaces.extensions.validator.core.proxy.ProxyHelper;

+import org.apache.myfaces.extensions.validator.core.proxy.DefaultProxyHelper;

+import org.apache.myfaces.extensions.validator.core.WebXmlParameter;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+

+/**

+ * @author Gerhard Petracek

+ * @since x.x.3

+ */

+@UsageInformation(UsageCategory.INTERNAL)

+public class ProxyUtils

+{

+    private static ProxyHelper proxyHelper;

+

+    public static <T> Class<T> getUnproxiedClass(Class currentClass, Class<T> targetType)

+    {

+        return getProxyHelper().getUnproxiedClass(currentClass, targetType);

+    }

+

+    public static Class getUnproxiedClass(Class currentClass)

+    {

+        return getProxyHelper().getUnproxiedClass(currentClass);

+    }

+

+    public static String getClassName(Class proxiedClass)

+    {

+        return getProxyHelper().getNameOfClass(proxiedClass);

+    }

+

+    public static String getClassNameOfObject(Object proxiedObject)

+    {

+        return getProxyHelper().getClassNameOfObject(proxiedObject);

+    }

+

+    public static boolean isProxiedClass(Class currentClass)

+    {

+        return getProxyHelper().isProxiedClass(currentClass);

+    }

+

+    public static boolean isProxiedObject(Object proxiedObject)

+    {

+        return getProxyHelper().isProxiedObject(proxiedObject);

+    }

+

+    private static ProxyHelper getProxyHelper()

+    {

+        if (proxyHelper == null)

+        {

+            //workaround for mojarra

+            if(!JsfUtils.isApplicationInitialized())

+            {

+                return new DefaultProxyHelper();

+            }

+

+            proxyHelper = createProxyHelper();

+        }

+        return proxyHelper;

+    }

+

+    //don't use the default approach (factory finder) - ProxyHelper is called too often...

+    private static ProxyHelper createProxyHelper()

+    {

+        String customProxyHelperClassName = WebXmlParameter.CUSTOM_PROXY_HELPER;

+

+        ProxyHelper result = null;

+        if(customProxyHelperClassName != null && !"".equals(customProxyHelperClassName))

+        {

+            result = (ProxyHelper)ClassUtils.tryToInstantiateClassForName(customProxyHelperClassName);

+        }

+        if(result == null)

+        {

+            result = new DefaultProxyHelper();

+        }

+

+        return result;

+    }

+}

diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/util/ReflectionUtils.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/util/ReflectionUtils.java
new file mode 100644
index 0000000..8e062bf
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/util/ReflectionUtils.java
@@ -0,0 +1,196 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.myfaces.extensions.validator.util;
+
+import org.apache.myfaces.extensions.validator.internal.UsageCategory;
+import org.apache.myfaces.extensions.validator.internal.UsageInformation;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.StringTokenizer;
+
+/**
+ * @author Gerhard Petracek
+ * @since 1.x.1
+ */
+@UsageInformation(UsageCategory.INTERNAL)
+public class ReflectionUtils
+{
+    public static Method tryToGetMethod(Class targetClass, String targetMethodName)
+    {
+        return tryToGetMethod(targetClass, targetMethodName, null);
+    }
+
+    public static Method tryToGetMethod(Class targetClass, String targetMethodName, Class... parameterTypes)
+    {
+        try
+        {
+            return getMethod(targetClass, targetMethodName, parameterTypes);
+        }
+        catch (Throwable t)
+        {
+            //do nothing - it's just a try
+            return null;
+        }
+    }
+
+    public static Method getMethod(Class targetClass, String targetMethodName)
+        throws NoSuchMethodException
+    {
+        return getMethod(targetClass, targetMethodName, null);
+    }
+
+    public static Method getMethod(Class targetClass, String targetMethodName, Class... parameterTypes)
+        throws NoSuchMethodException
+    {
+        Class currentClass = targetClass;
+        Method targetMethod = null;
+        
+        while (!Object.class.getName().equals(currentClass.getName()))
+        {
+            try
+            {
+                targetMethod = currentClass.getDeclaredMethod(targetMethodName, parameterTypes);
+                break;
+            }
+            catch (NoSuchMethodException e)
+            {
+                currentClass = currentClass.getSuperclass();
+            }
+        }
+
+        if(targetMethod == null)
+        {
+            for (Class currentInterface : targetClass.getInterfaces())
+            {
+                currentClass = currentInterface;
+
+                while (currentClass != null)
+                {
+                    try
+                    {
+                        targetMethod = currentClass.getDeclaredMethod(targetMethodName, parameterTypes);
+                        break;
+                    }
+                    catch (NoSuchMethodException e)
+                    {
+                        currentClass = currentClass.getSuperclass();
+                    }
+                }
+            }
+        }
+
+        if(targetMethod != null)
+        {
+            return targetMethod;
+        }
+
+        throw new NoSuchMethodException("there is no method with the name '" + targetMethodName + "'" +
+                " class: " + targetClass.getName());
+    }
+
+    public static Object tryToInvokeMethod(Object target, Method method)
+    {
+        return tryToInvokeMethod(target, method, null);
+    }
+
+    public static Object tryToInvokeMethodOfClass(Class target, Method method)
+    {
+        return tryToInvokeMethodOfClass(target, method, null);
+    }
+
+    public static Object tryToInvokeMethodOfClass(Class target, Method method, Object[] args)
+    {
+        try
+        {
+            return invokeMethodOfClass(target, method, args);
+        }
+        catch (Throwable e)
+        {
+            //do nothing - it's just a try
+            return null;
+        }
+    }
+
+    public static Object invokeMethodOfClass(Class target, Method method)
+        throws IllegalAccessException, InstantiationException, InvocationTargetException
+    {
+        return invokeMethod(target.newInstance(), method, null);
+    }
+
+    public static Object invokeMethodOfClass(Class target, Method method, Object... args)
+        throws IllegalAccessException, InstantiationException, InvocationTargetException
+    {
+        return invokeMethod(target.newInstance(), method, args);
+    }
+
+    public static Object tryToInvokeMethod(Object target, Method method, Object... args)
+    {
+        try
+        {
+            return invokeMethod(target, method, args);
+        }
+        catch (Throwable t)
+        {
+            //do nothing - it's just a try
+            return null;
+        }
+    }
+
+    public static Object invokeMethod(Object target, Method method)
+        throws InvocationTargetException, IllegalAccessException
+    {
+        return invokeMethod(target, method, null);
+    }
+
+    public static Object invokeMethod(Object target, Method method, Object... args)
+        throws InvocationTargetException, IllegalAccessException
+    {
+        method.setAccessible(true);
+        return method.invoke(target, args);
+    }
+
+    public static Object getBaseOfPropertyChain(Object baseObject, String propertyChain)
+    {
+        StringTokenizer tokenizer = new StringTokenizer(propertyChain, ".");
+
+        Object currentBase = baseObject;
+        String currentProperty;
+        Method currentMethod;
+
+        while(tokenizer.hasMoreTokens())
+        {
+            currentProperty = tokenizer.nextToken();
+
+            //ignore the last property
+            if(!tokenizer.hasMoreTokens())
+            {
+                break;
+            }
+
+            //no is - it's only possible at properties not at bean level
+            currentMethod = tryToGetMethod(ProxyUtils.getUnproxiedClass(currentBase.getClass()),
+                "get" + currentProperty.substring(0, 1).toUpperCase() +
+                    currentProperty.substring(1, currentProperty.length()));
+            currentBase = tryToInvokeMethod(currentBase, currentMethod);
+        }
+
+        return currentBase;
+    }
+}
diff --git a/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/util/WebXmlUtils.java b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/util/WebXmlUtils.java
new file mode 100644
index 0000000..db0769c
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/java/org/apache/myfaces/extensions/validator/util/WebXmlUtils.java
@@ -0,0 +1,49 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.util;

+

+import org.apache.myfaces.extensions.validator.ExtValInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+

+import javax.faces.context.FacesContext;

+

+/**

+ * @author Gerhard Petracek

+ * @since 1.x.1

+ */

+@UsageInformation(UsageCategory.INTERNAL)

+public class WebXmlUtils

+{

+    public static String getInitParameter(String key)

+    {

+        return getInitParameter(ExtValInformation.WEBXML_PARAM_PREFIX, key);

+    }

+

+    public static String getInitParameter(String prefix, String name)

+    {

+        String parameterName = name;

+        if(prefix != null)

+        {

+            parameterName = prefix + "." + name;

+        }

+        String value = FacesContext.getCurrentInstance().getExternalContext().getInitParameter(parameterName);

+        return (value != null) ? value.replace(" ", "").trim() : null;

+    }

+}

diff --git a/2_0_3_prepare/core/src/main/resources/LICENSE.txt b/2_0_3_prepare/core/src/main/resources/LICENSE.txt
new file mode 100644
index 0000000..c6055ec
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/resources/LICENSE.txt
@@ -0,0 +1,174 @@
+                                 Apache License

+                           Version 2.0, January 2004

+                        http://www.apache.org/licenses/

+

+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

+

+   1. Definitions.

+

+      "License" shall mean the terms and conditions for use, reproduction,

+      and distribution as defined by Sections 1 through 9 of this document.

+

+      "Licensor" shall mean the copyright owner or entity authorized by

+      the copyright owner that is granting the License.

+

+      "Legal Entity" shall mean the union of the acting entity and all

+      other entities that control, are controlled by, or are under common

+      control with that entity. For the purposes of this definition,

+      "control" means (i) the power, direct or indirect, to cause the

+      direction or management of such entity, whether by contract or

+      otherwise, or (ii) ownership of fifty percent (50%) or more of the

+      outstanding shares, or (iii) beneficial ownership of such entity.

+

+      "You" (or "Your") shall mean an individual or Legal Entity

+      exercising permissions granted by this License.

+

+      "Source" form shall mean the preferred form for making modifications,

+      including but not limited to software source code, documentation

+      source, and configuration files.

+

+      "Object" form shall mean any form resulting from mechanical

+      transformation or translation of a Source form, including but

+      not limited to compiled object code, generated documentation,

+      and conversions to other media types.

+

+      "Work" shall mean the work of authorship, whether in Source or

+      Object form, made available under the License, as indicated by a

+      copyright notice that is included in or attached to the work

+      (an example is provided in the Appendix below).

+

+      "Derivative Works" shall mean any work, whether in Source or Object

+      form, that is based on (or derived from) the Work and for which the

+      editorial revisions, annotations, elaborations, or other modifications

+      represent, as a whole, an original work of authorship. For the purposes

+      of this License, Derivative Works shall not include works that remain

+      separable from, or merely link (or bind by name) to the interfaces of,

+      the Work and Derivative Works thereof.

+

+      "Contribution" shall mean any work of authorship, including

+      the original version of the Work and any modifications or additions

+      to that Work or Derivative Works thereof, that is intentionally

+      submitted to Licensor for inclusion in the Work by the copyright owner

+      or by an individual or Legal Entity authorized to submit on behalf of

+      the copyright owner. For the purposes of this definition, "submitted"

+      means any form of electronic, verbal, or written communication sent

+      to the Licensor or its representatives, including but not limited to

+      communication on electronic mailing lists, source code control systems,

+      and issue tracking systems that are managed by, or on behalf of, the

+      Licensor for the purpose of discussing and improving the Work, but

+      excluding communication that is conspicuously marked or otherwise

+      designated in writing by the copyright owner as "Not a Contribution."

+

+      "Contributor" shall mean Licensor and any individual or Legal Entity

+      on behalf of whom a Contribution has been received by Licensor and

+      subsequently incorporated within the Work.

+

+   2. Grant of Copyright License. Subject to the terms and conditions of

+      this License, each Contributor hereby grants to You a perpetual,

+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable

+      copyright license to reproduce, prepare Derivative Works of,

+      publicly display, publicly perform, sublicense, and distribute the

+      Work and such Derivative Works in Source or Object form.

+

+   3. Grant of Patent License. Subject to the terms and conditions of

+      this License, each Contributor hereby grants to You a perpetual,

+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable

+      (except as stated in this section) patent license to make, have made,

+      use, offer to sell, sell, import, and otherwise transfer the Work,

+      where such license applies only to those patent claims licensable

+      by such Contributor that are necessarily infringed by their

+      Contribution(s) alone or by combination of their Contribution(s)

+      with the Work to which such Contribution(s) was submitted. If You

+      institute patent litigation against any entity (including a

+      cross-claim or counterclaim in a lawsuit) alleging that the Work

+      or a Contribution incorporated within the Work constitutes direct

+      or contributory patent infringement, then any patent licenses

+      granted to You under this License for that Work shall terminate

+      as of the date such litigation is filed.

+

+   4. Redistribution. You may reproduce and distribute copies of the

+      Work or Derivative Works thereof in any medium, with or without

+      modifications, and in Source or Object form, provided that You

+      meet the following conditions:

+

+      (a) You must give any other recipients of the Work or

+          Derivative Works a copy of this License; and

+

+      (b) You must cause any modified files to carry prominent notices

+          stating that You changed the files; and

+

+      (c) You must retain, in the Source form of any Derivative Works

+          that You distribute, all copyright, patent, trademark, and

+          attribution notices from the Source form of the Work,

+          excluding those notices that do not pertain to any part of

+          the Derivative Works; and

+

+      (d) If the Work includes a "NOTICE" text file as part of its

+          distribution, then any Derivative Works that You distribute must

+          include a readable copy of the attribution notices contained

+          within such NOTICE file, excluding those notices that do not

+          pertain to any part of the Derivative Works, in at least one

+          of the following places: within a NOTICE text file distributed

+          as part of the Derivative Works; within the Source form or

+          documentation, if provided along with the Derivative Works; or,

+          within a display generated by the Derivative Works, if and

+          wherever such third-party notices normally appear. The contents

+          of the NOTICE file are for informational purposes only and

+          do not modify the License. You may add Your own attribution

+          notices within Derivative Works that You distribute, alongside

+          or as an addendum to the NOTICE text from the Work, provided

+          that such additional attribution notices cannot be construed

+          as modifying the License.

+

+      You may add Your own copyright statement to Your modifications and

+      may provide additional or different license terms and conditions

+      for use, reproduction, or distribution of Your modifications, or

+      for any such Derivative Works as a whole, provided Your use,

+      reproduction, and distribution of the Work otherwise complies with

+      the conditions stated in this License.

+

+   5. Submission of Contributions. Unless You explicitly state otherwise,

+      any Contribution intentionally submitted for inclusion in the Work

+      by You to the Licensor shall be under the terms and conditions of

+      this License, without any additional terms or conditions.

+      Notwithstanding the above, nothing herein shall supersede or modify

+      the terms of any separate license agreement you may have executed

+      with Licensor regarding such Contributions.

+

+   6. Trademarks. This License does not grant permission to use the trade

+      names, trademarks, service marks, or product names of the Licensor,

+      except as required for reasonable and customary use in describing the

+      origin of the Work and reproducing the content of the NOTICE file.

+

+   7. Disclaimer of Warranty. Unless required by applicable law or

+      agreed to in writing, Licensor provides the Work (and each

+      Contributor provides its Contributions) on an "AS IS" BASIS,

+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or

+      implied, including, without limitation, any warranties or conditions

+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A

+      PARTICULAR PURPOSE. You are solely responsible for determining the

+      appropriateness of using or redistributing the Work and assume any

+      risks associated with Your exercise of permissions under this License.

+

+   8. Limitation of Liability. In no event and under no legal theory,

+      whether in tort (including negligence), contract, or otherwise,

+      unless required by applicable law (such as deliberate and grossly

+      negligent acts) or agreed to in writing, shall any Contributor be

+      liable to You for damages, including any direct, indirect, special,

+      incidental, or consequential damages of any character arising as a

+      result of this License or out of the use or inability to use the

+      Work (including but not limited to damages for loss of goodwill,

+      work stoppage, computer failure or malfunction, or any and all

+      other commercial damages or losses), even if such Contributor

+      has been advised of the possibility of such damages.

+

+   9. Accepting Warranty or Additional Liability. While redistributing

+      the Work or Derivative Works thereof, You may choose to offer,

+      and charge a fee for, acceptance of support, warranty, indemnity,

+      or other liability obligations and/or rights consistent with this

+      License. However, in accepting such obligations, You may act only

+      on Your own behalf and on Your sole responsibility, not on behalf

+      of any other Contributor, and only if You agree to indemnify,

+      defend, and hold each Contributor harmless for any liability

+      incurred by, or claims asserted against, such Contributor by reason

+      of your accepting any such warranty or additional liability.

diff --git a/2_0_3_prepare/core/src/main/resources/NOTICE.txt b/2_0_3_prepare/core/src/main/resources/NOTICE.txt
new file mode 100644
index 0000000..4278ef3
--- /dev/null
+++ b/2_0_3_prepare/core/src/main/resources/NOTICE.txt
@@ -0,0 +1,9 @@
+Apache MyFaces Extensions Validator

+Copyright 2007-2008 The Apache Software Foundation

+

+This product includes software developed by

+The Apache Software Foundation (http://www.apache.org/).

+

+------------------------------------------------------------------------

+See the file LICENSE.txt

+------------------------------------------------------------------------
\ No newline at end of file
diff --git a/2_0_3_prepare/core/src/site/apt/index.apt b/2_0_3_prepare/core/src/site/apt/index.apt
new file mode 100644
index 0000000..4a201d2
--- /dev/null
+++ b/2_0_3_prepare/core/src/site/apt/index.apt
@@ -0,0 +1,10 @@
+ ------

+Apache MyFaces Extensions Validator Core Module

+ ------

+

+Apache MyFaces Extensions Validator Core Module Overview

+

+    MyFaces Extensions Validator Core Module provides an extensible validation platform to implement validation based on meta-data.

+    Based on this module it is possible to implement validation modules.

+

+    MyFaces Extensions Validator is compatible with JSF 1.1.x and JSF 1.2.x. Both versions require Java 1.5+
\ No newline at end of file
diff --git a/2_0_3_prepare/examples/assembly/pom.xml b/2_0_3_prepare/examples/assembly/pom.xml
new file mode 100644
index 0000000..5d10260
--- /dev/null
+++ b/2_0_3_prepare/examples/assembly/pom.xml
@@ -0,0 +1,146 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+    Licensed to the Apache Software Foundation (ASF) under one

+    or more contributor license agreements.  See the NOTICE file

+    distributed with this work for additional information

+    regarding copyright ownership.  The ASF licenses this file

+    to you under the Apache License, Version 2.0 (the

+    "License"); you may not use this file except in compliance

+    with the License.  You may obtain a copy of the License at

+

+    http://www.apache.org/licenses/LICENSE-2.0

+

+    Unless required by applicable law or agreed to in writing,

+    software distributed under the License is distributed on an

+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+    KIND, either express or implied.  See the License for the

+    specific language governing permissions and limitations

+    under the License.

+-->

+<project xmlns="http://maven.apache.org/POM/4.0.0"

+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

+    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">

+    <modelVersion>4.0.0</modelVersion>

+    <packaging>pom</packaging>

+    <name>Apache MyFaces Extensions Validator Examples Assembly</name>

+    <groupId>org.apache.myfaces.extensions.validator.examples</groupId>

+    <artifactId>myfaces-extval-examples-assembly12</artifactId>

+

+    <parent>

+        <groupId>org.apache.myfaces.extensions.validator.examples</groupId>

+        <artifactId>examples-project</artifactId>

+        <version>2.0.3-SNAPSHOT</version>

+    </parent>

+

+    <build>

+        <plugins>

+            <plugin>

+                <groupId>org.codehaus.mojo</groupId>

+                <artifactId>dependency-maven-plugin</artifactId>

+                <executions>

+                    <execution>

+                        <id>copy-war</id>

+                        <phase>package</phase>

+                        <goals>

+                            <goal>copy</goal>

+                        </goals>

+                        <configuration>

+                            <artifactItems>

+                                <artifactItem>

+                                    <groupId>org.apache.myfaces.extensions.validator.examples</groupId>

+                                    <artifactId>examples-hello_world</artifactId>

+                                    <version>${project.version}</version>

+                                    <type>war</type>	

+                                </artifactItem>

+                                <artifactItem>

+                                    <groupId>org.apache.myfaces.extensions.validator.examples</groupId>

+                                    <artifactId>examples-feature-set_01</artifactId>

+                                    <version>${project.version}</version>

+                                    <type>war</type>

+                                </artifactItem>

+                            </artifactItems>

+                            <outputDirectory>${project.build.directory}/war</outputDirectory>

+                        </configuration>

+                    </execution>

+                    <execution>

+                        <id>copy-src</id>

+                        <phase>package</phase>

+                        <goals>

+                            <goal>copy</goal>

+                        </goals>

+                        <configuration>

+                            <artifactItems>

+                                <artifactItem>

+                                    <groupId>org.apache.myfaces.extensions.validator.examples</groupId>

+                                    <artifactId>examples-hello_world</artifactId>

+                                    <version>${project.version}</version>

+                                    <type>java-source</type>    

+                                </artifactItem>

+                                <artifactItem>

+                                    <groupId>org.apache.myfaces.extensions.validator.examples</groupId>

+                                    <artifactId>examples-feature-set_01</artifactId>

+                                    <version>${project.version}</version>

+                                    <type>java-source</type>

+                                </artifactItem>

+                            </artifactItems>

+                            <outputDirectory>${project.build.directory}/src</outputDirectory>

+                        </configuration>

+                    </execution>                    

+                </executions>

+            </plugin>

+

+            <plugin>

+                <!-- EXECUTE mvn package to generate assembly files -->

+                <artifactId>maven-assembly-plugin</artifactId>

+                <version>2.1</version>

+                <executions>

+                    <execution>

+                        <id>make_assembly_src</id>

+                        <phase>package</phase>

+                        <goals>

+                            <goal>assembly</goal>

+                        </goals>

+                        <configuration>

+                            <descriptors>   

+                                <descriptor>src/main/assembly/depsrc.xml</descriptor>

+                            </descriptors>

+                            <finalName>myfaces-extval-examples-${project.version}-src</finalName>

+                            <appendAssemblyId>false</appendAssemblyId>

+                            <outputDirectory>${project.build.directory}/out</outputDirectory>

+                            <workDirectory>${project.build.directory}/work</workDirectory>

+                        </configuration>                

+                    </execution>

+                    <execution>

+                        <id>make_assembly_bin</id>

+                        <phase>package</phase>

+                        <goals>

+                            <goal>assembly</goal>

+                        </goals>

+	                    <configuration>

+	                        <descriptors>   

+	                            <descriptor>src/main/assembly/dep.xml</descriptor>

+	                        </descriptors>

+	                        <finalName>myfaces-extval-examples-${project.version}</finalName>

+	                        <outputDirectory>${project.build.directory}/out</outputDirectory>

+	                        <workDirectory>${project.build.directory}/work</workDirectory>

+	                    </configuration>                        

+                    </execution>

+                </executions>

+            </plugin>

+	    

+            <plugin>

+                <groupId>org.apache.myfaces.maven</groupId>

+                <artifactId>wagon-maven-plugin</artifactId>

+                <version>1.0.1</version>

+                <configuration>

+                    <id>myfaces-nightly-builds</id>

+                    <url>scpexe://minotaur.apache.org/www/people.apache.org/builds/myfaces/nightly</url>

+                    <inputDirectory>${project.build.directory}/out</inputDirectory>

+                </configuration>

+            </plugin>

+

+        </plugins>

+

+    </build>

+

+</project>

diff --git a/2_0_3_prepare/examples/assembly/src/main/assembly/dep.xml b/2_0_3_prepare/examples/assembly/src/main/assembly/dep.xml
new file mode 100644
index 0000000..9bb3ec4
--- /dev/null
+++ b/2_0_3_prepare/examples/assembly/src/main/assembly/dep.xml
@@ -0,0 +1,17 @@
+<assembly>

+  <id>bin</id>

+  <includeBaseDirectory>false</includeBaseDirectory>

+  <formats>

+    <format>tar.gz</format>

+    <format>zip</format>

+  </formats>	

+  <fileSets>    

+    <fileSet>

+      <directory>target/war</directory>

+      <outputDirectory></outputDirectory>

+      <includes>

+        <include>*.war</include>

+      </includes>

+    </fileSet>     

+  </fileSets>

+</assembly>

diff --git a/2_0_3_prepare/examples/assembly/src/main/assembly/depsrc.xml b/2_0_3_prepare/examples/assembly/src/main/assembly/depsrc.xml
new file mode 100644
index 0000000..63a5803
--- /dev/null
+++ b/2_0_3_prepare/examples/assembly/src/main/assembly/depsrc.xml
@@ -0,0 +1,24 @@
+<assembly>

+  <id>src</id>

+  <includeBaseDirectory>false</includeBaseDirectory>

+  <formats>

+    <format>tar.gz</format>

+    <format>zip</format>

+  </formats>	

+  <fileSets>    

+    <fileSet>

+      <directory>target/src</directory>

+      <outputDirectory></outputDirectory>

+      <includes>

+        <include>*.jar</include>

+      </includes>

+    </fileSet>

+    <fileSet>

+      <directory>src/main/resources</directory>

+      <outputDirectory></outputDirectory>

+      <includes>

+        <include>*.txt</include>

+      </includes>

+    </fileSet>

+  </fileSets>

+</assembly>

diff --git a/2_0_3_prepare/examples/assembly/src/main/resources/LICENSE.txt b/2_0_3_prepare/examples/assembly/src/main/resources/LICENSE.txt
new file mode 100644
index 0000000..c6055ec
--- /dev/null
+++ b/2_0_3_prepare/examples/assembly/src/main/resources/LICENSE.txt
@@ -0,0 +1,174 @@
+                                 Apache License

+                           Version 2.0, January 2004

+                        http://www.apache.org/licenses/

+

+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

+

+   1. Definitions.

+

+      "License" shall mean the terms and conditions for use, reproduction,

+      and distribution as defined by Sections 1 through 9 of this document.

+

+      "Licensor" shall mean the copyright owner or entity authorized by

+      the copyright owner that is granting the License.

+

+      "Legal Entity" shall mean the union of the acting entity and all

+      other entities that control, are controlled by, or are under common

+      control with that entity. For the purposes of this definition,

+      "control" means (i) the power, direct or indirect, to cause the

+      direction or management of such entity, whether by contract or

+      otherwise, or (ii) ownership of fifty percent (50%) or more of the

+      outstanding shares, or (iii) beneficial ownership of such entity.

+

+      "You" (or "Your") shall mean an individual or Legal Entity

+      exercising permissions granted by this License.

+

+      "Source" form shall mean the preferred form for making modifications,

+      including but not limited to software source code, documentation

+      source, and configuration files.

+

+      "Object" form shall mean any form resulting from mechanical

+      transformation or translation of a Source form, including but

+      not limited to compiled object code, generated documentation,

+      and conversions to other media types.

+

+      "Work" shall mean the work of authorship, whether in Source or

+      Object form, made available under the License, as indicated by a

+      copyright notice that is included in or attached to the work

+      (an example is provided in the Appendix below).

+

+      "Derivative Works" shall mean any work, whether in Source or Object

+      form, that is based on (or derived from) the Work and for which the

+      editorial revisions, annotations, elaborations, or other modifications

+      represent, as a whole, an original work of authorship. For the purposes

+      of this License, Derivative Works shall not include works that remain

+      separable from, or merely link (or bind by name) to the interfaces of,

+      the Work and Derivative Works thereof.

+

+      "Contribution" shall mean any work of authorship, including

+      the original version of the Work and any modifications or additions

+      to that Work or Derivative Works thereof, that is intentionally

+      submitted to Licensor for inclusion in the Work by the copyright owner

+      or by an individual or Legal Entity authorized to submit on behalf of

+      the copyright owner. For the purposes of this definition, "submitted"

+      means any form of electronic, verbal, or written communication sent

+      to the Licensor or its representatives, including but not limited to

+      communication on electronic mailing lists, source code control systems,

+      and issue tracking systems that are managed by, or on behalf of, the

+      Licensor for the purpose of discussing and improving the Work, but

+      excluding communication that is conspicuously marked or otherwise

+      designated in writing by the copyright owner as "Not a Contribution."

+

+      "Contributor" shall mean Licensor and any individual or Legal Entity

+      on behalf of whom a Contribution has been received by Licensor and

+      subsequently incorporated within the Work.

+

+   2. Grant of Copyright License. Subject to the terms and conditions of

+      this License, each Contributor hereby grants to You a perpetual,

+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable

+      copyright license to reproduce, prepare Derivative Works of,

+      publicly display, publicly perform, sublicense, and distribute the

+      Work and such Derivative Works in Source or Object form.

+

+   3. Grant of Patent License. Subject to the terms and conditions of

+      this License, each Contributor hereby grants to You a perpetual,

+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable

+      (except as stated in this section) patent license to make, have made,

+      use, offer to sell, sell, import, and otherwise transfer the Work,

+      where such license applies only to those patent claims licensable

+      by such Contributor that are necessarily infringed by their

+      Contribution(s) alone or by combination of their Contribution(s)

+      with the Work to which such Contribution(s) was submitted. If You

+      institute patent litigation against any entity (including a

+      cross-claim or counterclaim in a lawsuit) alleging that the Work

+      or a Contribution incorporated within the Work constitutes direct

+      or contributory patent infringement, then any patent licenses

+      granted to You under this License for that Work shall terminate

+      as of the date such litigation is filed.

+

+   4. Redistribution. You may reproduce and distribute copies of the

+      Work or Derivative Works thereof in any medium, with or without

+      modifications, and in Source or Object form, provided that You

+      meet the following conditions:

+

+      (a) You must give any other recipients of the Work or

+          Derivative Works a copy of this License; and

+

+      (b) You must cause any modified files to carry prominent notices

+          stating that You changed the files; and

+

+      (c) You must retain, in the Source form of any Derivative Works

+          that You distribute, all copyright, patent, trademark, and

+          attribution notices from the Source form of the Work,

+          excluding those notices that do not pertain to any part of

+          the Derivative Works; and

+

+      (d) If the Work includes a "NOTICE" text file as part of its

+          distribution, then any Derivative Works that You distribute must

+          include a readable copy of the attribution notices contained

+          within such NOTICE file, excluding those notices that do not

+          pertain to any part of the Derivative Works, in at least one

+          of the following places: within a NOTICE text file distributed

+          as part of the Derivative Works; within the Source form or

+          documentation, if provided along with the Derivative Works; or,

+          within a display generated by the Derivative Works, if and

+          wherever such third-party notices normally appear. The contents

+          of the NOTICE file are for informational purposes only and

+          do not modify the License. You may add Your own attribution

+          notices within Derivative Works that You distribute, alongside

+          or as an addendum to the NOTICE text from the Work, provided

+          that such additional attribution notices cannot be construed

+          as modifying the License.

+

+      You may add Your own copyright statement to Your modifications and

+      may provide additional or different license terms and conditions

+      for use, reproduction, or distribution of Your modifications, or

+      for any such Derivative Works as a whole, provided Your use,

+      reproduction, and distribution of the Work otherwise complies with

+      the conditions stated in this License.

+

+   5. Submission of Contributions. Unless You explicitly state otherwise,

+      any Contribution intentionally submitted for inclusion in the Work

+      by You to the Licensor shall be under the terms and conditions of

+      this License, without any additional terms or conditions.

+      Notwithstanding the above, nothing herein shall supersede or modify

+      the terms of any separate license agreement you may have executed

+      with Licensor regarding such Contributions.

+

+   6. Trademarks. This License does not grant permission to use the trade

+      names, trademarks, service marks, or product names of the Licensor,

+      except as required for reasonable and customary use in describing the

+      origin of the Work and reproducing the content of the NOTICE file.

+

+   7. Disclaimer of Warranty. Unless required by applicable law or

+      agreed to in writing, Licensor provides the Work (and each

+      Contributor provides its Contributions) on an "AS IS" BASIS,

+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or

+      implied, including, without limitation, any warranties or conditions

+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A

+      PARTICULAR PURPOSE. You are solely responsible for determining the

+      appropriateness of using or redistributing the Work and assume any

+      risks associated with Your exercise of permissions under this License.

+

+   8. Limitation of Liability. In no event and under no legal theory,

+      whether in tort (including negligence), contract, or otherwise,

+      unless required by applicable law (such as deliberate and grossly

+      negligent acts) or agreed to in writing, shall any Contributor be

+      liable to You for damages, including any direct, indirect, special,

+      incidental, or consequential damages of any character arising as a

+      result of this License or out of the use or inability to use the

+      Work (including but not limited to damages for loss of goodwill,

+      work stoppage, computer failure or malfunction, or any and all

+      other commercial damages or losses), even if such Contributor

+      has been advised of the possibility of such damages.

+

+   9. Accepting Warranty or Additional Liability. While redistributing

+      the Work or Derivative Works thereof, You may choose to offer,

+      and charge a fee for, acceptance of support, warranty, indemnity,

+      or other liability obligations and/or rights consistent with this

+      License. However, in accepting such obligations, You may act only

+      on Your own behalf and on Your sole responsibility, not on behalf

+      of any other Contributor, and only if You agree to indemnify,

+      defend, and hold each Contributor harmless for any liability

+      incurred by, or claims asserted against, such Contributor by reason

+      of your accepting any such warranty or additional liability.

diff --git a/2_0_3_prepare/examples/assembly/src/main/resources/NOTICE.txt b/2_0_3_prepare/examples/assembly/src/main/resources/NOTICE.txt
new file mode 100644
index 0000000..4278ef3
--- /dev/null
+++ b/2_0_3_prepare/examples/assembly/src/main/resources/NOTICE.txt
@@ -0,0 +1,9 @@
+Apache MyFaces Extensions Validator

+Copyright 2007-2008 The Apache Software Foundation

+

+This product includes software developed by

+The Apache Software Foundation (http://www.apache.org/).

+

+------------------------------------------------------------------------

+See the file LICENSE.txt

+------------------------------------------------------------------------
\ No newline at end of file
diff --git a/2_0_3_prepare/examples/pom.xml b/2_0_3_prepare/examples/pom.xml
new file mode 100644
index 0000000..f852762
--- /dev/null
+++ b/2_0_3_prepare/examples/pom.xml
@@ -0,0 +1,95 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+    Licensed to the Apache Software Foundation (ASF) under one

+    or more contributor license agreements.  See the NOTICE file

+    distributed with this work for additional information

+    regarding copyright ownership.  The ASF licenses this file

+    to you under the Apache License, Version 2.0 (the

+    "License"); you may not use this file except in compliance

+    with the License.  You may obtain a copy of the License at

+

+    http://www.apache.org/licenses/LICENSE-2.0

+

+    Unless required by applicable law or agreed to in writing,

+    software distributed under the License is distributed on an

+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+    KIND, either express or implied.  See the License for the

+    specific language governing permissions and limitations

+    under the License.

+-->

+<project xmlns="http://maven.apache.org/POM/4.0.0"

+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">

+    <modelVersion>4.0.0</modelVersion>

+

+    <packaging>pom</packaging>

+

+    <groupId>org.apache.myfaces.extensions.validator.examples</groupId>

+    <artifactId>examples-project</artifactId>

+

+    <name>MyFaces Extensions-Validator examples project</name>

+    <version>2.0.3-SNAPSHOT</version>

+

+    <parent>

+        <groupId>org.apache.myfaces.extensions.validator</groupId>

+        <artifactId>myfaces-extval-parent</artifactId>

+        <version>2.0.3-SNAPSHOT</version>

+    </parent>

+

+    <scm>

+        <connection>scm:svn:http://svn.apache.org/repos/asf/myfaces/extensions/validator/branches/1_2_2_rc/examples</connection>

+        <developerConnection>scm:svn:https://svn.apache.org/repos/asf/myfaces/extensions/validator/branches/1_2_2_rc/examples</developerConnection>

+        <url>http://svn.apache.org/viewvc/myfaces/extensions/validator/branches/1_2_2_rc/examples</url>

+    </scm>

+    

+    <build>

+        <plugins>

+            <plugin>

+                <!--This plugin allows to run the example using mvn jetty:run -->

+                <groupId>org.mortbay.jetty</groupId>

+                <artifactId>maven-jetty-plugin</artifactId>

+                <version>6.1.8</version>

+                <configuration>

+                    <scanIntervalSeconds>10</scanIntervalSeconds>

+                </configuration>

+            </plugin>

+        </plugins>

+    </build>

+

+    <modules>

+        <!--module>hello_world</module-->

+        <!--module>hello_bean-validation</module-->

+        <!--module>feature-set_01</module-->

+    </modules>

+

+    <profiles>

+        <!-- This profile is invoked by -DprepareRelease=true.  This allows mvn release:prepare to

+            run successfully on the assembly projects. -->

+        <profile>

+            <id>prepare-release</id>

+            <activation>

+                <property>

+                    <name>prepareRelease</name>

+                </property>

+            </activation>

+            <modules>

+                <module>assembly</module>

+            </modules>

+            <build>

+                <plugins>

+                    <plugin>

+                        <artifactId>maven-release-plugin</artifactId>

+                        <configuration>

+                            <arguments>-DprepareRelease</arguments>

+                        </configuration>

+                    </plugin>

+                </plugins>

+            </build>

+        </profile>

+    </profiles>

+

+    <properties>

+        <trinidad.version>1.2.9</trinidad.version>

+    </properties>

+

+</project>

diff --git a/2_0_3_prepare/parent/LICENSE.txt b/2_0_3_prepare/parent/LICENSE.txt
new file mode 100644
index 0000000..75b5248
--- /dev/null
+++ b/2_0_3_prepare/parent/LICENSE.txt
@@ -0,0 +1,202 @@
+

+                                 Apache License

+                           Version 2.0, January 2004

+                        http://www.apache.org/licenses/

+

+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

+

+   1. Definitions.

+

+      "License" shall mean the terms and conditions for use, reproduction,

+      and distribution as defined by Sections 1 through 9 of this document.

+

+      "Licensor" shall mean the copyright owner or entity authorized by

+      the copyright owner that is granting the License.

+

+      "Legal Entity" shall mean the union of the acting entity and all

+      other entities that control, are controlled by, or are under common

+      control with that entity. For the purposes of this definition,

+      "control" means (i) the power, direct or indirect, to cause the

+      direction or management of such entity, whether by contract or

+      otherwise, or (ii) ownership of fifty percent (50%) or more of the

+      outstanding shares, or (iii) beneficial ownership of such entity.

+

+      "You" (or "Your") shall mean an individual or Legal Entity

+      exercising permissions granted by this License.

+

+      "Source" form shall mean the preferred form for making modifications,

+      including but not limited to software source code, documentation

+      source, and configuration files.

+

+      "Object" form shall mean any form resulting from mechanical

+      transformation or translation of a Source form, including but

+      not limited to compiled object code, generated documentation,

+      and conversions to other media types.

+

+      "Work" shall mean the work of authorship, whether in Source or

+      Object form, made available under the License, as indicated by a

+      copyright notice that is included in or attached to the work

+      (an example is provided in the Appendix below).

+

+      "Derivative Works" shall mean any work, whether in Source or Object

+      form, that is based on (or derived from) the Work and for which the

+      editorial revisions, annotations, elaborations, or other modifications

+      represent, as a whole, an original work of authorship. For the purposes

+      of this License, Derivative Works shall not include works that remain

+      separable from, or merely link (or bind by name) to the interfaces of,

+      the Work and Derivative Works thereof.

+

+      "Contribution" shall mean any work of authorship, including

+      the original version of the Work and any modifications or additions

+      to that Work or Derivative Works thereof, that is intentionally

+      submitted to Licensor for inclusion in the Work by the copyright owner

+      or by an individual or Legal Entity authorized to submit on behalf of

+      the copyright owner. For the purposes of this definition, "submitted"

+      means any form of electronic, verbal, or written communication sent

+      to the Licensor or its representatives, including but not limited to

+      communication on electronic mailing lists, source code control systems,

+      and issue tracking systems that are managed by, or on behalf of, the

+      Licensor for the purpose of discussing and improving the Work, but

+      excluding communication that is conspicuously marked or otherwise

+      designated in writing by the copyright owner as "Not a Contribution."

+

+      "Contributor" shall mean Licensor and any individual or Legal Entity

+      on behalf of whom a Contribution has been received by Licensor and

+      subsequently incorporated within the Work.

+

+   2. Grant of Copyright License. Subject to the terms and conditions of

+      this License, each Contributor hereby grants to You a perpetual,

+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable

+      copyright license to reproduce, prepare Derivative Works of,

+      publicly display, publicly perform, sublicense, and distribute the

+      Work and such Derivative Works in Source or Object form.

+

+   3. Grant of Patent License. Subject to the terms and conditions of

+      this License, each Contributor hereby grants to You a perpetual,

+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable

+      (except as stated in this section) patent license to make, have made,

+      use, offer to sell, sell, import, and otherwise transfer the Work,

+      where such license applies only to those patent claims licensable

+      by such Contributor that are necessarily infringed by their

+      Contribution(s) alone or by combination of their Contribution(s)

+      with the Work to which such Contribution(s) was submitted. If You

+      institute patent litigation against any entity (including a

+      cross-claim or counterclaim in a lawsuit) alleging that the Work

+      or a Contribution incorporated within the Work constitutes direct

+      or contributory patent infringement, then any patent licenses

+      granted to You under this License for that Work shall terminate

+      as of the date such litigation is filed.

+

+   4. Redistribution. You may reproduce and distribute copies of the

+      Work or Derivative Works thereof in any medium, with or without

+      modifications, and in Source or Object form, provided that You

+      meet the following conditions:

+

+      (a) You must give any other recipients of the Work or

+          Derivative Works a copy of this License; and

+

+      (b) You must cause any modified files to carry prominent notices

+          stating that You changed the files; and

+

+      (c) You must retain, in the Source form of any Derivative Works

+          that You distribute, all copyright, patent, trademark, and

+          attribution notices from the Source form of the Work,

+          excluding those notices that do not pertain to any part of

+          the Derivative Works; and

+

+      (d) If the Work includes a "NOTICE" text file as part of its

+          distribution, then any Derivative Works that You distribute must

+          include a readable copy of the attribution notices contained

+          within such NOTICE file, excluding those notices that do not

+          pertain to any part of the Derivative Works, in at least one

+          of the following places: within a NOTICE text file distributed

+          as part of the Derivative Works; within the Source form or

+          documentation, if provided along with the Derivative Works; or,

+          within a display generated by the Derivative Works, if and

+          wherever such third-party notices normally appear. The contents

+          of the NOTICE file are for informational purposes only and

+          do not modify the License. You may add Your own attribution

+          notices within Derivative Works that You distribute, alongside

+          or as an addendum to the NOTICE text from the Work, provided

+          that such additional attribution notices cannot be construed

+          as modifying the License.

+

+      You may add Your own copyright statement to Your modifications and

+      may provide additional or different license terms and conditions

+      for use, reproduction, or distribution of Your modifications, or

+      for any such Derivative Works as a whole, provided Your use,

+      reproduction, and distribution of the Work otherwise complies with

+      the conditions stated in this License.

+

+   5. Submission of Contributions. Unless You explicitly state otherwise,

+      any Contribution intentionally submitted for inclusion in the Work

+      by You to the Licensor shall be under the terms and conditions of

+      this License, without any additional terms or conditions.

+      Notwithstanding the above, nothing herein shall supersede or modify

+      the terms of any separate license agreement you may have executed

+      with Licensor regarding such Contributions.

+

+   6. Trademarks. This License does not grant permission to use the trade

+      names, trademarks, service marks, or product names of the Licensor,

+      except as required for reasonable and customary use in describing the

+      origin of the Work and reproducing the content of the NOTICE file.

+

+   7. Disclaimer of Warranty. Unless required by applicable law or

+      agreed to in writing, Licensor provides the Work (and each

+      Contributor provides its Contributions) on an "AS IS" BASIS,

+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or

+      implied, including, without limitation, any warranties or conditions

+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A

+      PARTICULAR PURPOSE. You are solely responsible for determining the

+      appropriateness of using or redistributing the Work and assume any

+      risks associated with Your exercise of permissions under this License.

+

+   8. Limitation of Liability. In no event and under no legal theory,

+      whether in tort (including negligence), contract, or otherwise,

+      unless required by applicable law (such as deliberate and grossly

+      negligent acts) or agreed to in writing, shall any Contributor be

+      liable to You for damages, including any direct, indirect, special,

+      incidental, or consequential damages of any character arising as a

+      result of this License or out of the use or inability to use the

+      Work (including but not limited to damages for loss of goodwill,

+      work stoppage, computer failure or malfunction, or any and all

+      other commercial damages or losses), even if such Contributor

+      has been advised of the possibility of such damages.

+

+   9. Accepting Warranty or Additional Liability. While redistributing

+      the Work or Derivative Works thereof, You may choose to offer,

+      and charge a fee for, acceptance of support, warranty, indemnity,

+      or other liability obligations and/or rights consistent with this

+      License. However, in accepting such obligations, You may act only

+      on Your own behalf and on Your sole responsibility, not on behalf

+      of any other Contributor, and only if You agree to indemnify,

+      defend, and hold each Contributor harmless for any liability

+      incurred by, or claims asserted against, such Contributor by reason

+      of your accepting any such warranty or additional liability.

+

+   END OF TERMS AND CONDITIONS

+

+   APPENDIX: How to apply the Apache License to your work.

+

+      To apply the Apache License to your work, attach the following

+      boilerplate notice, with the fields enclosed by brackets "[]"

+      replaced with your own identifying information. (Don't include

+      the brackets!)  The text should be enclosed in the appropriate

+      comment syntax for the file format. We also recommend that a

+      file or class name and description of purpose be included on the

+      same "printed page" as the copyright notice for easier

+      identification within third-party archives.

+

+   Copyright [yyyy] [name of copyright owner]

+

+   Licensed under the Apache License, Version 2.0 (the "License");

+   you may not use this file except in compliance with the License.

+   You may obtain a copy of the License at

+

+       http://www.apache.org/licenses/LICENSE-2.0

+

+   Unless required by applicable law or agreed to in writing, software

+   distributed under the License is distributed on an "AS IS" BASIS,

+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+   See the License for the specific language governing permissions and

+   limitations under the License.

diff --git a/2_0_3_prepare/parent/NOTICE.txt b/2_0_3_prepare/parent/NOTICE.txt
new file mode 100644
index 0000000..4278ef3
--- /dev/null
+++ b/2_0_3_prepare/parent/NOTICE.txt
@@ -0,0 +1,9 @@
+Apache MyFaces Extensions Validator

+Copyright 2007-2008 The Apache Software Foundation

+

+This product includes software developed by

+The Apache Software Foundation (http://www.apache.org/).

+

+------------------------------------------------------------------------

+See the file LICENSE.txt

+------------------------------------------------------------------------
\ No newline at end of file
diff --git a/2_0_3_prepare/parent/pom.xml b/2_0_3_prepare/parent/pom.xml
new file mode 100644
index 0000000..108e3c6
--- /dev/null
+++ b/2_0_3_prepare/parent/pom.xml
@@ -0,0 +1,280 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+    Licensed to the Apache Software Foundation (ASF) under one

+    or more contributor license agreements.  See the NOTICE file

+    distributed with this work for additional information

+    regarding copyright ownership.  The ASF licenses this file

+    to you under the Apache License, Version 2.0 (the

+    "License"); you may not use this file except in compliance

+    with the License.  You may obtain a copy of the License at

+

+    http://www.apache.org/licenses/LICENSE-2.0

+

+    Unless required by applicable law or agreed to in writing,

+    software distributed under the License is distributed on an

+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+    KIND, either express or implied.  See the License for the

+    specific language governing permissions and limitations

+    under the License.

+-->

+<!--

+  - Parent pom of all the myfaces extensions validator subprojects 

+    that help to build other myfaces projects.

+  -->

+<project xmlns="http://maven.apache.org/POM/4.0.0"

+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">

+    <modelVersion>4.0.0</modelVersion>

+

+    <parent>

+        <groupId>org.apache.myfaces</groupId>

+        <artifactId>myfaces</artifactId>

+        <version>6</version>

+    </parent>

+

+    <groupId>org.apache.myfaces.extensions.validator</groupId>

+    <artifactId>myfaces-extval-parent</artifactId>

+    <version>2.0.3-SNAPSHOT</version>

+    <packaging>pom</packaging>

+    <name>Apache MyFaces Extensions-Validator Project Parent</name>

+    <url>http://myfaces.apache.org/extensions/validator12</url>

+

+    <issueManagement>

+        <system>jira</system>

+        <url>http://issues.apache.org/jira/browse/EXTVAL</url>

+    </issueManagement>

+

+    <ciManagement>

+        <system>continuum</system>

+        <url>http://myfaces.zones.apache.org:8080/continuum</url>

+        <notifiers>

+            <notifier>

+                <type>mail</type>

+                <sendOnSuccess>true</sendOnSuccess>

+                <configuration>

+                    <address>commits@myfaces.apache.org</address>

+                </configuration>

+            </notifier>

+        </notifiers>

+    </ciManagement>

+    

+    <inceptionYear>2008</inceptionYear>

+

+    <build>

+        <resources>

+            <resource>

+                <directory>${basedir}</directory>

+                <targetPath>META-INF</targetPath>

+                <includes>

+                    <include>NOTICE.txt</include>

+                    <include>LICENSE.txt</include>

+                </includes>

+            </resource>

+            <resource>

+                <directory>${basedir}/src/main/resources</directory>

+            </resource>

+        </resources>

+

+        <pluginManagement>

+            <plugins>

+                <plugin>

+                    <artifactId>maven-jar-plugin</artifactId>

+                    <version>2.2</version>

+                    <configuration>

+                        <archive>

+                            <manifest>

+                                <addDefaultImplementationEntries>true</addDefaultImplementationEntries>

+                            </manifest>

+                        </archive>

+                    </configuration>

+                </plugin>

+            </plugins>

+        </pluginManagement>

+

+        <plugins>

+            <plugin>

+                <!--

+                    - Copy LICENSE.txt and NOTICE.txt so that they are included

+                    - in the -javadoc jar file for the component.

+                -->

+                <groupId>org.apache.maven.plugins</groupId>

+                <artifactId>maven-antrun-plugin</artifactId>

+                <executions>

+                    <execution>

+                        <id>javadoc.resources</id>

+                        <phase>generate-sources</phase>

+                        <goals>

+                            <goal>run</goal>

+                        </goals>

+                        <configuration>

+                            <tasks>

+                                <copy todir="${project.build.directory}/apidocs/META-INF">

+                                    <fileset dir="${basedir}">

+                                        <include name="LICENSE.txt" />

+                                        <include name="NOTICE.txt" />

+                                    </fileset>

+                                </copy>

+                            </tasks>

+                        </configuration>

+                    </execution>

+                    <execution>

+                        <id>javadoc.site.copy</id>

+                        <phase>site</phase>

+                        <goals>

+                            <goal>run</goal>

+                        </goals>

+                        <configuration>

+                            <tasks>

+                                <!-- Copy javadoc to another directory, to keep javadoc of previous versions on site -->

+                                <copy todir="${project.build.directory}/site/apidocs-${project.version}" failonerror="false">

+                                  <fileset dir="${project.build.directory}/site/apidocs"/>

+                                </copy>

+                            </tasks>

+                        </configuration>

+                    </execution>

+                </executions>

+            </plugin>

+            <!--

+                - Make a checkstyle violation a compile error. Note that if a compile error occurs,

+                - further information can be found in target/site/checkstyle.html (present even when

+                - just the compile goal and not the site goal has been run). Note also that child

+                - projects may redeclare this plugin and provide different configuration settings

+                - to use different checks (more or less strict than the default).

+            -->

+            

+            <plugin>

+                <groupId>org.apache.maven.plugins</groupId>

+                <artifactId>maven-checkstyle-plugin</artifactId>

+                <version>2.2</version>

+                <executions>

+                    <execution>

+                        <id>verify-style</id>

+                        <phase>verify</phase>

+                        <goals>

+                            <goal>check</goal>

+                        </goals>

+                    </execution>

+                </executions>

+                <configuration>

+                    <configLocation>default/myfaces-checks-standard.xml</configLocation>

+                    <headerLocation>default/myfaces-header.txt</headerLocation>

+                </configuration>

+            </plugin>

+            

+

+            <plugin>

+                <!-- Set compile source at 1.5, since the target JSF impl is 1.2 -->

+                <groupId>org.apache.maven.plugins</groupId>

+                <artifactId>maven-compiler-plugin</artifactId>

+                <configuration>

+                    <source>1.5</source>

+                    <target>1.5</target>

+                    <optimize>false</optimize>

+                </configuration>

+            </plugin>            

+        </plugins>

+    </build>

+

+    <repositories>

+        <repository>

+            <id>maven2-repository.dev.java.net</id>

+            <name>Java.net Repository for Maven</name>

+            <url>http://download.java.net/maven/2/</url>

+            <layout>default</layout>

+        </repository>

+    </repositories>

+

+    <reporting>

+        <plugins>

+            <plugin>

+                <artifactId>maven-javadoc-plugin</artifactId>

+                <version>2.3</version>

+            </plugin>

+            <plugin>

+                <artifactId>maven-jxr-plugin</artifactId>

+                <version>2.1</version>

+            </plugin>

+            <plugin>

+                <artifactId>maven-surefire-report-plugin</artifactId>

+                <version>2.4.3</version>

+            </plugin>

+            <plugin>

+                <artifactId>maven-project-info-reports-plugin</artifactId>

+                <version>2.0.1</version>

+            </plugin>

+            <plugin>

+                <artifactId>maven-pmd-plugin</artifactId>

+                <version>2.3</version>

+                <configuration>

+                    <rulesets>

+                        <ruleset>/rulesets/basic.xml</ruleset>

+                        <ruleset>/rulesets/unusedcode.xml</ruleset>

+                    </rulesets>

+                    <linkXref>true</linkXref>

+                    <minimumTokens>100</minimumTokens>

+                    <targetJdk>1.5</targetJdk>

+                </configuration>

+            </plugin>

+            <plugin>

+                <groupId>org.apache.maven.plugins</groupId>

+                <artifactId>maven-checkstyle-plugin</artifactId>

+                <version>2.2</version>

+                <configuration>

+                    <configLocation>default/myfaces-checks-standard.xml</configLocation>

+                    <headerLocation>default/myfaces-header.txt</headerLocation>

+                </configuration>

+            </plugin>

+        </plugins>

+    </reporting>

+

+    <scm>

+        <connection>scm:svn:http://svn.apache.org/repos/asf/myfaces/extensions/validator/branches/1_2_2_rc/parent</connection>

+        <developerConnection>scm:svn:https://svn.apache.org/repos/asf/myfaces/extensions/validator/branches/1_2_2_rc/parent</developerConnection>

+        <url>http://svn.apache.org/viewvc/myfaces/extensions/validator/branches/1_2_2_rc/parent</url>

+    </scm>

+

+    <distributionManagement>

+        <snapshotRepository>

+            <uniqueVersion>false</uniqueVersion>

+            <id>apache.snapshots</id>

+            <name>Apache Maven Snapshot Repository</name>

+            <url>scpexe://people.apache.org/www/people.apache.org/repo/m2-snapshot-repository</url>

+        </snapshotRepository>

+        <site>

+            <id>apache-site</id>

+            <url>scpexe://people.apache.org/www/myfaces.apache.org/extensions/validator12</url>

+        </site>

+    </distributionManagement>

+

+    <profiles>

+        <profile>

+            <id>generate-assembly</id>

+            <activation>

+                <property>

+                    <name>performRelease</name>

+                    <value>true</value>

+                </property>

+            </activation>

+            <build>

+                <plugins>

+                    <plugin>

+                        <artifactId>maven-javadoc-plugin</artifactId>

+                        <version>2.3</version>

+                        <executions>

+                            <execution>

+                                <id>attach-javadocs</id>

+                                <goals>

+                                    <goal>jar</goal>

+                                </goals>

+                            </execution>

+                        </executions>

+                    </plugin>

+                </plugins>

+            </build>

+        </profile>

+    </profiles>

+

+    <properties>

+        <jsf.version>1.2.4</jsf.version>

+    </properties>

+</project>

diff --git a/2_0_3_prepare/parent/src/site/apt/index.apt b/2_0_3_prepare/parent/src/site/apt/index.apt
new file mode 100644
index 0000000..6287930
--- /dev/null
+++ b/2_0_3_prepare/parent/src/site/apt/index.apt
@@ -0,0 +1,7 @@
+ ------

+Overview

+ ------

+

+Apache MyFaces Extensions Validator for JSF 1.2

+

+  Apache MyFaces Extensions Validator provides versions for JSF 1.1 and 1.2

diff --git a/2_0_3_prepare/parent/src/site/apt/javadoc.apt b/2_0_3_prepare/parent/src/site/apt/javadoc.apt
new file mode 100644
index 0000000..d9fd36f
--- /dev/null
+++ b/2_0_3_prepare/parent/src/site/apt/javadoc.apt
@@ -0,0 +1,15 @@
+ ------

+Javadoc

+ ------

+

+Javadoc

+

+    Here you can find the javadoc of previous extval versions.

+

+    * {{{http://myfaces.apache.org/extensions/validator12/myfaces-extval-core/apidocs-1.2.1/index.html}Myfaces ExtVal Core Version 1.2.1}}

+

+    * {{{http://myfaces.apache.org/extensions/validator12/validation-modules-project/myfaces-extval-property-validation/apidocs-1.2.1/index.html}Myfaces ExtVal Property Validation Version 1.2.1}}

+

+    * {{{http://myfaces.apache.org/extensions/validator12/myfaces-extval-core/apidocs-1.2.2/index.html}Myfaces ExtVal Core Version 1.2.2}}

+

+    * {{{http://myfaces.apache.org/extensions/validator12/validation-modules-project/myfaces-extval-property-validation/apidocs-1.2.2/index.html}Myfaces ExtVal Property Validation Version 1.2.2}}

diff --git a/2_0_3_prepare/parent/src/site/site.xml b/2_0_3_prepare/parent/src/site/site.xml
new file mode 100644
index 0000000..e5a4ff3
--- /dev/null
+++ b/2_0_3_prepare/parent/src/site/site.xml
@@ -0,0 +1,78 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>

+<!--

+ * Licensed to the Apache Software Foundation (ASF) under one or more

+ * contributor license agreements.  See the NOTICE file distributed with

+ * this work for additional information regarding copyright ownership.

+ * The ASF licenses this file to You under the Apache License, Version 2.0

+ * (the "License"); you may not use this file except in compliance with

+ * the License.  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing, software

+ * distributed under the License is distributed on an "AS IS" BASIS,

+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * See the License for the specific language governing permissions and

+ * limitations under the License.

+-->

+

+<project name="Apache MyFaces Extensions Validator">

+  <bannerLeft>

+    <name>Apache MyFaces ExtVal</name>

+    <src>images/extval_logo.png</src>

+    <href>http://myfaces.apache.org/extensions/validator/index.html</href>

+  </bannerLeft>

+

+  <bannerRight>

+    <name>Apache MyFaces</name>

+    <src>img/banners/MyFaces_logo.jpg</src>

+    <href>http://myfaces.apache.org/index.html</href>

+  </bannerRight>

+

+  <publishDate format="dd MMM yyyy"/>

+

+  <skin>

+    <groupId>org.apache.myfaces.maven</groupId>

+    <artifactId>myfaces-site-skin</artifactId>

+    <version>1-SNAPSHOT</version>

+  </skin>

+

+  <body>

+    <links>

+      <item name="Apache" href="http://www.apache.org"/>

+      <item name="MyFaces" href="http://myfaces.apache.org/index.html"/>

+      <item name="Download Myfaces ExtVal" href="http://myfaces.apache.org/extensions/validator/download.html"/>

+    </links>

+

+    <menu name="Apache MyFaces" inherit="top">

+      <item name="Overview"       href="http://myfaces.apache.org/index.html"/>

+      <item name="Download"       href="http://myfaces.apache.org/download.html"/>

+    </menu>

+

+    <menu name="Contents" inherit="top">

+        <item name="Main Site"         href="http://myfaces.apache.org/extensions/validator/index.html"/>

+        <item name="ExtVal for JSF 1.1"       href="http://myfaces.apache.org/extensions/validator11/index.html" collapse="true">

+            <item name="dummy"        href="dummy"/>

+        </item>

+        <item name="ExtVal for JSF 1.2"   href="http://myfaces.apache.org/extensions/validator12/index.html">

+              <item name="Core Module"           href="http://myfaces.apache.org/extensions/validator12/myfaces-extval-core/index.html"/>

+              <item name="Property Validation"   href="http://myfaces.apache.org/extensions/validator12/validation-modules-project/myfaces-extval-property-validation/index.html"/>

+              <item name="Trinidad Support"      href="http://myfaces.apache.org/extensions/validator12/component-support-modules-project/myfaces-extval-trinidad-support/index.html"/>

+              <item name="Generic Support"       href="http://myfaces.apache.org/extensions/validator12/component-support-modules-project/myfaces-extval-generic-support/index.html"/>

+        </item>

+    </menu>

+	

+    <menu name="Documentation">

+      <item name="Wiki"         href="http://wiki.apache.org/myfaces/Extensions/Validator/"/>

+      <item name="Javadoc"      href="http://myfaces.apache.org/extensions/validator12/javadoc.html"/>

+    </menu>

+

+    <menu ref="reports"/>

+

+    <menu name="Foundation" inherit="bottom">

+      <item name="ASF"            href="http://www.apache.org/" />

+      <item name="Sponsorship"    href="http://www.apache.org/foundation/sponsorship.html" />

+      <item name="Thanks"         href="http://www.apache.org/foundation/thanks.html" />

+    </menu>

+  </body>

+</project>

diff --git a/2_0_3_prepare/pom.xml b/2_0_3_prepare/pom.xml
new file mode 100644
index 0000000..fe20ec2
--- /dev/null
+++ b/2_0_3_prepare/pom.xml
@@ -0,0 +1,103 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+    Licensed to the Apache Software Foundation (ASF) under one

+    or more contributor license agreements.  See the NOTICE file

+    distributed with this work for additional information

+    regarding copyright ownership.  The ASF licenses this file

+    to you under the Apache License, Version 2.0 (the

+    "License"); you may not use this file except in compliance

+    with the License.  You may obtain a copy of the License at

+

+    http://www.apache.org/licenses/LICENSE-2.0

+

+    Unless required by applicable law or agreed to in writing,

+    software distributed under the License is distributed on an

+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+    KIND, either express or implied.  See the License for the

+    specific language governing permissions and limitations

+    under the License.

+-->

+<project xmlns="http://maven.apache.org/POM/4.0.0"

+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">

+    <modelVersion>4.0.0</modelVersion>

+

+    <parent>

+        <groupId>org.apache.myfaces</groupId>

+        <artifactId>myfaces</artifactId>

+        <version>6</version>

+    </parent>

+

+    <groupId>org.apache.myfaces.extensions.validator</groupId>

+    <artifactId>myfaces-extval-module</artifactId>

+    <version>2.0.3-SNAPSHOT</version>

+    <packaging>pom</packaging>

+    <name>Apache MyFaces Extensions-Validator Module</name>

+    <url>http://myfaces.apache.org/extensions/validator12</url>

+

+    <scm>

+        <connection>scm:svn:http://svn.apache.org/repos/asf/myfaces/extensions/validator/trunk/</connection>

+        <developerConnection>scm:svn:https://svn.apache.org/repos/asf/myfaces/extensions/validator/trunk/</developerConnection>

+        <url>http://svn.apache.org/viewvc/myfaces/extensions/validator/trunk/</url>

+    </scm>

+

+    <distributionManagement>

+        <snapshotRepository>

+            <uniqueVersion>false</uniqueVersion>

+            <id>apache.snapshots</id>

+            <name>Apache Maven Snapshot Repository</name>

+            <url>scpexe://people.apache.org/www/people.apache.org/repo/m2-snapshot-repository</url>

+        </snapshotRepository>

+        <site>

+            <id>apache-site</id>

+            <url>scpexe://people.apache.org/www/myfaces.apache.org/extensions/validator12</url>

+        </site>

+    </distributionManagement>

+

+    <!-- WARNING: DO NOT GENERATE SITE FROM HERE DIRECTLY

+    Since this project has an async release procedure (not

+    all modules should be released at once), the parent pom.xml 

+    is not this (there is a module for that). Use maven site 

+    plugin here cause problems when the site is generated.

+    The procedure must execute site commmand first on parent 

+    module and then on each module listed below. 

+     -->

+

+    <modules>

+        <module>parent</module>

+        <module>core</module>

+        <module>validation-modules</module>

+        <module>component-support</module>

+        <module>examples</module>

+    </modules>

+

+    <profiles>

+        <!-- This profile is invoked by -DprepareRelease=true.  This allows mvn release:prepare to

+            run successfully on the assembly projects. -->

+        <profile>

+            <id>prepare-release</id>

+            <activation>

+                <property>

+                    <name>prepareRelease</name>

+                </property>

+            </activation>

+            <modules>

+                <module>assembly</module>

+            </modules>

+            <build>

+                <plugins>

+                    <plugin>

+                        <artifactId>maven-release-plugin</artifactId>

+                        <configuration>

+                            <arguments>-DprepareRelease</arguments>

+                        </configuration>

+                    </plugin>

+                </plugins>

+            </build>

+        </profile>

+    </profiles>

+    

+    <properties>

+        <jsf.version>1.2.4</jsf.version>

+    </properties>

+</project>

diff --git a/2_0_3_prepare/site/pom.xml b/2_0_3_prepare/site/pom.xml
new file mode 100644
index 0000000..bc86435
--- /dev/null
+++ b/2_0_3_prepare/site/pom.xml
@@ -0,0 +1,64 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+    * Licensed to the Apache Software Foundation (ASF) under one or more

+    * contributor license agreements.  See the NOTICE file distributed with

+    * this work for additional information regarding copyright ownership.

+    * The ASF licenses this file to You under the Apache License, Version 2.0

+    * (the "License"); you may not use this file except in compliance with

+    * the License.  You may obtain a copy of the License at

+    *

+    *      http://www.apache.org/licenses/LICENSE-2.0

+    *

+    * Unless required by applicable law or agreed to in writing, software

+    * distributed under the License is distributed on an "AS IS" BASIS,

+    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+    * See the License for the specific language governing permissions and

+    * limitations under the License.

+-->

+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

+    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">

+    <modelVersion>4.0.0</modelVersion>

+

+    <parent>

+        <groupId>org.apache.myfaces</groupId>

+        <artifactId>myfaces</artifactId>

+        <version>6</version>

+    </parent>

+    <groupId>org.apache.myfaces.extensions.validator</groupId>

+    <artifactId>myfaces-extval-site</artifactId>

+    <version>2.0.3-SNAPSHOT</version>

+    <packaging>pom</packaging>

+    <name>Apache MyFaces Extensions-Validator</name>

+    <url>http://myfaces.apache.org/extensions/validator</url>

+

+    <build>

+        <defaultGoal>site</defaultGoal>

+        <extensions>

+          <extension>

+            <groupId>org.apache.maven.wagon</groupId>

+            <artifactId>wagon-ssh-external</artifactId>

+            <version>1.0-alpha-5</version>

+          </extension>

+        </extensions>

+    </build>

+    <reporting>

+        <plugins>

+            <plugin>

+                <artifactId>maven-project-info-reports-plugin</artifactId>

+            </plugin>

+        </plugins>

+    </reporting>

+    <scm>

+        <connection>scm:svn:http://svn.apache.org/repos/asf/myfaces/extensions/validator/trunk/site</connection>

+        <developerConnection>scm:svn:https://svn.apache.org/repos/asf/myfaces/extensions/validator/trunk/site</developerConnection>

+        <url>http://svn.apache.org/viewcvs.cgi/myfaces/extensions/validator/trunk/site</url>

+    </scm>

+    <distributionManagement>

+      <site>

+        <id>apache-site</id>

+        <name>Apache Website</name>

+        <url>scpexe://people.apache.org/www/myfaces.apache.org/extensions/validator</url>

+      </site>

+    </distributionManagement>

+

+</project>

diff --git a/2_0_3_prepare/site/src/site/apt/download.apt b/2_0_3_prepare/site/src/site/apt/download.apt
new file mode 100644
index 0000000..7c514e0
--- /dev/null
+++ b/2_0_3_prepare/site/src/site/apt/download.apt
@@ -0,0 +1,108 @@
+ ~~ Licensed to the Apache Software Foundation (ASF) under one or more

+ ~~ contributor license agreements.  See the NOTICE file distributed with

+ ~~ this work for additional information regarding copyright ownership.

+ ~~ The ASF licenses this file to You under the Apache License, Version 2.0

+ ~~ (the "License"); you may not use this file except in compliance with

+ ~~ the License.  You may obtain a copy of the License at

+ ~~

+ ~~      http://www.apache.org/licenses/LICENSE-2.0

+ ~~

+ ~~ Unless required by applicable law or agreed to in writing, software

+ ~~ distributed under the License is distributed on an "AS IS" BASIS,

+ ~~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ ~~ See the License for the specific language governing permissions and

+ ~~ limitations under the License.

+ 

+ ------

+Download Apache MyFaces Extensions Validator

+ ------

+

+Download Apache MyFaces Extensions Validator

+

+

+  Use the links below to download a distribution of Apache MyFaces Extensions Validator from

+  one of our mirrors. It is good practice to verify the integrity of the

+  distribution files.

+

+  You will be prompted for a mirror - if the file is not found on yours, please be patient, as it may take 24

+  hours to reach all mirrors.

+

+  Apache MyFaces Extensions Validator is distributed as a <<<zip>>> archive (for Windows) and

+  as a <<<tar.gz>>> archive (for UNIX). The content is the same. Please note

+  that the <<<tar.gz>>> archives contain file names longer than 100 characters and have been

+  created using GNU tar extensions. Thus they must be untarred with a GNU compatible

+  version of tar.

+

+  << Apache MyFaces Extensions Validator 1.0.0 Distribution >>

+

+*-------------------------+---------+----------+-----------+

+|                         | Mirrors | Checksum | Signature |

+*-------------------------+---------+----------+-----------+

+| MyFaces Extensions Validator for JSF 1.1 1.1.2 (tar.gz)     | {{{http://www.apache.org/dyn/closer.cgi/myfaces/binaries/myfaces-extval11-1.1.2-bin.tar.gz} myfaces-extval11-1.1.2-bin.tar.gz}} | {{{http://www.apache.org/dist/myfaces/binaries/myfaces-extval11-1.1.2-bin.tar.gz.md5} myfaces-extval11-1.1.2-bin.tar.gz.md5}} | {{{http://www.apache.org/dist/myfaces/binaries/myfaces-extval11-1.1.2-bin.tar.gz.asc} myfaces-extval11-1.1.2-bin.tar.gz.asc}} |

+*-------------------------+---------+----------+-----------+

+| MyFaces Extensions Validator for JSF 1.1 1.1.2 (zip)      | {{{http://www.apache.org/dyn/closer.cgi/myfaces/binaries/myfaces-extval11-1.1.2-bin.zip} myfaces-extval11-1.1.2-bin.zip}} | {{{http://www.apache.org/dist/myfaces/binaries/myfaces-extval11-1.1.2-bin.zip.md5} myfaces-extval11-1.1.2-bin.zip.md5}} | {{{http://www.apache.org/dist/myfaces/binaries/myfaces-extval11-1.1.2-bin.zip.asc} myfaces-extval11-1.1.2-bin.zip.asc}} |

+*-------------------------+---------+----------+-----------+

+| MyFaces Extensions Validator for JSF 1.1 1.1.2 Source (tar.gz)     | {{{http://www.apache.org/dyn/closer.cgi/myfaces/source/myfaces-extval11-1.1.2-src.tar.gz} myfaces-extval11-1.1.2-src.tar.gz}} | {{{http://www.apache.org/dist/myfaces/source/myfaces-extval11-1.1.2-src.tar.gz.md5} myfaces-extval11-1.1.2-src.tar.gz.md5}} | {{{http://www.apache.org/dist/myfaces/source/myfaces-extval11-1.1.2-src.tar.gz.asc} myfaces-extval11-1.1.2-src.tar.gz.asc}} |

+*-------------------------+---------+----------+-----------+

+| MyFaces Extensions Validator for JSF 1.1 1.1.2 Source (zip)      | {{{http://www.apache.org/dyn/closer.cgi/myfaces/source/myfaces-extval11-1.1.2-src.zip} myfaces-extval11-1.1.2-src.zip}} | {{{http://www.apache.org/dist/myfaces/source/myfaces-extval11-1.1.2-src.zip.md5} myfaces-extval11-1.1.2-src.zip.md5}} | {{{http://www.apache.org/dist/myfaces/source/myfaces-extval11-1.1.2-src.zip.asc} myfaces-extval11-1.1.2-src.zip.asc}} |

+*-------------------------+---------+----------+-----------+

+| MyFaces Extensions Validator for JSF 1.2 1.2.2 (tar.gz)     | {{{http://www.apache.org/dyn/closer.cgi/myfaces/binaries/myfaces-extval12-1.2.2-bin.tar.gz} myfaces-extval12-1.2.2-bin.tar.gz}} | {{{http://www.apache.org/dist/myfaces/binaries/myfaces-extval12-1.2.2-bin.tar.gz.md5} myfaces-extval12-1.2.2-bin.tar.gz.md5}} | {{{http://www.apache.org/dist/myfaces/binaries/myfaces-extval12-1.2.2-bin.tar.gz.asc} myfaces-extval12-1.2.2-bin.tar.gz.asc}} |

+*-------------------------+---------+----------+-----------+

+| MyFaces Extensions Validator for JSF 1.2 1.2.2 (zip)      | {{{http://www.apache.org/dyn/closer.cgi/myfaces/binaries/myfaces-extval12-1.2.2-bin.zip} myfaces-extval12-1.2.2-bin.zip}} | {{{http://www.apache.org/dist/myfaces/binaries/myfaces-extval12-1.2.2-bin.zip.md5} myfaces-extval12-1.2.2-bin.zip.md5}} | {{{http://www.apache.org/dist/myfaces/binaries/myfaces-extval12-1.2.2-bin.zip.asc} myfaces-extval12-1.2.2-bin.zip.asc}} |

+*-------------------------+---------+----------+-----------+

+| MyFaces Extensions Validator for JSF 1.2 1.2.2 Source (tar.gz)     | {{{http://www.apache.org/dyn/closer.cgi/myfaces/source/myfaces-extval12-1.2.2-src.tar.gz} myfaces-extval12-1.2.2-src.tar.gz}} | {{{http://www.apache.org/dist/myfaces/source/myfaces-extval12-1.2.2-src.tar.gz.md5} myfaces-extval12-1.2.2-src.tar.gz.md5}} | {{{http://www.apache.org/dist/myfaces/source/myfaces-extval12-1.2.2-src.tar.gz.asc} myfaces-extval12-1.2.2-src.tar.gz.asc}} |

+*-------------------------+---------+----------+-----------+

+| MyFaces Extensions Validator for JSF 1.2 1.2.2 Source (zip)      | {{{http://www.apache.org/dyn/closer.cgi/myfaces/source/myfaces-extval12-1.2.2-src.zip} myfaces-extval12-1.2.2-src.zip}} | {{{http://www.apache.org/dist/myfaces/source/myfaces-extval12-1.2.2-src.zip.md5} myfaces-extval12-1.2.2-src.zip.md5}} | {{{http://www.apache.org/dist/myfaces/source/myfaces-extval12-1.2.2-src.zip.asc} myfaces-extval12-1.2.2-src.zip.asc}} |

+*-------------------------+---------+----------+-----------+

+

+Latest source code from SVN repository

+

+    If you want to use the latest Apache MyFaces Extensions Validator features, the source code is under

+    version control with SVN.  Click {{{source-repository.html} here }}

+    for information on how to use the ASF Extensions Validator SVN Repository.

+

+Verifying checksums

+

+    It is essential that you verify the integrity of the downloaded

+    files using the PGP and MD5 signatures. MD5 verification ensures the

+    file was not corrupted during the download process. PGP verification

+    ensures that the file came from a certain person.

+

+    To verify the MD5 signature on the files, you need to use a program

+    called <<<md5>>> or <<<md5sum>>>, which is

+    included in many UNIX distributions.  It is also available as part of

+    {{{http://www.gnu.org/software/textutils/textutils.html}GNU Textutils}}.

+    Windows users can get binary md5 programs from {{{http://www.fourmilab.ch/md5/}here}},

+    {{{http://www.pc-tools.net/win32/freeware/console/}here}}, or

+    {{{http://www.slavasoft.com/fsum/}here}}.

+

+Verifying signatures

+

+  	PGP verification ensures that the file came from a certain person.  We strongly recommend

+	  you verify your downloads with both PGP and MD5.

+

+	The PGP signatures can be verified using {{{http://www.pgpi.org/}PGP}} or 

+	{{{http://www.gnupg.org/}GPG}}.  First download the Apache MyFaces 

+	{{{http://www.apache.org/dist/myfaces/KEYS}KEYS}}	as well as the <<<asc>>> signature file 

+	for the particular distribution. It is important that you get these files from the ultimate

+	trusted source - the main ASF distribution site, rather than from a mirror.

+	Then verify the signatures using ...

+

+	  <<<

+	  % pgpk -a KEYS

+	  % pgpv myfaces-extval11-1.1.2-bin.tar.gz.asc myfaces-extval11-1.1.2-bin.tar.gz

+	  >>>

+

+	  <or>

+

+	  <<<

+	  % pgp -ka KEYS

+	  % pgp myfaces-extval11-1.1.2-bin.tar.gz.asc myfaces-extval11-1.1.2-bin.tar.gz

+	  >>>

+

+	  <or>

+

+	  <<<

+  	% gpg --import KEYS

+	  % gpg --verify myfaces-extval11-1.1.2-bin.tar.gz.asc myfaces-extval11-1.1.2-bin.tar.gz

+	  >>>

diff --git a/2_0_3_prepare/site/src/site/apt/index.apt b/2_0_3_prepare/site/src/site/apt/index.apt
new file mode 100644
index 0000000..a42539b
--- /dev/null
+++ b/2_0_3_prepare/site/src/site/apt/index.apt
@@ -0,0 +1,14 @@
+ ------

+Apache MyFaces Extensions Validator

+ ------

+

+Apache MyFaces Extensions Validator Overview

+

+    MyFaces Extensions Validator is a JSF centric validation framework.

+  

+    It offers powerful and easy to use field based validation based on annotations.

+It has a pluggable architecture, so it is possible to add new validation modules or support for component libraries like Trinidad or other 3rd party frameworks.

+

+    MyFaces Extensions Validator is compatible with JSF 1.1.x and JSF 1.2.x. Both versions require Java 1.5+

+

+    Further information are available at the {{{http://wiki.apache.org/myfaces/Extensions/Validator/}Wiki}}.
\ No newline at end of file
diff --git a/2_0_3_prepare/site/src/site/site.xml b/2_0_3_prepare/site/src/site/site.xml
new file mode 100644
index 0000000..3ebc9ff
--- /dev/null
+++ b/2_0_3_prepare/site/src/site/site.xml
@@ -0,0 +1,74 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>

+<!--

+ * Licensed to the Apache Software Foundation (ASF) under one or more

+ * contributor license agreements.  See the NOTICE file distributed with

+ * this work for additional information regarding copyright ownership.

+ * The ASF licenses this file to You under the Apache License, Version 2.0

+ * (the "License"); you may not use this file except in compliance with

+ * the License.  You may obtain a copy of the License at

+ *

+ *      http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing, software

+ * distributed under the License is distributed on an "AS IS" BASIS,

+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * See the License for the specific language governing permissions and

+ * limitations under the License.

+-->

+

+<project name="Apache Myfaces Extensions Validator">

+  <bannerLeft>

+    <name>Apache MyFaces ExtVal</name>

+    <src>images/extval_logo.png</src>

+    <href>http://myfaces.apache.org/extensions/validator/index.html</href>

+  </bannerLeft>

+

+  <bannerRight>

+    <name>Apache MyFaces</name>

+    <src>img/banners/MyFaces_logo.jpg</src>

+    <href>http://myfaces.apache.org/index.html</href>

+  </bannerRight> 

+

+  <publishDate format="dd MMM yyyy"/>

+

+  <skin>

+    <groupId>org.apache.myfaces.maven</groupId>

+    <artifactId>myfaces-site-skin</artifactId>

+    <version>1-SNAPSHOT</version>

+  </skin>

+

+  <body>

+    <links>

+      <item name="Apache" href="http://www.apache.org"/>

+      <item name="MyFaces" href="http://myfaces.apache.org/index.html"/>

+      <item name="Download Myfaces ExtVal"       href="download.html"/>

+    </links>

+

+    <menu name="Apache MyFaces" inherit="top">

+      <item name="Overview"       href="http://myfaces.apache.org/index.html"/>

+      <item name="Download"       href="http://myfaces.apache.org/download.html"/>

+    </menu>

+

+    <menu name="Contents" inherit="top">

+        <item name="Main Site"         href="http://myfaces.apache.org/extensions/validator/index.html"/>

+        <item name="ExtVal for JSF 1.1"       href="http://myfaces.apache.org/extensions/validator11/index.html" collapse="true">

+            <item name="dummy"        href="dummy"/>

+        </item>

+        <item name="ExtVal for JSF 1.2"       href="http://myfaces.apache.org/extensions/validator12/index.html" collapse="true">

+            <item name="dummy"        href="dummy"/>

+        </item>

+    </menu>

+

+    <menu name="Documentation">

+      <item name="Wiki"         href="http://wiki.apache.org/myfaces/Extensions/Validator/"/>

+    </menu>

+

+    <menu ref="reports"/>

+

+    <menu name="Foundation" inherit="top">

+      <item name="ASF"            href="http://www.apache.org/" />

+      <item name="Sponsorship"    href="http://www.apache.org/foundation/sponsorship.html" />

+      <item name="Thanks"         href="http://www.apache.org/foundation/thanks.html" />

+    </menu>

+  </body>

+</project>

diff --git a/2_0_3_prepare/validation-modules/bean-validation/pom.xml b/2_0_3_prepare/validation-modules/bean-validation/pom.xml
new file mode 100644
index 0000000..5a51c11
--- /dev/null
+++ b/2_0_3_prepare/validation-modules/bean-validation/pom.xml
@@ -0,0 +1,152 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+    Licensed to the Apache Software Foundation (ASF) under one

+    or more contributor license agreements.  See the NOTICE file

+    distributed with this work for additional information

+    regarding copyright ownership.  The ASF licenses this file

+    to you under the Apache License, Version 2.0 (the

+    "License"); you may not use this file except in compliance

+    with the License.  You may obtain a copy of the License at

+

+    http://www.apache.org/licenses/LICENSE-2.0

+

+    Unless required by applicable law or agreed to in writing,

+    software distributed under the License is distributed on an

+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+    KIND, either express or implied.  See the License for the

+    specific language governing permissions and limitations

+    under the License.

+-->

+<project xmlns="http://maven.apache.org/POM/4.0.0"

+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">

+    <modelVersion>4.0.0</modelVersion>

+    <packaging>jar</packaging>

+

+    <groupId>org.apache.myfaces.extensions.validator.validation-modules</groupId>

+    <artifactId>myfaces-extval-bean-validation</artifactId>

+

+    <name>MyFaces Extensions-Validator Bean-Validation-Integration-Module (JSR 303)</name>

+    <version>2.0.3-SNAPSHOT</version>

+

+    <parent>

+        <groupId>org.apache.myfaces.extensions.validator.validation-modules</groupId>

+        <artifactId>validation-modules-project</artifactId>

+        <version>2.0.3-SNAPSHOT</version>

+    </parent>

+

+    <repositories>

+        <repository>

+            <id>jboss</id>

+            <url>http://repository.jboss.com/maven2</url>

+            <releases>

+                <enabled>true</enabled>

+            </releases>

+            <snapshots>

+                <enabled>false</enabled>

+            </snapshots>

+        </repository>

+        <repository>

+            <id>jboss-snapshot</id>

+            <url>http://snapshots.jboss.org/maven2</url>

+            <releases>

+                <enabled>true</enabled>

+            </releases>

+            <snapshots>

+                <enabled>true</enabled>

+            </snapshots>

+        </repository>

+    </repositories>

+

+    <dependencies>

+        <dependency>

+            <groupId>org.apache.myfaces.extensions.validator</groupId>

+            <artifactId>myfaces-extval-core</artifactId>

+            <version>2.0.3-SNAPSHOT</version>

+            <scope>compile</scope>

+        </dependency>

+

+        <dependency>

+            <groupId>javax.validation</groupId>

+            <artifactId>validation-api</artifactId>

+            <version>1.0.0.GA</version>

+            <scope>compile</scope>

+        </dependency>

+

+        <dependency>

+            <groupId>javax.faces</groupId>

+            <artifactId>jsf-api</artifactId>

+            <version>2.0</version>

+            <scope>provided</scope>

+        </dependency>

+

+        <dependency>

+            <groupId>javax.el</groupId>

+            <artifactId>el-api</artifactId>

+            <version>1.0</version>

+            <scope>provided</scope>

+        </dependency>

+

+        <dependency>

+            <groupId>commons-logging</groupId>

+            <artifactId>commons-logging</artifactId>

+            <version>1.1.1</version>

+            <scope>compile</scope>

+        </dependency>

+

+    </dependencies>

+

+    <build>

+        <resources>

+            <resource>

+                <directory>src/main/config</directory>

+                <includes>

+                    <include>**/*xml</include>

+                </includes>

+                <targetPath>/META-INF</targetPath>

+            </resource>

+            <resource>

+                <directory>src/main/resources</directory>

+                <includes>

+                    <include>LICENSE.txt</include>

+                    <include>NOTICE.txt</include>

+                </includes>

+                <targetPath>/META-INF</targetPath>

+            </resource>

+            <resource>

+                <directory>src/main/java</directory>

+                <includes>

+                    <include>**/*properties</include>

+                </includes>

+            </resource>

+        </resources>

+        <plugins>

+            <plugin>

+                <inherited>true</inherited>

+                <groupId>org.apache.maven.plugins</groupId>

+                <artifactId>maven-source-plugin</artifactId>

+

+                <executions>

+                    <execution>

+                        <id>attach-sources</id>

+                        <goals>

+                            <goal>jar</goal>

+                        </goals>

+                    </execution>

+                </executions>

+            </plugin>

+            <plugin>

+                <artifactId>maven-surefire-plugin</artifactId>

+                <version>2.4.2</version>

+                <configuration>

+                    <excludes>

+                        <exclude>**/Abstract*.java</exclude>

+                        <exclude>**/TestUtils.java</exclude>

+                        <exclude>**/*Bean.java</exclude>

+                    </excludes>

+                </configuration>

+            </plugin>            

+        </plugins>

+    </build>

+

+</project>

diff --git a/2_0_3_prepare/validation-modules/bean-validation/src/main/config/faces-config.xml b/2_0_3_prepare/validation-modules/bean-validation/src/main/config/faces-config.xml
new file mode 100644
index 0000000..1967f44
--- /dev/null
+++ b/2_0_3_prepare/validation-modules/bean-validation/src/main/config/faces-config.xml
@@ -0,0 +1,30 @@
+<!--

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+-->

+<faces-config xmlns="http://java.sun.com/xml/ns/javaee"

+              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

+              xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_1_2.xsd"

+              version="2.0">

+    <factory>

+        <application-factory>org.apache.myfaces.extensions.validator.beanval.factory.ExtValApplicationFactory</application-factory>

+    </factory>

+    <lifecycle>

+        <phase-listener>org.apache.myfaces.extensions.validator.beanval.startup.JSF2AwareBeanValidationStartupListener</phase-listener>

+        <phase-listener>org.apache.myfaces.extensions.validator.beanval.startup.BeanValidationStartupListener</phase-listener>

+    </lifecycle>

+</faces-config>
\ No newline at end of file
diff --git a/2_0_3_prepare/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/BeanAwareConstraintValidatorFactory.java b/2_0_3_prepare/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/BeanAwareConstraintValidatorFactory.java
new file mode 100644
index 0000000..27a7404
--- /dev/null
+++ b/2_0_3_prepare/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/BeanAwareConstraintValidatorFactory.java
@@ -0,0 +1,72 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.beanval;

+

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+import org.apache.myfaces.extensions.validator.internal.ToDo;

+import org.apache.myfaces.extensions.validator.internal.Priority;

+import org.apache.myfaces.extensions.validator.util.ExtValUtils;

+

+import javax.validation.ConstraintValidatorFactory;

+import javax.validation.ConstraintValidator;

+import java.beans.Introspector;

+

+/**

+ * @author Gerhard Petracek

+ * @since x.x.3

+ */

+@UsageInformation(UsageCategory.INTERNAL)

+class BeanAwareConstraintValidatorFactory implements ConstraintValidatorFactory

+{

+    private ConstraintValidatorFactory constraintValidatorFactory;

+

+    public BeanAwareConstraintValidatorFactory(ConstraintValidatorFactory constraintValidatorFactory)

+    {

+        setConstraintValidatorFactory(constraintValidatorFactory);

+    }

+

+    public void setConstraintValidatorFactory(ConstraintValidatorFactory constraintValidatorFactory)

+    {

+        if(constraintValidatorFactory == null)

+        {

+            throw new IllegalStateException("null is not allowed here");

+        }

+        this.constraintValidatorFactory = constraintValidatorFactory;

+    }

+

+    @SuppressWarnings({"unchecked"})

+    @ToDo(value = Priority.MEDIUM, description = "allow the registration of a custom prefix")

+    public <T extends ConstraintValidator<?, ?>> T getInstance(Class<T> targetClass)

+    {

+        String validatorClassName = targetClass.getSimpleName();

+        Object result = ExtValUtils.getELHelper().getBean(createBeanName(validatorClassName));

+

+        if(result != null && targetClass.isAssignableFrom(result.getClass()))

+        {

+            return (T)result;

+        }

+        return this.constraintValidatorFactory.getInstance(targetClass);

+    }

+

+    private String createBeanName(String validatorClassName)

+    {

+        return Introspector.decapitalize(validatorClassName);

+    }

+}
\ No newline at end of file
diff --git a/2_0_3_prepare/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/BeanAwareValidatorFactory.java b/2_0_3_prepare/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/BeanAwareValidatorFactory.java
new file mode 100644
index 0000000..47d76c6
--- /dev/null
+++ b/2_0_3_prepare/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/BeanAwareValidatorFactory.java
@@ -0,0 +1,83 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.beanval;

+

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+

+import javax.validation.ValidatorFactory;

+import javax.validation.Validator;

+import javax.validation.ValidatorContext;

+import javax.validation.MessageInterpolator;

+import javax.validation.TraversableResolver;

+import javax.validation.ConstraintValidatorFactory;

+

+/**

+ * @author Gerhard Petracek

+ * @since x.x.3

+ */

+@UsageInformation(UsageCategory.INTERNAL)

+public class BeanAwareValidatorFactory implements ValidatorFactory

+{

+    private ValidatorFactory validatorFactory;

+

+    public BeanAwareValidatorFactory(ValidatorFactory validatorFactory)

+    {

+        setValidatorFactory(validatorFactory);

+    }

+

+    public void setValidatorFactory(ValidatorFactory validatorFactory)

+    {

+        if(validatorFactory == null)

+        {

+            throw new IllegalStateException("null is not allowed here");

+        }

+        this.validatorFactory = validatorFactory;

+    }

+

+    public Validator getValidator()

+    {

+        return validatorFactory.getValidator();

+    }

+

+    public ValidatorContext usingContext()

+    {

+        return validatorFactory.usingContext();

+    }

+

+    public MessageInterpolator getMessageInterpolator()

+    {

+        return validatorFactory.getMessageInterpolator();

+    }

+

+    public TraversableResolver getTraversableResolver()

+    {

+        return validatorFactory.getTraversableResolver();

+    }

+

+    public ConstraintValidatorFactory getConstraintValidatorFactory()

+    {

+        return new BeanAwareConstraintValidatorFactory(validatorFactory.getConstraintValidatorFactory());

+    }

+

+    public <T> T unwrap(Class<T> tClass)

+    {

+        return validatorFactory.unwrap(tClass);

+    }

+}

diff --git a/2_0_3_prepare/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/BeanValidationModuleKey.java b/2_0_3_prepare/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/BeanValidationModuleKey.java
new file mode 100644
index 0000000..e453627
--- /dev/null
+++ b/2_0_3_prepare/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/BeanValidationModuleKey.java
@@ -0,0 +1,33 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.beanval;

+

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+import org.apache.myfaces.extensions.validator.core.ValidationModuleKey;

+

+/**

+ * @author Gerhard Petracek

+ * @since x.x.3

+ */

+@ValidationModuleKey

+@UsageInformation(UsageCategory.API)

+public interface BeanValidationModuleKey

+{

+}

diff --git a/2_0_3_prepare/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/BeanValidationModuleValidationInterceptor.java b/2_0_3_prepare/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/BeanValidationModuleValidationInterceptor.java
new file mode 100644
index 0000000..a98c910
--- /dev/null
+++ b/2_0_3_prepare/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/BeanValidationModuleValidationInterceptor.java
@@ -0,0 +1,146 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.beanval;

+

+import org.apache.myfaces.extensions.validator.core.interceptor.AbstractValidationInterceptor;

+import org.apache.myfaces.extensions.validator.core.metadata.extractor.MetaDataExtractor;

+import org.apache.myfaces.extensions.validator.core.property.PropertyDetails;

+import org.apache.myfaces.extensions.validator.core.property.PropertyInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.beanval.util.BeanValidationUtils;

+

+import javax.faces.component.UIComponent;

+import javax.faces.context.FacesContext;

+import javax.validation.ConstraintViolation;

+import java.util.Set;

+import java.util.Map;

+

+/**

+ * @author Gerhard Petracek

+ * @since x.x.3

+ */

+@UsageInformation(UsageCategory.INTERNAL)

+public class BeanValidationModuleValidationInterceptor extends AbstractValidationInterceptor

+{

+    BeanValidationModuleValidationInterceptorInternals bviUtils =

+            new BeanValidationModuleValidationInterceptorInternals(this.logger);

+

+    @Override

+    protected boolean isRequiredInitializationSupported()

+    {

+        return true;

+    }

+

+    protected void initComponent(FacesContext facesContext, UIComponent uiComponent)

+    {

+        if (logger.isTraceEnabled())

+        {

+            logger.trace("start to init component " + uiComponent.getClass().getName());

+        }

+

+        PropertyDetails propertyDetails = bviUtils.extractPropertyDetails(

+                facesContext, uiComponent, getPropertiesForComponentMetaDataExtractor(uiComponent));

+

+        if (propertyDetails != null)

+        {

+            initComponentWithPropertyDetails(facesContext, uiComponent, propertyDetails);

+        }

+

+        if (logger.isTraceEnabled())

+        {

+            logger.trace("init component of " + uiComponent.getClass().getName() + " finished");

+        }

+    }

+

+    protected void initComponentWithPropertyDetails(FacesContext facesContext,

+                                                    UIComponent uiComponent,

+                                                    PropertyDetails propertyDetails)

+    {

+        this.bviUtils.initComponentWithPropertyDetails(facesContext, uiComponent, propertyDetails);

+    }

+

+    protected void processValidation(FacesContext facesContext, UIComponent uiComponent, Object convertedObject)

+    {

+        PropertyInformation propertyInformation = getPropertyInformation(facesContext, uiComponent);

+

+        boolean validateProperty = hasBeanValidationConstraints(propertyInformation);

+        try

+        {

+            if (validateProperty)

+            {

+                if (logger.isTraceEnabled())

+                {

+                    logger.trace("jsr303 start validation");

+                }

+

+                processFieldValidation(facesContext, uiComponent, convertedObject, propertyInformation);

+            }

+        }

+        finally

+        {

+            if (validateProperty)

+            {

+                if (logger.isTraceEnabled())

+                {

+                    logger.trace("jsr303 validation finished");

+                }

+            }

+        }

+    }

+

+    protected MetaDataExtractor getComponentMetaDataExtractor(Map<String, Object> properties)

+    {

+        return bviUtils.getComponentMetaDataExtractor(properties);

+    }

+

+    protected boolean hasBeanValidationConstraints(PropertyInformation propertyInformation)

+    {

+        return this.bviUtils.hasBeanValidationConstraints(propertyInformation);

+    }

+

+    protected void processFieldValidation(FacesContext facesContext,

+                                          UIComponent uiComponent,

+                                          Object convertedObject,

+                                          PropertyInformation propertyInformation)

+    {

+        /*not used yet supportMultipleViolationsPerField()*/

+        Set<ConstraintViolation> violations = this.bviUtils

+                .validate(facesContext, uiComponent, convertedObject, propertyInformation);

+

+        processConstraintViolations(facesContext, uiComponent, convertedObject, violations);

+    }

+

+    protected void processConstraintViolations(FacesContext facesContext,

+                                             UIComponent uiComponent,

+                                             Object convertedObject,

+                                             Set<ConstraintViolation> violations)

+    {

+        if(violations != null && !violations.isEmpty())

+        {

+            BeanValidationUtils.processConstraintViolations(facesContext, uiComponent, convertedObject, violations);

+        }

+    }

+

+    @Override

+    protected Class getModuleKey()

+    {

+        return BeanValidationModuleKey.class;

+    }

+}

diff --git a/2_0_3_prepare/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/BeanValidationModuleValidationInterceptorInternals.java b/2_0_3_prepare/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/BeanValidationModuleValidationInterceptorInternals.java
new file mode 100644
index 0000000..e0f8a7b
--- /dev/null
+++ b/2_0_3_prepare/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/BeanValidationModuleValidationInterceptorInternals.java
@@ -0,0 +1,253 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.beanval;

+

+import org.apache.commons.logging.Log;

+import org.apache.myfaces.extensions.validator.beanval.validation.strategy.BeanValidationVirtualValidationStrategy;

+import org.apache.myfaces.extensions.validator.core.metadata.MetaDataEntry;

+import org.apache.myfaces.extensions.validator.core.metadata.extractor.MetaDataExtractor;

+import org.apache.myfaces.extensions.validator.core.metadata.transformer.MetaDataTransformer;

+import org.apache.myfaces.extensions.validator.core.property.PropertyDetails;

+import org.apache.myfaces.extensions.validator.core.property.PropertyInformation;

+import org.apache.myfaces.extensions.validator.core.property.PropertyInformationKeys;

+import org.apache.myfaces.extensions.validator.internal.Priority;

+import org.apache.myfaces.extensions.validator.internal.ToDo;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.util.ExtValUtils;

+import org.apache.myfaces.extensions.validator.util.ProxyUtils;

+

+import javax.faces.component.UIComponent;

+import javax.faces.context.FacesContext;

+import javax.validation.ConstraintViolation;

+import javax.validation.ValidatorFactory;

+import javax.validation.groups.Default;

+import javax.validation.metadata.BeanDescriptor;

+import javax.validation.metadata.ConstraintDescriptor;

+import javax.validation.metadata.ElementDescriptor;

+import java.util.HashMap;

+import java.util.Map;

+import java.util.Set;

+

+/**

+ * @author Gerhard Petracek

+ * @since x.x.3

+ */

+@UsageInformation(UsageCategory.INTERNAL)

+class BeanValidationModuleValidationInterceptorInternals

+{

+    private Log logger;

+

+    BeanValidationModuleValidationInterceptorInternals(Log logger)

+    {

+        this.logger = logger;

+    }

+

+    PropertyDetails extractPropertyDetails(

+            FacesContext facesContext, UIComponent uiComponent, Map<String, Object> propertiesForExtraction)

+    {

+        PropertyDetails result = getComponentMetaDataExtractor(propertiesForExtraction)

+                .extract(facesContext, uiComponent)

+                .getInformation(PropertyInformationKeys.PROPERTY_DETAILS, PropertyDetails.class);

+

+        if (result.getBaseObject() == null && this.logger.isWarnEnabled())

+        {

+            this.logger.warn("no base object at " + result.getKey() +

+                    " component-id: " + uiComponent.getClientId(facesContext));

+        }

+

+        return result.getBaseObject() != null ? result : null;

+    }

+

+    /*

+     * also invokes meta-data extraction interceptors

+     * (see e.g. ExtValBeanValidationMetaDataExtractionInterceptor)

+     */

+    MetaDataExtractor getComponentMetaDataExtractor(Map<String, Object> properties)

+    {

+        return ExtValUtils.getComponentMetaDataExtractorWith(properties);

+    }

+

+    void initComponentWithPropertyDetails(

+            FacesContext facesContext, UIComponent uiComponent, PropertyDetails propertyDetails)

+    {

+        Class[] foundGroups = resolveGroups(facesContext, uiComponent);

+

+        if (foundGroups == null)

+        {

+            return;

+        }

+        else if (foundGroups.length == 0)

+        {

+            foundGroups = new Class[]{Default.class};

+        }

+

+        Class targetClass = propertyDetails.getBaseObject().getClass();

+

+        targetClass = ProxyUtils.getUnproxiedClass(targetClass);

+

+        ElementDescriptor elementDescriptor = getDescriptorFor(targetClass, propertyDetails.getProperty());

+

+        if (elementDescriptor == null)

+        {

+            return;

+        }

+

+        processElementDescriptor(facesContext, uiComponent, foundGroups, elementDescriptor);

+    }

+

+    void processElementDescriptor(FacesContext facesContext,

+                                  UIComponent uiComponent,

+                                  Class[] foundGroups,

+                                  ElementDescriptor elementDescriptor)

+    {

+        Map<String, Object> metaData;

+

+        for (ConstraintDescriptor<?> constraintDescriptor :

+                elementDescriptor.findConstraints().unorderedAndMatchingGroups(foundGroups).getConstraintDescriptors())

+        {

+            metaData = transformConstraintDescriptorToMetaData(

+                    constraintDescriptor, elementDescriptor.getElementClass());

+

+            if (metaData != null && !metaData.isEmpty())

+            {

+                ExtValUtils.configureComponentWithMetaData(facesContext, uiComponent, metaData);

+            }

+        }

+    }

+

+    @ToDo(value = Priority.MEDIUM, description = "ConstraintDescriptor#isReportAsSingleViolation")

+    private Map<String, Object> transformConstraintDescriptorToMetaData(

+            ConstraintDescriptor<?> constraintDescriptor, Class elementClass)

+    {

+        Map<String, Object> result = new HashMap<String, Object>();

+        MetaDataTransformer metaDataTransformer;

+

+        metaDataTransformer = ExtValUtils.getMetaDataTransformerForValidationStrategy(

+                new BeanValidationVirtualValidationStrategy(constraintDescriptor, elementClass));

+

+        if (metaDataTransformer != null)

+        {

+            result.putAll(transformMetaData(metaDataTransformer, constraintDescriptor));

+        }

+

+        if (!constraintDescriptor.isReportAsSingleViolation())

+        {

+            Set<ConstraintDescriptor<?>> composingConstraints = constraintDescriptor.getComposingConstraints();

+            if (composingConstraints != null && !composingConstraints.isEmpty())

+            {

+                result.putAll(transformComposingConstraints(composingConstraints, elementClass));

+            }

+        }

+

+        return result;

+    }

+

+    private Map<String, Object> transformComposingConstraints(

+            Set<ConstraintDescriptor<?>> composingConstraints, Class elementClass)

+    {

+        Map<String, Object> result = new HashMap<String, Object>();

+        for (ConstraintDescriptor constraintDescriptor : composingConstraints)

+        {

+            result.putAll(transformConstraintDescriptorToMetaData(constraintDescriptor, elementClass));

+        }

+

+        return result;

+    }

+

+    private Map<String, Object> transformMetaData(

+            MetaDataTransformer metaDataTransformer, ConstraintDescriptor<?> constraintDescriptor)

+    {

+        MetaDataEntry entry;

+        Map<String, Object> result;

+        if (this.logger.isDebugEnabled())

+        {

+            this.logger.debug(metaDataTransformer.getClass().getName() + " instantiated");

+        }

+

+        entry = new MetaDataEntry();

+        entry.setKey(constraintDescriptor.getAnnotation().annotationType().getName());

+        entry.setValue(constraintDescriptor);

+

+        result = metaDataTransformer.convertMetaData(entry);

+        return result;

+    }

+

+    boolean hasBeanValidationConstraints(PropertyInformation propertyInformation)

+    {

+        PropertyDetails propertyDetails = ExtValUtils.getPropertyDetails(propertyInformation);

+

+        Class targetClass = ProxyUtils.getUnproxiedClass(propertyDetails.getBaseObject().getClass());

+

+        return getDescriptorFor(targetClass, propertyDetails.getProperty()) != null;

+    }

+

+    @SuppressWarnings({"unchecked"})

+    Set<ConstraintViolation> validate(FacesContext facesContext,

+                                      UIComponent uiComponent,

+                                      Object convertedObject,

+                                      PropertyInformation propertyInformation)

+    {

+        Class baseBeanClass = getBaseClassType(propertyInformation);

+        String propertyName = getPropertyToValidate(propertyInformation);

+

+        Class[] groups = resolveGroups(facesContext, uiComponent);

+

+        if (groups == null)

+        {

+            return null;

+        }

+

+        ValidatorFactory validatorFactory = ExtValBeanValidationContext.getCurrentInstance().getValidatorFactory();

+        return validatorFactory

+                .usingContext()

+                .messageInterpolator(ExtValBeanValidationContext.getCurrentInstance().getMessageInterpolator())

+                .constraintValidatorFactory(validatorFactory.getConstraintValidatorFactory())

+                .traversableResolver(validatorFactory.getTraversableResolver())

+                .getValidator()

+                .validateValue(baseBeanClass, propertyName, convertedObject, groups);

+    }

+

+    Class getBaseClassType(PropertyInformation propertyInformation)

+    {

+        Class result = ExtValUtils.getPropertyDetails(propertyInformation).getBaseObject().getClass();

+

+        return ProxyUtils.getUnproxiedClass(result);

+    }

+

+    String getPropertyToValidate(PropertyInformation propertyInformation)

+    {

+        return ExtValUtils.getPropertyDetails(propertyInformation).getProperty();

+    }

+

+    Class[] resolveGroups(FacesContext facesContext, UIComponent uiComponent)

+    {

+        return ExtValBeanValidationContext.getCurrentInstance().getGroups(

+                facesContext.getViewRoot().getViewId(),

+                uiComponent.getClientId(facesContext));

+    }

+

+    ElementDescriptor getDescriptorFor(Class targetClass, String property)

+    {

+        BeanDescriptor beanDescriptor = ExtValBeanValidationContext.getCurrentInstance().getValidatorFactory()

+                .getValidator().getConstraintsForClass(targetClass);

+

+        return beanDescriptor.getConstraintsForProperty(property);

+    }

+}

diff --git a/2_0_3_prepare/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/ExtValBeanValidationContext.java b/2_0_3_prepare/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/ExtValBeanValidationContext.java
new file mode 100644
index 0000000..78f5bb2
--- /dev/null
+++ b/2_0_3_prepare/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/ExtValBeanValidationContext.java
@@ -0,0 +1,181 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.beanval;

+

+import org.apache.myfaces.extensions.validator.beanval.validation.message.interpolator.DefaultMessageInterpolator;

+import org.apache.myfaces.extensions.validator.beanval.validation.message.interpolator.ExtValMessageInterpolatorAdapter;

+import org.apache.myfaces.extensions.validator.beanval.validation.strategy.BeanValidationVirtualValidationStrategy;

+import org.apache.myfaces.extensions.validator.beanval.storage.ModelValidationEntry;

+import org.apache.myfaces.extensions.validator.beanval.storage.ModelValidationStorage;

+import org.apache.myfaces.extensions.validator.beanval.annotation.BeanValidation;

+import org.apache.myfaces.extensions.validator.beanval.annotation.ModelValidation;

+import org.apache.myfaces.extensions.validator.beanval.util.BeanValidationUtils;

+import org.apache.myfaces.extensions.validator.core.validation.message.resolver.MessageResolver;

+import org.apache.myfaces.extensions.validator.core.validation.strategy.ValidationStrategy;

+import org.apache.myfaces.extensions.validator.core.storage.GroupStorage;

+import org.apache.myfaces.extensions.validator.core.ExtValContext;

+import org.apache.myfaces.extensions.validator.util.ExtValUtils;

+import org.apache.myfaces.extensions.validator.internal.ToDo;

+import org.apache.myfaces.extensions.validator.internal.Priority;

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+import org.apache.commons.logging.Log;

+import org.apache.commons.logging.LogFactory;

+

+import javax.faces.context.FacesContext;

+import javax.validation.MessageInterpolator;

+import javax.validation.ValidatorFactory;

+import java.util.Map;

+import java.util.List;

+

+/**

+ * @author Gerhard Petracek

+ * @since x.x.3

+ */

+@UsageInformation(UsageCategory.API)

+public class ExtValBeanValidationContext implements GroupStorage, ModelValidationStorage

+{

+    protected final Log logger = LogFactory.getLog(getClass());

+

+    private static final String KEY = ExtValBeanValidationContext.class.getName() + ":KEY";

+

+    private MessageInterpolator defaultMessageInterpolator;

+

+    private MessageResolver messageResolver;

+

+    private GroupStorage groupStorage;

+

+    private ModelValidationStorage modelValidationStorage;

+

+    private ExtValBeanValidationContext()

+    {

+        initGroupStorage();

+        initModelValidationStorage();

+

+        initMessageResolver();

+        initMessageInterpolator();

+    }

+

+    @SuppressWarnings({"unchecked"})

+    public static ExtValBeanValidationContext getCurrentInstance()

+    {

+        FacesContext facesContext = FacesContext.getCurrentInstance();

+

+        Map requestMap = facesContext.getExternalContext().getRequestMap();

+

+        ExtValBeanValidationContext currentContext = (ExtValBeanValidationContext)requestMap.get(KEY);

+

+        if(currentContext == null)

+        {

+            currentContext = new ExtValBeanValidationContext();

+            requestMap.put(KEY, currentContext);

+        }

+

+        return currentContext;

+    }

+

+    public ValidatorFactory getValidatorFactory()

+    {

+        Object validatorFactory = ExtValContext.getContext().getGlobalProperty(ValidatorFactory.class.getName());

+

+        if(validatorFactory instanceof ValidatorFactory)

+        {

+            return (ValidatorFactory)validatorFactory;

+        }

+

+        if(this.logger.isWarnEnabled())

+        {

+            this.logger.warn("fallback to the default bv validator factory");

+        }

+        return BeanValidationUtils.getDefaultValidatorFactory();

+    }

+

+    public MessageInterpolator getMessageInterpolator()

+    {

+        if(this.messageResolver != null)

+        {

+            return new ExtValMessageInterpolatorAdapter(this.defaultMessageInterpolator, this.messageResolver);

+        }

+

+        return this.defaultMessageInterpolator;

+    }

+

+    public void addGroup(Class groupClass, String viewId, String clientId)

+    {

+        this.groupStorage.addGroup(groupClass, viewId, clientId);

+    }

+

+    public void restrictGroup(Class groupClass, String viewId, String clientId)

+    {

+        this.groupStorage.restrictGroup(groupClass, viewId, clientId);

+    }

+

+    public Class[] getGroups(String viewId, String clientId)

+    {

+        return this.groupStorage.getGroups(viewId, clientId);

+    }

+

+    public void addModelValidationEntry(ModelValidationEntry modelValidationEntry)

+    {

+        this.modelValidationStorage.addModelValidationEntry(modelValidationEntry);

+    }

+

+    public List<ModelValidationEntry> getModelValidationEntriesToValidate()

+    {

+        return this.modelValidationStorage.getModelValidationEntriesToValidate();

+    }

+

+    private void initGroupStorage()

+    {

+        this.groupStorage = ExtValUtils

+                .getStorage(GroupStorage.class, BeanValidation.class.getName());

+    }

+

+    private void initModelValidationStorage()

+    {

+        this.modelValidationStorage = ExtValUtils.

+                getStorage(ModelValidationStorage.class, ModelValidation.class.getName());

+    }

+

+    @ToDo(Priority.HIGH)

+    private void initMessageInterpolator()

+    {

+        Object foundBean = ExtValUtils.getELHelper().getBean(MessageInterpolator.class.getName().replace(".", "_"));

+

+        if(foundBean instanceof MessageInterpolator)

+        {

+            this.defaultMessageInterpolator = (MessageInterpolator)foundBean;

+        }

+        else

+        {

+            this.defaultMessageInterpolator = new DefaultMessageInterpolator(

+                BeanValidationUtils.getDefaultValidatorFactory().getMessageInterpolator());

+        }

+    }

+

+    private void initMessageResolver()

+    {

+        this.messageResolver = ExtValUtils.getMessageResolverForValidationStrategy(getBeanValidationStrategy());

+    }

+

+    private ValidationStrategy getBeanValidationStrategy()

+    {

+        return new BeanValidationVirtualValidationStrategy(null, null);

+    }

+}

diff --git a/2_0_3_prepare/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/HtmlCoreComponentsComponentInitializer.java b/2_0_3_prepare/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/HtmlCoreComponentsComponentInitializer.java
new file mode 100644
index 0000000..7ec69d3
--- /dev/null
+++ b/2_0_3_prepare/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/HtmlCoreComponentsComponentInitializer.java
@@ -0,0 +1,61 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.myfaces.extensions.validator.beanval;
+
+import org.apache.myfaces.extensions.validator.core.initializer.component
+        .AbstractHtmlCoreComponentsComponentInitializer;
+import org.apache.myfaces.extensions.validator.core.metadata.CommonMetaDataKeys;
+import org.apache.myfaces.extensions.validator.core.InvocationOrder;
+import org.apache.myfaces.extensions.validator.internal.UsageInformation;
+import org.apache.myfaces.extensions.validator.internal.UsageCategory;
+import org.apache.myfaces.extensions.validator.util.ExtValUtils;
+
+import javax.faces.component.EditableValueHolder;
+import javax.faces.component.UIComponent;
+import javax.faces.context.FacesContext;
+import java.util.Map;
+
+/**
+ * @author Gerhard Petracek
+ * @since x.x.3
+ */
+@InvocationOrder(200)
+@UsageInformation(UsageCategory.INTERNAL)
+public class HtmlCoreComponentsComponentInitializer extends AbstractHtmlCoreComponentsComponentInitializer
+{
+    protected void configureRequiredAttribute(FacesContext facesContext,
+                                              UIComponent uiComponent,
+                                              Map<String, Object> metaData)
+    {
+        if(!ExtValUtils.interpretEmptyStringValuesAsNull())
+        {
+            return;
+        }
+
+        if(Boolean.TRUE.equals(metaData.get(CommonMetaDataKeys.REQUIRED)) ||
+                Boolean.TRUE.equals(isComponentRequired(uiComponent)))
+        {
+            ((EditableValueHolder)uiComponent).setRequired(true);
+        }
+        else
+        {
+            ((EditableValueHolder)uiComponent).setRequired(false);
+        }
+    }
+}
\ No newline at end of file
diff --git a/2_0_3_prepare/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/annotation/BeanValidation.java b/2_0_3_prepare/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/annotation/BeanValidation.java
new file mode 100644
index 0000000..c6933a9
--- /dev/null
+++ b/2_0_3_prepare/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/annotation/BeanValidation.java
@@ -0,0 +1,58 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.beanval.annotation;

+

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+

+import javax.validation.groups.Default;

+import java.lang.annotation.Target;

+import java.lang.annotation.Retention;

+import java.lang.annotation.Documented;

+import static java.lang.annotation.RetentionPolicy.RUNTIME;

+import static java.lang.annotation.ElementType.TYPE;

+import static java.lang.annotation.ElementType.METHOD;

+import static java.lang.annotation.ElementType.FIELD;

+

+/**

+ * @author Gerhard Petracek

+ * @since x.x.3

+ */

+

+@Target({METHOD, FIELD, TYPE})

+@Retention(RUNTIME)

+@UsageInformation(UsageCategory.API)

+@Documented

+public @interface BeanValidation

+{

+    String[] viewIds() default "*";

+

+    Class[] useGroups() default Default.class;

+

+    Class[] restrictGroups() default {};

+

+    String[] conditions() default "#{true}";

+

+    ModelValidation modelValidation() default @ModelValidation;

+    

+    @Retention(RUNTIME) static @interface List

+    {

+        BeanValidation[] value();

+    }

+}
\ No newline at end of file
diff --git a/2_0_3_prepare/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/annotation/ModelValidation.java b/2_0_3_prepare/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/annotation/ModelValidation.java
new file mode 100644
index 0000000..86c78dd
--- /dev/null
+++ b/2_0_3_prepare/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/annotation/ModelValidation.java
@@ -0,0 +1,55 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.beanval.annotation;

+

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+import org.apache.myfaces.extensions.validator.internal.ToDo;

+import org.apache.myfaces.extensions.validator.internal.Priority;

+

+import java.lang.annotation.Target;

+import java.lang.annotation.Retention;

+import java.lang.annotation.Documented;

+import static java.lang.annotation.RetentionPolicy.RUNTIME;

+import static java.lang.annotation.ElementType.TYPE;

+import static java.lang.annotation.ElementType.METHOD;

+import static java.lang.annotation.ElementType.FIELD;

+

+/**

+ * @author Gerhard Petracek

+ * @since x.x.3

+ */

+

+@Target({METHOD, FIELD, TYPE})

+@Retention(RUNTIME)

+@UsageInformation(UsageCategory.API)

+@Documented

+public @interface ModelValidation

+{

+    public static final String DEFAULT = "";

+

+    boolean isActive() default false;

+

+    boolean displayInline() default false;

+

+    @ToDo(value = Priority.MEDIUM, description = "support property chain syntax")

+    String[] validationTargets() default DEFAULT;

+

+    String message() default DEFAULT;

+}
\ No newline at end of file
diff --git a/2_0_3_prepare/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/annotation/extractor/DefaultGroupControllerScanningExtractor.java b/2_0_3_prepare/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/annotation/extractor/DefaultGroupControllerScanningExtractor.java
new file mode 100644
index 0000000..216f135
--- /dev/null
+++ b/2_0_3_prepare/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/annotation/extractor/DefaultGroupControllerScanningExtractor.java
@@ -0,0 +1,61 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.beanval.annotation.extractor;

+

+import org.apache.myfaces.extensions.validator.core.metadata.extractor.DefaultComponentMetaDataExtractor;

+import org.apache.myfaces.extensions.validator.core.property.PropertyInformation;

+import org.apache.myfaces.extensions.validator.core.property.DefaultPropertyInformation;

+import org.apache.myfaces.extensions.validator.core.property.PropertyDetails;

+import org.apache.myfaces.extensions.validator.core.property.PropertyInformationKeys;

+import org.apache.myfaces.extensions.validator.internal.ToDo;

+import org.apache.myfaces.extensions.validator.internal.Priority;

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+import org.apache.myfaces.extensions.validator.util.ProxyUtils;

+

+import javax.faces.context.FacesContext;

+

+/**

+ * @author Gerhard Petracek

+ * @since x.x.3

+ */

+@ToDo(value = Priority.MEDIUM, description = "use meta-data storage - but a special impl.")

+@UsageInformation(UsageCategory.INTERNAL)

+public class DefaultGroupControllerScanningExtractor extends DefaultComponentMetaDataExtractor

+{

+    @Override

+    public PropertyInformation extract(FacesContext facesContext, Object object)

+    {

+        if (!(object instanceof PropertyDetails))

+        {

+            throw new IllegalStateException(object.getClass() + " is not a " + PropertyDetails.class.getName());

+        }

+

+        PropertyDetails propertyDetails = (PropertyDetails)object;

+

+        Class entityClass = ProxyUtils.getUnproxiedClass(propertyDetails.getBaseObject().getClass());

+

+        PropertyInformation propertyInformation = new DefaultPropertyInformation();

+        propertyInformation.setInformation(PropertyInformationKeys.PROPERTY_DETAILS, propertyDetails);

+

+        extractAnnotations(propertyInformation, propertyDetails, entityClass);

+

+        return propertyInformation;

+    }

+}

diff --git a/2_0_3_prepare/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/factory/ExtValApplicationFactory.java b/2_0_3_prepare/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/factory/ExtValApplicationFactory.java
new file mode 100644
index 0000000..6f75dca
--- /dev/null
+++ b/2_0_3_prepare/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/factory/ExtValApplicationFactory.java
@@ -0,0 +1,74 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.beanval.factory;

+

+import org.apache.myfaces.extensions.validator.internal.ToDo;

+import org.apache.myfaces.extensions.validator.internal.Priority;

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+

+import javax.faces.application.ApplicationFactory;

+import javax.faces.application.Application;

+import javax.faces.application.ApplicationWrapper;

+

+/**

+ * @author Gerhard Petracek

+ * @since 2.x.3

+ */

+@UsageInformation(UsageCategory.INTERNAL)

+public class ExtValApplicationFactory extends ApplicationFactory

+{

+    private ApplicationFactory wrapped;

+

+    public ExtValApplicationFactory(ApplicationFactory wrapped)

+    {

+        this.wrapped = wrapped;

+    }

+

+    public ApplicationFactory getWrapped()

+    {

+        return wrapped.getWrapped();

+    }

+

+    @ToDo(value = Priority.HIGH, description = "context param. to deactivate this wrapper")

+    public Application getApplication()

+    {

+        return new ApplicationWrapper() {

+

+            public Application getWrapped()

+            {

+                return wrapped.getApplication();

+            }

+

+            @Override

+            public void addDefaultValidatorId(String s)

+            {

+                if(!"javax.faces.Bean".equals(s))

+                {

+                    super.addDefaultValidatorId(s);

+                }

+            }

+        };

+    }

+

+    public void setApplication(Application application)

+    {

+        wrapped.setApplication(application);

+    }

+}

diff --git a/2_0_3_prepare/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/interceptor/BeanValidationExceptionInterceptor.java b/2_0_3_prepare/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/interceptor/BeanValidationExceptionInterceptor.java
new file mode 100644
index 0000000..d3775c7
--- /dev/null
+++ b/2_0_3_prepare/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/interceptor/BeanValidationExceptionInterceptor.java
@@ -0,0 +1,66 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.beanval.interceptor;

+

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+import org.apache.myfaces.extensions.validator.core.interceptor.ValidationExceptionInterceptor;

+import org.apache.myfaces.extensions.validator.core.InvocationOrder;

+import org.apache.myfaces.extensions.validator.core.ExtValContext;

+import org.apache.myfaces.extensions.validator.core.validation.strategy.ValidationStrategy;

+import org.apache.myfaces.extensions.validator.core.metadata.MetaDataEntry;

+

+import javax.faces.component.UIComponent;

+import javax.faces.component.EditableValueHolder;

+import javax.faces.validator.ValidatorException;

+import javax.faces.context.FacesContext;

+

+/**

+ * extracts and adds the extval bv meta-data (e.g. validation groups) to the ExtValBeanValidationContext

+ *

+ * @author Gerhard Petracek

+ * @since x.x.3

+ */

+@InvocationOrder(200)

+@UsageInformation(UsageCategory.INTERNAL)

+public class BeanValidationExceptionInterceptor implements ValidationExceptionInterceptor

+{

+

+    public boolean afterThrowing(UIComponent uiComponent,

+                                 MetaDataEntry metaDataEntry,

+                                 Object convertedObject,

+                                 ValidatorException validatorException,

+                                 ValidationStrategy validatorExceptionSource)

+    {

+        if(uiComponent instanceof EditableValueHolder && isBlockingException(uiComponent, validatorException))

+        {

+            //bv integration doesn't throw exceptions to support multiple messages -> set component state

+            ((EditableValueHolder)uiComponent).setValid(false);

+        }

+        return true;

+    }

+

+    private boolean isBlockingException(UIComponent uiComponent, ValidatorException validatorException)

+    {

+        return ExtValContext.getContext().getViolationSeverityInterpreter().severityCausesValidatorException(

+                FacesContext.getCurrentInstance(),

+                uiComponent,

+                validatorException.getFacesMessage().getSeverity());

+    }

+}
\ No newline at end of file
diff --git a/2_0_3_prepare/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/interceptor/BeanValidationTagAwareValidationInterceptor.java b/2_0_3_prepare/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/interceptor/BeanValidationTagAwareValidationInterceptor.java
new file mode 100644
index 0000000..27c4638
--- /dev/null
+++ b/2_0_3_prepare/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/interceptor/BeanValidationTagAwareValidationInterceptor.java
@@ -0,0 +1,119 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.beanval.interceptor;

+

+import org.apache.myfaces.extensions.validator.core.interceptor.PropertyValidationInterceptor;

+import org.apache.myfaces.extensions.validator.core.property.PropertyInformation;

+import org.apache.myfaces.extensions.validator.util.ClassUtils;

+import org.apache.myfaces.extensions.validator.internal.ToDo;

+import org.apache.myfaces.extensions.validator.internal.Priority;

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+import org.apache.myfaces.extensions.validator.beanval.ExtValBeanValidationContext;

+import org.apache.commons.logging.Log;

+import org.apache.commons.logging.LogFactory;

+

+import javax.faces.context.FacesContext;

+import javax.faces.component.UIComponent;

+import javax.faces.component.EditableValueHolder;

+import javax.faces.validator.BeanValidator;

+import javax.faces.validator.Validator;

+import java.util.Arrays;

+import java.util.ArrayList;

+import java.util.List;

+import java.util.Map;

+

+/**

+ * @author Gerhard Petracek

+ * @since 2.x.3

+ */

+@UsageInformation(UsageCategory.INTERNAL)

+public class BeanValidationTagAwareValidationInterceptor implements PropertyValidationInterceptor

+{

+    protected final Log logger = LogFactory.getLog(getClass());

+

+    public boolean beforeValidation(FacesContext facesContext,

+                             UIComponent uiComponent,

+                             Object convertedObject,

+                             Map<String, Object> properties)

+    {

+        if(uiComponent instanceof EditableValueHolder && //"filter" cross-validation calls

+                properties.containsKey(PropertyInformation.class.getName()))

+        {

+            inspectValidators(facesContext.getViewRoot().getViewId(),

+                    (EditableValueHolder)uiComponent,

+                    uiComponent.getClientId(facesContext),

+                    ((EditableValueHolder)uiComponent).getValidators());

+        }

+

+        return true;

+    }

+

+    public void afterValidation(FacesContext facesContext,

+                             UIComponent uiComponent,

+                             Object convertedObject,

+                             Map<String, Object> properties)

+    {

+        //not used

+    }

+

+    @ToDo.List({@ToDo(value = Priority.HIGH, description = "optimize"),

+            @ToDo(value = Priority.HIGH, description = "use reflection instead of BeanValidator for jsf 1.x versions"),

+            @ToDo(value = Priority.HIGH, description = "test")

+    })

+    private void inspectValidators(String viewId,

+                                   EditableValueHolder editableValueHolder,

+                                   String clientId,

+                                   Validator[] validators)

+    {

+        List<String> validatorsOfTagList = new ArrayList<String>();

+

+        for (Validator validator : validators)

+        {

+            //don't check with instanceof

+            if (validator.getClass().getName().equals(BeanValidator.class.getName()))

+            {

+                validatorsOfTagList.addAll(

+                        Arrays.asList(((BeanValidator) validator).getValidationGroups().split(",")));

+

+                //prevent double-validation

+                editableValueHolder.removeValidator(validator);

+                editableValueHolder.addValidator(new BeanValidatorWrapper((BeanValidator)validator));

+            }

+        }

+

+        Class currentClass;

+        for(String groupClassName : validatorsOfTagList)

+        {

+            currentClass = ClassUtils.tryToLoadClassForName(groupClassName);

+

+            if(currentClass != null && currentClass.isInterface())

+            {

+                ExtValBeanValidationContext.getCurrentInstance().addGroup(currentClass, viewId, clientId);

+            }

+            else

+            {

+                if(this.logger.isErrorEnabled())

+                {

+                    this.logger.error(groupClassName + " is no valid group - only existing interfaces are allowed");

+                }

+            }

+        }

+    }

+}
\ No newline at end of file
diff --git a/2_0_3_prepare/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/interceptor/BeanValidatorWrapper.java b/2_0_3_prepare/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/interceptor/BeanValidatorWrapper.java
new file mode 100644
index 0000000..4fec297
--- /dev/null
+++ b/2_0_3_prepare/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/interceptor/BeanValidatorWrapper.java
@@ -0,0 +1,113 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.beanval.interceptor;

+

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+

+import javax.faces.validator.BeanValidator;

+import javax.faces.context.FacesContext;

+import javax.faces.component.UIComponent;

+

+/**

+ * replacement for BeanValidator which gets added due to f:validateBean

+ *

+ * @author Gerhard Petracek

+ * @since 2.x.3

+ */

+@UsageInformation(UsageCategory.INTERNAL)

+class BeanValidatorWrapper extends BeanValidator

+{

+    private BeanValidator wrapped;

+

+    BeanValidatorWrapper(BeanValidator wrapped)

+    {

+        this.wrapped = wrapped;

+    }

+

+    public BeanValidator getWrappedBeanValidator()

+    {

+        return this.wrapped;

+    }

+

+    public void setWrapped(BeanValidator wrapped)

+    {

+        this.wrapped = wrapped;

+    }

+

+    public void setValidationGroups(String s)

+    {

+        wrapped.setValidationGroups(s);

+    }

+

+    public String getValidationGroups()

+    {

+        return wrapped.getValidationGroups();

+    }

+

+    public void validate(FacesContext facesContext, UIComponent uiComponent, Object o)

+    {

+        //don't validate - the extval bean-validation adapter will do that

+    }

+

+    /*

+    public Object saveState(FacesContext facesContext)

+    {

+        Object result[] = new Object[1];

+        result[0] = wrapped.getValidationGroups();

+        return result;

+    }

+

+    public void restoreState(FacesContext facesContext, Object state)

+    {

+        this.wrapped = new BeanValidator();

+

+        if (state != null)

+        {

+            Object values[] = (Object[]) state;

+            this.wrapped.setValidationGroups((String) values[0]);

+        }

+    }

+    */

+

+    public void markInitialState()

+    {

+        wrapped.markInitialState();

+    }

+

+    public boolean initialStateMarked()

+    {

+        return wrapped.initialStateMarked();

+    }

+

+    public void clearInitialState()

+    {

+        wrapped.clearInitialState();

+    }

+

+    public boolean isTransient()

+    {

+        return wrapped.isTransient();

+    }

+

+    public void setTransient(boolean b)

+    {

+        wrapped.setTransient(b);

+    }

+}

diff --git a/2_0_3_prepare/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/interceptor/ExtValBeanValidationMetaDataExtractionInterceptor.java b/2_0_3_prepare/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/interceptor/ExtValBeanValidationMetaDataExtractionInterceptor.java
new file mode 100644
index 0000000..4fcf70f
--- /dev/null
+++ b/2_0_3_prepare/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/interceptor/ExtValBeanValidationMetaDataExtractionInterceptor.java
@@ -0,0 +1,86 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.beanval.interceptor;

+

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+import org.apache.myfaces.extensions.validator.core.interceptor.MetaDataExtractionInterceptor;

+import org.apache.myfaces.extensions.validator.core.property.PropertyInformation;

+import org.apache.myfaces.extensions.validator.core.property.PropertyDetails;

+import org.apache.myfaces.extensions.validator.core.property.PropertyInformationKeys;

+import org.apache.myfaces.extensions.validator.core.ValidationModuleAware;

+import org.apache.myfaces.extensions.validator.core.InvocationOrder;

+import org.apache.myfaces.extensions.validator.beanval.BeanValidationModuleKey;

+import org.apache.myfaces.extensions.validator.beanval.util.BeanValidationUtils;

+import org.apache.myfaces.extensions.validator.util.ExtValUtils;

+import org.apache.myfaces.extensions.validator.util.JsfUtils;

+

+import javax.faces.component.UIComponent;

+import java.util.Map;

+

+/**

+ * extracts and adds the extval bv meta-data (e.g. validation groups) to the ExtValBeanValidationContext

+ *

+ * @author Gerhard Petracek

+ * @since x.x.3

+ */

+@InvocationOrder(200)

+@UsageInformation(UsageCategory.INTERNAL)

+public class ExtValBeanValidationMetaDataExtractionInterceptor

+        implements MetaDataExtractionInterceptor, ValidationModuleAware

+{

+    public void afterExtracting(PropertyInformation propertyInformation)

+    {

+        if(propertyInformation.containsInformation(PropertyInformationKeys.CUSTOM_PROPERTIES))

+        {

+            Map properties = propertyInformation.getInformation(PropertyInformationKeys.CUSTOM_PROPERTIES, Map.class);

+

+            if(properties != null && properties.containsKey(UIComponent.class.getName()))

+            {

+                UIComponent uiComponent = (UIComponent)properties.get(UIComponent.class.getName());

+                PropertyDetails propertyDetails = ExtValUtils.getPropertyDetails(propertyInformation);

+

+                processExtValBeanValidationMetaData(uiComponent, propertyDetails);

+            }

+        }

+    }

+

+    /**

+     * adds the extval bv meta-data to the ExtValBeanValidationContext

+     *

+     * @param uiComponent current component

+     * @param propertyDetails property details of the value-binding

+     */

+    private void processExtValBeanValidationMetaData(UIComponent uiComponent, PropertyDetails propertyDetails)

+    {

+        if(JsfUtils.isRenderResponsePhase())

+        {

+            BeanValidationUtils.addMetaDataToContext(uiComponent, propertyDetails, false);

+        }

+        else

+        {

+            BeanValidationUtils.addMetaDataToContext(uiComponent, propertyDetails, true);

+        }

+    }

+

+    public String[] getModuleKeys()

+    {

+        return new String[] {BeanValidationModuleKey.class.getName()};

+    }

+}

diff --git a/2_0_3_prepare/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/interceptor/ResetBeanValidationRendererInterceptor.java b/2_0_3_prepare/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/interceptor/ResetBeanValidationRendererInterceptor.java
new file mode 100644
index 0000000..c21d133
--- /dev/null
+++ b/2_0_3_prepare/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/interceptor/ResetBeanValidationRendererInterceptor.java
@@ -0,0 +1,64 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.beanval.interceptor;

+

+import org.apache.myfaces.extensions.validator.core.interceptor.AbstractRendererInterceptor;

+import org.apache.myfaces.extensions.validator.core.renderkit.exception.SkipBeforeInterceptorsException;

+import org.apache.myfaces.extensions.validator.core.renderkit.exception.SkipRendererDelegationException;

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+

+import javax.faces.context.FacesContext;

+import javax.faces.component.UIComponent;

+import javax.faces.component.EditableValueHolder;

+import javax.faces.render.Renderer;

+import javax.faces.validator.Validator;

+import java.io.IOException;

+

+/**

+ * separated for easier sync

+ *

+ * @author Gerhard Petracek

+ * @since 2.x.3

+ */

+@UsageInformation(UsageCategory.INTERNAL)

+public class ResetBeanValidationRendererInterceptor extends AbstractRendererInterceptor

+{

+    @Override

+    public void beforeEncodeBegin(FacesContext facesContext, UIComponent uiComponent, Renderer wrapped)

+            throws IOException, SkipBeforeInterceptorsException, SkipRendererDelegationException

+    {

+        if(uiComponent instanceof EditableValueHolder)

+        {

+            switchBackValidators((EditableValueHolder)uiComponent);

+        }

+    }

+

+    private void switchBackValidators(EditableValueHolder editableValueHolder)

+    {

+        for(Validator validator : editableValueHolder.getValidators())

+        {

+            if(validator instanceof BeanValidatorWrapper)

+            {

+                editableValueHolder.addValidator(((BeanValidatorWrapper)validator).getWrappedBeanValidator());

+                editableValueHolder.removeValidator(validator);

+            }

+        }

+    }

+}

diff --git a/2_0_3_prepare/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/metadata/transformer/AbstractBeanValidationMetaDataTransformer.java b/2_0_3_prepare/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/metadata/transformer/AbstractBeanValidationMetaDataTransformer.java
new file mode 100644
index 0000000..1bfda0d
--- /dev/null
+++ b/2_0_3_prepare/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/metadata/transformer/AbstractBeanValidationMetaDataTransformer.java
@@ -0,0 +1,90 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.beanval.metadata.transformer;

+

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+import org.apache.myfaces.extensions.validator.core.metadata.transformer.MetaDataTransformer;

+import org.apache.myfaces.extensions.validator.core.metadata.MetaDataEntry;

+import org.apache.myfaces.extensions.validator.beanval.payload.ViolationSeverity;

+import org.apache.myfaces.extensions.validator.beanval.payload.DisableClientSideValidation;

+import org.apache.myfaces.extensions.validator.util.ExtValUtils;

+

+import javax.validation.metadata.ConstraintDescriptor;

+import javax.validation.Payload;

+import javax.faces.application.FacesMessage;

+import java.util.Map;

+import java.util.Collections;

+import java.lang.annotation.Annotation;

+

+/**

+ * @author Gerhard Petracek

+ * @since x.x.3

+ */

+@UsageInformation({UsageCategory.REUSE})

+public abstract class AbstractBeanValidationMetaDataTransformer<T extends Annotation> implements MetaDataTransformer

+{

+    @SuppressWarnings({"unchecked"})

+    public Map<String, Object> convertMetaData(MetaDataEntry metaDataEntry)

+    {

+        ConstraintDescriptor<? extends T> constraintDescriptor = metaDataEntry.getValue(ConstraintDescriptor.class);

+

+        if(isClientSideValidationEnabled(constraintDescriptor) && isBlockingConstraint(constraintDescriptor))

+        {

+            return transformMetaData((ConstraintDescriptor<T>)constraintDescriptor);

+        }

+        return Collections.emptyMap();

+    }

+

+    protected boolean isClientSideValidationEnabled(ConstraintDescriptor<? extends T> constraintDescriptor)

+    {

+        for(Class<? extends Payload> payload : constraintDescriptor.getPayload())

+        {

+            if(ExtValUtils.getValidationParameterClassFor(DisableClientSideValidation.class).isAssignableFrom(payload))

+            {

+                return false;

+            }

+        }

+        return true;

+    }

+

+    protected boolean isBlockingConstraint(ConstraintDescriptor<?> constraintDescriptor)

+    {

+        FacesMessage testMessage = new FacesMessage();

+        testMessage.setSeverity(ViolationSeverity.Error.VALUE);

+

+        for (Class<? extends Payload> payload : constraintDescriptor.getPayload())

+        {

+            if (ExtValUtils.getValidationParameterClassFor(ViolationSeverity.Warn.class).isAssignableFrom(payload))

+            {

+                testMessage.setSeverity(ViolationSeverity.Warn.VALUE);

+            }

+            else if(ExtValUtils.getValidationParameterClassFor(ViolationSeverity.Info.class).isAssignableFrom(payload))

+            {

+                testMessage.setSeverity(ViolationSeverity.Info.VALUE);

+            }

+            else if(ExtValUtils.getValidationParameterClassFor(ViolationSeverity.Fatal.class).isAssignableFrom(payload))

+            {

+                testMessage.setSeverity(ViolationSeverity.Fatal.VALUE);

+            }

+        }

+        return ExtValUtils.severityBlocksSubmitForComponentId(null, testMessage);

+    }

+    protected abstract Map<String, Object> transformMetaData(ConstraintDescriptor<T> constraintDescriptor);

+}

diff --git a/2_0_3_prepare/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/metadata/transformer/NotNullMetaDataTransformer.java b/2_0_3_prepare/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/metadata/transformer/NotNullMetaDataTransformer.java
new file mode 100644
index 0000000..2008d5a
--- /dev/null
+++ b/2_0_3_prepare/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/metadata/transformer/NotNullMetaDataTransformer.java
@@ -0,0 +1,48 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.beanval.metadata.transformer;

+

+import org.apache.myfaces.extensions.validator.core.metadata.CommonMetaDataKeys;

+import org.apache.myfaces.extensions.validator.util.ExtValUtils;

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+

+import javax.validation.constraints.NotNull;

+import javax.validation.metadata.ConstraintDescriptor;

+import java.util.Map;

+import java.util.HashMap;

+

+/**

+ * @author Gerhard Petracek

+ * @since x.x.3

+ */

+@UsageInformation(UsageCategory.INTERNAL)

+public class NotNullMetaDataTransformer extends AbstractBeanValidationMetaDataTransformer<NotNull>

+{

+    protected Map<String, Object> transformMetaData(ConstraintDescriptor<NotNull> constraintDescriptor)

+    {

+        Map<String, Object> results = new HashMap<String, Object>();

+

+        if(ExtValUtils.interpretEmptyStringValuesAsNull())

+        {

+            results.put(CommonMetaDataKeys.WEAK_REQUIRED, true);

+        }

+        return results;

+    }

+}

diff --git a/2_0_3_prepare/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/metadata/transformer/StringSizeMetaDataTransformer.java b/2_0_3_prepare/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/metadata/transformer/StringSizeMetaDataTransformer.java
new file mode 100644
index 0000000..4a9ff58
--- /dev/null
+++ b/2_0_3_prepare/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/metadata/transformer/StringSizeMetaDataTransformer.java
@@ -0,0 +1,65 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.beanval.metadata.transformer;

+

+import org.apache.myfaces.extensions.validator.core.metadata.CommonMetaDataKeys;

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+

+import javax.validation.constraints.Size;

+import javax.validation.metadata.ConstraintDescriptor;

+import java.util.Map;

+import java.util.HashMap;

+

+/**

+ * @author Gerhard Petracek

+ * @since x.x.3

+ */

+@UsageInformation(UsageCategory.INTERNAL)

+public class StringSizeMetaDataTransformer extends AbstractBeanValidationMetaDataTransformer<Size>

+{

+    protected Map<String, Object> transformMetaData(ConstraintDescriptor<Size> constraintDescriptor)

+    {

+        Map<String, Object> results = new HashMap<String, Object>();

+        Size annotation = constraintDescriptor.getAnnotation();

+

+        int minimum = annotation.min();

+

+        if(minimum != 0)

+        {

+            results.put(CommonMetaDataKeys.MIN_LENGTH, minimum);

+        }

+        else

+        {

+            results.put(CommonMetaDataKeys.MIN_LENGTH_DEFAULT, minimum);

+        }

+

+        int maximum = annotation.max();

+        if(maximum != Integer.MAX_VALUE)

+        {

+            results.put(CommonMetaDataKeys.MAX_LENGTH, maximum);

+        }

+        else

+        {

+            results.put(CommonMetaDataKeys.MAX_LENGTH_DEFAULT, maximum);

+        }

+

+        return results;

+    }

+}

diff --git a/2_0_3_prepare/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/metadata/transformer/mapper/AbstractBeanValidationVirtualValidationStrategyToMetaDataTransformerNameMapper.java b/2_0_3_prepare/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/metadata/transformer/mapper/AbstractBeanValidationVirtualValidationStrategyToMetaDataTransformerNameMapper.java
new file mode 100644
index 0000000..40e031c
--- /dev/null
+++ b/2_0_3_prepare/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/metadata/transformer/mapper/AbstractBeanValidationVirtualValidationStrategyToMetaDataTransformerNameMapper.java
@@ -0,0 +1,55 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.beanval.metadata.transformer.mapper;

+

+import org.apache.myfaces.extensions.validator.core.metadata.transformer.mapper

+        .AbstractValidationStrategyToMetaDataTransformerNameMapper;

+import org.apache.myfaces.extensions.validator.core.validation.strategy.ValidationStrategy;

+import org.apache.myfaces.extensions.validator.beanval.validation.strategy.BeanValidationVirtualValidationStrategy;

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+

+/**

+ * @author Gerhard Petracek

+ * @since x.x.3

+ */

+@UsageInformation({UsageCategory.REUSE})

+public abstract class AbstractBeanValidationVirtualValidationStrategyToMetaDataTransformerNameMapper

+    extends AbstractValidationStrategyToMetaDataTransformerNameMapper

+{

+    public final String createName(ValidationStrategy source)

+    {

+        if(isBeanValidationStrategy(source))

+        {

+            BeanValidationVirtualValidationStrategy beanValidationAdapter =

+                    (BeanValidationVirtualValidationStrategy)source;

+

+            return createBeanValidationTransformerName(beanValidationAdapter);

+        }

+        return null;

+    }

+

+    private boolean isBeanValidationStrategy(ValidationStrategy source)

+    {

+        return source instanceof BeanValidationVirtualValidationStrategy;

+    }

+

+    protected  abstract String createBeanValidationTransformerName(

+            BeanValidationVirtualValidationStrategy validationStrategy);

+}

diff --git a/2_0_3_prepare/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/metadata/transformer/mapper/NotNullNameMapper.java b/2_0_3_prepare/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/metadata/transformer/mapper/NotNullNameMapper.java
new file mode 100644
index 0000000..8328786
--- /dev/null
+++ b/2_0_3_prepare/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/metadata/transformer/mapper/NotNullNameMapper.java
@@ -0,0 +1,53 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.beanval.metadata.transformer.mapper;

+

+import org.apache.myfaces.extensions.validator.beanval.metadata.transformer.NotNullMetaDataTransformer;

+import org.apache.myfaces.extensions.validator.beanval.validation.strategy.BeanValidationVirtualValidationStrategy;

+import org.apache.myfaces.extensions.validator.core.Nested;

+import org.apache.myfaces.extensions.validator.core.InvocationOrder;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+

+import javax.validation.constraints.NotNull;

+

+/**

+ * @author Gerhard Petracek

+ * @since x.x.3

+ */

+@Nested

+@InvocationOrder(200)

+@UsageInformation({UsageCategory.INTERNAL})

+public class NotNullNameMapper extends AbstractBeanValidationVirtualValidationStrategyToMetaDataTransformerNameMapper

+{

+    protected String createBeanValidationTransformerName(BeanValidationVirtualValidationStrategy adapter)

+    {

+        if(isNotNullConstraint(adapter))

+        {

+            return NotNullMetaDataTransformer.class.getName();

+        }

+        return null;

+    }

+

+    private boolean isNotNullConstraint(BeanValidationVirtualValidationStrategy adapter)

+    {

+        return NotNull.class.getName().equals(

+                adapter.getConstraintDescriptor().getAnnotation().annotationType().getName());

+    }

+}
\ No newline at end of file
diff --git a/2_0_3_prepare/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/metadata/transformer/mapper/SizeNameMapper.java b/2_0_3_prepare/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/metadata/transformer/mapper/SizeNameMapper.java
new file mode 100644
index 0000000..1c890c6
--- /dev/null
+++ b/2_0_3_prepare/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/metadata/transformer/mapper/SizeNameMapper.java
@@ -0,0 +1,54 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.beanval.metadata.transformer.mapper;

+

+import org.apache.myfaces.extensions.validator.core.Nested;

+import org.apache.myfaces.extensions.validator.core.InvocationOrder;

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+import org.apache.myfaces.extensions.validator.beanval.validation.strategy.BeanValidationVirtualValidationStrategy;

+import org.apache.myfaces.extensions.validator.beanval.metadata.transformer.StringSizeMetaDataTransformer;

+

+import javax.validation.constraints.Size;

+

+/**

+ * @author Gerhard Petracek

+ * @since x.x.3

+ */

+@Nested

+@InvocationOrder(210)

+@UsageInformation({UsageCategory.INTERNAL})

+public class SizeNameMapper extends AbstractBeanValidationVirtualValidationStrategyToMetaDataTransformerNameMapper

+{

+    protected String createBeanValidationTransformerName(BeanValidationVirtualValidationStrategy adapter)

+    {

+        if(isStringSizeConstraint(adapter))

+        {

+            return StringSizeMetaDataTransformer.class.getName();

+        }

+        return null;

+    }

+

+    private boolean isStringSizeConstraint(BeanValidationVirtualValidationStrategy adapter)

+    {

+        return Size.class.getName().equals(

+                adapter.getConstraintDescriptor().getAnnotation().annotationType().getName()) &&

+                String.class.getName().equals(adapter.getElementClass().getName());

+    }

+}

diff --git a/2_0_3_prepare/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/payload/DisableClientSideValidation.java b/2_0_3_prepare/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/payload/DisableClientSideValidation.java
new file mode 100644
index 0000000..ab2d22f
--- /dev/null
+++ b/2_0_3_prepare/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/payload/DisableClientSideValidation.java
@@ -0,0 +1,33 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.beanval.payload;

+

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+

+import javax.validation.Payload;

+

+/**

+ * @author Gerhard Petracek

+ * @since x.x.3

+ */

+@UsageInformation(UsageCategory.API)

+public interface DisableClientSideValidation extends Payload

+{

+}

diff --git a/2_0_3_prepare/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/payload/ViolationSeverity.java b/2_0_3_prepare/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/payload/ViolationSeverity.java
new file mode 100644
index 0000000..2388b2d
--- /dev/null
+++ b/2_0_3_prepare/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/payload/ViolationSeverity.java
@@ -0,0 +1,53 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.beanval.payload;

+

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+

+import javax.validation.Payload;

+import javax.faces.application.FacesMessage;

+

+/**

+ * @author Gerhard Petracek

+ * @since x.x.3

+ */

+@UsageInformation(UsageCategory.API)

+public interface ViolationSeverity

+{

+    interface Info extends Payload

+    {

+        FacesMessage.Severity VALUE = FacesMessage.SEVERITY_INFO;

+    }

+

+    interface Warn extends Payload

+    {

+        FacesMessage.Severity VALUE = FacesMessage.SEVERITY_WARN;

+    }

+

+    interface Error extends Payload

+    {

+        FacesMessage.Severity VALUE = FacesMessage.SEVERITY_ERROR;

+    }

+

+    interface Fatal extends Payload

+    {

+        FacesMessage.Severity VALUE = FacesMessage.SEVERITY_FATAL;

+    }

+}

diff --git a/2_0_3_prepare/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/startup/BeanValidationStartupListener.java b/2_0_3_prepare/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/startup/BeanValidationStartupListener.java
new file mode 100644
index 0000000..8d269ef
--- /dev/null
+++ b/2_0_3_prepare/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/startup/BeanValidationStartupListener.java
@@ -0,0 +1,164 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.beanval.startup;

+

+import org.apache.myfaces.extensions.validator.beanval.BeanValidationModuleValidationInterceptor;

+import org.apache.myfaces.extensions.validator.beanval.HtmlCoreComponentsComponentInitializer;

+import org.apache.myfaces.extensions.validator.beanval.BeanAwareValidatorFactory;

+import org.apache.myfaces.extensions.validator.beanval.payload.ViolationSeverity;

+import org.apache.myfaces.extensions.validator.beanval.payload.DisableClientSideValidation;

+import org.apache.myfaces.extensions.validator.beanval.util.BeanValidationUtils;

+import org.apache.myfaces.extensions.validator.beanval.interceptor.ExtValBeanValidationMetaDataExtractionInterceptor;

+import org.apache.myfaces.extensions.validator.beanval.interceptor.BeanValidationExceptionInterceptor;

+import org.apache.myfaces.extensions.validator.beanval.validation.ModelValidationPhaseListener;

+import org.apache.myfaces.extensions.validator.beanval.metadata.transformer.mapper.SizeNameMapper;

+import org.apache.myfaces.extensions.validator.beanval.metadata.transformer.mapper.NotNullNameMapper;

+import org.apache.myfaces.extensions.validator.beanval.storage.DefaultModelValidationStorageManager;

+import org.apache.myfaces.extensions.validator.beanval.storage.ModelValidationStorage;

+import org.apache.myfaces.extensions.validator.beanval.storage.mapper.BeanValidationGroupStorageNameMapper;

+import org.apache.myfaces.extensions.validator.beanval.storage.mapper.ModelValidationStorageNameMapper;

+import org.apache.myfaces.extensions.validator.core.ExtValContext;

+import org.apache.myfaces.extensions.validator.core.factory.AbstractNameMapperAwareFactory;

+import org.apache.myfaces.extensions.validator.core.factory.FactoryNames;

+import org.apache.myfaces.extensions.validator.core.startup.AbstractStartupListener;

+import org.apache.myfaces.extensions.validator.core.storage.GroupStorage;

+import org.apache.myfaces.extensions.validator.core.storage.StorageManager;

+import org.apache.myfaces.extensions.validator.core.storage.StorageManagerHolder;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.util.ExtValUtils;

+import org.apache.myfaces.extensions.validator.util.JsfUtils;

+

+import javax.validation.ValidatorFactory;

+

+/**

+ * @author Gerhard Petracek

+ * @since x.x.3

+ */

+@UsageInformation(UsageCategory.INTERNAL)

+public class BeanValidationStartupListener extends AbstractStartupListener

+{

+    private static final long serialVersionUID = -5025748399876833394L;

+

+    protected void init()

+    {

+        registerValidatorFactory();

+        registerBeanValidationInterceptor();

+        registerMetaDataTransformerNameMapper();

+        registerGroupStorageNameMapper();

+        registerModelValidationStorageNameMapper();

+        registerComponentInitializers();

+        registerMetaDataExtractionInterceptors();

+        registerPhaseListeners();

+        registerExceptionInterceptor();

+        registerViolationSeverityPayload();

+        registerDisableClientSideValidationPayload();

+    }

+

+    protected void registerValidatorFactory()

+    {

+        ExtValContext.getContext().addGlobalProperty(ValidatorFactory.class.getName(),

+                new BeanAwareValidatorFactory(BeanValidationUtils.getDefaultValidatorFactory()), false);

+    }

+

+    protected void registerBeanValidationInterceptor()

+    {

+        ExtValContext.getContext().registerRendererInterceptor(new BeanValidationModuleValidationInterceptor());

+    }

+

+    protected void registerMetaDataTransformerNameMapper()

+    {

+        ExtValUtils.registerValidationStrategyToMetaDataTransformerNameMapper(new SizeNameMapper());

+        ExtValUtils.registerValidationStrategyToMetaDataTransformerNameMapper(new NotNullNameMapper());

+    }

+

+    @SuppressWarnings({"unchecked"})

+    protected void registerGroupStorageNameMapper()

+    {

+        StorageManager storageManager = getStorageManagerHolder().getStorageManager(GroupStorage.class);

+

+        if (storageManager instanceof AbstractNameMapperAwareFactory)

+        {

+            ((AbstractNameMapperAwareFactory<String>) storageManager)

+                    .register(new BeanValidationGroupStorageNameMapper());

+        }

+        else

+        {

+            if (this.logger.isWarnEnabled())

+            {

+                this.logger.warn(storageManager.getClass().getName() +

+                        " has to implement AbstractNameMapperAwareFactory " + getClass().getName() +

+                        " couldn't register " + BeanValidationGroupStorageNameMapper.class.getName());

+            }

+        }

+    }

+

+    protected void registerModelValidationStorageNameMapper()

+    {

+        DefaultModelValidationStorageManager modelValidationStorageManager = new DefaultModelValidationStorageManager();

+        modelValidationStorageManager.register(new ModelValidationStorageNameMapper());

+        getStorageManagerHolder().setStorageManager(ModelValidationStorage.class, modelValidationStorageManager, false);

+    }

+

+    protected void registerComponentInitializers()

+    {

+        ExtValContext.getContext().addComponentInitializer(new HtmlCoreComponentsComponentInitializer());

+    }

+

+    protected StorageManagerHolder getStorageManagerHolder()

+    {

+        return (ExtValContext.getContext()

+                .getFactoryFinder()

+                .getFactory(FactoryNames.STORAGE_MANAGER_FACTORY, StorageManagerHolder.class));

+    }

+

+    protected void registerMetaDataExtractionInterceptors()

+    {

+        ExtValContext.getContext()

+                .addMetaDataExtractionInterceptor(new ExtValBeanValidationMetaDataExtractionInterceptor());

+    }

+

+    protected void registerPhaseListeners()

+    {

+        JsfUtils.registerPhaseListener(new ModelValidationPhaseListener());

+        JsfUtils.registerPhaseListener(new ModelValidationPhaseListener());

+    }

+

+    protected void registerExceptionInterceptor()

+    {

+        ExtValContext.getContext().addValidationExceptionInterceptor(new BeanValidationExceptionInterceptor());

+    }

+

+    protected void registerViolationSeverityPayload()

+    {

+        ExtValContext extValContext = ExtValContext.getContext();

+

+        extValContext.addGlobalProperty(ViolationSeverity.Info.class.getName(), ViolationSeverity.Info.class, false);

+        extValContext.addGlobalProperty(ViolationSeverity.Warn.class.getName(), ViolationSeverity.Warn.class, false);

+        extValContext.addGlobalProperty(ViolationSeverity.Fatal.class.getName(), ViolationSeverity.Fatal.class, false);

+

+        //no need to register "error" it's the default

+    }

+

+    private void registerDisableClientSideValidationPayload()

+    {

+        ExtValContext.getContext().addGlobalProperty(

+                DisableClientSideValidation.class.getName(), DisableClientSideValidation.class, false);

+    }

+}

diff --git a/2_0_3_prepare/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/startup/JSF2AwareBeanValidationStartupListener.java b/2_0_3_prepare/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/startup/JSF2AwareBeanValidationStartupListener.java
new file mode 100644
index 0000000..4a694d9
--- /dev/null
+++ b/2_0_3_prepare/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/startup/JSF2AwareBeanValidationStartupListener.java
@@ -0,0 +1,45 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.beanval.startup;

+

+import org.apache.myfaces.extensions.validator.core.startup.AbstractStartupListener;

+import org.apache.myfaces.extensions.validator.core.ExtValContext;

+import org.apache.myfaces.extensions.validator.beanval.interceptor.ResetBeanValidationRendererInterceptor;

+import org.apache.myfaces.extensions.validator.beanval.interceptor.BeanValidationTagAwareValidationInterceptor;

+import org.apache.myfaces.extensions.validator.internal.ToDo;

+import org.apache.myfaces.extensions.validator.internal.Priority;

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+

+/**

+ * @author Gerhard Petracek

+ * @since 2.x.3

+ */

+@ToDo(value = Priority.HIGH, description = "add optional web.xml param to deactivate")

+@UsageInformation(UsageCategory.INTERNAL)

+public class JSF2AwareBeanValidationStartupListener extends AbstractStartupListener

+{

+    private static final long serialVersionUID = -5025748399876833393L;

+

+    protected void init()

+    {

+        ExtValContext.getContext().registerRendererInterceptor(new ResetBeanValidationRendererInterceptor());

+        ExtValContext.getContext().addPropertyValidationInterceptor(new BeanValidationTagAwareValidationInterceptor());

+    }

+}
\ No newline at end of file
diff --git a/2_0_3_prepare/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/storage/DefaultBeanValidationGroupStorage.java b/2_0_3_prepare/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/storage/DefaultBeanValidationGroupStorage.java
new file mode 100644
index 0000000..b60376e
--- /dev/null
+++ b/2_0_3_prepare/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/storage/DefaultBeanValidationGroupStorage.java
@@ -0,0 +1,47 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.beanval.storage;

+

+import org.apache.myfaces.extensions.validator.core.storage.DefaultGroupStorage;

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import static org.apache.myfaces.extensions.validator.internal.UsageCategory.INTERNAL;

+

+/**

+ * default storage implementation for bean-validation groups

+ *

+ * @author Gerhard Petracek

+ * @since x.x.3

+ */

+@UsageInformation(INTERNAL)

+public class DefaultBeanValidationGroupStorage extends DefaultGroupStorage

+{

+    @Override

+    public Class[] getGroups(String viewId, String clientId)

+    {

+        Class[] result = super.getGroups(viewId, clientId);

+

+        if(result == null)

+        {

+            //the default group will be validated automatically

+            return new Class[] {};

+        }

+

+        return result;

+    }

+}

diff --git a/2_0_3_prepare/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/storage/DefaultModelValidationStorage.java b/2_0_3_prepare/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/storage/DefaultModelValidationStorage.java
new file mode 100644
index 0000000..2800f8b
--- /dev/null
+++ b/2_0_3_prepare/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/storage/DefaultModelValidationStorage.java
@@ -0,0 +1,191 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.beanval.storage;

+

+import org.apache.myfaces.extensions.validator.util.GroupUtils;

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import static org.apache.myfaces.extensions.validator.internal.UsageCategory.INTERNAL;

+

+import javax.faces.context.FacesContext;

+import java.util.List;

+import java.util.Map;

+import java.util.HashMap;

+import java.util.ArrayList;

+

+/**

+ * storage implementation for model-validation entries

+ *

+ * @author Gerhard Petracek

+ * @since x.x.3

+ */

+@UsageInformation(INTERNAL)

+public class DefaultModelValidationStorage implements ModelValidationStorage

+{

+    private Map<String, List<ModelValidationEntry>> modelValidationEntries =

+            new HashMap<String, List<ModelValidationEntry>>();

+

+    private List<String> componentsOfRequest = new ArrayList<String>();

+

+    public void addModelValidationEntry(ModelValidationEntry modelValidationEntry)

+    {

+        String clientId = getCurrentClientId(modelValidationEntry);

+

+        List<ModelValidationEntry> modelValidationEntryList = resolveModelValidationEntryList(

+                modelValidationEntry, clientId);

+

+        addModelValidationEntry(modelValidationEntryList, modelValidationEntry);

+    }

+

+    private String getCurrentClientId(ModelValidationEntry modelValidationEntry)

+    {

+        String clientId = null;

+

+        if(modelValidationEntry.getComponent() != null)

+        {

+            clientId = modelValidationEntry.getComponent().getClientId(FacesContext.getCurrentInstance());

+

+            if(!this.componentsOfRequest.contains(clientId))

+            {

+                this.componentsOfRequest.add(clientId);

+            }

+        }

+        return clientId;

+    }

+

+    private List<ModelValidationEntry> resolveModelValidationEntryList(

+            ModelValidationEntry modelValidationEntry, String clientId)

+    {

+        List<ModelValidationEntry> modelValidationEntryList =

+                this.modelValidationEntries.get(GroupUtils.getGroupKey(

+                        modelValidationEntry.getViewId(), clientId));

+

+        if(modelValidationEntryList == null)

+        {

+            modelValidationEntryList = new ArrayList<ModelValidationEntry>();

+            this.modelValidationEntries.put(GroupUtils.getGroupKey(

+                    modelValidationEntry.getViewId(), clientId), modelValidationEntryList);

+        }

+        return modelValidationEntryList;

+    }

+

+    private void addModelValidationEntry(

+            List<ModelValidationEntry> modelValidationEntryList, ModelValidationEntry modelValidationEntry)

+    {

+        if(!modelValidationEntryList.contains(modelValidationEntry))

+        {

+            modelValidationEntryList.add(modelValidationEntry);

+        }

+    }

+

+    public List<ModelValidationEntry> getModelValidationEntriesToValidate()

+    {

+        String viewId = FacesContext.getCurrentInstance().getViewRoot().getViewId();

+        List<ModelValidationEntry> result = new ArrayList<ModelValidationEntry>();

+

+        addEntriesForComponents(viewId, result);

+

+        addEntriesForPage(viewId, result);

+

+        return result;

+    }

+

+    private void addEntriesForComponents(String viewId, List<ModelValidationEntry> result)

+    {

+        for(String currentClientId : this.componentsOfRequest)

+        {

+            result.addAll(getModelValidationEntries(viewId, currentClientId));

+        }

+    }

+

+    private void addEntriesForPage(String viewId, List<ModelValidationEntry> result)

+    {

+        result.addAll(getModelValidationEntries(viewId));

+    }

+

+    private List<ModelValidationEntry> buildModelValidationEntryList(

+            String key, Map<String, List<ModelValidationEntry>> groupStorage)

+    {

+        List<ModelValidationEntry> list;

+

+        if(key != null && key.endsWith("*"))

+        {

+            list = new ArrayList<ModelValidationEntry>();

+            for(Map.Entry<String,List<ModelValidationEntry>> entry : groupStorage.entrySet())

+            {

+                if(entry.getKey().substring(0, entry.getKey().indexOf("@"))

+                        .equals(key.substring(0, key.indexOf("@"))))

+                {

+                    list.addAll(entry.getValue());

+                }

+            }

+            return list;

+        }

+

+        list = groupStorage.get(key);

+        return (list != null) ? list : new ArrayList<ModelValidationEntry>();

+    }

+

+    private List<ModelValidationEntry> getModelValidationEntries(String viewId)

+    {

+        return getModelValidationEntries(viewId, null);

+    }

+

+    private List<ModelValidationEntry> getModelValidationEntries(String viewId, String clientId)

+    {

+        if(this.modelValidationEntries.size() < 1)

+        {

+            return new ArrayList<ModelValidationEntry>();

+        }

+

+        //add found groups

+        String key;

+        List<ModelValidationEntry> resultListForPage = null;

+

+        if(!"*".equals(clientId))

+        {

+            key = GroupUtils.getGroupKey(viewId, null);

+            resultListForPage =

+                    buildModelValidationEntryList(key, this.modelValidationEntries);

+        }

+

+        key = GroupUtils.getGroupKey(viewId, clientId);

+        List<ModelValidationEntry> resultListForComponent =

+                buildModelValidationEntryList(key, this.modelValidationEntries);

+

+        if(resultListForPage == null || resultListForPage.isEmpty())

+        {

+            return resultListForComponent;

+        }

+        else if(resultListForComponent.isEmpty())

+        {

+            return resultListForPage;

+        }

+

+        return mergeResults(resultListForPage, resultListForComponent);

+    }

+

+    private List<ModelValidationEntry> mergeResults(

+            List<ModelValidationEntry> resultListForPage, List<ModelValidationEntry> resultListForComponent)

+    {

+        List<ModelValidationEntry> mergedResult = new ArrayList<ModelValidationEntry>();

+        mergedResult.addAll(resultListForPage);

+        mergedResult.addAll(resultListForComponent);

+        return mergedResult;

+    }

+}

diff --git a/2_0_3_prepare/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/storage/DefaultModelValidationStorageManager.java b/2_0_3_prepare/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/storage/DefaultModelValidationStorageManager.java
new file mode 100644
index 0000000..1831012
--- /dev/null
+++ b/2_0_3_prepare/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/storage/DefaultModelValidationStorageManager.java
@@ -0,0 +1,40 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.beanval.storage;

+

+import org.apache.myfaces.extensions.validator.core.storage.StorageManager;

+import org.apache.myfaces.extensions.validator.core.storage.AbstractRequestScopeAwareStorageManager;

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import static org.apache.myfaces.extensions.validator.internal.UsageCategory.INTERNAL;

+

+/**

+ * default storage-manager for model-validation entries

+ *

+ * @author Gerhard Petracek

+ * @since x.x.3

+ */

+@UsageInformation(INTERNAL)

+public class DefaultModelValidationStorageManager

+        extends AbstractRequestScopeAwareStorageManager<ModelValidationStorage>

+{

+    public String getStorageManagerKey()

+    {

+        return StorageManager.class.getName() + "_FOR_MODEL_VALIDATION:KEY";

+    }

+}
\ No newline at end of file
diff --git a/2_0_3_prepare/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/storage/ModelValidationEntry.java b/2_0_3_prepare/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/storage/ModelValidationEntry.java
new file mode 100644
index 0000000..a78a8f3
--- /dev/null
+++ b/2_0_3_prepare/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/storage/ModelValidationEntry.java
@@ -0,0 +1,197 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.beanval.storage;

+

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import static org.apache.myfaces.extensions.validator.internal.UsageCategory.API;

+import org.apache.myfaces.extensions.validator.beanval.annotation.ModelValidation;

+

+import javax.faces.component.UIComponent;

+import javax.faces.context.FacesContext;

+import java.util.List;

+import java.util.ArrayList;

+

+/**

+ * @author Gerhard Petracek

+ * @since x.x.3

+ */

+@UsageInformation(API)

+public class ModelValidationEntry

+{

+    private UIComponent component;

+    private List<Class> groups = new ArrayList<Class>();

+    private List<Object> validationTargets = new ArrayList<Object>();

+    private boolean displayMessageInline = false;

+    private String customMessage = ModelValidation.DEFAULT;

+    

+    //the original source where the extval-bv meta-data has been found

+    private Object metaDataSourceObject;

+    private String viewId = FacesContext.getCurrentInstance().getViewRoot().getViewId();

+

+    public void addGroup(Class group)

+    {

+        if(!this.groups.contains(group))

+        {

+            if(!(this.groups instanceof ArrayList))

+            {

+                List<Class> newGroupList = new ArrayList<Class>();

+

+                for(Class currentClass : this.groups)

+                {

+                    newGroupList.add(currentClass);

+                }

+                this.groups = newGroupList;

+            }

+

+            this.groups.add(group);

+        }

+    }

+

+    public void removeGroup(Class group)

+    {

+        this.groups.remove(group);

+    }

+

+    public void addValidationTarget(Object target)

+    {

+        if(!this.validationTargets.contains(target))

+        {

+            if(!(this.validationTargets instanceof ArrayList))

+            {

+                List<Object> validationTargetList = new ArrayList<Object>();

+

+                for(Object currentTarget : this.validationTargets)

+                {

+                    validationTargetList.add(currentTarget);

+                }

+                this.validationTargets = validationTargetList;

+            }

+

+            this.validationTargets.add(target);

+        }

+    }

+

+    /*

+     * generated

+     */

+    public UIComponent getComponent()

+    {

+        return component;

+    }

+

+    public void setComponent(UIComponent component)

+    {

+        this.component = component;

+    }

+

+    public Class[] getGroups()

+    {

+        return this.groups.toArray(new Class[this.groups.size()]);

+    }

+

+    public void setGroups(List<Class> groups)

+    {

+        this.groups = groups;

+    }

+

+    public List<Object> getValidationTargets()

+    {

+        return validationTargets;

+    }

+

+    public Object getMetaDataSourceObject()

+    {

+        return metaDataSourceObject;

+    }

+

+    public void setMetaDataSourceObject(Object metaDataSourceObject)

+    {

+        this.metaDataSourceObject = metaDataSourceObject;

+    }

+

+    @SuppressWarnings({"RedundantIfStatement"})

+    @Override

+    public boolean equals(Object o)

+    {

+        if (this == o)

+        {

+            return true;

+        }

+        if (o == null || getClass() != o.getClass())

+        {

+            return false;

+        }

+

+        ModelValidationEntry that = (ModelValidationEntry) o;

+

+        if (component != null ? !component.equals(that.component) : that.component != null)

+        {

+            return false;

+        }

+        if (!groups.equals(that.groups))

+        {

+            return false;

+        }

+        if (!validationTargets.equals(that.validationTargets))

+        {

+            return false;

+        }

+

+        return true;

+    }

+

+    public boolean isDisplayMessageInline()

+    {

+        return displayMessageInline;

+    }

+

+    public void setDisplayMessageInline(boolean displayMessageInline)

+    {

+        this.displayMessageInline = displayMessageInline;

+    }

+

+    public String getCustomMessage()

+    {

+        return customMessage;

+    }

+

+    public void setCustomMessage(String customMessage)

+    {

+        this.customMessage = customMessage;

+    }

+

+    @Override

+    public int hashCode()

+    {

+        int result = component != null ? component.hashCode() : 0;

+        result = 31 * result + groups.hashCode();

+        result = 31 * result + validationTargets.hashCode();

+        return result;

+    }

+

+    public String getViewId()

+    {

+        return viewId;

+    }

+

+    public void setViewId(String viewId)

+    {

+        this.viewId = viewId;

+    }

+}

diff --git a/2_0_3_prepare/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/storage/ModelValidationStorage.java b/2_0_3_prepare/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/storage/ModelValidationStorage.java
new file mode 100644
index 0000000..6dbdf93
--- /dev/null
+++ b/2_0_3_prepare/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/storage/ModelValidationStorage.java
@@ -0,0 +1,40 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.beanval.storage;

+

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+

+import java.util.List;

+

+/**

+ * suggested interface for a model-validation storage

+ * <p/>

+ * it allows to manage model-validation-entries for the current request

+ * 

+ * @author Gerhard Petracek

+ * @since x.x.3

+ */

+@UsageInformation(UsageCategory.API)

+public interface ModelValidationStorage

+{

+    void addModelValidationEntry(ModelValidationEntry modelValidationEntry);

+

+    List<ModelValidationEntry> getModelValidationEntriesToValidate();

+}

diff --git a/2_0_3_prepare/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/storage/mapper/BeanValidationGroupStorageNameMapper.java b/2_0_3_prepare/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/storage/mapper/BeanValidationGroupStorageNameMapper.java
new file mode 100644
index 0000000..4ec2e39
--- /dev/null
+++ b/2_0_3_prepare/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/storage/mapper/BeanValidationGroupStorageNameMapper.java
@@ -0,0 +1,41 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.beanval.storage.mapper;

+

+import org.apache.myfaces.extensions.validator.core.mapper.NameMapper;

+import org.apache.myfaces.extensions.validator.core.InvocationOrder;

+import org.apache.myfaces.extensions.validator.beanval.annotation.BeanValidation;

+import org.apache.myfaces.extensions.validator.beanval.storage.DefaultBeanValidationGroupStorage;

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import static org.apache.myfaces.extensions.validator.internal.UsageCategory.INTERNAL;

+

+/**

+ * @author Gerhard Petracek

+ * @since x.x.3

+ */

+@InvocationOrder(200)

+@UsageInformation(INTERNAL)

+public class BeanValidationGroupStorageNameMapper implements NameMapper<String>

+{

+    public String createName(String key)

+    {

+        return (BeanValidation.class.getName().equals(key)) ?

+                DefaultBeanValidationGroupStorage.class.getName() : null;

+    }

+}
\ No newline at end of file
diff --git a/2_0_3_prepare/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/storage/mapper/ModelValidationStorageNameMapper.java b/2_0_3_prepare/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/storage/mapper/ModelValidationStorageNameMapper.java
new file mode 100644
index 0000000..ba62050
--- /dev/null
+++ b/2_0_3_prepare/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/storage/mapper/ModelValidationStorageNameMapper.java
@@ -0,0 +1,41 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.beanval.storage.mapper;

+

+import org.apache.myfaces.extensions.validator.core.mapper.NameMapper;

+import org.apache.myfaces.extensions.validator.core.InvocationOrder;

+import org.apache.myfaces.extensions.validator.beanval.annotation.ModelValidation;

+import org.apache.myfaces.extensions.validator.beanval.storage.DefaultModelValidationStorage;

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import static org.apache.myfaces.extensions.validator.internal.UsageCategory.INTERNAL;

+

+/**

+ * @author Gerhard Petracek

+ * @since x.x.3

+ */

+@InvocationOrder(200)

+@UsageInformation(INTERNAL)

+public class ModelValidationStorageNameMapper implements NameMapper<String>

+{

+    public String createName(String key)

+    {

+        return (ModelValidation.class.getName().equals(key)) ?

+                DefaultModelValidationStorage.class.getName() : null;

+    }

+}
\ No newline at end of file
diff --git a/2_0_3_prepare/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/util/BeanValidationUtils.java b/2_0_3_prepare/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/util/BeanValidationUtils.java
new file mode 100644
index 0000000..b76d173
--- /dev/null
+++ b/2_0_3_prepare/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/util/BeanValidationUtils.java
@@ -0,0 +1,172 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.beanval.util;

+

+import org.apache.commons.logging.Log;

+import org.apache.commons.logging.LogFactory;

+import org.apache.myfaces.extensions.validator.beanval.storage.ModelValidationEntry;

+import org.apache.myfaces.extensions.validator.core.property.PropertyDetails;

+import org.apache.myfaces.extensions.validator.core.validation.message.FacesMessageHolder;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.util.ExtValUtils;

+

+import javax.faces.application.FacesMessage;

+import javax.faces.component.UIComponent;

+import javax.faces.context.FacesContext;

+import javax.faces.validator.ValidatorException;

+import javax.validation.ConstraintViolation;

+import javax.validation.ValidatorFactory;

+import javax.validation.Validation;

+import java.util.ArrayList;

+import java.util.List;

+import java.util.Set;

+import java.util.Map;

+

+/**

+ * @author Gerhard Petracek

+ * @since x.x.3

+ */

+@UsageInformation(UsageCategory.INTERNAL)

+public class BeanValidationUtils

+{

+    private static final Log LOGGER = LogFactory.getLog(BeanValidationUtils.class);

+    private static ExtValBeanValidationMetaDataInternals bvmi = new ExtValBeanValidationMetaDataInternals(LOGGER);

+    private static final String VALIDATOR_FACTORY_KEY = "javax.faces.validator.beanValidator.ValidatorFactory";

+

+    public static void addMetaDataToContext(

+            UIComponent component, PropertyDetails propertyDetails, boolean processModelValidation)

+    {

+        String[] key = propertyDetails.getKey().split("\\.");

+

+        Object firstBean = ExtValUtils.getELHelper().getBean(key[0]);

+

+        List<Class> foundGroupsForPropertyValidation = new ArrayList<Class>();

+        List<Class> restrictedGroupsForPropertyValidation = new ArrayList<Class>();

+        List<ModelValidationEntry> modelValidationEntryList = new ArrayList<ModelValidationEntry>();

+        List<Class> restrictedGroupsForModelValidation = new ArrayList<Class>();

+

+        bvmi.extractExtValBeanValidationMetaData(propertyDetails,

+                processModelValidation,

+                key,

+                firstBean,

+                foundGroupsForPropertyValidation,

+                restrictedGroupsForPropertyValidation,

+                modelValidationEntryList,

+                restrictedGroupsForModelValidation);

+

+        bvmi.processExtValBeanValidationMetaData(component,

+                propertyDetails,

+                foundGroupsForPropertyValidation,

+                restrictedGroupsForPropertyValidation,

+                modelValidationEntryList,

+                restrictedGroupsForModelValidation);

+    }

+

+    public static void processConstraintViolations(FacesContext facesContext,

+                                                   UIComponent uiComponent,

+                                                   Object convertedObject,

+                                                   Set<ConstraintViolation> violations)

+    {

+        List<FacesMessageHolder> facesMessageHolderList = new ArrayList<FacesMessageHolder>();

+

+        FacesMessage facesMessage;

+        for (ConstraintViolation violation : violations)

+        {

+            facesMessage = createFacesMessageForConstraintViolation(uiComponent, convertedObject, violation);

+

+            if (facesMessage == null)

+            {

+                continue;

+            }

+

+            bvmi.processFacesMessage(facesContext, uiComponent, facesMessageHolderList, facesMessage);

+        }

+

+        processViolationMessages(facesMessageHolderList);

+    }

+

+    public static FacesMessage createFacesMessageForConstraintViolation(UIComponent uiComponent,

+                                                                        Object convertedObject,

+                                                                        ConstraintViolation violation)

+    {

+        String violationMessage = violation.getMessage();

+

+        String labeledMessageSummary = bvmi.createLabeledMessage(violationMessage, false);

+        String labeledMessageDetail = bvmi.createLabeledMessage(violationMessage, true);

+

+        FacesMessage.Severity severity = bvmi.calcSeverity(violation);

+

+        ValidatorException validatorException = bvmi

+                .createValidatorException(labeledMessageSummary, labeledMessageDetail, severity);

+

+        if (!bvmi.executeAfterThrowingInterceptors(uiComponent, convertedObject, validatorException))

+        {

+            return null;

+        }

+

+        if (bvmi.isMessageTextUnchanged(validatorException, labeledMessageSummary, labeledMessageDetail))

+        {

+            return ExtValUtils.createFacesMessage(severity, violationMessage, violationMessage);

+        }

+        else

+        {

+            return ExtValUtils.createFacesMessage(severity,

+                    validatorException.getFacesMessage().getSummary(),

+                    validatorException.getFacesMessage().getDetail());

+        }

+    }

+

+    public static void processViolationMessages(List<FacesMessageHolder> violationMessageHolderList)

+    {

+        if (violationMessageHolderList == null || violationMessageHolderList.isEmpty())

+        {

+            return;

+        }

+

+        List<FacesMessageHolder> facesMessageListWithLowSeverity =

+                bvmi.getFacesMessageListWithLowSeverity(violationMessageHolderList);

+        List<FacesMessageHolder> facesMessageListWithHighSeverity =

+                bvmi.getFacesMessageListWithHighSeverity(violationMessageHolderList);

+

+        bvmi.addMessages(facesMessageListWithHighSeverity);

+        bvmi.addMessages(facesMessageListWithLowSeverity);

+    }

+

+    public static ValidatorFactory getDefaultValidatorFactory()

+    {

+        Map<String, Object> applicationMap = FacesContext.getCurrentInstance().getExternalContext().getApplicationMap();

+        ValidatorFactory validatorFactory = null;

+

+        if (applicationMap.containsKey(VALIDATOR_FACTORY_KEY))

+        {

+            if (applicationMap.get(VALIDATOR_FACTORY_KEY) instanceof ValidatorFactory)

+            {

+                validatorFactory = (ValidatorFactory) applicationMap.get(VALIDATOR_FACTORY_KEY);

+            }

+        }

+

+        if (validatorFactory == null)

+        {

+            validatorFactory = Validation.buildDefaultValidatorFactory();

+            applicationMap.put(VALIDATOR_FACTORY_KEY, validatorFactory);

+        }

+        return validatorFactory;

+    }

+}

diff --git a/2_0_3_prepare/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/util/ExtValBeanValidationMetaDataInternals.java b/2_0_3_prepare/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/util/ExtValBeanValidationMetaDataInternals.java
new file mode 100644
index 0000000..1b21894
--- /dev/null
+++ b/2_0_3_prepare/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/util/ExtValBeanValidationMetaDataInternals.java
@@ -0,0 +1,668 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.beanval.util;

+

+import org.apache.commons.logging.Log;

+import org.apache.myfaces.extensions.validator.beanval.ExtValBeanValidationContext;

+import org.apache.myfaces.extensions.validator.beanval.payload.ViolationSeverity;

+import org.apache.myfaces.extensions.validator.beanval.annotation.BeanValidation;

+import org.apache.myfaces.extensions.validator.beanval.annotation.ModelValidation;

+import org.apache.myfaces.extensions.validator.beanval.annotation.extractor.DefaultGroupControllerScanningExtractor;

+import org.apache.myfaces.extensions.validator.beanval.storage.ModelValidationEntry;

+import org.apache.myfaces.extensions.validator.core.el.ELHelper;

+import org.apache.myfaces.extensions.validator.core.el.ValueBindingExpression;

+import org.apache.myfaces.extensions.validator.core.metadata.MetaDataEntry;

+import org.apache.myfaces.extensions.validator.core.property.PropertyDetails;

+import org.apache.myfaces.extensions.validator.core.property.PropertyInformation;

+import org.apache.myfaces.extensions.validator.core.validation.message.FacesMessageHolder;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.ToDo;

+import org.apache.myfaces.extensions.validator.internal.Priority;

+import org.apache.myfaces.extensions.validator.util.ExtValUtils;

+import org.apache.myfaces.extensions.validator.util.ReflectionUtils;

+import org.apache.myfaces.extensions.validator.util.ProxyUtils;

+

+import javax.faces.application.FacesMessage;

+import javax.faces.component.UIComponent;

+import javax.faces.context.FacesContext;

+import javax.faces.validator.ValidatorException;

+import javax.validation.ConstraintViolation;

+import javax.validation.Payload;

+import java.lang.reflect.Method;

+import java.util.ArrayList;

+import java.util.Arrays;

+import java.util.List;

+

+/**

+ * @author Gerhard Petracek

+ * @since x.x.3

+ */

+@UsageInformation(UsageCategory.INTERNAL)

+class ExtValBeanValidationMetaDataInternals

+{

+    private Log logger;

+    private LabeledMessageInternals labeledMessageInternals = new LabeledMessageInternals();

+

+    ExtValBeanValidationMetaDataInternals(Log logger)

+    {

+        this.logger = logger;

+    }

+

+    void extractExtValBeanValidationMetaData(PropertyDetails propertyDetails,

+                                             boolean processModelValidation,

+                                             String[] key,

+                                             Object firstBean,

+                                             List<Class> foundGroupsForPropertyValidation,

+                                             List<Class> restrictedGroupsForPropertyValidation,

+                                             List<ModelValidationEntry> modelValidationEntryList,

+                                             List<Class> restrictedGroupsForModelValidation)

+    {

+        inspectFirstBean(processModelValidation,

+                firstBean,

+                foundGroupsForPropertyValidation,

+                restrictedGroupsForPropertyValidation,

+                modelValidationEntryList,

+                restrictedGroupsForModelValidation);

+

+        inspectFirstProperty(processModelValidation,

+                key,

+                firstBean,

+                foundGroupsForPropertyValidation,

+                restrictedGroupsForPropertyValidation,

+                modelValidationEntryList,

+                restrictedGroupsForModelValidation,

+                key.length == 2);

+

+        inspectBaseOfProperty(propertyDetails,

+                processModelValidation,

+                foundGroupsForPropertyValidation,

+                restrictedGroupsForPropertyValidation,

+                modelValidationEntryList,

+                restrictedGroupsForModelValidation);

+

+        inspectLastProperty(propertyDetails,

+                processModelValidation,

+                foundGroupsForPropertyValidation,

+                restrictedGroupsForPropertyValidation,

+                modelValidationEntryList,

+                restrictedGroupsForModelValidation);

+    }

+

+    void processExtValBeanValidationMetaData(UIComponent component,

+                                             PropertyDetails propertyDetails,

+                                             List<Class> foundGroupsForPropertyValidation,

+                                             List<Class> restrictedGroupsForPropertyValidation,

+                                             List<ModelValidationEntry> modelValidationEntryList,

+                                             List<Class> restrictedGroupsForModelValidation)

+    {

+        ExtValBeanValidationContext extValBeanValidationContext = ExtValBeanValidationContext.getCurrentInstance();

+        String currentViewId = FacesContext.getCurrentInstance().getViewRoot().getViewId();

+

+        String clientId = component.getClientId(FacesContext.getCurrentInstance());

+

+        processFoundGroups(extValBeanValidationContext, currentViewId, clientId,

+                foundGroupsForPropertyValidation);

+

+        processRestrictedGroups(extValBeanValidationContext, currentViewId, clientId,

+                restrictedGroupsForPropertyValidation);

+

+        initModelValidation(extValBeanValidationContext, component, propertyDetails,

+                modelValidationEntryList, restrictedGroupsForModelValidation);

+    }

+

+    private void inspectFirstBean(boolean processModelValidation,

+                                  Object firstBean,

+                                  List<Class> foundGroupsForPropertyValidation,

+                                  List<Class> restrictedGroupsForPropertyValidation,

+                                  List<ModelValidationEntry> modelValidationEntryList,

+                                  List<Class> restrictedGroupsForModelValidation)

+    {

+        processClass(firstBean,

+                foundGroupsForPropertyValidation,

+                restrictedGroupsForPropertyValidation,

+                modelValidationEntryList,

+                restrictedGroupsForModelValidation,

+                processModelValidation);

+    }

+

+    private void inspectFirstProperty(boolean processModelValidation,

+                                      String[] key,

+                                      Object firstBean,

+                                      List<Class> foundGroupsForPropertyValidation,

+                                      List<Class> restrictedGroupsForPropertyValidation,

+                                      List<ModelValidationEntry> modelValidationEntryList,

+                                      List<Class> restrictedGroupsForModelValidation,

+                                      boolean isLastProperty)

+    {

+        processFieldsAndProperties(key[0] + "." + key[1],

+                firstBean,

+                key[1],

+                foundGroupsForPropertyValidation,

+                restrictedGroupsForPropertyValidation,

+                modelValidationEntryList,

+                restrictedGroupsForModelValidation,

+                processModelValidation,

+                isLastProperty);

+    }

+

+    private void inspectBaseOfProperty(PropertyDetails propertyDetails,

+                                       boolean processModelValidation,

+                                       List<Class> foundGroupsForPropertyValidation,

+                                       List<Class> restrictedGroupsForPropertyValidation,

+                                       List<ModelValidationEntry> modelValidationEntryList,

+                                       List<Class> restrictedGroupsForModelValidation)

+    {

+        processClass(propertyDetails.getBaseObject(),

+                foundGroupsForPropertyValidation,

+                restrictedGroupsForPropertyValidation,

+                modelValidationEntryList,

+                restrictedGroupsForModelValidation,

+                processModelValidation);

+    }

+

+    private void inspectLastProperty(PropertyDetails propertyDetails,

+                                     boolean processModelValidation,

+                                     List<Class> foundGroupsForPropertyValidation,

+                                     List<Class> restrictedGroupsForPropertyValidation,

+                                     List<ModelValidationEntry> modelValidationEntryList,

+                                     List<Class> restrictedGroupsForModelValidation)

+    {

+        processFieldsAndProperties(

+                propertyDetails.getKey(),

+                propertyDetails.getBaseObject(),

+                propertyDetails.getProperty(),

+                foundGroupsForPropertyValidation,

+                restrictedGroupsForPropertyValidation,

+                modelValidationEntryList,

+                restrictedGroupsForModelValidation,

+                processModelValidation,

+                true);

+    }

+

+    private void processClass(Object objectToInspect,

+                              List<Class> foundGroupsForPropertyValidation,

+                              List<Class> restrictedGroupsForPropertyValidation,

+                              List<ModelValidationEntry> modelValidationEntryList,

+                              List<Class> restrictedGroupsForModelValidation,

+                              boolean processModelValidation)

+    {

+        Class classToInspect = ProxyUtils.getUnproxiedClass(objectToInspect.getClass());

+

+        while (!Object.class.getName().equals(classToInspect.getName()))

+        {

+            transferGroupValidationInformationToFoundGroups(objectToInspect,

+                    foundGroupsForPropertyValidation,

+                    restrictedGroupsForPropertyValidation,

+                    modelValidationEntryList,

+                    restrictedGroupsForModelValidation,

+                    processModelValidation);

+

+            processInterfaces(objectToInspect.getClass(), objectToInspect,

+                    foundGroupsForPropertyValidation,

+                    restrictedGroupsForPropertyValidation,

+                    modelValidationEntryList,

+                    restrictedGroupsForModelValidation,

+                    processModelValidation);

+

+            classToInspect = classToInspect.getSuperclass();

+        }

+    }

+

+    private void processFieldsAndProperties(String key,

+                                            Object base,

+                                            String property,

+                                            List<Class> foundGroupsForPropertyValidation,

+                                            List<Class> restrictedGroupsForPropertyValidation,

+                                            List<ModelValidationEntry> modelValidationEntryList,

+                                            List<Class> restrictedGroupsForModelValidation,

+                                            boolean processModelValidation,

+                                            boolean isLastProperty)

+    {

+        PropertyInformation propertyInformation = new DefaultGroupControllerScanningExtractor()

+                .extract(FacesContext.getCurrentInstance(), new PropertyDetails(key, base, property));

+

+        for (MetaDataEntry metaDataEntry : propertyInformation.getMetaDataEntries())

+        {

+            if (metaDataEntry.getValue() instanceof BeanValidation)

+            {

+                tryToProcessMetaData((BeanValidation) metaDataEntry.getValue(),

+                        tryToCreateNewTarget(base, property, isLastProperty),

+                        foundGroupsForPropertyValidation,

+                        restrictedGroupsForPropertyValidation,

+                        modelValidationEntryList,

+                        restrictedGroupsForModelValidation,

+                        processModelValidation);

+            }

+            else if (metaDataEntry.getValue() instanceof BeanValidation.List)

+            {

+                for (BeanValidation currentBeanValidation : ((BeanValidation.List) metaDataEntry.getValue()).value())

+                {

+                    tryToProcessMetaData(currentBeanValidation,

+                            tryToCreateNewTarget(base, property, isLastProperty),

+                            foundGroupsForPropertyValidation,

+                            restrictedGroupsForPropertyValidation,

+                            modelValidationEntryList,

+                            restrictedGroupsForModelValidation,

+                            processModelValidation);

+                }

+            }

+        }

+    }

+

+    private Object tryToCreateNewTarget(Object base, String property, boolean isLastProperty)

+    {

+        if(isLastProperty)

+        {

+            return base;

+        }

+        

+        Object result = getValueOfProperty(base, property);

+

+        if (result == null)

+        {

+            return base;

+        }

+

+        return result;

+    }

+

+    private Object getValueOfProperty(Object base, String property)

+    {

+        property = property.substring(0, 1).toUpperCase() + property.substring(1, property.length());

+

+        Class targetClass = ProxyUtils.getUnproxiedClass(base.getClass());

+

+        Method targetMethod = ReflectionUtils.tryToGetMethod(targetClass, "get" + property);

+

+        if (targetMethod == null)

+        {

+            targetMethod = ReflectionUtils.tryToGetMethod(targetClass, "is" + property);

+        }

+

+        if (targetMethod == null)

+        {

+            throw new IllegalStateException(

+                    "class " + targetClass + " has no public get/is " + property.toLowerCase());

+        }

+        return ReflectionUtils.tryToInvokeMethod(base, targetMethod);

+    }

+

+    private void processFoundGroups(ExtValBeanValidationContext extValBeanValidationContext,

+                                    String currentViewId,

+                                    String clientId,

+                                    List<Class> foundGroupsForPropertyValidation)

+    {

+        /*

+         * add found groups to context

+         */

+        for (Class currentGroupClass : foundGroupsForPropertyValidation)

+        {

+            extValBeanValidationContext.addGroup(currentGroupClass, currentViewId, clientId);

+        }

+    }

+

+    private void processRestrictedGroups(ExtValBeanValidationContext extValBeanValidationContext,

+                                         String currentViewId,

+                                         String clientId,

+                                         List<Class> restrictedGroupsForPropertyValidation)

+    {

+        /*

+         * add restricted groups

+         */

+        for (Class currentGroupClass : restrictedGroupsForPropertyValidation)

+        {

+            extValBeanValidationContext.restrictGroup(currentGroupClass, currentViewId, clientId);

+        }

+    }

+

+    private void initModelValidation(ExtValBeanValidationContext extValBeanValidationContext,

+                                     UIComponent component,

+                                     PropertyDetails propertyDetails,

+                                     List<ModelValidationEntry> modelValidationEntryList,

+                                     List<Class> restrictedGroupsForModelValidation)

+    {

+        /*

+         * add model validation entry list

+         */

+        for (ModelValidationEntry modelValidationEntry : modelValidationEntryList)

+        {

+            for (Class restrictedGroup : restrictedGroupsForModelValidation)

+            {

+                modelValidationEntry.removeGroup(restrictedGroup);

+            }

+

+            if (modelValidationEntry.getGroups().length > 0)

+            {

+                if (modelValidationEntry.getValidationTargets().isEmpty())

+                {

+                    modelValidationEntry.addValidationTarget(propertyDetails.getBaseObject());

+                }

+                modelValidationEntry.setComponent(component);

+                extValBeanValidationContext.addModelValidationEntry(modelValidationEntry);

+            }

+        }

+    }

+

+    @ToDo(value = Priority.MEDIUM, description = "test proxy support")

+    private void transferGroupValidationInformationToFoundGroups(

+            Object objectToInspect,

+            List<Class> foundGroupsForPropertyValidation,

+            List<Class> restrictedGroupsForPropertyValidation,

+            List<ModelValidationEntry> modelValidationEntryList,

+            List<Class> restrictedGroupsForModelValidation,

+            boolean processModelValidation)

+    {

+        if (objectToInspect.getClass().isAnnotationPresent(BeanValidation.class))

+        {

+            tryToProcessMetaData(objectToInspect.getClass().getAnnotation(BeanValidation.class),

+                    objectToInspect,

+                    foundGroupsForPropertyValidation,

+                    restrictedGroupsForPropertyValidation,

+                    modelValidationEntryList,

+                    restrictedGroupsForModelValidation,

+                    processModelValidation);

+        }

+        else if (objectToInspect.getClass().isAnnotationPresent(BeanValidation.List.class))

+        {

+            for (BeanValidation currentBeanValidation :

+                    (objectToInspect.getClass().getAnnotation(BeanValidation.List.class)).value())

+            {

+                tryToProcessMetaData(currentBeanValidation,

+                        objectToInspect,

+                        foundGroupsForPropertyValidation,

+                        restrictedGroupsForPropertyValidation,

+                        modelValidationEntryList,

+                        restrictedGroupsForModelValidation,

+                        processModelValidation);

+            }

+        }

+    }

+

+    private void processInterfaces(Class currentClass,

+                                   Object metaDataSourceObject,

+                                   List<Class> foundGroupsForPropertyValidation,

+                                   List<Class> restrictedGroupsForPropertyValidation,

+                                   List<ModelValidationEntry> modelValidationEntryList,

+                                   List<Class> restrictedGroupsForModelValidation,

+                                   boolean processModelValidation)

+    {

+        for (Class currentInterface : currentClass.getInterfaces())

+        {

+            transferGroupValidationInformationToFoundGroups(metaDataSourceObject,

+                    foundGroupsForPropertyValidation,

+                    restrictedGroupsForPropertyValidation,

+                    modelValidationEntryList,

+                    restrictedGroupsForModelValidation,

+                    processModelValidation);

+

+            processInterfaces(currentInterface, metaDataSourceObject,

+                    foundGroupsForPropertyValidation,

+                    restrictedGroupsForPropertyValidation,

+                    modelValidationEntryList,

+                    restrictedGroupsForModelValidation,

+                    processModelValidation);

+        }

+    }

+

+    private void tryToProcessMetaData(BeanValidation beanValidation,

+                                      Object metaDataSourceObject,

+                                      List<Class> foundGroupsForPropertyValidation,

+                                      List<Class> restrictedGroupsForPropertyValidation,

+                                      List<ModelValidationEntry> modelValidationEntryList,

+                                      List<Class> restrictedGroupsForModelValidation,

+                                      boolean processModelValidation)

+    {

+        for (String currentViewId : beanValidation.viewIds())

+        {

+            if (useMetaDataForViewId(beanValidation, currentViewId))

+            {

+                processMetaData(beanValidation,

+                        metaDataSourceObject,

+                        foundGroupsForPropertyValidation,

+                        restrictedGroupsForPropertyValidation,

+                        modelValidationEntryList,

+                        restrictedGroupsForModelValidation,

+                        processModelValidation);

+                break;

+            }

+        }

+    }

+

+    private boolean useMetaDataForViewId(BeanValidation beanValidation, String currentViewId)

+    {

+        return (currentViewId.equals(FacesContext.getCurrentInstance().getViewRoot().getViewId()) ||

+                currentViewId.equals("*")) && isValidationPermitted(beanValidation);

+    }

+

+    private void processMetaData(BeanValidation beanValidation,

+                                 Object metaDataSourceObject,

+                                 List<Class> foundGroupsForPropertyValidation,

+                                 List<Class> restrictedGroupsForPropertyValidation,

+                                 List<ModelValidationEntry> modelValidationEntryList,

+                                 List<Class> restrictedGroupsForModelValidation,

+                                 boolean processModelValidation)

+    {

+        if (processModelValidation && isModelValidation(beanValidation))

+        {

+            addModelValidationEntry(

+                    beanValidation, metaDataSourceObject,

+                    modelValidationEntryList, restrictedGroupsForModelValidation);

+        }

+        else if (!isModelValidation(beanValidation))

+        {

+            processGroups(

+                    beanValidation, foundGroupsForPropertyValidation, restrictedGroupsForPropertyValidation);

+        }

+    }

+

+    private boolean isValidationPermitted(BeanValidation beanValidation)

+    {

+        ELHelper elHelper = ExtValUtils.getELHelper();

+

+        for (String condition : beanValidation.conditions())

+        {

+            if (elHelper.isELTermWellFormed(condition) &&

+                    elHelper.isELTermValid(FacesContext.getCurrentInstance(), condition))

+            {

+                if (Boolean.TRUE.equals(elHelper.getValueOfExpression(

+                        FacesContext.getCurrentInstance(), new ValueBindingExpression(condition))))

+                {

+                    return true;

+                }

+            }

+            else

+            {

+                if (this.logger.isErrorEnabled())

+                {

+                    this.logger.error("an invalid condition is used: " + condition);

+                }

+            }

+        }

+        return false;

+    }

+

+    private boolean isModelValidation(BeanValidation beanValidation)

+    {

+        return beanValidation.modelValidation().isActive();

+    }

+

+    private void addModelValidationEntry(BeanValidation beanValidation,

+                                         Object metaDataSourceObject,

+                                         List<ModelValidationEntry> modelValidationEntryList,

+                                         List<Class> restrictedGroupsForModelValidation)

+    {

+        ModelValidationEntry modelValidationEntry = new ModelValidationEntry();

+

+        modelValidationEntry.setGroups(Arrays.asList(beanValidation.useGroups()));

+        modelValidationEntry.setDisplayMessageInline(beanValidation.modelValidation().displayInline());

+        modelValidationEntry.setCustomMessage(beanValidation.modelValidation().message());

+        modelValidationEntry.setMetaDataSourceObject(metaDataSourceObject);

+

+        Object validationTarget;

+        for (String validationTargetExpression : beanValidation.modelValidation().validationTargets())

+        {

+            if (ModelValidation.DEFAULT.equals(validationTargetExpression))

+            {

+                continue;

+            }

+

+            validationTarget = tryToResolveValidationTargetExpression(validationTargetExpression);

+            if (validationTarget != null)

+            {

+                modelValidationEntry.addValidationTarget(validationTarget);

+            }

+        }

+

+        if (beanValidation.restrictGroups().length > 0)

+        {

+            restrictedGroupsForModelValidation.addAll(Arrays.asList(beanValidation.restrictGroups()));

+        }

+

+        if (modelValidationEntry.getValidationTargets().isEmpty())

+        {

+            modelValidationEntry.addValidationTarget(metaDataSourceObject);

+        }

+

+        modelValidationEntryList.add(modelValidationEntry);

+    }

+

+    private Object tryToResolveValidationTargetExpression(String validationTargetExpression)

+    {

+        ValueBindingExpression valueBindingExpression = new ValueBindingExpression(validationTargetExpression);

+        return ExtValUtils.getELHelper()

+                .getValueOfExpression(FacesContext.getCurrentInstance(), valueBindingExpression);

+    }

+

+    private void processGroups(BeanValidation beanValidation,

+                               List<Class> foundGroupsForPropertyValidation,

+                               List<Class> restrictedGroupsForPropertyValidation)

+    {

+        foundGroupsForPropertyValidation.addAll(Arrays.asList(beanValidation.useGroups()));

+

+        if (beanValidation.restrictGroups().length > 0)

+        {

+            restrictedGroupsForPropertyValidation.addAll(Arrays.asList(beanValidation.restrictGroups()));

+        }

+    }

+

+    String createLabeledMessage(String violationMessage, boolean isDetailMessage)

+    {

+        return this.labeledMessageInternals.createLabeledMessage(violationMessage, isDetailMessage);

+    }

+

+    FacesMessage.Severity calcSeverity(ConstraintViolation<?> violation)

+    {

+        for (Class<? extends Payload> payload : violation.getConstraintDescriptor().getPayload())

+        {

+            if (ExtValUtils.getValidationParameterClassFor(ViolationSeverity.Warn.class).isAssignableFrom(payload))

+            {

+                return FacesMessage.SEVERITY_WARN;

+            }

+            else if (ExtValUtils

+                    .getValidationParameterClassFor(ViolationSeverity.Info.class).isAssignableFrom(payload))

+            {

+                return FacesMessage.SEVERITY_INFO;

+            }

+            else if (ExtValUtils

+                    .getValidationParameterClassFor(ViolationSeverity.Fatal.class).isAssignableFrom(payload))

+            {

+                return FacesMessage.SEVERITY_FATAL;

+            }

+        }

+        return FacesMessage.SEVERITY_ERROR;

+    }

+

+    void processFacesMessage(FacesContext facesContext, UIComponent uiComponent,

+                             List<FacesMessageHolder> facesMessageHolderList, FacesMessage facesMessage)

+    {

+        FacesMessageHolder facesMessageHolder = new FacesMessageHolder(facesMessage);

+

+        facesMessageHolder.setClientId(uiComponent.getClientId(facesContext));

+

+        facesMessageHolderList.add(facesMessageHolder);

+    }

+

+    boolean executeAfterThrowingInterceptors(UIComponent uiComponent,

+                                             Object convertedObject,

+                                             ValidatorException validatorException)

+    {

+        return ExtValUtils.executeAfterThrowingInterceptors(

+                uiComponent,

+                null,

+                convertedObject,

+                validatorException,

+                null);

+    }

+

+    boolean isMessageTextUnchanged(

+            ValidatorException validatorException, String violationSummaryMessage, String violationDetailMessage)

+    {

+        return violationSummaryMessage.equals(validatorException.getFacesMessage().getSummary()) &&

+                violationDetailMessage.equals(validatorException.getFacesMessage().getDetail());

+    }

+

+    ValidatorException createValidatorException(

+            String violationSummaryMessage, String violationDetailMessage, FacesMessage.Severity severity)

+    {

+        return new ValidatorException(

+                ExtValUtils.createFacesMessage(severity, violationSummaryMessage, violationDetailMessage));

+    }

+

+    List<FacesMessageHolder> getFacesMessageListWithLowSeverity(

+            List<FacesMessageHolder> violationMessages)

+    {

+        List<FacesMessageHolder> result = new ArrayList<FacesMessageHolder>();

+

+        for (FacesMessageHolder facesMessageHolder : violationMessages)

+        {

+            if (FacesMessage.SEVERITY_WARN.equals(facesMessageHolder.getFacesMessage().getSeverity()) ||

+                    FacesMessage.SEVERITY_INFO.equals(facesMessageHolder.getFacesMessage().getSeverity()))

+            {

+                result.add(facesMessageHolder);

+            }

+        }

+        return result;

+    }

+

+    List<FacesMessageHolder> getFacesMessageListWithHighSeverity(

+            List<FacesMessageHolder> violationMessageHolderList)

+    {

+        List<FacesMessageHolder> result = new ArrayList<FacesMessageHolder>();

+

+        for (FacesMessageHolder facesMessageHolder : violationMessageHolderList)

+        {

+            if (FacesMessage.SEVERITY_ERROR.equals(facesMessageHolder.getFacesMessage().getSeverity()) ||

+                    FacesMessage.SEVERITY_FATAL.equals(facesMessageHolder.getFacesMessage().getSeverity()))

+            {

+                result.add(facesMessageHolder);

+            }

+        }

+        return result;

+    }

+

+    void addMessages(List<FacesMessageHolder> facesMessageHolderListWithLowSeverity)

+    {

+        for (FacesMessageHolder facesMessageHolder : facesMessageHolderListWithLowSeverity)

+        {

+            ExtValUtils.tryToAddViolationMessageForComponentId(

+                    facesMessageHolder.getClientId(), facesMessageHolder.getFacesMessage());

+        }

+    }

+}

diff --git a/2_0_3_prepare/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/util/LabeledMessageInternals.java b/2_0_3_prepare/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/util/LabeledMessageInternals.java
new file mode 100644
index 0000000..f40b783
--- /dev/null
+++ b/2_0_3_prepare/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/util/LabeledMessageInternals.java
@@ -0,0 +1,108 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.beanval.util;

+

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+import org.apache.myfaces.extensions.validator.util.JsfUtils;

+

+import java.util.MissingResourceException;

+

+/**

+ * @author Gerhard Petracek

+ * @since x.x.3

+ */

+@UsageInformation(UsageCategory.INTERNAL)

+class LabeledMessageInternals

+{

+    //there is no concurrency issue here - it always leads to the same result

+    private final String defaultSummaryMessageTemplate = "{1}: {0}";

+    private final String defaultDetailMessageTemplate = "{1}: {0}";

+    private String summaryMessageTemplate = defaultSummaryMessageTemplate;

+    private String detailMessageTemplate = defaultDetailMessageTemplate;

+    private static final String JAVAX_FACES_VALIDATOR_BEANVALIDATOR_MESSAGE =

+            "javax.faces.validator.BeanValidator.MESSAGE";

+    private static final String JAVAX_FACES_VALIDATOR_BEANVALIDATOR_MESSAGE_DETAIL =

+            "javax.faces.validator.BeanValidator.MESSAGE_detail";

+

+    String createLabeledMessage(String violationMessage, boolean isDetailMessage)

+    {

+        if(isDetailMessage)

+        {

+            return tryToResolveDetailMessage(violationMessage);

+        }

+        else

+        {

+            return tryToResolveSummaryMessage(violationMessage);

+        }

+    }

+

+    private String tryToResolveSummaryMessage(String violationMessage)

+    {

+        if(summaryMessageTemplate == null)

+        {

+            return this.defaultSummaryMessageTemplate.replace("{0}", violationMessage);

+        }

+

+        this.summaryMessageTemplate = loadStandardMessageTemplate(false);

+

+        if(summaryMessageTemplate == null)

+        {

+            return createLabeledMessage(violationMessage, false);

+        }

+        return summaryMessageTemplate.replace("{0}", violationMessage);

+    }

+

+    private String tryToResolveDetailMessage(String violationMessage)

+    {

+        if(detailMessageTemplate == null)

+        {

+            return this.defaultDetailMessageTemplate.replace("{0}", violationMessage);

+        }

+

+        this.detailMessageTemplate = loadStandardMessageTemplate(true);

+

+        if(detailMessageTemplate == null)

+        {

+            return createLabeledMessage(violationMessage, true);

+        }

+        return detailMessageTemplate.replace("{0}", violationMessage);

+    }

+

+    private String loadStandardMessageTemplate(boolean isDetailMessage)

+    {

+        try

+        {

+            if(isDetailMessage)

+            {

+                return JsfUtils.getMessageFromApplicationMessageBundle(

+                        JAVAX_FACES_VALIDATOR_BEANVALIDATOR_MESSAGE_DETAIL);

+            }

+            else

+            {

+                return JsfUtils.getMessageFromApplicationMessageBundle(

+                        JAVAX_FACES_VALIDATOR_BEANVALIDATOR_MESSAGE);

+            }

+        }

+        catch (MissingResourceException e)

+        {

+            return null;

+        }

+    }

+}

diff --git a/2_0_3_prepare/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/validation/ModelValidationPhaseListener.java b/2_0_3_prepare/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/validation/ModelValidationPhaseListener.java
new file mode 100644
index 0000000..0dc2895
--- /dev/null
+++ b/2_0_3_prepare/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/validation/ModelValidationPhaseListener.java
@@ -0,0 +1,479 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.beanval.validation;

+

+import org.apache.commons.logging.Log;

+import org.apache.commons.logging.LogFactory;

+import org.apache.myfaces.extensions.validator.beanval.BeanValidationModuleKey;

+import org.apache.myfaces.extensions.validator.beanval.ExtValBeanValidationContext;

+import org.apache.myfaces.extensions.validator.beanval.annotation.ModelValidation;

+import org.apache.myfaces.extensions.validator.beanval.storage.ModelValidationEntry;

+import org.apache.myfaces.extensions.validator.beanval.util.BeanValidationUtils;

+import org.apache.myfaces.extensions.validator.core.property.DefaultPropertyInformation;

+import org.apache.myfaces.extensions.validator.core.property.PropertyDetails;

+import org.apache.myfaces.extensions.validator.core.property.PropertyInformation;

+import org.apache.myfaces.extensions.validator.core.property.PropertyInformationKeys;

+import org.apache.myfaces.extensions.validator.core.validation.message.FacesMessageHolder;

+import org.apache.myfaces.extensions.validator.util.ExtValUtils;

+import org.apache.myfaces.extensions.validator.internal.ToDo;

+import org.apache.myfaces.extensions.validator.internal.Priority;

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+

+import javax.faces.component.UIComponent;

+import javax.faces.context.FacesContext;

+import javax.faces.event.PhaseEvent;

+import javax.faces.event.PhaseId;

+import javax.faces.event.PhaseListener;

+import javax.validation.ConstraintViolation;

+import javax.validation.MessageInterpolator;

+import javax.validation.Path;

+import javax.validation.ValidatorFactory;

+import javax.validation.metadata.ConstraintDescriptor;

+import java.util.Map;

+import java.util.HashMap;

+import java.util.ArrayList;

+import java.util.Iterator;

+import java.util.List;

+import java.util.Set;

+

+/**

+ * @author Gerhard Petracek

+ * @since x.x.3

+ */

+@ToDo(value = Priority.MEDIUM, description = "refactor implementation details")

+@UsageInformation(UsageCategory.INTERNAL)

+public class ModelValidationPhaseListener implements PhaseListener

+{

+    private static final long serialVersionUID = -3482233893186708878L;

+

+    protected final Log logger = LogFactory.getLog(getClass());

+

+    public void afterPhase(PhaseEvent phaseEvent)

+    {

+        if (logger.isTraceEnabled())

+        {

+            logger.trace("jsr303 start model validation");

+        }

+

+        Map<Object, List<Class>> processedValidationTargets = new HashMap<Object, List<Class>>();

+

+        Map<String, ModelValidationResult> results = new HashMap<String, ModelValidationResult>();

+

+        for (ModelValidationEntry modelValidationEntry : getModelValidationEntriesToValidate())

+        {

+            processModelValidation(modelValidationEntry, processedValidationTargets, results);

+        }

+

+        processModelValidationResults(results);

+

+        executeGlobalAfterValidationInterceptorsFor(results);

+

+        if (logger.isTraceEnabled())

+        {

+            logger.trace("jsr303 validation finished");

+        }

+    }

+

+    private List<ModelValidationEntry> getModelValidationEntriesToValidate()

+    {

+        return ExtValBeanValidationContext.getCurrentInstance().getModelValidationEntriesToValidate();

+    }

+

+    private void processModelValidation(ModelValidationEntry modelValidationEntry,

+                                        Map<Object, List<Class>> processedValidationTargets,

+                                        Map<String, ModelValidationResult> results)

+    {

+        FacesContext facesContext = FacesContext.getCurrentInstance();

+        PropertyInformation propertyInformation;

+        Set<ConstraintViolation<Object>> violations;

+        Class[] groupsToValidate;

+

+        for (Object validationTarget : modelValidationEntry.getValidationTargets())

+        {

+            propertyInformation = createPropertyInformation(modelValidationEntry, validationTarget);

+

+            if (!executeGlobalBeforeValidationInterceptors(

+                    facesContext, modelValidationEntry.getComponent(), validationTarget, propertyInformation))

+            {

+                continue;

+            }

+

+            if(modelValidationEntry.isDisplayMessageInline())

+            {

+                groupsToValidate = modelValidationEntry.getGroups();

+            }

+            //if violation should displayed inline validation has to take place with all groups

+            //which means: global messages -> filter groups already used for the validation target

+            else

+            {

+                groupsToValidate = filterGroupsToValidate(

+                        modelValidationEntry, validationTarget, processedValidationTargets);

+            }

+

+            if(!shouldContinueValidation(modelValidationEntry, groupsToValidate))

+            {

+                continue;

+            }

+

+            addProcessedTarget(validationTarget, groupsToValidate, processedValidationTargets);

+            violations = validateTarget(validationTarget, groupsToValidate);

+

+            if (violations != null && !violations.isEmpty())

+            {

+                processViolations(facesContext, modelValidationEntry, validationTarget, violations, results);

+            }

+        }

+    }

+

+    private Class[] filterGroupsToValidate(ModelValidationEntry modelValidationEntry,

+                                           Object validationTarget,

+                                           Map<Object, List<Class>> processedValidationTargets)

+    {

+        if(!processedValidationTargets.containsKey(validationTarget))

+        {

+            return modelValidationEntry.getGroups();

+        }

+

+        List<Class> result = new ArrayList<Class>();

+        List<Class> validatedGroups = processedValidationTargets.get(validationTarget);

+

+        for(Class group : modelValidationEntry.getGroups())

+        {

+            if(!validatedGroups.contains(group))

+            {

+                result.add(group);

+            }

+        }

+        return result.toArray(new Class[result.size()]);

+    }

+

+    private boolean shouldContinueValidation(ModelValidationEntry modelValidationEntry, Class[] groupsToValidate)

+    {

+        return !(groupsToValidate == null || groupsToValidate.length == 0) ||

+                modelValidationEntry.isDisplayMessageInline();

+    }

+

+    private void addProcessedTarget(Object validationTarget,

+                                    Class[] groups,

+                                    Map<Object, List<Class>> processedValidationTargets)

+    {

+        if(!processedValidationTargets.containsKey(validationTarget))

+        {

+            processedValidationTargets.put(validationTarget, new ArrayList<Class>());

+        }

+

+        List<Class> validatedGroups = processedValidationTargets.get(validationTarget);

+

+        for(Class group : groups)

+        {

+            if(!validatedGroups.contains(group))

+            {

+                validatedGroups.add(group);

+            }

+        }

+    }

+

+    private PropertyInformation createPropertyInformation(

+            ModelValidationEntry modelValidationEntry, Object validationTarget)

+    {

+        PropertyInformation propertyInformation;

+        PropertyDetails propertyDetails;

+        propertyInformation = new DefaultPropertyInformation();

+        if (modelValidationEntry.getComponent() != null)

+        {

+            propertyDetails = ExtValUtils.getELHelper()

+                    .getPropertyDetailsOfValueBinding(modelValidationEntry.getComponent());

+        }

+        else

+        {

+            propertyDetails = new PropertyDetails(null, validationTarget, null);

+        }

+        propertyInformation.setInformation(PropertyInformationKeys.PROPERTY_DETAILS, propertyDetails);

+        return propertyInformation;

+    }

+

+    private boolean executeGlobalBeforeValidationInterceptors(FacesContext facesContext,

+                                                              UIComponent uiComponent,

+                                                              Object validationTarget,

+                                                              PropertyInformation propertyInformation)

+    {

+        return ExtValUtils.executeGlobalBeforeValidationInterceptors(facesContext, uiComponent, validationTarget,

+                PropertyInformation.class.getName(), propertyInformation, BeanValidationModuleKey.class);

+    }

+

+    private void executeGlobalAfterValidationInterceptors(FacesContext facesContext,

+                                                          UIComponent uiComponent,

+                                                          Object validationTarget,

+                                                          PropertyInformation propertyInformation)

+    {

+        ExtValUtils.executeGlobalAfterValidationInterceptors(facesContext, uiComponent, validationTarget,

+                PropertyInformation.class.getName(), propertyInformation, BeanValidationModuleKey.class);

+    }

+

+    private Set<ConstraintViolation<Object>> validateTarget(Object validationTarget, Class[] groups)

+    {

+        if(groups == null || groups.length == 0)

+        {

+            return null;

+        }

+

+        ValidatorFactory validatorFactory = ExtValBeanValidationContext.getCurrentInstance().getValidatorFactory();

+        return validatorFactory

+                .usingContext()

+                .messageInterpolator(ExtValBeanValidationContext.getCurrentInstance().getMessageInterpolator())

+                .constraintValidatorFactory(validatorFactory.getConstraintValidatorFactory())

+                .traversableResolver(validatorFactory.getTraversableResolver())

+                .getValidator()

+                .validate(validationTarget, groups);

+    }

+

+    private void processViolations(FacesContext facesContext,

+                                   ModelValidationEntry modelValidationEntry,

+                                   Object validationTarget,

+                                   Set<ConstraintViolation<Object>> violations,

+                                   Map<String, ModelValidationResult> results)

+    {

+        //jsf 2.0 is able to display multiple messages per component - so process all violations

+        //jsf < 2.0 will just use the first one (for inline messages - so it's only a little overhead)

+        Iterator<ConstraintViolation<Object>> violationsIterator = violations.iterator();

+        ConstraintViolation<Object> constraintViolation;

+        ModelValidationResult result;

+        while (violationsIterator.hasNext())

+        {

+            tryToCreateModelValidationResult(facesContext, modelValidationEntry, results);

+

+            result = resolveModelValidationResult(facesContext, modelValidationEntry, results);

+

+            constraintViolation = violationsIterator.next();

+            addViolationMessage(modelValidationEntry, validationTarget, constraintViolation, result);

+        }

+    }

+

+    private void tryToCreateModelValidationResult(FacesContext facesContext,

+                                                  ModelValidationEntry modelValidationEntry,

+                                                  Map<String, ModelValidationResult> results)

+    {

+        ModelValidationResult result;

+        if (!isModelValidationResultAvailableFor(facesContext, modelValidationEntry, results))

+        {

+            result = new ModelValidationResult();

+            results.put(modelValidationEntry.getComponent().getClientId(facesContext), result);

+        }

+    }

+

+    private ModelValidationResult resolveModelValidationResult(FacesContext facesContext,

+                                                               ModelValidationEntry modelValidationEntry,

+                                                               Map<String, ModelValidationResult> results)

+    {

+        return results.get(modelValidationEntry.getComponent().getClientId(facesContext));

+    }

+

+    private boolean isModelValidationResultAvailableFor(FacesContext facesContext,

+                                                        ModelValidationEntry modelValidationEntry,

+                                                        Map<String, ModelValidationResult> results)

+    {

+        return results.containsKey(modelValidationEntry.getComponent().getClientId(facesContext));

+    }

+

+    private void addViolationMessage(ModelValidationEntry modelValidationEntry,

+                                     Object validationTarget,

+                                     ConstraintViolation<Object> constraintViolation,

+                                     ModelValidationResult result)

+    {

+        if (modelValidationEntry.isDisplayMessageInline())

+        {

+            result.addFacesMessageHolder(createFacesMessageHolderForConstraintViolation(

+                    constraintViolation, modelValidationEntry, validationTarget, true));

+        }

+        else

+        {

+            result.addFacesMessageHolder(createFacesMessageHolderForConstraintViolation(

+                    constraintViolation, modelValidationEntry, validationTarget, false));

+        }

+    }

+

+    private FacesMessageHolder createFacesMessageHolderForConstraintViolation(final ConstraintViolation violation,

+                                                                              ModelValidationEntry modelValidationEntry,

+                                                                              final Object validationTarget,

+                                                                              boolean displayAtComponent)

+    {

+        final String newViolationMessage = tryToChangeViolationMessage(

+                modelValidationEntry, validationTarget, violation);

+

+        ConstraintViolation newConstraintViolation = new ConstraintViolation()

+        {

+            private ConstraintViolation wrapped = violation;

+

+            public String getMessage()

+            {

+                return newViolationMessage;

+            }

+

+            public String getMessageTemplate()

+            {

+                return wrapped.getMessageTemplate();

+            }

+

+            public Object getRootBean()

+            {

+                return wrapped.getRootBean();

+            }

+

+            public Class getRootBeanClass()

+            {

+                return wrapped.getRootBeanClass();

+            }

+

+            public Object getLeafBean()

+            {

+                return wrapped.getLeafBean();

+            }

+

+            public Path getPropertyPath()

+            {

+                return wrapped.getPropertyPath();

+            }

+

+            public Object getInvalidValue()

+            {

+                return wrapped.getInvalidValue();

+            }

+

+            public ConstraintDescriptor getConstraintDescriptor()

+            {

+                return wrapped.getConstraintDescriptor();

+            }

+        };

+

+

+        UIComponent uiComponent = null;

+        String clientId = null;

+

+        if (displayAtComponent)

+        {

+            uiComponent = modelValidationEntry.getComponent();

+            clientId = uiComponent.getClientId(FacesContext.getCurrentInstance());

+        }

+

+        FacesMessageHolder result = new FacesMessageHolder(BeanValidationUtils

+                .createFacesMessageForConstraintViolation(uiComponent, validationTarget, newConstraintViolation));

+        result.setClientId(clientId);

+        return result;

+    }

+

+    private String tryToChangeViolationMessage(ModelValidationEntry modelValidationEntry,

+                                               Object validationTarget,

+                                               ConstraintViolation violation)

+    {

+        if (!isDefaultMessage(modelValidationEntry))

+        {

+            return interpolateValidationErrorMessage(

+                    modelValidationEntry.getCustomMessage(), validationTarget, violation);

+        }

+        return violation.getMessage();

+    }

+

+    private boolean isDefaultMessage(ModelValidationEntry modelValidationEntry)

+    {

+        return ModelValidation.DEFAULT.equals(modelValidationEntry.getCustomMessage());

+    }

+

+    private String interpolateValidationErrorMessage(String extValInlineMessage,

+                                                     final Object validationTarget, final ConstraintViolation violation)

+    {

+        return ExtValBeanValidationContext.getCurrentInstance().getMessageInterpolator()

+                .interpolate(

+                        extValInlineMessage,

+                        new MessageInterpolator.Context()

+                        {

+                            public ConstraintDescriptor<?> getConstraintDescriptor()

+                            {

+                                return violation.getConstraintDescriptor();

+                            }

+

+                            public Object getValidatedValue()

+                            {

+                                return validationTarget;

+                            }

+                        }

+                );

+    }

+

+    @ToDo(Priority.MEDIUM)

+    private void processModelValidationResults(Map<String, ModelValidationResult> results)

+    {

+        for (ModelValidationResult result : results.values())

+        {

+            BeanValidationUtils.processViolationMessages(result.getFacesMessageHolderList());

+        }

+    }

+

+    private void executeGlobalAfterValidationInterceptorsFor(Map<String, ModelValidationResult> results)

+    {

+        FacesContext facesContext = FacesContext.getCurrentInstance();

+        UIComponent component;

+        for (ModelValidationResult result : results.values())

+        {

+            for (FacesMessageHolder facesMessageHolder : result.getFacesMessageHolderList())

+            {

+                component = null;

+                if (facesMessageHolder.getClientId() != null && !facesMessageHolder.getClientId().equals("*"))

+                {

+                    component = facesContext.getViewRoot().findComponent(facesMessageHolder.getClientId());

+                }

+                executeGlobalAfterValidationInterceptors(facesContext, component, null, null);

+            }

+        }

+    }

+

+    public void beforePhase(PhaseEvent phaseEvent)

+    {

+        //do nothing

+    }

+

+    public PhaseId getPhaseId()

+    {

+        return PhaseId.UPDATE_MODEL_VALUES;

+    }

+

+    /*

+     * generated

+     */

+    @Override

+    public boolean equals(Object o)

+    {

+        if (this == o)

+        {

+            return true;

+        }

+        if (!(o instanceof ModelValidationPhaseListener))

+        {

+            return false;

+        }

+

+        return true;

+    }

+

+    @Override

+    public int hashCode()

+    {

+        return super.hashCode();

+    }

+}

diff --git a/2_0_3_prepare/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/validation/ModelValidationResult.java b/2_0_3_prepare/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/validation/ModelValidationResult.java
new file mode 100644
index 0000000..e3c198b
--- /dev/null
+++ b/2_0_3_prepare/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/validation/ModelValidationResult.java
@@ -0,0 +1,49 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.beanval.validation;

+

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+import org.apache.myfaces.extensions.validator.internal.ToDo;

+import org.apache.myfaces.extensions.validator.internal.Priority;

+import org.apache.myfaces.extensions.validator.core.validation.message.FacesMessageHolder;

+

+import java.util.List;

+import java.util.ArrayList;

+

+/**

+ * @author Gerhard Petracek

+ * @since x.x.3

+ */

+@ToDo(value = Priority.LOW, description = "refactor")

+@UsageInformation(UsageCategory.INTERNAL)

+class ModelValidationResult

+{

+    private List<FacesMessageHolder> facesMessageHolderList = new ArrayList<FacesMessageHolder>();

+

+    public void addFacesMessageHolder(FacesMessageHolder facesMessageHolder)

+    {

+        this.facesMessageHolderList.add(facesMessageHolder);

+    }

+

+    public List<FacesMessageHolder> getFacesMessageHolderList()

+    {

+        return facesMessageHolderList;

+    }

+}

diff --git a/2_0_3_prepare/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/validation/message/interpolator/DefaultMessageInterpolator.java b/2_0_3_prepare/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/validation/message/interpolator/DefaultMessageInterpolator.java
new file mode 100644
index 0000000..aa8392f
--- /dev/null
+++ b/2_0_3_prepare/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/validation/message/interpolator/DefaultMessageInterpolator.java
@@ -0,0 +1,60 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.beanval.validation.message.interpolator;

+

+import org.apache.commons.logging.Log;

+import org.apache.commons.logging.LogFactory;

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+

+import javax.validation.MessageInterpolator;

+import javax.faces.context.FacesContext;

+import java.util.Locale;

+

+/**

+ * @author Gerhard Petracek

+ * @since x.x.3

+ */

+@UsageInformation(UsageCategory.INTERNAL)

+public class DefaultMessageInterpolator implements MessageInterpolator

+{

+    protected final Log logger = LogFactory.getLog(getClass());

+    

+    private MessageInterpolator wrapped;

+

+    public DefaultMessageInterpolator(MessageInterpolator wrapped)

+    {

+        this.wrapped = wrapped;

+    }

+

+    public String interpolate(String messageOrKey, Context context)

+    {

+        return interpolate(messageOrKey, context, null);

+    }

+

+    public String interpolate(String messageOrKey, Context context, Locale locale)

+    {

+        return this.wrapped.interpolate(messageOrKey, context, getCurrentLocale());

+    }

+

+    protected Locale getCurrentLocale()

+    {

+        return FacesContext.getCurrentInstance().getViewRoot().getLocale();

+    }

+}

diff --git a/2_0_3_prepare/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/validation/message/interpolator/ExtValMessageInterpolatorAdapter.java b/2_0_3_prepare/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/validation/message/interpolator/ExtValMessageInterpolatorAdapter.java
new file mode 100644
index 0000000..46e9f33
--- /dev/null
+++ b/2_0_3_prepare/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/validation/message/interpolator/ExtValMessageInterpolatorAdapter.java
@@ -0,0 +1,91 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.beanval.validation.message.interpolator;

+

+import org.apache.myfaces.extensions.validator.core.validation.message.resolver.MessageResolver;

+import org.apache.myfaces.extensions.validator.core.validation.message.resolver.AbstractValidationErrorMessageResolver;

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+

+import javax.validation.MessageInterpolator;

+import java.util.Locale;

+

+/**

+ * @author Gerhard Petracek

+ * @since x.x.3

+ */

+@UsageInformation(UsageCategory.INTERNAL)

+public class ExtValMessageInterpolatorAdapter extends DefaultMessageInterpolator

+{

+    private MessageResolver messageResolver;

+

+    public ExtValMessageInterpolatorAdapter(MessageInterpolator wrapped, MessageResolver messageResolver)

+    {

+        super(wrapped);

+        this.messageResolver = messageResolver;

+    }

+

+    @Override

+    public String interpolate(String messageOrKey, Context context)

+    {

+        return interpolate(messageOrKey, context, getCurrentLocale());

+    }

+

+    @Override

+    public String interpolate(String messageOrKey, Context context, Locale locale)

+    {

+        if(this.messageResolver != null)

+        {

+            if(isBeanValidationMessageKeyFormat(messageOrKey))

+            {

+                String newMessageOrKey = this.messageResolver.getMessage(extractKey(messageOrKey), getCurrentLocale());

+

+                if(isValideMessage(newMessageOrKey))

+                {

+                    messageOrKey = newMessageOrKey;

+                }

+            }

+            else

+            {

+                if(this.logger.isTraceEnabled())

+                {

+                    this.logger.trace("you tried to use an extval message-resolver for" +

+                            "jsr303 validation with an invalid key -> using a default interpolator");

+                }

+            }

+        }

+        return super.interpolate(messageOrKey, context, getCurrentLocale());

+    }

+

+    private boolean isBeanValidationMessageKeyFormat(String messageOrKey)

+    {

+        return messageOrKey.startsWith("{") && messageOrKey.endsWith("}");

+    }

+

+    private String extractKey(String messageOrKey)

+    {

+        return messageOrKey.substring(1, messageOrKey.length() - 1);

+    }

+

+    private boolean isValideMessage(String newMessageOrKey)

+    {

+        return !(newMessageOrKey.startsWith(AbstractValidationErrorMessageResolver.MISSING_RESOURCE_MARKER) &&

+                        newMessageOrKey.endsWith(AbstractValidationErrorMessageResolver.MISSING_RESOURCE_MARKER));

+    }

+}

diff --git a/2_0_3_prepare/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/validation/strategy/BeanValidationVirtualValidationStrategy.java b/2_0_3_prepare/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/validation/strategy/BeanValidationVirtualValidationStrategy.java
new file mode 100644
index 0000000..1ddeef6
--- /dev/null
+++ b/2_0_3_prepare/validation-modules/bean-validation/src/main/java/org/apache/myfaces/extensions/validator/beanval/validation/strategy/BeanValidationVirtualValidationStrategy.java
@@ -0,0 +1,57 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.beanval.validation.strategy;

+

+import org.apache.myfaces.extensions.validator.core.validation.strategy.AbstractVirtualValidationStrategy;

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+

+import javax.validation.metadata.ConstraintDescriptor;

+

+/**

+ * @author Gerhard Petracek

+ * @since x.x.3

+ */

+@UsageInformation(UsageCategory.INTERNAL)

+public class BeanValidationVirtualValidationStrategy extends AbstractVirtualValidationStrategy

+{

+    private ConstraintDescriptor constraintDescriptor;

+    private Class elementClass; //property type

+

+    public BeanValidationVirtualValidationStrategy(ConstraintDescriptor constraintDescriptor, Class elementClass)

+    {

+        this.constraintDescriptor = constraintDescriptor;

+        this.elementClass = elementClass;

+    }

+

+    public ConstraintDescriptor getConstraintDescriptor()

+    {

+        return constraintDescriptor;

+    }

+

+    public Class getElementClass()

+    {

+        return elementClass;

+    }

+

+    public String getId()

+    {

+        return this.constraintDescriptor.getAnnotation().annotationType().getName();

+    }

+}

diff --git a/2_0_3_prepare/validation-modules/bean-validation/src/main/resources/LICENSE.txt b/2_0_3_prepare/validation-modules/bean-validation/src/main/resources/LICENSE.txt
new file mode 100644
index 0000000..c6055ec
--- /dev/null
+++ b/2_0_3_prepare/validation-modules/bean-validation/src/main/resources/LICENSE.txt
@@ -0,0 +1,174 @@
+                                 Apache License

+                           Version 2.0, January 2004

+                        http://www.apache.org/licenses/

+

+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

+

+   1. Definitions.

+

+      "License" shall mean the terms and conditions for use, reproduction,

+      and distribution as defined by Sections 1 through 9 of this document.

+

+      "Licensor" shall mean the copyright owner or entity authorized by

+      the copyright owner that is granting the License.

+

+      "Legal Entity" shall mean the union of the acting entity and all

+      other entities that control, are controlled by, or are under common

+      control with that entity. For the purposes of this definition,

+      "control" means (i) the power, direct or indirect, to cause the

+      direction or management of such entity, whether by contract or

+      otherwise, or (ii) ownership of fifty percent (50%) or more of the

+      outstanding shares, or (iii) beneficial ownership of such entity.

+

+      "You" (or "Your") shall mean an individual or Legal Entity

+      exercising permissions granted by this License.

+

+      "Source" form shall mean the preferred form for making modifications,

+      including but not limited to software source code, documentation

+      source, and configuration files.

+

+      "Object" form shall mean any form resulting from mechanical

+      transformation or translation of a Source form, including but

+      not limited to compiled object code, generated documentation,

+      and conversions to other media types.

+

+      "Work" shall mean the work of authorship, whether in Source or

+      Object form, made available under the License, as indicated by a

+      copyright notice that is included in or attached to the work

+      (an example is provided in the Appendix below).

+

+      "Derivative Works" shall mean any work, whether in Source or Object

+      form, that is based on (or derived from) the Work and for which the

+      editorial revisions, annotations, elaborations, or other modifications

+      represent, as a whole, an original work of authorship. For the purposes

+      of this License, Derivative Works shall not include works that remain

+      separable from, or merely link (or bind by name) to the interfaces of,

+      the Work and Derivative Works thereof.

+

+      "Contribution" shall mean any work of authorship, including

+      the original version of the Work and any modifications or additions

+      to that Work or Derivative Works thereof, that is intentionally

+      submitted to Licensor for inclusion in the Work by the copyright owner

+      or by an individual or Legal Entity authorized to submit on behalf of

+      the copyright owner. For the purposes of this definition, "submitted"

+      means any form of electronic, verbal, or written communication sent

+      to the Licensor or its representatives, including but not limited to

+      communication on electronic mailing lists, source code control systems,

+      and issue tracking systems that are managed by, or on behalf of, the

+      Licensor for the purpose of discussing and improving the Work, but

+      excluding communication that is conspicuously marked or otherwise

+      designated in writing by the copyright owner as "Not a Contribution."

+

+      "Contributor" shall mean Licensor and any individual or Legal Entity

+      on behalf of whom a Contribution has been received by Licensor and

+      subsequently incorporated within the Work.

+

+   2. Grant of Copyright License. Subject to the terms and conditions of

+      this License, each Contributor hereby grants to You a perpetual,

+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable

+      copyright license to reproduce, prepare Derivative Works of,

+      publicly display, publicly perform, sublicense, and distribute the

+      Work and such Derivative Works in Source or Object form.

+

+   3. Grant of Patent License. Subject to the terms and conditions of

+      this License, each Contributor hereby grants to You a perpetual,

+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable

+      (except as stated in this section) patent license to make, have made,

+      use, offer to sell, sell, import, and otherwise transfer the Work,

+      where such license applies only to those patent claims licensable

+      by such Contributor that are necessarily infringed by their

+      Contribution(s) alone or by combination of their Contribution(s)

+      with the Work to which such Contribution(s) was submitted. If You

+      institute patent litigation against any entity (including a

+      cross-claim or counterclaim in a lawsuit) alleging that the Work

+      or a Contribution incorporated within the Work constitutes direct

+      or contributory patent infringement, then any patent licenses

+      granted to You under this License for that Work shall terminate

+      as of the date such litigation is filed.

+

+   4. Redistribution. You may reproduce and distribute copies of the

+      Work or Derivative Works thereof in any medium, with or without

+      modifications, and in Source or Object form, provided that You

+      meet the following conditions:

+

+      (a) You must give any other recipients of the Work or

+          Derivative Works a copy of this License; and

+

+      (b) You must cause any modified files to carry prominent notices

+          stating that You changed the files; and

+

+      (c) You must retain, in the Source form of any Derivative Works

+          that You distribute, all copyright, patent, trademark, and

+          attribution notices from the Source form of the Work,

+          excluding those notices that do not pertain to any part of

+          the Derivative Works; and

+

+      (d) If the Work includes a "NOTICE" text file as part of its

+          distribution, then any Derivative Works that You distribute must

+          include a readable copy of the attribution notices contained

+          within such NOTICE file, excluding those notices that do not

+          pertain to any part of the Derivative Works, in at least one

+          of the following places: within a NOTICE text file distributed

+          as part of the Derivative Works; within the Source form or

+          documentation, if provided along with the Derivative Works; or,

+          within a display generated by the Derivative Works, if and

+          wherever such third-party notices normally appear. The contents

+          of the NOTICE file are for informational purposes only and

+          do not modify the License. You may add Your own attribution

+          notices within Derivative Works that You distribute, alongside

+          or as an addendum to the NOTICE text from the Work, provided

+          that such additional attribution notices cannot be construed

+          as modifying the License.

+

+      You may add Your own copyright statement to Your modifications and

+      may provide additional or different license terms and conditions

+      for use, reproduction, or distribution of Your modifications, or

+      for any such Derivative Works as a whole, provided Your use,

+      reproduction, and distribution of the Work otherwise complies with

+      the conditions stated in this License.

+

+   5. Submission of Contributions. Unless You explicitly state otherwise,

+      any Contribution intentionally submitted for inclusion in the Work

+      by You to the Licensor shall be under the terms and conditions of

+      this License, without any additional terms or conditions.

+      Notwithstanding the above, nothing herein shall supersede or modify

+      the terms of any separate license agreement you may have executed

+      with Licensor regarding such Contributions.

+

+   6. Trademarks. This License does not grant permission to use the trade

+      names, trademarks, service marks, or product names of the Licensor,

+      except as required for reasonable and customary use in describing the

+      origin of the Work and reproducing the content of the NOTICE file.

+

+   7. Disclaimer of Warranty. Unless required by applicable law or

+      agreed to in writing, Licensor provides the Work (and each

+      Contributor provides its Contributions) on an "AS IS" BASIS,

+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or

+      implied, including, without limitation, any warranties or conditions

+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A

+      PARTICULAR PURPOSE. You are solely responsible for determining the

+      appropriateness of using or redistributing the Work and assume any

+      risks associated with Your exercise of permissions under this License.

+

+   8. Limitation of Liability. In no event and under no legal theory,

+      whether in tort (including negligence), contract, or otherwise,

+      unless required by applicable law (such as deliberate and grossly

+      negligent acts) or agreed to in writing, shall any Contributor be

+      liable to You for damages, including any direct, indirect, special,

+      incidental, or consequential damages of any character arising as a

+      result of this License or out of the use or inability to use the

+      Work (including but not limited to damages for loss of goodwill,

+      work stoppage, computer failure or malfunction, or any and all

+      other commercial damages or losses), even if such Contributor

+      has been advised of the possibility of such damages.

+

+   9. Accepting Warranty or Additional Liability. While redistributing

+      the Work or Derivative Works thereof, You may choose to offer,

+      and charge a fee for, acceptance of support, warranty, indemnity,

+      or other liability obligations and/or rights consistent with this

+      License. However, in accepting such obligations, You may act only

+      on Your own behalf and on Your sole responsibility, not on behalf

+      of any other Contributor, and only if You agree to indemnify,

+      defend, and hold each Contributor harmless for any liability

+      incurred by, or claims asserted against, such Contributor by reason

+      of your accepting any such warranty or additional liability.

diff --git a/2_0_3_prepare/validation-modules/bean-validation/src/main/resources/NOTICE.txt b/2_0_3_prepare/validation-modules/bean-validation/src/main/resources/NOTICE.txt
new file mode 100644
index 0000000..4278ef3
--- /dev/null
+++ b/2_0_3_prepare/validation-modules/bean-validation/src/main/resources/NOTICE.txt
@@ -0,0 +1,9 @@
+Apache MyFaces Extensions Validator

+Copyright 2007-2008 The Apache Software Foundation

+

+This product includes software developed by

+The Apache Software Foundation (http://www.apache.org/).

+

+------------------------------------------------------------------------

+See the file LICENSE.txt

+------------------------------------------------------------------------
\ No newline at end of file
diff --git a/2_0_3_prepare/validation-modules/pom.xml b/2_0_3_prepare/validation-modules/pom.xml
new file mode 100644
index 0000000..6204a10
--- /dev/null
+++ b/2_0_3_prepare/validation-modules/pom.xml
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+    Licensed to the Apache Software Foundation (ASF) under one

+    or more contributor license agreements.  See the NOTICE file

+    distributed with this work for additional information

+    regarding copyright ownership.  The ASF licenses this file

+    to you under the Apache License, Version 2.0 (the

+    "License"); you may not use this file except in compliance

+    with the License.  You may obtain a copy of the License at

+

+    http://www.apache.org/licenses/LICENSE-2.0

+

+    Unless required by applicable law or agreed to in writing,

+    software distributed under the License is distributed on an

+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+    KIND, either express or implied.  See the License for the

+    specific language governing permissions and limitations

+    under the License.

+-->

+<project xmlns="http://maven.apache.org/POM/4.0.0"

+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">

+    <modelVersion>4.0.0</modelVersion>

+

+    <packaging>pom</packaging>

+

+    <groupId>org.apache.myfaces.extensions.validator.validation-modules</groupId>

+    <artifactId>validation-modules-project</artifactId>

+

+    <name>MyFaces Extensions-Validator Validation-Modules</name>

+    <version>2.0.3-SNAPSHOT</version>

+

+    <parent>

+        <groupId>org.apache.myfaces.extensions.validator</groupId>

+        <artifactId>myfaces-extval-parent</artifactId>

+        <version>2.0.3-SNAPSHOT</version>

+    </parent>

+

+    <scm>

+        <connection>scm:svn:http://svn.apache.org/repos/asf/myfaces/extensions/validator/branches/1_2_2_rc/validation-modules</connection>

+        <developerConnection>scm:svn:https://svn.apache.org/repos/asf/myfaces/extensions/validator/branches/1_2_2_rc/validation-modules</developerConnection>

+        <url>http://svn.apache.org/viewvc/myfaces/extensions/validator/branches/1_2_2_rc/validation-modules</url>

+    </scm>

+

+    <modules>

+        <module>property-validation</module>

+        <module>bean-validation</module>

+    </modules>

+

+    <dependencies>

+        <dependency>

+            <groupId>org.apache.myfaces.extensions.validator</groupId>

+            <artifactId>myfaces-extval-core</artifactId>

+            <version>2.0.3-SNAPSHOT</version>

+            <scope>compile</scope>

+        </dependency>

+    </dependencies>

+

+</project>

diff --git a/2_0_3_prepare/validation-modules/property-validation/pom.xml b/2_0_3_prepare/validation-modules/property-validation/pom.xml
new file mode 100644
index 0000000..a382b3f
--- /dev/null
+++ b/2_0_3_prepare/validation-modules/property-validation/pom.xml
@@ -0,0 +1,156 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!--

+    Licensed to the Apache Software Foundation (ASF) under one

+    or more contributor license agreements.  See the NOTICE file

+    distributed with this work for additional information

+    regarding copyright ownership.  The ASF licenses this file

+    to you under the Apache License, Version 2.0 (the

+    "License"); you may not use this file except in compliance

+    with the License.  You may obtain a copy of the License at

+

+    http://www.apache.org/licenses/LICENSE-2.0

+

+    Unless required by applicable law or agreed to in writing,

+    software distributed under the License is distributed on an

+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+    KIND, either express or implied.  See the License for the

+    specific language governing permissions and limitations

+    under the License.

+-->

+<project xmlns="http://maven.apache.org/POM/4.0.0"

+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">

+    <modelVersion>4.0.0</modelVersion>

+    <packaging>jar</packaging>

+

+    <groupId>org.apache.myfaces.extensions.validator.validation-modules</groupId>

+    <artifactId>myfaces-extval-property-validation</artifactId>

+

+    <name>MyFaces Extensions-Validator Property-Validation-Module</name>

+    <version>2.0.3-SNAPSHOT</version>

+

+    <parent>

+        <groupId>org.apache.myfaces.extensions.validator.validation-modules</groupId>

+        <artifactId>validation-modules-project</artifactId>

+        <version>2.0.3-SNAPSHOT</version>

+    </parent>

+

+    <dependencies>

+        <dependency>

+            <groupId>org.apache.myfaces.extensions.validator</groupId>

+            <artifactId>myfaces-extval-core</artifactId>

+            <version>2.0.3-SNAPSHOT</version>

+            <scope>compile</scope>

+        </dependency>

+        <dependency>

+            <groupId>javax.persistence</groupId>

+            <artifactId>persistence-api</artifactId>

+            <version>1.0</version>

+            <scope>compile</scope>

+        </dependency>

+        <dependency>

+            <groupId>javax.faces</groupId>

+            <artifactId>jsf-api</artifactId>

+            <version>2.0</version>

+            <scope>provided</scope>

+        </dependency>

+

+        <dependency>

+            <groupId>commons-logging</groupId>

+            <artifactId>commons-logging</artifactId>

+            <version>1.1.1</version>

+            <scope>compile</scope>

+        </dependency>

+        <dependency>

+            <groupId>javax.servlet</groupId>

+            <artifactId>servlet-api</artifactId>

+            <version>2.5</version>

+            <scope>test</scope>

+        </dependency>

+        <dependency>

+            <groupId>javax.servlet.jsp</groupId>

+            <artifactId>jsp-api</artifactId>

+            <version>2.1</version>

+            <scope>test</scope>

+        </dependency>

+        <dependency>

+            <groupId>org.apache.shale</groupId>

+            <artifactId>shale-test</artifactId>

+            <version>1.0.4</version>

+            <scope>test</scope>

+            <exclusions>

+                <exclusion>

+                    <groupId>org.apache.myfaces</groupId>

+                    <artifactId>myfaces-api</artifactId>

+                </exclusion>

+                <exclusion>

+                    <groupId>org.apache.myfaces</groupId>

+                    <artifactId>myfaces-impl</artifactId>

+                </exclusion>

+                <exclusion>

+                    <groupId>myfaces</groupId>

+                    <artifactId>myfaces-api</artifactId>

+                </exclusion>

+                <exclusion>

+                    <groupId>myfaces</groupId>

+                    <artifactId>myfaces-impl</artifactId>

+                </exclusion>

+            </exclusions>

+        </dependency>

+        

+    </dependencies>

+

+    <build>

+        <resources>

+            <resource>

+                <directory>src/main/config</directory>

+                <includes>

+                    <include>**/*xml</include>

+                </includes>

+                <targetPath>/META-INF</targetPath>

+            </resource>

+            <resource>

+                <directory>src/main/resources</directory>

+                <includes>

+                    <include>LICENSE.txt</include>

+                    <include>NOTICE.txt</include>

+                </includes>

+                <targetPath>/META-INF</targetPath>

+            </resource>

+            <resource>

+                <directory>src/main/java</directory>

+                <includes>

+                    <include>**/*properties</include>

+                </includes>

+            </resource>

+        </resources>

+        <plugins>

+            <plugin>

+                <inherited>true</inherited>

+                <groupId>org.apache.maven.plugins</groupId>

+                <artifactId>maven-source-plugin</artifactId>

+

+                <executions>

+                    <execution>

+                        <id>attach-sources</id>

+                        <goals>

+                            <goal>jar</goal>

+                        </goals>

+                    </execution>

+                </executions>

+            </plugin>

+            <plugin>

+                <artifactId>maven-surefire-plugin</artifactId>

+                <version>2.4.2</version>

+                <configuration>

+                    <excludes>

+                        <exclude>**/Abstract*.java</exclude>

+                        <exclude>**/TestUtils.java</exclude>

+                        <exclude>**/*Bean.java</exclude>

+                    </excludes>

+                </configuration>

+            </plugin>            

+        </plugins>

+    </build>

+

+</project>

diff --git a/2_0_3_prepare/validation-modules/property-validation/src/main/config/faces-config.xml b/2_0_3_prepare/validation-modules/property-validation/src/main/config/faces-config.xml
new file mode 100644
index 0000000..1c47d9b
--- /dev/null
+++ b/2_0_3_prepare/validation-modules/property-validation/src/main/config/faces-config.xml
@@ -0,0 +1,26 @@
+<!--

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+-->

+<faces-config xmlns="http://java.sun.com/xml/ns/javaee"

+              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

+              xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_1_2.xsd"

+              version="2.0">

+    <lifecycle>

+        <phase-listener>org.apache.myfaces.extensions.validator.PropertyValidationModuleStartupListener</phase-listener>

+    </lifecycle>

+</faces-config>
\ No newline at end of file
diff --git a/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/HtmlCoreComponentsComponentInitializer.java b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/HtmlCoreComponentsComponentInitializer.java
new file mode 100644
index 0000000..83785d6
--- /dev/null
+++ b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/HtmlCoreComponentsComponentInitializer.java
@@ -0,0 +1,58 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.myfaces.extensions.validator;
+
+import org.apache.myfaces.extensions.validator.core.initializer.component
+        .AbstractHtmlCoreComponentsComponentInitializer;
+import org.apache.myfaces.extensions.validator.core.metadata.CommonMetaDataKeys;
+import org.apache.myfaces.extensions.validator.core.InvocationOrder;
+import org.apache.myfaces.extensions.validator.internal.UsageInformation;
+import org.apache.myfaces.extensions.validator.internal.UsageCategory;
+
+import javax.faces.component.EditableValueHolder;
+import javax.faces.component.UIComponent;
+import javax.faces.context.FacesContext;
+import java.util.Map;
+
+/**
+ * @author Gerhard Petracek
+ * @since 1.x.1
+ */
+@InvocationOrder(200)
+@UsageInformation(UsageCategory.INTERNAL)
+public class HtmlCoreComponentsComponentInitializer extends AbstractHtmlCoreComponentsComponentInitializer
+{
+    protected void configureRequiredAttribute(FacesContext facesContext,
+                                              UIComponent uiComponent,
+                                              Map<String, Object> metaData)
+    {
+        if((Boolean.TRUE.equals(metaData.get(CommonMetaDataKeys.WEAK_REQUIRED)) ||
+             Boolean.TRUE.equals(metaData.get(CommonMetaDataKeys.REQUIRED)))
+            &&
+            Boolean.TRUE.equals(isComponentRequired(uiComponent)))
+        {
+            ((EditableValueHolder)uiComponent).setRequired(true);
+        }
+        else if(Boolean.TRUE.equals(metaData.get(CommonMetaDataKeys.SKIP_VALIDATION)) &&
+               !Boolean.TRUE.equals(metaData.get(CommonMetaDataKeys.REQUIRED)))
+        {
+            ((EditableValueHolder)uiComponent).setRequired(false);
+        }
+    }
+}
diff --git a/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/JoinValidationMetaDataStorageFilter.java b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/JoinValidationMetaDataStorageFilter.java
new file mode 100644
index 0000000..aa123cd
--- /dev/null
+++ b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/JoinValidationMetaDataStorageFilter.java
@@ -0,0 +1,210 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator;

+

+import org.apache.myfaces.extensions.validator.baseval.annotation.JoinValidation;

+import org.apache.myfaces.extensions.validator.core.metadata.MetaDataEntry;

+import org.apache.myfaces.extensions.validator.core.metadata.extractor.DefaultComponentMetaDataExtractor;

+import org.apache.myfaces.extensions.validator.core.property.DefaultPropertyInformation;

+import org.apache.myfaces.extensions.validator.core.property.PropertyDetails;

+import org.apache.myfaces.extensions.validator.core.property.PropertyInformation;

+import org.apache.myfaces.extensions.validator.core.property.PropertyInformationKeys;

+import org.apache.myfaces.extensions.validator.core.storage.MetaDataStorageFilter;

+import org.apache.myfaces.extensions.validator.util.ClassUtils;

+import org.apache.myfaces.extensions.validator.util.ExtValUtils;

+import org.apache.myfaces.extensions.validator.util.ProxyUtils;

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+

+import java.util.ArrayList;

+import java.util.Collections;

+import java.util.List;

+

+/**

+ * EXTVAL-59

+ *

+ * @author Gerhard Petracek

+ * @since x.x.3

+ */

+@UsageInformation(UsageCategory.INTERNAL)

+public class JoinValidationMetaDataStorageFilter implements MetaDataStorageFilter

+{

+    private static final String STATIC_SEPARATOR = ":";

+

+    public void filter(PropertyInformation propertyInformation)

+    {

+        if (propertyInformation != null)

+        {

+            List<MetaDataEntry> result = new ArrayList<MetaDataEntry>();

+

+            resolveJoinValidationMetaData(propertyInformation, result);

+

+            propertyInformation.resetMetaDataEntries();

+

+            setDefaultPropertyDetails(propertyInformation, result);

+

+            if (containsJoinValidationConstraint(result))

+            {

+                filter(propertyInformation);

+            }

+        }

+    }

+

+    private void resolveJoinValidationMetaData(PropertyInformation propertyInformation, List<MetaDataEntry> result)

+    {

+        for (MetaDataEntry metaDataEntry : propertyInformation.getMetaDataEntries())

+        {

+            result.addAll(tryToTransformEntry(metaDataEntry));

+        }

+    }

+

+    private void setDefaultPropertyDetails(PropertyInformation propertyInformation, List<MetaDataEntry> result)

+    {

+        for (MetaDataEntry metaDataEntry : result)

+        {

+            metaDataEntry.setProperty(PropertyInformationKeys.PROPERTY_DETAILS,

+                    propertyInformation.getInformation(PropertyInformationKeys.PROPERTY_DETAILS));

+            propertyInformation.addMetaDataEntry(metaDataEntry);

+        }

+    }

+

+    private boolean containsJoinValidationConstraint(List<MetaDataEntry> result)

+    {

+        for (MetaDataEntry entry : result)

+        {

+            if (entry.getValue() instanceof JoinValidation)

+            {

+                return true;

+            }

+        }

+

+        return false;

+    }

+

+    private List<MetaDataEntry> tryToTransformEntry(MetaDataEntry metaDataEntry)

+    {

+        List<MetaDataEntry> result = new ArrayList<MetaDataEntry>();

+

+        if (metaDataEntry.getValue() instanceof JoinValidation)

+        {

+            JoinValidation annotation = metaDataEntry.getValue(JoinValidation.class);

+

+            replaceMetaData(annotation, metaDataEntry, result);

+        }

+        else

+        {

+            result.add(metaDataEntry);

+        }

+

+        return result;

+    }

+

+    private void replaceMetaData(JoinValidation annotation, MetaDataEntry metaDataEntry, List<MetaDataEntry> result)

+    {

+        for (String target : annotation.value())

+        {

+            tryToReplaceMetaDataOfTarget(target, metaDataEntry, result);

+        }

+    }

+

+    private void tryToReplaceMetaDataOfTarget(String target, MetaDataEntry metaDataEntry, List<MetaDataEntry> result)

+    {

+        try

+        {

+            if (isStaticSyntax(target))

+            {

+                addMetaData(result, extractStaticMetaData(target));

+            }

+            else

+            {

+                addMetaData(result, extractDynamicMetaData(metaDataEntry, target));

+            }

+        }

+        catch (Throwable t)

+        {

+            //do nothing a different filter might introduce a new syntax which causes the exception

+        }

+    }

+

+    private void addMetaData(List<MetaDataEntry> result, MetaDataEntry[] metaDataEntries)

+    {

+        Collections.addAll(result, metaDataEntries);

+    }

+

+    private boolean isStaticSyntax(String target)

+    {

+        return target.contains(STATIC_SEPARATOR);

+    }

+

+    private MetaDataEntry[] extractStaticMetaData(String target)

+    {

+        int separatorIndex = target.lastIndexOf(STATIC_SEPARATOR);

+

+        Class targetClass = loadClass(target.substring(0, separatorIndex));

+        String propertyName = target.substring(separatorIndex + 1);

+

+        return new StaticSyntaxMetaDataExtractor().extract(targetClass, propertyName).getMetaDataEntries();

+    }

+

+    private Class loadClass(String className)

+    {

+        try

+        {

+            return ClassUtils.loadClassForName(className);

+        }

+        catch (ClassNotFoundException e)

+        {

+            throw new IllegalArgumentException(e);

+        }

+    }

+

+    private MetaDataEntry[] extractDynamicMetaData(MetaDataEntry metaDataEntry, String target)

+    {

+        PropertyDetails propertyDetails = ExtValUtils.createPropertyDetailsForNewTarget(metaDataEntry, target);

+

+        Class targetClass = ProxyUtils.getUnproxiedClass(propertyDetails.getBaseObject().getClass());

+        return new StaticSyntaxMetaDataExtractor().extract(

+                targetClass, propertyDetails.getProperty()).getMetaDataEntries();

+    }

+

+    private class StaticSyntaxMetaDataExtractor extends DefaultComponentMetaDataExtractor

+    {

+        public PropertyInformation extract(Class targetClass, String targetProperty)

+        {

+            PropertyInformation propertyInformation = new DefaultPropertyInformation();

+

+            addPropertyAccessAnnotations(targetClass, targetProperty, propertyInformation);

+            addFieldAccessAnnotations(targetClass, targetProperty, propertyInformation);

+

+            return propertyInformation;

+        }

+    }

+

+    @Override

+    public boolean equals(Object obj)

+    {

+        return obj != null && getClass().equals(obj.getClass());

+    }

+

+    @Override

+    public int hashCode()

+    {

+        return super.hashCode();

+    }

+}

diff --git a/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/PropertyValidationGroupStorageNameMapper.java b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/PropertyValidationGroupStorageNameMapper.java
new file mode 100644
index 0000000..240cde0
--- /dev/null
+++ b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/PropertyValidationGroupStorageNameMapper.java
@@ -0,0 +1,43 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator;

+

+import org.apache.myfaces.extensions.validator.core.mapper.NameMapper;

+import org.apache.myfaces.extensions.validator.core.storage.DefaultGroupStorage;

+import org.apache.myfaces.extensions.validator.core.validation.parameter.ValidationParameter;

+import org.apache.myfaces.extensions.validator.core.InvocationOrder;

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import static org.apache.myfaces.extensions.validator.internal.UsageCategory.INTERNAL;

+

+/**

+ * name mapper for group implementations via validation parameters

+ *

+ * @author Gerhard Petracek

+ * @since x.x.3

+ */

+@InvocationOrder(200)

+@UsageInformation(INTERNAL)

+public class PropertyValidationGroupStorageNameMapper implements NameMapper<String>

+{

+    public String createName(String source)

+    {

+        return (ValidationParameter.class.getName().equals(source)) ?

+                DefaultGroupStorage.class.getName() : null;

+    }

+}

diff --git a/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/PropertyValidationModuleKey.java b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/PropertyValidationModuleKey.java
new file mode 100644
index 0000000..4b74843
--- /dev/null
+++ b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/PropertyValidationModuleKey.java
@@ -0,0 +1,33 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator;

+

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+import org.apache.myfaces.extensions.validator.core.ValidationModuleKey;

+

+/**

+ * @author Gerhard Petracek

+ * @since x.x.3

+ */

+@ValidationModuleKey

+@UsageInformation(UsageCategory.API)

+public interface PropertyValidationModuleKey

+{

+}

diff --git a/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/PropertyValidationModuleStartupListener.java b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/PropertyValidationModuleStartupListener.java
new file mode 100644
index 0000000..d8e0f8d
--- /dev/null
+++ b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/PropertyValidationModuleStartupListener.java
@@ -0,0 +1,164 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator;

+

+import org.apache.myfaces.extensions.validator.baseval.WebXmlParameter;

+import org.apache.myfaces.extensions.validator.baseval.annotation.SkipValidationSupport;

+import org.apache.myfaces.extensions.validator.core.startup.AbstractStartupListener;

+import org.apache.myfaces.extensions.validator.core.ExtValContext;

+import org.apache.myfaces.extensions.validator.core.factory.FactoryNames;

+import org.apache.myfaces.extensions.validator.core.factory.AbstractNameMapperAwareFactory;

+import org.apache.myfaces.extensions.validator.core.storage.StorageManagerHolder;

+import org.apache.myfaces.extensions.validator.core.storage.StorageManager;

+import org.apache.myfaces.extensions.validator.core.storage.GroupStorage;

+import org.apache.myfaces.extensions.validator.core.storage.MetaDataStorage;

+import org.apache.myfaces.extensions.validator.core.metadata.CommonMetaDataKeys;

+import org.apache.myfaces.extensions.validator.core.interceptor.ValidationInterceptor;

+import org.apache.myfaces.extensions.validator.core.initializer.configuration.StaticResourceBundleConfiguration;

+import org.apache.myfaces.extensions.validator.core.initializer.configuration.StaticConfiguration;

+import org.apache.myfaces.extensions.validator.core.initializer.configuration.StaticConfigurationNames;

+import org.apache.myfaces.extensions.validator.core.initializer.configuration.StaticInMemoryConfiguration;

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+import org.apache.myfaces.extensions.validator.crossval.recorder.CrossValidationUserInputRecorder;

+import org.apache.myfaces.extensions.validator.crossval.storage.CrossValidationStorage;

+import org.apache.myfaces.extensions.validator.crossval.storage.DefaultCrossValidationStorageManager;

+import org.apache.myfaces.extensions.validator.crossval.storage.DefaultProcessedInformationStorageManager;

+import org.apache.myfaces.extensions.validator.crossval.storage.ProcessedInformationStorage;

+import org.apache.myfaces.extensions.validator.crossval.storage.mapper.CrossValidationStorageNameMapper;

+import org.apache.myfaces.extensions.validator.crossval.storage.mapper.ProcessedInformationStorageNameMapper;

+import org.apache.myfaces.extensions.validator.crossval.CrossValidationPhaseListener;

+import org.apache.myfaces.extensions.validator.util.ExtValUtils;

+import org.apache.myfaces.extensions.validator.util.JsfUtils;

+

+/**

+ * @author Gerhard Petracek

+ * @since 1.x.1

+ */

+@UsageInformation(UsageCategory.INTERNAL)

+public class PropertyValidationModuleStartupListener extends AbstractStartupListener

+{

+    private static final long serialVersionUID = -2474361612857222283L;

+

+    protected void init()

+    {

+        initProcessedInformationRecorders();

+        initStaticStrategyMappings();

+        initDefaultComponentInitializer();

+        addSkipValidationSupport();

+        initStorageManagerAndNameMappers();

+        initSkipValidationEvaluator();

+        initMetaDataStorageFilters();

+        initPhaseListeners();

+    }

+

+    private void initProcessedInformationRecorders()

+    {

+        ExtValContext.getContext().addProcessedInformationRecorder(new CrossValidationUserInputRecorder());

+    }

+

+    private void initStaticStrategyMappings()

+    {

+        String jpaBasedValidation = WebXmlParameter.DEACTIVATE_JPA_BASED_VALIDATION;

+        if (jpaBasedValidation == null

+                || !jpaBasedValidation.equalsIgnoreCase("true"))

+        {

+            StaticConfiguration<String, String> staticConfig = new StaticResourceBundleConfiguration();

+            staticConfig.setSourceOfMapping(

+                ExtValInformation.EXTENSIONS_VALIDATOR_BASE_PACKAGE_NAME +".jpa_strategy_mappings");

+

+            ExtValContext.getContext().addStaticConfiguration(

+             StaticConfigurationNames.META_DATA_TO_VALIDATION_STRATEGY_CONFIG, staticConfig);

+        }

+    }

+

+    private void initDefaultComponentInitializer()

+    {

+        ExtValContext.getContext().addComponentInitializer(new HtmlCoreComponentsComponentInitializer());

+    }

+

+    private void addSkipValidationSupport()

+    {

+        if(logger.isInfoEnabled())

+        {

+            logger.info("adding support for @SkipValidation");

+        }

+

+        ExtValContext.getContext().denyRendererInterceptor(ValidationInterceptor.class);

+        ExtValContext.getContext().registerRendererInterceptor(new PropertyValidationModuleValidationInterceptor());

+

+        StaticInMemoryConfiguration config = new StaticInMemoryConfiguration();

+        //it's just required to set the target

+        config.addMapping(CommonMetaDataKeys.SKIP_VALIDATION, SkipValidationSupport.class.getName());

+

+        ExtValContext.getContext()

+                .addStaticConfiguration(StaticConfigurationNames.SKIP_VALIDATION_SUPPORT_CONFIG, config);

+

+        //config.addMapping(CommonMetaDataKeys.SKIP_VALIDATION, RequiredStrategy.class.getName());

+    }

+

+    @SuppressWarnings({"unchecked"})

+    private void initStorageManagerAndNameMappers()

+    {

+        StorageManagerHolder storageManagerHolder =

+                (ExtValContext.getContext()

+                .getFactoryFinder()

+                .getFactory(FactoryNames.STORAGE_MANAGER_FACTORY, StorageManagerHolder.class));

+

+        //processed-information

+        DefaultProcessedInformationStorageManager processedInfoStorageManager =

+                new DefaultProcessedInformationStorageManager();

+        processedInfoStorageManager.register(new ProcessedInformationStorageNameMapper());

+        storageManagerHolder.setStorageManager(ProcessedInformationStorage.class, processedInfoStorageManager, false);

+

+        //cross-validation

+        DefaultCrossValidationStorageManager crossValidationStorageManager =

+                new DefaultCrossValidationStorageManager();

+        crossValidationStorageManager.register(new CrossValidationStorageNameMapper());

+        storageManagerHolder.setStorageManager(CrossValidationStorage.class, crossValidationStorageManager, false);

+

+        //group-validation light

+        StorageManager storageManager = storageManagerHolder.getStorageManager(GroupStorage.class);

+

+        if(storageManager instanceof AbstractNameMapperAwareFactory)

+        {

+            ((AbstractNameMapperAwareFactory<String>)storageManager)

+                    .register(new PropertyValidationGroupStorageNameMapper());

+        }

+    }

+

+    private void initSkipValidationEvaluator()

+    {

+        ExtValContext.getContext().setSkipValidationEvaluator(new PropertyValidationSkipValidationEvaluator(), false);

+    }

+

+    private void initMetaDataStorageFilters()

+    {

+         MetaDataStorage metaDataStorage = ExtValUtils.getStorage(

+                 MetaDataStorage.class, MetaDataStorage.class.getName());

+

+        metaDataStorage.registerFilter(new JoinValidationMetaDataStorageFilter());

+        //metaDataStorage.registerFilter(new CompositeMetaDataStorageFilter());

+    }

+

+    private void initPhaseListeners()

+    {

+        JsfUtils.registerPhaseListener(new CrossValidationPhaseListener());

+    }

+}

diff --git a/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/PropertyValidationModuleValidationInterceptor.java b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/PropertyValidationModuleValidationInterceptor.java
new file mode 100644
index 0000000..78c4526
--- /dev/null
+++ b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/PropertyValidationModuleValidationInterceptor.java
@@ -0,0 +1,44 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.myfaces.extensions.validator;
+
+import org.apache.myfaces.extensions.validator.internal.UsageCategory;
+import org.apache.myfaces.extensions.validator.internal.UsageInformation;
+import org.apache.myfaces.extensions.validator.internal.ToDo;
+import org.apache.myfaces.extensions.validator.internal.Priority;
+import org.apache.myfaces.extensions.validator.core.interceptor.ValidationInterceptor;
+
+/**
+ * the skip validation support was refactored to an independent mechanism
+ * see SkipValidationEvaluator
+ *
+ * @author Gerhard Petracek
+ * @since 1.x.1
+ */
+@UsageInformation(UsageCategory.INTERNAL)
+@ToDo(value = Priority.MEDIUM, description = "change the add-ons" +
+        "old name: ValidationInterceptorWithSkipValidationSupport")
+public class PropertyValidationModuleValidationInterceptor extends ValidationInterceptor
+{
+    @Override
+    protected Class getModuleKey()
+    {
+        return PropertyValidationModuleKey.class;
+    }
+}
diff --git a/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/PropertyValidationSkipValidationEvaluator.java b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/PropertyValidationSkipValidationEvaluator.java
new file mode 100644
index 0000000..75a6adc
--- /dev/null
+++ b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/PropertyValidationSkipValidationEvaluator.java
@@ -0,0 +1,63 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.myfaces.extensions.validator;
+
+import org.apache.myfaces.extensions.validator.internal.UsageCategory;
+import org.apache.myfaces.extensions.validator.internal.UsageInformation;
+import org.apache.myfaces.extensions.validator.core.validation.strategy.ValidationStrategy;
+import org.apache.myfaces.extensions.validator.core.validation.SkipValidationEvaluator;
+import org.apache.myfaces.extensions.validator.core.metadata.MetaDataEntry;
+import org.apache.myfaces.extensions.validator.core.metadata.CommonMetaDataKeys;
+import org.apache.myfaces.extensions.validator.util.PropertyValidationUtils;
+import org.apache.myfaces.extensions.validator.util.JsfUtils;
+
+import javax.faces.context.FacesContext;
+import javax.faces.component.UIComponent;
+import java.util.List;
+
+/**
+ * @author Gerhard Petracek
+ * @since x.x.3
+ */
+@UsageInformation(UsageCategory.INTERNAL)
+public class PropertyValidationSkipValidationEvaluator implements SkipValidationEvaluator
+{
+    public boolean skipValidation(FacesContext facesContext,
+                                     UIComponent uiComponent,
+                                     ValidationStrategy validationStrategy,
+                                     MetaDataEntry metaDataEntry)
+    {
+        boolean result = false;
+        
+        if(JsfUtils.isRenderResponsePhase())
+        {
+            result = !isClientSideValidationEnabled(metaDataEntry);
+        }
+        return result || PropertyValidationUtils.isValidationSkipped(facesContext, validationStrategy, metaDataEntry);
+    }
+
+    @SuppressWarnings({"unchecked"})
+    private boolean isClientSideValidationEnabled(MetaDataEntry entry)
+    {
+        List<String> keysToDisable = entry.getProperty(
+                                CommonMetaDataKeys.DISABLE_CLIENT_SIDE_VALIDATION, List.class);
+
+        return keysToDisable == null || !keysToDisable.contains(entry.getKey());
+    }
+}
\ No newline at end of file
diff --git a/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/baseval/WebXmlParameter.java b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/baseval/WebXmlParameter.java
new file mode 100644
index 0000000..b777a4e
--- /dev/null
+++ b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/baseval/WebXmlParameter.java
@@ -0,0 +1,41 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.baseval;

+

+import org.apache.myfaces.extensions.validator.util.WebXmlUtils;

+import org.apache.myfaces.extensions.validator.internal.ToDo;

+import org.apache.myfaces.extensions.validator.internal.Priority;

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+

+/**

+ * centralized in order that these information arn't spread over the complete code base

+ *

+ * @author Gerhard Petracek

+ * @since 1.x.1

+ */

+@ToDo(value = Priority.MEDIUM, description = "documentation")

+@UsageInformation(UsageCategory.INTERNAL)

+public interface WebXmlParameter

+{

+    static final String VALIDATION_MESSAGES_JPA = WebXmlUtils

+            .getInitParameter("JPA_VALIDATION_ERROR_MESSAGES");

+    static final String DEACTIVATE_JPA_BASED_VALIDATION = WebXmlUtils

+            .getInitParameter("DEACTIVATE_JPA_BASED_VALIDATION");

+}
\ No newline at end of file
diff --git a/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/baseval/annotation/DoubleRange.java b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/baseval/annotation/DoubleRange.java
new file mode 100644
index 0000000..cb4e02f
--- /dev/null
+++ b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/baseval/annotation/DoubleRange.java
@@ -0,0 +1,48 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.baseval.annotation;

+

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+import org.apache.myfaces.extensions.validator.core.validation.parameter.ValidationParameter;

+import org.apache.myfaces.extensions.validator.core.validation.parameter.ViolationSeverity;

+

+import static java.lang.annotation.ElementType.FIELD;

+import static java.lang.annotation.ElementType.METHOD;

+import java.lang.annotation.Retention;

+import static java.lang.annotation.RetentionPolicy.RUNTIME;

+import java.lang.annotation.Target;

+import java.lang.annotation.Documented;

+

+/**

+ * @author Gerhard Petracek

+ * @since 1.x.1

+ */

+@Target({METHOD, FIELD})

+@Retention(RUNTIME)

+@Documented

+@UsageInformation(UsageCategory.API)

+public @interface DoubleRange

+{

+    double minimum() default Double.MIN_VALUE;

+

+    double maximum() default Double.MAX_VALUE;

+

+    Class<? extends ValidationParameter>[] parameters() default ViolationSeverity.Error.class;

+}
\ No newline at end of file
diff --git a/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/baseval/annotation/JoinValidation.java b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/baseval/annotation/JoinValidation.java
new file mode 100644
index 0000000..ac9a899
--- /dev/null
+++ b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/baseval/annotation/JoinValidation.java
@@ -0,0 +1,42 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.baseval.annotation;

+

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+

+import static java.lang.annotation.ElementType.FIELD;

+import static java.lang.annotation.ElementType.METHOD;

+import java.lang.annotation.Retention;

+import static java.lang.annotation.RetentionPolicy.RUNTIME;

+import java.lang.annotation.Target;

+import java.lang.annotation.Documented;

+

+/**

+ * @author Gerhard Petracek

+ * @since 1.x.1

+ */

+@Target({METHOD, FIELD})

+@Retention(RUNTIME)

+@Documented

+@UsageInformation(UsageCategory.API)

+public @interface JoinValidation

+{

+    String[] value();

+}

diff --git a/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/baseval/annotation/Length.java b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/baseval/annotation/Length.java
new file mode 100644
index 0000000..2c437d1
--- /dev/null
+++ b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/baseval/annotation/Length.java
@@ -0,0 +1,48 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.baseval.annotation;

+

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+import org.apache.myfaces.extensions.validator.core.validation.parameter.ValidationParameter;

+import org.apache.myfaces.extensions.validator.core.validation.parameter.ViolationSeverity;

+

+import static java.lang.annotation.ElementType.FIELD;

+import static java.lang.annotation.ElementType.METHOD;

+import java.lang.annotation.Retention;

+import static java.lang.annotation.RetentionPolicy.RUNTIME;

+import java.lang.annotation.Target;

+import java.lang.annotation.Documented;

+

+/**

+ * @author Gerhard Petracek

+ * @since 1.x.1

+ */

+@Target({METHOD, FIELD})

+@Retention(RUNTIME)

+@Documented

+@UsageInformation(UsageCategory.API)

+public @interface Length

+{

+    int minimum() default 0;

+

+    int maximum() default Integer.MAX_VALUE;

+

+    Class<? extends ValidationParameter>[] parameters() default ViolationSeverity.Error.class;

+}
\ No newline at end of file
diff --git a/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/baseval/annotation/LongRange.java b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/baseval/annotation/LongRange.java
new file mode 100644
index 0000000..f4251ef
--- /dev/null
+++ b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/baseval/annotation/LongRange.java
@@ -0,0 +1,48 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.baseval.annotation;

+

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+import org.apache.myfaces.extensions.validator.core.validation.parameter.ValidationParameter;

+import org.apache.myfaces.extensions.validator.core.validation.parameter.ViolationSeverity;

+

+import static java.lang.annotation.ElementType.FIELD;

+import static java.lang.annotation.ElementType.METHOD;

+import java.lang.annotation.Retention;

+import static java.lang.annotation.RetentionPolicy.RUNTIME;

+import java.lang.annotation.Target;

+import java.lang.annotation.Documented;

+

+/**

+ * @author Gerhard Petracek

+ * @since 1.x.1

+ */

+@Target({METHOD, FIELD})

+@Retention(RUNTIME)

+@Documented

+@UsageInformation(UsageCategory.API)

+public @interface LongRange

+{

+    long minimum() default Long.MIN_VALUE;

+

+    long maximum() default Long.MAX_VALUE;

+

+    Class<? extends ValidationParameter>[] parameters() default ViolationSeverity.Error.class;

+}
\ No newline at end of file
diff --git a/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/baseval/annotation/Pattern.java b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/baseval/annotation/Pattern.java
new file mode 100644
index 0000000..e775d89
--- /dev/null
+++ b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/baseval/annotation/Pattern.java
@@ -0,0 +1,48 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.baseval.annotation;

+

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+import org.apache.myfaces.extensions.validator.core.validation.parameter.ValidationParameter;

+import org.apache.myfaces.extensions.validator.core.validation.parameter.ViolationSeverity;

+

+import static java.lang.annotation.ElementType.FIELD;

+import static java.lang.annotation.ElementType.METHOD;

+import java.lang.annotation.Retention;

+import static java.lang.annotation.RetentionPolicy.RUNTIME;

+import java.lang.annotation.Target;

+import java.lang.annotation.Documented;

+

+/**

+ * @author Gerhard Petracek

+ * @since 1.x.1

+ */

+@Target({METHOD, FIELD})

+@Retention(RUNTIME)

+@Documented

+@UsageInformation(UsageCategory.API)

+public @interface Pattern

+{

+    String[] value();

+

+    String validationErrorMsgKey() default "no_match";

+

+    Class<? extends ValidationParameter>[] parameters() default ViolationSeverity.Error.class;

+}
\ No newline at end of file
diff --git a/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/baseval/annotation/Required.java b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/baseval/annotation/Required.java
new file mode 100644
index 0000000..11ce128
--- /dev/null
+++ b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/baseval/annotation/Required.java
@@ -0,0 +1,52 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.baseval.annotation;

+

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+import org.apache.myfaces.extensions.validator.core.validation.parameter.ValidationParameter;

+import org.apache.myfaces.extensions.validator.core.validation.parameter.ViolationSeverity;

+

+import static java.lang.annotation.ElementType.FIELD;

+import static java.lang.annotation.ElementType.METHOD;

+import java.lang.annotation.Retention;

+import static java.lang.annotation.RetentionPolicy.RUNTIME;

+import java.lang.annotation.Target;

+import java.lang.annotation.Documented;

+

+/**

+ * @author Gerhard Petracek

+ * @since 1.x.1

+ */

+@Target({METHOD, FIELD})

+@Retention(RUNTIME)

+@Documented

+@UsageInformation(UsageCategory.API)

+public @interface Required

+{

+    /**

+     * to customize the error message or

+     * to override the default jsf required message with the usage of the message resolver mechanism

+     *

+     * @return an optional error message key

+     */

+    String validationErrorMsgKey() default "field_required";

+

+    Class<? extends ValidationParameter>[] parameters() default ViolationSeverity.Error.class;

+}

diff --git a/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/baseval/annotation/SkipValidation.java b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/baseval/annotation/SkipValidation.java
new file mode 100644
index 0000000..02c529b
--- /dev/null
+++ b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/baseval/annotation/SkipValidation.java
@@ -0,0 +1,45 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.baseval.annotation;

+

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+import org.apache.myfaces.extensions.validator.core.validation.parameter.ValidationParameter;

+

+import static java.lang.annotation.ElementType.FIELD;

+import static java.lang.annotation.ElementType.METHOD;

+import java.lang.annotation.Retention;

+import static java.lang.annotation.RetentionPolicy.RUNTIME;

+import java.lang.annotation.Target;

+import java.lang.annotation.Documented;

+

+/**

+ * @author Gerhard Petracek

+ * @since 1.x.1

+ */

+@Target({METHOD, FIELD})

+@Retention(RUNTIME)

+@Documented

+@UsageInformation(UsageCategory.API)

+public @interface SkipValidation

+{

+    String[] value();

+

+    Class<? extends ValidationParameter>[] parameters() default {};

+}
\ No newline at end of file
diff --git a/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/baseval/annotation/SkipValidationSupport.java b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/baseval/annotation/SkipValidationSupport.java
new file mode 100644
index 0000000..7107621
--- /dev/null
+++ b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/baseval/annotation/SkipValidationSupport.java
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.myfaces.extensions.validator.baseval.annotation;
+
+import org.apache.myfaces.extensions.validator.internal.UsageInformation;
+import org.apache.myfaces.extensions.validator.internal.UsageCategory;
+
+import static java.lang.annotation.ElementType.TYPE;
+import java.lang.annotation.Target;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Documented;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+/**
+ * @author Gerhard Petracek
+ * @since 1.x.1
+ */
+@Target(TYPE)
+@Retention(RUNTIME)
+@Documented
+@UsageInformation(UsageCategory.API)
+public @interface SkipValidationSupport
+{
+}
\ No newline at end of file
diff --git a/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/baseval/annotation/Validator.java b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/baseval/annotation/Validator.java
new file mode 100644
index 0000000..fb38aca
--- /dev/null
+++ b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/baseval/annotation/Validator.java
@@ -0,0 +1,46 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.baseval.annotation;

+

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+import org.apache.myfaces.extensions.validator.core.validation.parameter.ValidationParameter;

+import org.apache.myfaces.extensions.validator.core.validation.parameter.ViolationSeverity;

+

+import static java.lang.annotation.ElementType.FIELD;

+import static java.lang.annotation.ElementType.METHOD;

+import java.lang.annotation.Retention;

+import static java.lang.annotation.RetentionPolicy.RUNTIME;

+import java.lang.annotation.Target;

+import java.lang.annotation.Documented;

+

+/**

+ * @author Gerhard Petracek

+ * @since 1.x.1

+ */

+@Target({METHOD, FIELD})

+@Retention(RUNTIME)

+@Documented

+@UsageInformation(UsageCategory.API)

+public @interface Validator

+{

+    Class<? extends javax.faces.validator.Validator>[] value();

+

+    Class<? extends ValidationParameter>[] parameters() default ViolationSeverity.Error.class;

+}
\ No newline at end of file
diff --git a/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/baseval/annotation/extractor/DefaultPropertyScanningMetaDataExtractor.java b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/baseval/annotation/extractor/DefaultPropertyScanningMetaDataExtractor.java
new file mode 100644
index 0000000..8a0eeba
--- /dev/null
+++ b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/baseval/annotation/extractor/DefaultPropertyScanningMetaDataExtractor.java
@@ -0,0 +1,82 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.myfaces.extensions.validator.baseval.annotation.extractor;
+
+import org.apache.myfaces.extensions.validator.core.property.PropertyInformation;
+import org.apache.myfaces.extensions.validator.core.property.PropertyInformationKeys;
+import org.apache.myfaces.extensions.validator.core.property.DefaultPropertyInformation;
+import org.apache.myfaces.extensions.validator.core.property.PropertyDetails;
+import org.apache.myfaces.extensions.validator.core.metadata.extractor.DefaultComponentMetaDataExtractor;
+import org.apache.myfaces.extensions.validator.core.metadata.extractor.MetaDataExtractor;
+import org.apache.myfaces.extensions.validator.internal.ToDo;
+import org.apache.myfaces.extensions.validator.internal.Priority;
+import org.apache.myfaces.extensions.validator.internal.UsageInformation;
+import org.apache.myfaces.extensions.validator.internal.UsageCategory;
+import org.apache.myfaces.extensions.validator.util.ExtValUtils;
+import org.apache.myfaces.extensions.validator.util.ProxyUtils;
+import org.apache.myfaces.extensions.validator.PropertyValidationModuleKey;
+
+import javax.faces.context.FacesContext;
+
+/**
+ * @author Gerhard Petracek
+ * @since 1.x.1
+ */
+@Deprecated
+@UsageInformation(UsageCategory.INTERNAL)
+public class DefaultPropertyScanningMetaDataExtractor extends DefaultComponentMetaDataExtractor
+{
+    private DefaultPropertyScanningMetaDataExtractor()
+    {
+    }
+
+    public static MetaDataExtractor getInstance()
+    {
+        return ExtValUtils.createInterceptedMetaDataExtractorFor(
+                new DefaultPropertyScanningMetaDataExtractor(), PropertyValidationModuleKey.class);
+    }
+
+    @Override
+    @ToDo(Priority.MEDIUM)
+    public PropertyInformation extract(FacesContext facesContext, Object object)
+    {
+        PropertyInformation propertyInformation = new DefaultPropertyInformation();
+
+        if (!(object instanceof PropertyDetails))
+        {
+            throw new IllegalStateException(object.getClass() + " is not a " + PropertyDetails.class.getName());
+        }
+
+        PropertyDetails propertyDetails = (PropertyDetails)object;
+
+        Class entityClass = ProxyUtils.getUnproxiedClass(propertyDetails.getBaseObject().getClass());
+
+        //TODO test with complex components
+        propertyInformation.setInformation(
+            PropertyInformationKeys.PROPERTY_DETAILS, propertyDetails);
+
+        /*
+         * find and add annotations
+         */
+        addPropertyAccessAnnotations(entityClass, propertyDetails.getProperty(), propertyInformation);
+        addFieldAccessAnnotations(entityClass, propertyDetails.getProperty(), propertyInformation);
+
+        return propertyInformation;
+    }
+}
diff --git a/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/baseval/message/bundle/validation_messages.properties b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/baseval/message/bundle/validation_messages.properties
new file mode 100644
index 0000000..08e8012
--- /dev/null
+++ b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/baseval/message/bundle/validation_messages.properties
@@ -0,0 +1,19 @@
+# Licensed to the Apache Software Foundation (ASF) under one

+# or more contributor license agreements.  See the NOTICE file

+# distributed with this work for additional information

+# regarding copyright ownership.  The ASF licenses this file

+# to you under the Apache License, Version 2.0 (the

+# "License"); you may not use this file except in compliance

+# with the License.  You may obtain a copy of the License at

+#

+#   http://www.apache.org/licenses/LICENSE-2.0

+#

+# Unless required by applicable law or agreed to in writing,

+# software distributed under the License is distributed on an

+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+# KIND, either express or implied.  See the License for the

+# specific language governing permissions and limitations

+# under the License.

+

+no_match=Invalid format

+no_match_detail=The required formate is: {0}
\ No newline at end of file
diff --git a/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/baseval/message/bundle/validation_messages_ar.properties b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/baseval/message/bundle/validation_messages_ar.properties
new file mode 100644
index 0000000..97ab543
--- /dev/null
+++ b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/baseval/message/bundle/validation_messages_ar.properties
@@ -0,0 +1,19 @@
+# Licensed to the Apache Software Foundation (ASF) under one

+# or more contributor license agreements.  See the NOTICE file

+# distributed with this work for additional information

+# regarding copyright ownership.  The ASF licenses this file

+# to you under the Apache License, Version 2.0 (the

+# "License"); you may not use this file except in compliance

+# with the License.  You may obtain a copy of the License at

+#

+#   http://www.apache.org/licenses/LICENSE-2.0

+#

+# Unless required by applicable law or agreed to in writing,

+# software distributed under the License is distributed on an

+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+# KIND, either express or implied.  See the License for the

+# specific language governing permissions and limitations

+# under the License.

+

+no_match=\u0627\u0644\u0635\u064a\u063a\u0629 \u062e\u0627\u0637\u0626\u0629

+no_match_detail=\u0627\u0644\u0635\u064a\u063a\u0629 \u0627\u0644\u0645\u0637\u0644\u0648\u0628\u0629 \u0647\u0649: {0}
\ No newline at end of file
diff --git a/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/baseval/message/bundle/validation_messages_ca.properties b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/baseval/message/bundle/validation_messages_ca.properties
new file mode 100644
index 0000000..98d6490
--- /dev/null
+++ b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/baseval/message/bundle/validation_messages_ca.properties
@@ -0,0 +1,19 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+no_match=Format inv\u00e0lid
+no_match_detail=El format requerit \u00e9s: {0}
\ No newline at end of file
diff --git a/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/baseval/message/bundle/validation_messages_de.properties b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/baseval/message/bundle/validation_messages_de.properties
new file mode 100644
index 0000000..9ee701b
--- /dev/null
+++ b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/baseval/message/bundle/validation_messages_de.properties
@@ -0,0 +1,19 @@
+# Licensed to the Apache Software Foundation (ASF) under one

+# or more contributor license agreements.  See the NOTICE file

+# distributed with this work for additional information

+# regarding copyright ownership.  The ASF licenses this file

+# to you under the Apache License, Version 2.0 (the

+# "License"); you may not use this file except in compliance

+# with the License.  You may obtain a copy of the License at

+#

+#   http://www.apache.org/licenses/LICENSE-2.0

+#

+# Unless required by applicable law or agreed to in writing,

+# software distributed under the License is distributed on an

+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+# KIND, either express or implied.  See the License for the

+# specific language governing permissions and limitations

+# under the License.

+

+no_match=Ungültiges Format

+no_match_detail=Das erforderliche Format ist: {0}
\ No newline at end of file
diff --git a/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/baseval/message/bundle/validation_messages_en.properties b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/baseval/message/bundle/validation_messages_en.properties
new file mode 100644
index 0000000..08e8012
--- /dev/null
+++ b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/baseval/message/bundle/validation_messages_en.properties
@@ -0,0 +1,19 @@
+# Licensed to the Apache Software Foundation (ASF) under one

+# or more contributor license agreements.  See the NOTICE file

+# distributed with this work for additional information

+# regarding copyright ownership.  The ASF licenses this file

+# to you under the Apache License, Version 2.0 (the

+# "License"); you may not use this file except in compliance

+# with the License.  You may obtain a copy of the License at

+#

+#   http://www.apache.org/licenses/LICENSE-2.0

+#

+# Unless required by applicable law or agreed to in writing,

+# software distributed under the License is distributed on an

+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+# KIND, either express or implied.  See the License for the

+# specific language governing permissions and limitations

+# under the License.

+

+no_match=Invalid format

+no_match_detail=The required formate is: {0}
\ No newline at end of file
diff --git a/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/baseval/message/bundle/validation_messages_es.properties b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/baseval/message/bundle/validation_messages_es.properties
new file mode 100644
index 0000000..93bb98c
--- /dev/null
+++ b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/baseval/message/bundle/validation_messages_es.properties
@@ -0,0 +1,19 @@
+# Licensed to the Apache Software Foundation (ASF) under one

+# or more contributor license agreements.  See the NOTICE file

+# distributed with this work for additional information

+# regarding copyright ownership.  The ASF licenses this file

+# to you under the Apache License, Version 2.0 (the

+# "License"); you may not use this file except in compliance

+# with the License.  You may obtain a copy of the License at

+#

+#   http://www.apache.org/licenses/LICENSE-2.0

+#

+# Unless required by applicable law or agreed to in writing,

+# software distributed under the License is distributed on an

+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+# KIND, either express or implied.  See the License for the

+# specific language governing permissions and limitations

+# under the License.

+

+no_match=Formato inv\u00e1lido 

+no_match_detail=El formato requerido es: {0}
\ No newline at end of file
diff --git a/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/baseval/message/bundle/validation_messages_fr.properties b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/baseval/message/bundle/validation_messages_fr.properties
new file mode 100644
index 0000000..120a223
--- /dev/null
+++ b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/baseval/message/bundle/validation_messages_fr.properties
@@ -0,0 +1,20 @@
+# Licensed to the Apache Software Foundation (ASF) under one

+# or more contributor license agreements.  See the NOTICE file

+# distributed with this work for additional information

+# regarding copyright ownership.  The ASF licenses this file

+# to you under the Apache License, Version 2.0 (the

+# "License"); you may not use this file except in compliance

+# with the License.  You may obtain a copy of the License at

+#

+#   http://www.apache.org/licenses/LICENSE-2.0

+#

+# Unless required by applicable law or agreed to in writing,

+# software distributed under the License is distributed on an

+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+# KIND, either express or implied.  See the License for the

+# specific language governing permissions and limitations

+# under the License.

+

+no_match=Le format est invalide

+no_match_detail=Le format doit &ecirc;tre de la forme: {0}

+

diff --git a/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/baseval/message/bundle/validation_messages_it.properties b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/baseval/message/bundle/validation_messages_it.properties
new file mode 100644
index 0000000..e18748c
--- /dev/null
+++ b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/baseval/message/bundle/validation_messages_it.properties
@@ -0,0 +1,19 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+no_match=Formato non valido
+no_match_detail=Il formato richiesto &egrave;: {0}
\ No newline at end of file
diff --git a/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/baseval/message/bundle/validation_messages_tr.properties b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/baseval/message/bundle/validation_messages_tr.properties
new file mode 100644
index 0000000..a94bc74
--- /dev/null
+++ b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/baseval/message/bundle/validation_messages_tr.properties
@@ -0,0 +1,19 @@
+# Licensed to the Apache Software Foundation (ASF) under one

+# or more contributor license agreements.  See the NOTICE file

+# distributed with this work for additional information

+# regarding copyright ownership.  The ASF licenses this file

+# to you under the Apache License, Version 2.0 (the

+# "License"); you may not use this file except in compliance

+# with the License.  You may obtain a copy of the License at

+#

+#   http://www.apache.org/licenses/LICENSE-2.0

+#

+# Unless required by applicable law or agreed to in writing,

+# software distributed under the License is distributed on an

+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+# KIND, either express or implied.  See the License for the

+# specific language governing permissions and limitations

+# under the License.

+

+no_match=Ge\u00e7ersiz bi\u00e7im

+no_match_detail=gereken bi\u00e7im: {0}
\ No newline at end of file
diff --git a/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/baseval/message/resolver/DefaultValidationErrorMessageResolver.java b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/baseval/message/resolver/DefaultValidationErrorMessageResolver.java
new file mode 100644
index 0000000..4aae64b
--- /dev/null
+++ b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/baseval/message/resolver/DefaultValidationErrorMessageResolver.java
@@ -0,0 +1,45 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.baseval.message.resolver;

+

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+

+/**

+ * @author Gerhard Petracek

+ * @since 1.x.1

+ */

+@UsageInformation(UsageCategory.INTERNAL)

+public class DefaultValidationErrorMessageResolver

+        extends

+        org.apache.myfaces.extensions.validator.core.validation.message.resolver.DefaultValidationErrorMessageResolver

+{

+    private static String baseName = null;

+

+    @Override

+    protected String getBaseName()

+    {

+        if (baseName == null)

+        {

+            baseName = super.getBaseName();

+        }

+

+        return baseName;

+    }

+}
\ No newline at end of file
diff --git a/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/baseval/message/resolver/JpaValidationErrorMessageResolver.java b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/baseval/message/resolver/JpaValidationErrorMessageResolver.java
new file mode 100644
index 0000000..d476ad9
--- /dev/null
+++ b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/baseval/message/resolver/JpaValidationErrorMessageResolver.java
@@ -0,0 +1,59 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.baseval.message.resolver;

+

+import org.apache.myfaces.extensions.validator.baseval.WebXmlParameter;

+import org.apache.myfaces.extensions.validator.core.validation.message.resolver.AbstractValidationErrorMessageResolver;

+import org.apache.myfaces.extensions.validator.core.ExtValContext;

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+

+/**

+ * @author Gerhard Petracek

+ * @since 1.x.1

+ */

+/*

+ * the jpa support is an exception in view of some mechanisms - so there's no convention for the message bundle.

+ * instead of the convention there is a global property to have an alternative to web.xml configuration

+ */

+@UsageInformation(UsageCategory.INTERNAL)

+public class JpaValidationErrorMessageResolver extends AbstractValidationErrorMessageResolver

+{

+    public static final String JPA_VALIDATION_ERROR_MESSAGES = "JPA_VALIDATION_ERROR_MESSAGES";

+

+    private static final String CUSTOM_BASE_NAME = WebXmlParameter.VALIDATION_MESSAGES_JPA;

+    private static final String BASE_NAME = JpaValidationErrorMessageResolver.class

+            .getPackage().getName().replace(".message.resolver", ".message.bundle")+ ".jpa_messages";

+

+    protected String getCustomBaseName()

+    {

+        if(CUSTOM_BASE_NAME != null)

+        {

+            return CUSTOM_BASE_NAME;

+        }

+

+        return (String)ExtValContext.getContext().getGlobalProperty(JPA_VALIDATION_ERROR_MESSAGES);

+    }

+

+    protected String getBaseName()

+    {

+        return BASE_NAME;

+    }

+

+}
\ No newline at end of file
diff --git a/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/baseval/metadata/transformer/AbstractValidationParameterAwareTransformer.java b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/baseval/metadata/transformer/AbstractValidationParameterAwareTransformer.java
new file mode 100644
index 0000000..495cd44
--- /dev/null
+++ b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/baseval/metadata/transformer/AbstractValidationParameterAwareTransformer.java
@@ -0,0 +1,80 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.baseval.metadata.transformer;

+

+import org.apache.myfaces.extensions.validator.core.metadata.MetaDataEntry;

+import org.apache.myfaces.extensions.validator.core.metadata.transformer.MetaDataTransformer;

+import org.apache.myfaces.extensions.validator.core.validation.parameter.ViolationSeverity;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.util.ExtValUtils;

+

+import javax.faces.application.FacesMessage;

+import java.lang.annotation.Annotation;

+import java.util.List;

+import java.util.Map;

+import java.util.Collections;

+

+/**

+ * @author Gerhard Petracek

+ * @since x.x.3

+ */

+@UsageInformation(UsageCategory.REUSE)

+public abstract class AbstractValidationParameterAwareTransformer implements MetaDataTransformer

+{

+    public Map<String, Object> convertMetaData(MetaDataEntry metaData)

+    {

+        if (isBlockingMetaData(metaData))

+        {

+            return transformMetaData(metaData);

+        }

+        return Collections.emptyMap();

+    }

+

+    protected abstract Map<String, Object> transformMetaData(MetaDataEntry metaData);

+

+    protected boolean isBlockingMetaData(MetaDataEntry metaDataEntry)

+    {

+        FacesMessage testMessage = new FacesMessage();

+        testMessage.setSeverity(FacesMessage.SEVERITY_ERROR);

+

+        FacesMessage.Severity severity = tryToTransformViolationSeverity(metaDataEntry);

+

+        if(severity != null)

+        {

+            testMessage.setSeverity(severity);

+        }

+

+        return ExtValUtils.severityBlocksSubmitForComponentId(null, testMessage);

+    }

+

+    private FacesMessage.Severity tryToTransformViolationSeverity(MetaDataEntry metaDataEntry)

+    {

+        List<FacesMessage.Severity> result = ExtValUtils.getValidationParameterExtractor()

+                .extract(metaDataEntry.getValue(Annotation.class),

+                        ExtValUtils.getValidationParameterClassFor(ViolationSeverity.class),

+                        FacesMessage.Severity.class);

+

+        if (result != null && !result.isEmpty())

+        {

+            return result.iterator().next();

+        }

+        return null;

+    }

+}

diff --git a/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/baseval/metadata/transformer/DoubleRangeMetaDataTransformer.java b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/baseval/metadata/transformer/DoubleRangeMetaDataTransformer.java
new file mode 100644
index 0000000..08e9e4e
--- /dev/null
+++ b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/baseval/metadata/transformer/DoubleRangeMetaDataTransformer.java
@@ -0,0 +1,66 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.baseval.metadata.transformer;

+

+import org.apache.myfaces.extensions.validator.baseval.annotation.DoubleRange;

+import org.apache.myfaces.extensions.validator.core.metadata.CommonMetaDataKeys;

+import org.apache.myfaces.extensions.validator.core.metadata.MetaDataEntry;

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+

+import java.util.HashMap;

+import java.util.Map;

+

+/**

+ * @author Gerhard Petracek

+ * @since 1.x.1

+ */

+@UsageInformation(UsageCategory.INTERNAL)

+public class DoubleRangeMetaDataTransformer extends AbstractValidationParameterAwareTransformer

+{

+    protected Map<String, Object> transformMetaData(MetaDataEntry metaDataEntry)

+    {

+        Map<String, Object> results = new HashMap<String, Object>();

+        DoubleRange annotation = metaDataEntry.getValue(DoubleRange.class);

+

+        double minimum = annotation.minimum();

+

+        if(minimum != Double.MIN_VALUE)

+        {

+            results.put(CommonMetaDataKeys.RANGE_MIN, minimum);

+        }

+        else

+        {

+            results.put(CommonMetaDataKeys.RANGE_MIN_DEFAULT, minimum);

+        }

+

+        double maximum = annotation.maximum();

+

+        if(maximum != Double.MAX_VALUE)

+        {

+            results.put(CommonMetaDataKeys.RANGE_MAX, maximum);

+        }

+        else

+        {

+            results.put(CommonMetaDataKeys.RANGE_MAX_DEFAULT, maximum);

+        }

+

+        return results;

+    }

+}

diff --git a/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/baseval/metadata/transformer/JoinMetaDataTransformer.java b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/baseval/metadata/transformer/JoinMetaDataTransformer.java
new file mode 100644
index 0000000..df35324
--- /dev/null
+++ b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/baseval/metadata/transformer/JoinMetaDataTransformer.java
@@ -0,0 +1,117 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.baseval.metadata.transformer;

+

+import org.apache.myfaces.extensions.validator.baseval.annotation.JoinValidation;

+import org.apache.myfaces.extensions.validator.baseval.annotation.extractor.DefaultPropertyScanningMetaDataExtractor;

+import org.apache.myfaces.extensions.validator.core.metadata.MetaDataEntry;

+import org.apache.myfaces.extensions.validator.core.metadata.extractor.MetaDataExtractor;

+import org.apache.myfaces.extensions.validator.core.metadata.transformer.MetaDataTransformer;

+import org.apache.myfaces.extensions.validator.core.validation.strategy.ValidationStrategy;

+import org.apache.myfaces.extensions.validator.core.validation.parameter.DisableClientSideValidation;

+import org.apache.myfaces.extensions.validator.core.property.PropertyDetails;

+import org.apache.myfaces.extensions.validator.util.ExtValUtils;

+import org.apache.myfaces.extensions.validator.util.PropertyValidationUtils;

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+import org.apache.commons.logging.Log;

+import org.apache.commons.logging.LogFactory;

+

+import javax.faces.context.FacesContext;

+import java.util.HashMap;

+import java.util.Map;

+import java.util.Collections;

+import java.lang.annotation.Annotation;

+

+/**

+ * @author Gerhard Petracek

+ * @since 1.x.1

+ */

+@UsageInformation(UsageCategory.INTERNAL)

+@Deprecated

+public class JoinMetaDataTransformer implements MetaDataTransformer

+{

+    protected final Log logger = LogFactory.getLog(getClass());

+

+    public Map<String, Object> convertMetaData(MetaDataEntry metaDataEntry)

+    {

+        try

+        {

+            return convert(metaDataEntry);

+        }

+        catch (Throwable t)

+        {

+            if(this.logger.isWarnEnabled())

+            {

+                this.logger.warn("this class is replaced by a meta-data storage filter. " +

+                        "if it gets invoked and an exception occurs, a custom syntax is used." +

+                        "this class might be used by an old add-on. please check for a newer version.");

+            }

+            return Collections.emptyMap();

+        }

+    }

+

+    private Map<String, Object> convert(MetaDataEntry metaDataEntry)

+    {

+        MetaDataExtractor extractor = DefaultPropertyScanningMetaDataExtractor.getInstance();

+

+        String[] targetExpressions = metaDataEntry.getValue(JoinValidation.class).value();

+

+        ValidationStrategy validationStrategy;

+        MetaDataTransformer metaDataTransformer;

+

+        Map<String, Object> results = new HashMap<String, Object>();

+

+        PropertyDetails propertyDetails;

+        for (String targetExpression : targetExpressions)

+        {

+            propertyDetails = ExtValUtils

+                .createPropertyDetailsForNewTarget(metaDataEntry, targetExpression);

+

+            for (MetaDataEntry entry : extractor.extract(FacesContext.getCurrentInstance(),

+                                                            propertyDetails).getMetaDataEntries())

+            {

+                validationStrategy = ExtValUtils.getValidationStrategyForMetaData(entry.getKey());

+

+                if(validationStrategy == null ||

+                        PropertyValidationUtils.isValidationSkipped(FacesContext.getCurrentInstance(),

+                                validationStrategy, entry))

+                {

+                    continue;

+                }

+

+                metaDataTransformer = ExtValUtils.getMetaDataTransformerForValidationStrategy(validationStrategy);

+

+                if (metaDataTransformer != null)

+                {

+                    if(!(entry.getValue() instanceof Annotation &&

+                            ExtValUtils.getValidationParameterExtractor()

+                                    .extract(entry.getValue(Annotation.class),

+                                            ExtValUtils

+                                                    .getValidationParameterClassFor(DisableClientSideValidation.class))

+                                    .iterator().hasNext()))

+                    {

+                        results.putAll(metaDataTransformer.convertMetaData(entry));

+                    }

+                }

+            }

+        }

+        return results;

+    }

+}

diff --git a/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/baseval/metadata/transformer/JpaMetaDataTransformer.java b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/baseval/metadata/transformer/JpaMetaDataTransformer.java
new file mode 100644
index 0000000..dce1011
--- /dev/null
+++ b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/baseval/metadata/transformer/JpaMetaDataTransformer.java
@@ -0,0 +1,73 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.baseval.metadata.transformer;

+

+import org.apache.myfaces.extensions.validator.core.metadata.CommonMetaDataKeys;

+import org.apache.myfaces.extensions.validator.core.metadata.MetaDataEntry;

+import org.apache.myfaces.extensions.validator.internal.Priority;

+import org.apache.myfaces.extensions.validator.internal.ToDo;

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+import org.apache.myfaces.extensions.validator.util.ExtValUtils;

+

+import javax.persistence.Basic;

+import javax.persistence.Column;

+import javax.persistence.Id;

+import java.util.HashMap;

+import java.util.Map;

+import java.lang.annotation.Annotation;

+

+/**

+ * @author Gerhard Petracek

+ * @since 1.x.1

+ */

+@UsageInformation(UsageCategory.INTERNAL)

+public class JpaMetaDataTransformer extends AbstractValidationParameterAwareTransformer

+{

+    @ToDo(value = Priority.MEDIUM, description = "impl. the rest")

+    protected Map<String, Object> transformMetaData(MetaDataEntry metaDataEntry)

+    {

+        Map<String, Object> results = new HashMap<String, Object>();

+

+        Annotation annotation = metaDataEntry.getValue(Annotation.class);

+

+        if(annotation instanceof Column)

+        {

+            if((!((Column) annotation).nullable()) && ExtValUtils.interpretEmptyStringValuesAsNull())

+            {

+                results.put(CommonMetaDataKeys.REQUIRED, true);

+            }

+

+            results.put(CommonMetaDataKeys.MAX_LENGTH, ((Column) annotation).length());

+        }

+        else if(annotation instanceof Basic)

+        {

+            if(!((Basic) annotation).optional())

+            {

+                results.put(CommonMetaDataKeys.REQUIRED, true);

+            }

+        }

+        else if(annotation instanceof Id)

+        {

+            results.put(CommonMetaDataKeys.REQUIRED, true);

+        }

+        //TODO impl. the rest!!!

+        return results;

+    }

+}

diff --git a/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/baseval/metadata/transformer/LengthMetaDataTransformer.java b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/baseval/metadata/transformer/LengthMetaDataTransformer.java
new file mode 100644
index 0000000..b391f9a
--- /dev/null
+++ b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/baseval/metadata/transformer/LengthMetaDataTransformer.java
@@ -0,0 +1,65 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.baseval.metadata.transformer;

+

+import org.apache.myfaces.extensions.validator.baseval.annotation.Length;

+import org.apache.myfaces.extensions.validator.core.metadata.CommonMetaDataKeys;

+import org.apache.myfaces.extensions.validator.core.metadata.MetaDataEntry;

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+

+import java.util.HashMap;

+import java.util.Map;

+

+/**

+ * @author Gerhard Petracek

+ * @since 1.x.1

+ */

+@UsageInformation(UsageCategory.INTERNAL)

+public class LengthMetaDataTransformer  extends AbstractValidationParameterAwareTransformer

+{

+    protected Map<String, Object> transformMetaData(MetaDataEntry metaDataEntry)

+    {

+        Map<String, Object> results = new HashMap<String, Object>();

+        Length annotation = metaDataEntry.getValue(Length.class);

+

+        int minimum = annotation.minimum();

+

+        if(minimum != 0)

+        {

+            results.put(CommonMetaDataKeys.MIN_LENGTH, minimum);

+        }

+        else

+        {

+            results.put(CommonMetaDataKeys.MIN_LENGTH_DEFAULT, minimum);

+        }

+

+        int maximum = annotation.maximum();

+        if(maximum != Integer.MAX_VALUE)

+        {

+            results.put(CommonMetaDataKeys.MAX_LENGTH, maximum);

+        }

+        else

+        {

+            results.put(CommonMetaDataKeys.MAX_LENGTH_DEFAULT, maximum);

+        }

+

+        return results;

+    }

+}

diff --git a/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/baseval/metadata/transformer/LongRangeMetaDataTransformer.java b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/baseval/metadata/transformer/LongRangeMetaDataTransformer.java
new file mode 100644
index 0000000..d0a332b
--- /dev/null
+++ b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/baseval/metadata/transformer/LongRangeMetaDataTransformer.java
@@ -0,0 +1,66 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.baseval.metadata.transformer;

+

+import org.apache.myfaces.extensions.validator.baseval.annotation.LongRange;

+import org.apache.myfaces.extensions.validator.core.metadata.CommonMetaDataKeys;

+import org.apache.myfaces.extensions.validator.core.metadata.MetaDataEntry;

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+

+import java.util.HashMap;

+import java.util.Map;

+

+/**

+ * @author Gerhard Petracek

+ * @since 1.x.1

+ */

+@UsageInformation(UsageCategory.INTERNAL)

+public class LongRangeMetaDataTransformer extends AbstractValidationParameterAwareTransformer

+{

+    protected Map<String, Object> transformMetaData(MetaDataEntry metaDataEntry)

+    {

+        Map<String, Object> results = new HashMap<String, Object>();

+        LongRange annotation = metaDataEntry.getValue(LongRange.class);

+

+        long minimum = annotation.minimum();

+

+        if(minimum != Long.MIN_VALUE)

+        {

+            results.put(CommonMetaDataKeys.RANGE_MIN, minimum);

+        }

+        else

+        {

+            results.put(CommonMetaDataKeys.RANGE_MIN_DEFAULT, minimum);

+        }

+

+        long maximum = annotation.maximum();

+

+        if(maximum != Long.MAX_VALUE)

+        {

+            results.put(CommonMetaDataKeys.RANGE_MAX, maximum);

+        }

+        else

+        {

+            results.put(CommonMetaDataKeys.RANGE_MAX_DEFAULT, maximum);

+        }

+

+        return results;

+    }

+}

diff --git a/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/baseval/metadata/transformer/PatternMetaDataTransformer.java b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/baseval/metadata/transformer/PatternMetaDataTransformer.java
new file mode 100644
index 0000000..410be65
--- /dev/null
+++ b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/baseval/metadata/transformer/PatternMetaDataTransformer.java
@@ -0,0 +1,60 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.baseval.metadata.transformer;

+

+import org.apache.myfaces.extensions.validator.core.metadata.CommonMetaDataKeys;

+import org.apache.myfaces.extensions.validator.core.validation.strategy.ValidationStrategy;

+import org.apache.myfaces.extensions.validator.core.metadata.MetaDataEntry;

+import org.apache.myfaces.extensions.validator.baseval.annotation.Pattern;

+import org.apache.myfaces.extensions.validator.util.ExtValUtils;

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+

+import javax.faces.context.FacesContext;

+import java.util.HashMap;

+import java.util.Map;

+import java.util.Locale;

+

+/**

+ * @author Gerhard Petracek

+ * @since 1.x.1

+ */

+@UsageInformation(UsageCategory.INTERNAL)

+public class PatternMetaDataTransformer  extends AbstractValidationParameterAwareTransformer

+{

+    protected Map<String, Object> transformMetaData(MetaDataEntry metaDataEntry)

+    {

+        Map<String, Object> results = new HashMap<String, Object>();

+        Pattern annotation = metaDataEntry.getValue(Pattern.class);

+        

+        results.put(CommonMetaDataKeys.PATTERN, (annotation).value());

+

+        String validationErrorMsgKey = (annotation).validationErrorMsgKey();

+        Locale currentLocale = FacesContext.getCurrentInstance().getViewRoot().getLocale();

+

+        ValidationStrategy validationStrategy =

+            ExtValUtils.getValidationStrategyForMetaData(annotation.annotationType().getName());

+

+        String validationErrorMsg = ExtValUtils.getMessageResolverForValidationStrategy(validationStrategy)

+            .getMessage(validationErrorMsgKey, currentLocale);

+

+        results.put(CommonMetaDataKeys.PATTERN_VALIDATION_ERROR_MESSAGE, validationErrorMsg);

+        return results;

+    }

+}

diff --git a/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/baseval/metadata/transformer/RequiredMetaDataTransformer.java b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/baseval/metadata/transformer/RequiredMetaDataTransformer.java
new file mode 100644
index 0000000..4bbecc9
--- /dev/null
+++ b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/baseval/metadata/transformer/RequiredMetaDataTransformer.java
@@ -0,0 +1,42 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.baseval.metadata.transformer;

+

+import org.apache.myfaces.extensions.validator.core.metadata.CommonMetaDataKeys;

+import org.apache.myfaces.extensions.validator.core.metadata.MetaDataEntry;

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+

+import java.util.HashMap;

+import java.util.Map;

+

+/**

+ * @author Gerhard Petracek

+ * @since 1.x.1

+ */

+@UsageInformation(UsageCategory.INTERNAL)

+public class RequiredMetaDataTransformer extends AbstractValidationParameterAwareTransformer

+{

+    public Map<String, Object> transformMetaData(MetaDataEntry metaDataEntry)

+    {

+        Map<String, Object> results = new HashMap<String, Object>();

+        results.put(CommonMetaDataKeys.WEAK_REQUIRED, true);

+        return results;

+    }

+}

diff --git a/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/baseval/metadata/transformer/SkipMetaDataTransformer.java b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/baseval/metadata/transformer/SkipMetaDataTransformer.java
new file mode 100644
index 0000000..7dc64ab
--- /dev/null
+++ b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/baseval/metadata/transformer/SkipMetaDataTransformer.java
@@ -0,0 +1,42 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.baseval.metadata.transformer;

+

+import org.apache.myfaces.extensions.validator.core.metadata.MetaDataEntry;

+import org.apache.myfaces.extensions.validator.core.metadata.CommonMetaDataKeys;

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+

+import java.util.HashMap;

+import java.util.Map;

+

+/**

+ * @author Gerhard Petracek

+ * @since 1.x.2

+ */

+@UsageInformation(UsageCategory.INTERNAL)

+public class SkipMetaDataTransformer  extends AbstractValidationParameterAwareTransformer

+{

+    protected Map<String, Object> transformMetaData(MetaDataEntry metaDataEntry)

+    {

+        Map<String, Object> results = new HashMap<String, Object>();

+        results.put(CommonMetaDataKeys.SKIP_VALIDATION, true);

+        return results;

+    }

+}

diff --git a/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/baseval/metadata/transformer/ValidatorMetaDataTransformer.java b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/baseval/metadata/transformer/ValidatorMetaDataTransformer.java
new file mode 100644
index 0000000..ed05ab0
--- /dev/null
+++ b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/baseval/metadata/transformer/ValidatorMetaDataTransformer.java
@@ -0,0 +1,61 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.baseval.metadata.transformer;

+

+import org.apache.myfaces.extensions.validator.baseval.annotation.Validator;

+import org.apache.myfaces.extensions.validator.core.metadata.CommonMetaDataKeys;

+import org.apache.myfaces.extensions.validator.core.metadata.MetaDataEntry;

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+

+import java.util.HashMap;

+import java.util.Map;

+import java.util.List;

+import java.util.ArrayList;

+

+/**

+ * @author Gerhard Petracek

+ * @since 1.x.1

+ */

+@UsageInformation(UsageCategory.INTERNAL)

+public class ValidatorMetaDataTransformer  extends AbstractValidationParameterAwareTransformer

+{

+    protected Map<String, Object> transformMetaData(MetaDataEntry metaDataEntry)

+    {

+        Map<String, Object> results = new HashMap<String, Object>();

+        Validator annotation = metaDataEntry.getValue(Validator.class);

+

+        Class[] validators = annotation.value();

+

+        List<String> value = new ArrayList<String>();

+

+        for(Class currentClass : validators)

+        {

+            if(currentClass.getSimpleName().toLowerCase().contains(CommonMetaDataKeys.EMAIL))

+            {

+                value.add(CommonMetaDataKeys.EMAIL);

+            }

+            value.add(currentClass.getName());

+        }

+

+        results.put(CommonMetaDataKeys.CUSTOM, value);

+

+        return results;

+    }

+}

diff --git a/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/baseval/strategy/DoubleRangeStrategy.java b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/baseval/strategy/DoubleRangeStrategy.java
new file mode 100644
index 0000000..f175933
--- /dev/null
+++ b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/baseval/strategy/DoubleRangeStrategy.java
@@ -0,0 +1,55 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.baseval.strategy;

+

+import org.apache.myfaces.extensions.validator.baseval.annotation.DoubleRange;

+import org.apache.myfaces.extensions.validator.baseval.annotation.SkipValidationSupport;

+import org.apache.myfaces.extensions.validator.core.metadata.MetaDataEntry;

+import org.apache.myfaces.extensions.validator.core.validation.strategy.AbstractValidationStrategy;

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+

+import javax.faces.component.UIComponent;

+import javax.faces.context.FacesContext;

+import javax.faces.validator.DoubleRangeValidator;

+import javax.faces.validator.ValidatorException;

+

+/**

+ * @author Gerhard Petracek

+ * @since 1.x.1

+ */

+@SkipValidationSupport

+@UsageInformation(UsageCategory.INTERNAL)

+public class DoubleRangeStrategy extends AbstractValidationStrategy

+{

+    protected void processValidation(FacesContext facesContext,

+            UIComponent uiComponent, MetaDataEntry metaDataEntry,

+            Object convertedObject) throws ValidatorException

+    {

+

+        DoubleRange annotation = metaDataEntry.getValue(DoubleRange.class);

+        DoubleRangeValidator doubleRangeValidator = (DoubleRangeValidator)facesContext.getApplication()

+                                                        .createValidator("javax.faces.DoubleRange");

+

+        doubleRangeValidator.setMinimum(annotation.minimum());

+        doubleRangeValidator.setMaximum(annotation.maximum());

+

+        doubleRangeValidator.validate(facesContext, uiComponent, convertedObject);

+    }

+}

diff --git a/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/baseval/strategy/JoinValidationStrategy.java b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/baseval/strategy/JoinValidationStrategy.java
new file mode 100644
index 0000000..54da1ac
--- /dev/null
+++ b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/baseval/strategy/JoinValidationStrategy.java
@@ -0,0 +1,110 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.baseval.strategy;

+

+import org.apache.myfaces.extensions.validator.baseval.annotation.JoinValidation;

+import org.apache.myfaces.extensions.validator.baseval.annotation.extractor.DefaultPropertyScanningMetaDataExtractor;

+import org.apache.myfaces.extensions.validator.core.metadata.MetaDataEntry;

+import org.apache.myfaces.extensions.validator.core.metadata.extractor.MetaDataExtractor;

+import org.apache.myfaces.extensions.validator.core.validation.strategy.AbstractValidationStrategy;

+import org.apache.myfaces.extensions.validator.core.validation.strategy.ValidationStrategy;

+import org.apache.myfaces.extensions.validator.core.property.PropertyDetails;

+import org.apache.myfaces.extensions.validator.util.ExtValUtils;

+import org.apache.myfaces.extensions.validator.util.ProxyUtils;

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+

+import javax.faces.component.UIComponent;

+import javax.faces.context.FacesContext;

+import javax.faces.validator.ValidatorException;

+import javax.faces.FacesException;

+

+/**

+ * @author Gerhard Petracek

+ * @since 1.x.1

+ */

+@UsageInformation(UsageCategory.INTERNAL)

+@Deprecated

+public class JoinValidationStrategy extends AbstractValidationStrategy

+{

+    public void processValidation(FacesContext facesContext,

+                                  UIComponent uiComponent, MetaDataEntry metaDataEntry,

+                                  Object convertedObject) throws ValidatorException

+    {

+        try

+        {

+            validateJoinValidation(facesContext, uiComponent, metaDataEntry, convertedObject);

+        }

+        catch (FacesException t)

+        {

+            throw t;

+        }

+        catch (Throwable t)

+        {

+            if(this.logger.isWarnEnabled())

+            {

+                this.logger.warn("this class is replaced by a meta-data storage filter. " +

+                        "if it gets invoked and an exception occurs, a custom syntax is used." +

+                        "this class might be used by an old add-on. please check for a newer version.");

+            }

+        }

+    }

+

+    private void validateJoinValidation(FacesContext facesContext,

+                                        UIComponent uiComponent,

+                                        MetaDataEntry metaDataEntry,

+                                        Object convertedObject)

+    {

+        MetaDataExtractor extractor = DefaultPropertyScanningMetaDataExtractor.getInstance();

+

+        String[] targetExpressions = metaDataEntry.getValue(JoinValidation.class).value();

+

+        ValidationStrategy validationStrategy;

+

+        PropertyDetails propertyDetails;

+        for (String targetExpression : targetExpressions)

+        {

+            propertyDetails = ExtValUtils

+                .createPropertyDetailsForNewTarget(metaDataEntry, targetExpression);

+

+            for (MetaDataEntry entry : extractor.extract(facesContext, propertyDetails).getMetaDataEntries())

+            {

+                validationStrategy = ExtValUtils.getValidationStrategyForMetaData(entry.getKey());

+

+                if (validationStrategy != null)

+                {

+                    if(ExtValUtils.processMetaDataEntryAfterSkipValidation(ProxyUtils.getUnproxiedClass(

+                            validationStrategy.getClass(), ValidationStrategy.class), entry))

+                    {

+                        continue;

+                    }

+

+                    validationStrategy.validate(facesContext, uiComponent, entry, convertedObject);

+                }

+                else

+                {

+                    if(logger.isTraceEnabled())

+                    {

+                        logger.trace("no validation strategy found for " + entry.getValue());

+                    }

+                }

+            }

+        }

+    }

+}

diff --git a/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/baseval/strategy/JpaValidationStrategy.java b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/baseval/strategy/JpaValidationStrategy.java
new file mode 100644
index 0000000..3e41a93
--- /dev/null
+++ b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/baseval/strategy/JpaValidationStrategy.java
@@ -0,0 +1,206 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.baseval.strategy;

+

+import org.apache.myfaces.extensions.validator.core.metadata.CommonMetaDataKeys;

+import org.apache.myfaces.extensions.validator.core.metadata.MetaDataEntry;

+import org.apache.myfaces.extensions.validator.core.validation.strategy.AbstractAnnotationValidationStrategy;

+import org.apache.myfaces.extensions.validator.core.validation.message.resolver.AbstractValidationErrorMessageResolver;

+import org.apache.myfaces.extensions.validator.core.validation.exception.RequiredValidatorException;

+import org.apache.myfaces.extensions.validator.core.validation.NullValueAwareValidationStrategy;

+import org.apache.myfaces.extensions.validator.core.validation.EmptyValueAwareValidationStrategy;

+import org.apache.myfaces.extensions.validator.internal.Priority;

+import org.apache.myfaces.extensions.validator.internal.ToDo;

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+import org.apache.myfaces.extensions.validator.util.ExtValUtils;

+

+import javax.faces.component.UIComponent;

+import javax.faces.context.FacesContext;

+import javax.faces.validator.ValidatorException;

+import javax.faces.application.FacesMessage;

+import javax.persistence.Basic;

+import javax.persistence.Column;

+import javax.persistence.ManyToOne;

+import javax.persistence.OneToOne;

+import javax.persistence.Id;

+import java.lang.annotation.Annotation;

+

+/**

+ * @author Gerhard Petracek

+ * @since 1.x.1

+ */

+@NullValueAwareValidationStrategy

+@EmptyValueAwareValidationStrategy

+@UsageInformation(UsageCategory.INTERNAL)

+public class JpaValidationStrategy extends AbstractAnnotationValidationStrategy

+{

+    private boolean useFacesBundle = false;

+    private static final String VALIDATE_LENGTH = "length";

+

+    private String violation;

+    private int maxLength;

+

+    public void processValidation(FacesContext facesContext,

+                                  UIComponent uiComponent,

+                                  MetaDataEntry metaDataEntry,

+                                  Object convertedObject) throws ValidatorException

+    {

+        Annotation annotation = metaDataEntry.getValue(Annotation.class);

+        if (annotation instanceof Column)

+        {

+            validateColumnAnnotation((Column) annotation, convertedObject);

+        }

+        else if (annotation instanceof Basic)

+        {

+            validateBasicAnnotation((Basic) annotation, convertedObject);

+        }

+        else if (annotation instanceof Id)

+        {

+            checkRequiredConvertedObject(convertedObject);

+        }

+        else if (annotation instanceof OneToOne)

+        {

+            validateOneToOneAnnotation((OneToOne) annotation, convertedObject);

+        }

+        else if (annotation instanceof ManyToOne)

+        {

+            validateManyToOneAnnotation((ManyToOne) annotation, convertedObject);

+        }

+    }

+

+    private void validateColumnAnnotation(Column column, Object convertedObject) throws ValidatorException

+    {

+        if (!column.nullable())

+        {

+            checkRequiredConvertedObject(convertedObject);

+        }

+

+        if (convertedObject == null)

+        {

+            return;

+        }

+

+        if (convertedObject instanceof String

+                && column.length() < ((String) convertedObject).length())

+        {

+            this.violation = VALIDATE_LENGTH;

+            this.maxLength = column.length();

+            throw new ValidatorException(getValidationErrorFacesMessage(null));

+        }

+    }

+

+    private void validateBasicAnnotation(Basic basic, Object convertedObject) throws ValidatorException

+    {

+        if (!basic.optional())

+        {

+            checkRequiredConvertedObject(convertedObject);

+        }

+    }

+

+    private void validateOneToOneAnnotation(OneToOne oneToOne, Object convertedObject)

+    {

+        if (!oneToOne.optional())

+        {

+            checkRequiredConvertedObject(convertedObject);

+        }

+    }

+

+    private void validateManyToOneAnnotation(ManyToOne manyToOne, Object convertedObject)

+    {

+        if (!manyToOne.optional())

+        {

+            checkRequiredConvertedObject(convertedObject);

+        }

+    }

+

+    @ToDo(Priority.MEDIUM)

+    private void checkRequiredConvertedObject(Object convertedObject) throws ValidatorException

+    {

+        if (convertedObject == null || ("".equals(convertedObject) && ExtValUtils.interpretEmptyStringValuesAsNull()))

+        {

+            this.violation = CommonMetaDataKeys.REQUIRED;

+            throw new RequiredValidatorException(getValidationErrorFacesMessage(null));

+        }

+    }

+

+    protected String getValidationErrorMsgKey(Annotation annotation)

+    {

+        if (VALIDATE_LENGTH.equals(this.violation))

+        {

+            return "field_too_long";

+        }

+        else

+        {

+            return "field_required";

+        }

+    }

+

+    protected String getErrorMessageDetail(Annotation annotation)

+    {

+        String message = super.getErrorMessageDetail(annotation);

+

+        if (VALIDATE_LENGTH.equals(this.violation))

+        {

+            return message.replace("{0}", "" + this.maxLength);

+        }

+        else

+        {

+            return message;

+        }

+    }

+

+    @Override

+    protected String resolveMessage(String key)

+    {

+        String result = super.resolveMessage(key);

+        String marker = AbstractValidationErrorMessageResolver.MISSING_RESOURCE_MARKER;

+

+        if((marker + key + marker).equals(result))

+        {

+            this.useFacesBundle = true;

+        }

+

+        return result;

+    }

+

+    @Override

+    protected boolean processAfterValidatorException(FacesContext facesContext,

+                                                     UIComponent uiComponent,

+                                                     MetaDataEntry metaDataEntry,

+                                                     Object convertedObject,

+                                                     ValidatorException e)

+    {

+        FacesMessage facesMessage = e.getFacesMessage();

+

+        if(this.useFacesBundle)

+        {

+            if(VALIDATE_LENGTH.equals(this.violation))

+            {

+                ExtValUtils.replaceWithDefaultMaximumMessage(facesMessage, this.maxLength);

+            }

+            else

+            {

+                ExtValUtils.replaceWithDefaultRequiredMessage(facesMessage);

+            }

+        }

+

+        return super.processAfterValidatorException(facesContext, uiComponent, metaDataEntry, convertedObject, e);

+    }

+}

diff --git a/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/baseval/strategy/LengthStrategy.java b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/baseval/strategy/LengthStrategy.java
new file mode 100644
index 0000000..9cd0558
--- /dev/null
+++ b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/baseval/strategy/LengthStrategy.java
@@ -0,0 +1,54 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.baseval.strategy;

+

+import org.apache.myfaces.extensions.validator.baseval.annotation.Length;

+import org.apache.myfaces.extensions.validator.baseval.annotation.SkipValidationSupport;

+import org.apache.myfaces.extensions.validator.core.metadata.MetaDataEntry;

+import org.apache.myfaces.extensions.validator.core.validation.strategy.AbstractValidationStrategy;

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+

+import javax.faces.component.UIComponent;

+import javax.faces.context.FacesContext;

+import javax.faces.validator.LengthValidator;

+import javax.faces.validator.ValidatorException;

+

+/**

+ * @author Gerhard Petracek

+ * @since 1.x.1

+ */

+@SkipValidationSupport

+@UsageInformation(UsageCategory.INTERNAL)

+public class LengthStrategy extends AbstractValidationStrategy

+{

+    protected void processValidation(FacesContext facesContext,

+            UIComponent uiComponent, MetaDataEntry metaDataEntry,

+            Object convertedObject) throws ValidatorException

+    {

+        Length annotation = metaDataEntry.getValue(Length.class);

+        LengthValidator lengthValidator = (LengthValidator)facesContext.getApplication()

+                                            .createValidator("javax.faces.Length");

+

+        lengthValidator.setMinimum(annotation.minimum());

+        lengthValidator.setMaximum(annotation.maximum());

+

+        lengthValidator.validate(facesContext, uiComponent, convertedObject);

+    }

+}

diff --git a/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/baseval/strategy/LongRangeStrategy.java b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/baseval/strategy/LongRangeStrategy.java
new file mode 100644
index 0000000..6358202
--- /dev/null
+++ b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/baseval/strategy/LongRangeStrategy.java
@@ -0,0 +1,55 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.baseval.strategy;

+

+import org.apache.myfaces.extensions.validator.baseval.annotation.LongRange;

+import org.apache.myfaces.extensions.validator.baseval.annotation.SkipValidationSupport;

+import org.apache.myfaces.extensions.validator.core.metadata.MetaDataEntry;

+import org.apache.myfaces.extensions.validator.core.validation.strategy.AbstractValidationStrategy;

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+

+import javax.faces.component.UIComponent;

+import javax.faces.context.FacesContext;

+import javax.faces.validator.LongRangeValidator;

+import javax.faces.validator.ValidatorException;

+

+/**

+ * @author Gerhard Petracek

+ * @since 1.x.1

+ */

+@SkipValidationSupport

+@UsageInformation(UsageCategory.INTERNAL)

+public class LongRangeStrategy extends AbstractValidationStrategy

+{

+    protected void processValidation(FacesContext facesContext,

+            UIComponent uiComponent, MetaDataEntry metaDataEntry,

+            Object convertedObject) throws ValidatorException

+    {

+

+        LongRange annotation = metaDataEntry.getValue(LongRange.class);

+        LongRangeValidator longRangeValidator = (LongRangeValidator)facesContext.getApplication()

+                                                    .createValidator("javax.faces.LongRange");

+

+        longRangeValidator.setMinimum(annotation.minimum());

+        longRangeValidator.setMaximum(annotation.maximum());

+

+        longRangeValidator.validate(facesContext, uiComponent, convertedObject);

+    }

+}

diff --git a/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/baseval/strategy/PatternStrategy.java b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/baseval/strategy/PatternStrategy.java
new file mode 100644
index 0000000..6a3f4ef
--- /dev/null
+++ b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/baseval/strategy/PatternStrategy.java
@@ -0,0 +1,63 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.baseval.strategy;

+

+import org.apache.myfaces.extensions.validator.baseval.annotation.Pattern;

+import org.apache.myfaces.extensions.validator.baseval.annotation.SkipValidationSupport;

+import org.apache.myfaces.extensions.validator.core.metadata.MetaDataEntry;

+import org.apache.myfaces.extensions.validator.core.validation.strategy.AbstractAnnotationValidationStrategy;

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+

+import javax.faces.application.FacesMessage;

+import javax.faces.component.UIComponent;

+import javax.faces.context.FacesContext;

+import javax.faces.validator.ValidatorException;

+

+/**

+ * @author Gerhard Petracek

+ * @since 1.x.1

+ */

+@SkipValidationSupport

+@UsageInformation(UsageCategory.INTERNAL)

+public class PatternStrategy extends AbstractAnnotationValidationStrategy<Pattern>

+{

+    protected void processValidation(FacesContext facesContext,

+            UIComponent uiComponent, MetaDataEntry metaDataEntry,

+            Object convertedObject) throws ValidatorException

+    {

+        Pattern annotation = metaDataEntry.getValue(Pattern.class);

+

+        for (String expression : annotation.value())

+        {

+            if (!java.util.regex.Pattern.compile(expression).matcher(convertedObject.toString()).matches())

+            {

+                throw new ValidatorException(new FacesMessage(

+                        FacesMessage.SEVERITY_ERROR,

+                        getErrorMessageSummary(annotation),

+                        getErrorMessageDetail(annotation).replace("{0}", expression)));

+            }

+        }

+    }

+

+    protected String getValidationErrorMsgKey(Pattern annotation)

+    {

+        return annotation.validationErrorMsgKey();

+    }

+}

diff --git a/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/baseval/strategy/RequiredStrategy.java b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/baseval/strategy/RequiredStrategy.java
new file mode 100644
index 0000000..c09e4c7
--- /dev/null
+++ b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/baseval/strategy/RequiredStrategy.java
@@ -0,0 +1,97 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.baseval.strategy;

+

+import org.apache.myfaces.extensions.validator.baseval.annotation.Required;

+import org.apache.myfaces.extensions.validator.baseval.annotation.SkipValidationSupport;

+import org.apache.myfaces.extensions.validator.core.metadata.MetaDataEntry;

+import org.apache.myfaces.extensions.validator.core.validation.strategy.AbstractAnnotationValidationStrategy;

+import org.apache.myfaces.extensions.validator.core.validation.message.resolver.AbstractValidationErrorMessageResolver;

+import org.apache.myfaces.extensions.validator.core.validation.exception.RequiredValidatorException;

+import org.apache.myfaces.extensions.validator.core.validation.NullValueAwareValidationStrategy;

+import org.apache.myfaces.extensions.validator.core.validation.EmptyValueAwareValidationStrategy;

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+import org.apache.myfaces.extensions.validator.util.ExtValUtils;

+

+import javax.faces.component.UIComponent;

+import javax.faces.context.FacesContext;

+import javax.faces.validator.ValidatorException;

+import java.util.Map;

+import java.util.Collection;

+

+/**

+ * @author Gerhard Petracek

+ * @since 1.x.1

+ */

+@SkipValidationSupport

+@NullValueAwareValidationStrategy

+@EmptyValueAwareValidationStrategy

+@UsageInformation(UsageCategory.INTERNAL)

+public class RequiredStrategy extends AbstractAnnotationValidationStrategy<Required>

+{

+    private boolean useFacesBundle = false;

+

+    public void processValidation(FacesContext facesContext,

+            UIComponent uiComponent, MetaDataEntry metaDataEntry,

+            Object convertedObject) throws ValidatorException

+    {

+        if (convertedObject == null || convertedObject.equals("") ||

+                (convertedObject instanceof Collection && ((Collection)convertedObject).isEmpty()) ||

+                (convertedObject instanceof Map && ((Map)convertedObject).isEmpty()))

+        {

+            throw new RequiredValidatorException(

+                    getValidationErrorFacesMessage(metaDataEntry.getValue(Required.class)));

+        }

+    }

+

+    protected String getValidationErrorMsgKey(Required annotation)

+    {

+        return annotation.validationErrorMsgKey();

+    }

+

+    @Override

+    protected String resolveMessage(String key)

+    {

+        String result = super.resolveMessage(key);

+        String marker = AbstractValidationErrorMessageResolver.MISSING_RESOURCE_MARKER;

+

+        if((marker + key + marker).equals(result))

+        {

+            this.useFacesBundle = true;

+        }

+

+        return result;

+    }

+

+    @Override

+    protected boolean processAfterValidatorException(FacesContext facesContext,

+                                                     UIComponent uiComponent,

+                                                     MetaDataEntry metaDataEntry,

+                                                     Object convertedObject,

+                                                     ValidatorException e)

+    {

+        if(this.useFacesBundle)

+        {

+            ExtValUtils.replaceWithDefaultRequiredMessage(e.getFacesMessage());

+        }

+

+        return super.processAfterValidatorException(facesContext, uiComponent, metaDataEntry, convertedObject, e);

+    }

+}

diff --git a/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/baseval/strategy/SkipValidationStrategy.java b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/baseval/strategy/SkipValidationStrategy.java
new file mode 100644
index 0000000..adf0d8e
--- /dev/null
+++ b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/baseval/strategy/SkipValidationStrategy.java
@@ -0,0 +1,62 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.baseval.strategy;

+

+import org.apache.myfaces.extensions.validator.baseval.annotation.SkipValidation;

+import org.apache.myfaces.extensions.validator.core.property.PropertyInformationKeys;

+import org.apache.myfaces.extensions.validator.core.metadata.MetaDataEntry;

+import org.apache.myfaces.extensions.validator.core.validation.strategy.ValidationStrategy;

+import org.apache.myfaces.extensions.validator.core.validation.NullValueAwareValidationStrategy;

+import org.apache.myfaces.extensions.validator.core.validation.EmptyValueAwareValidationStrategy;

+import org.apache.myfaces.extensions.validator.core.el.ValueBindingExpression;

+import org.apache.myfaces.extensions.validator.util.ExtValUtils;

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+

+import javax.faces.component.UIComponent;

+import javax.faces.context.FacesContext;

+import javax.faces.validator.ValidatorException;

+

+/**

+ * @author Gerhard Petracek

+ * @since 1.x.1

+ */

+@NullValueAwareValidationStrategy

+@EmptyValueAwareValidationStrategy

+@UsageInformation(UsageCategory.INTERNAL)

+public class SkipValidationStrategy implements ValidationStrategy

+{

+    public void validate(FacesContext facesContext,

+                                  UIComponent uiComponent,

+                                  MetaDataEntry metaDataEntry,

+                                  Object convertedObject) throws ValidatorException

+    {

+        String[] valueBindingExpressions = metaDataEntry.getValue(SkipValidation.class).value();

+

+        for(String valueBindingExpression : valueBindingExpressions)

+        {

+            if(Boolean.TRUE.equals(ExtValUtils.getELHelper().getValueOfExpression(

+                facesContext, new ValueBindingExpression(valueBindingExpression))))

+            {

+                metaDataEntry.setProperty(PropertyInformationKeys.SKIP_VALIDATION, true);

+                break;

+            }

+        }

+    }

+}

diff --git a/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/baseval/strategy/ValidatorStrategy.java b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/baseval/strategy/ValidatorStrategy.java
new file mode 100644
index 0000000..bb3cc91
--- /dev/null
+++ b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/baseval/strategy/ValidatorStrategy.java
@@ -0,0 +1,67 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.baseval.strategy;

+

+import org.apache.myfaces.extensions.validator.baseval.annotation.Validator;

+import org.apache.myfaces.extensions.validator.baseval.annotation.SkipValidationSupport;

+import org.apache.myfaces.extensions.validator.core.metadata.MetaDataEntry;

+import org.apache.myfaces.extensions.validator.core.validation.strategy.AbstractValidationStrategy;

+import org.apache.myfaces.extensions.validator.util.ClassUtils;

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+

+import javax.faces.component.UIComponent;

+import javax.faces.context.FacesContext;

+import javax.faces.validator.ValidatorException;

+

+/**

+ * @author Gerhard Petracek

+ * @since 1.x.1

+ */

+@SkipValidationSupport

+@UsageInformation(UsageCategory.INTERNAL)

+public class ValidatorStrategy extends AbstractValidationStrategy

+{

+    protected void processValidation(FacesContext facesContext,

+            UIComponent uiComponent, MetaDataEntry metaDataEntry,

+            Object convertedObject) throws ValidatorException

+    {

+

+        Class<? extends javax.faces.validator.Validator>[] validatorClasses =

+            metaDataEntry.getValue(Validator.class).value();

+

+        javax.faces.validator.Validator validator;

+        for (Class validatorClassName : validatorClasses)

+        {

+            validator = (javax.faces.validator.Validator) ClassUtils

+                    .tryToInstantiateClass(validatorClassName);

+

+            if (validator == null)

+            {

+                if(logger.isTraceEnabled())

+                {

+                    logger.trace(validatorClassName.getName() + " not found");

+                }

+

+                continue;

+            }

+            validator.validate(facesContext, uiComponent, convertedObject);

+        }

+    }

+}

diff --git a/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/crossval/CrossValidationPhaseListener.java b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/crossval/CrossValidationPhaseListener.java
new file mode 100644
index 0000000..c66ac60
--- /dev/null
+++ b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/crossval/CrossValidationPhaseListener.java
@@ -0,0 +1,190 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.crossval;

+

+import org.apache.myfaces.extensions.validator.util.CrossValidationUtils;

+import org.apache.myfaces.extensions.validator.util.JsfUtils;

+import org.apache.myfaces.extensions.validator.util.ReflectionUtils;

+import org.apache.myfaces.extensions.validator.util.ExtValUtils;

+import org.apache.myfaces.extensions.validator.util.ProxyUtils;

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+import org.apache.myfaces.extensions.validator.crossval.strategy.AbstractCrossValidationStrategy;

+import org.apache.myfaces.extensions.validator.crossval.storage.CrossValidationStorage;

+import org.apache.myfaces.extensions.validator.crossval.storage.CrossValidationStorageEntry;

+import org.apache.myfaces.extensions.validator.PropertyValidationModuleKey;

+

+import javax.faces.application.FacesMessage;

+import javax.faces.event.PhaseEvent;

+import javax.faces.event.PhaseId;

+import javax.faces.event.PhaseListener;

+import javax.faces.validator.ValidatorException;

+import javax.faces.FacesException;

+import javax.faces.context.FacesContext;

+

+/**

+ * This phase listener processes cross validation as soon as it finds a special request scoped storage.<br/>

+ * So it's possible to add information during the process validation phase. At the end of this phase it gets processed.

+ * After that the storage gets reseted.<p/>

+ * If you provide a custom extension and you add the same storage type within a different phase,

+ * it also gets processed at the end of that phase.

+ *

+ * @author Gerhard Petracek

+ * @since 1.x.1

+ */

+@UsageInformation(UsageCategory.INTERNAL)

+public class CrossValidationPhaseListener implements PhaseListener

+{

+    private boolean isInitialized = false;

+    private static final long serialVersionUID = -5333405897635742732L;

+

+    public void afterPhase(PhaseEvent event)

+    {

+        try

+        {

+            CrossValidationStorage crossValidationStorage = CrossValidationUtils.getOrInitCrossValidationStorage();

+            for (CrossValidationStorageEntry entry : crossValidationStorage.getCrossValidationStorageEntries())

+            {

+                try

+                {

+                    if(!ExtValUtils.executeGlobalBeforeValidationInterceptors(

+                            FacesContext.getCurrentInstance(),

+                            entry.getComponent(),

+                            entry.getConvertedObject(),

+                            CrossValidationStorageEntry.class.getName(),

+                            entry,

+                            PropertyValidationModuleKey.class))

+                    {

+                        continue;

+                    }

+

+                    //call init-method

+                    if(entry.getValidationStrategy() instanceof AbstractCrossValidationStrategy)

+                    {

+                        ReflectionUtils.tryToInvokeMethod(

+                                entry.getValidationStrategy(),

+                                ReflectionUtils.tryToGetMethod(

+                                        ProxyUtils.getUnproxiedClass(entry.getValidationStrategy().getClass()),

+                                        "initCrossValidation",

+                                        CrossValidationStorageEntry.class),

+                                entry);

+                    }

+

+                    /*

+                     * validation

+                     */

+                    entry.getValidationStrategy().processCrossValidation(entry, crossValidationStorage);

+                }

+                catch (ValidatorException validatorException)

+                {

+                    boolean addMessage = true;

+

+                    if(entry.getValidationStrategy() instanceof AbstractCrossValidationStrategy)

+                    {

+                        try

+                        {

+                            addMessage = (Boolean)ReflectionUtils.tryToInvokeMethod(

+                                    entry.getValidationStrategy(),

+                                    ReflectionUtils.tryToGetMethod(

+                                            ProxyUtils.getUnproxiedClass(entry.getValidationStrategy().getClass()),

+                                            "processAfterCrossValidatorException",

+                                            CrossValidationStorageEntry.class,

+                                            validatorException.getClass()),

+                                    entry,

+                                    validatorException);

+                        }

+                        catch (Throwable e)

+                        {

+                            throw new FacesException(e);

+                        }

+                    }

+

+                    if(addMessage)

+                    {

+                        FacesMessage facesMessage = validatorException.getFacesMessage();

+

+                        if (facesMessage != null &&

+                                facesMessage.getSummary() != null && facesMessage.getDetail() != null)

+                        {

+                            ExtValUtils.tryToAddViolationMessageForComponentId(entry.getClientId(), facesMessage);

+                        }

+

+                        ExtValUtils.tryToBlocksNavigationForComponentId(entry.getClientId(), facesMessage);

+                    }

+                }

+                finally

+                {

+                    ExtValUtils.executeGlobalAfterValidationInterceptors(

+                            FacesContext.getCurrentInstance(),

+                            entry.getComponent(),

+                            entry.getConvertedObject(),

+                            CrossValidationStorageEntry.class.getName(),

+                            entry,

+                            PropertyValidationModuleKey.class);

+                }

+            }

+        }

+        finally

+        {

+            CrossValidationUtils.resetCrossValidationStorage();

+        }

+    }

+

+    public void beforePhase(PhaseEvent event)

+    {

+        if (!isInitialized)

+        {

+            if (WebXmlParameter.DEACTIVATE_CROSSVALIDATION != null

+                    && WebXmlParameter.DEACTIVATE_CROSSVALIDATION.equalsIgnoreCase("true"))

+            {

+                JsfUtils.deregisterPhaseListener(this);

+            }

+            else

+            {

+                isInitialized = true;

+            }

+        }

+    }

+

+    public PhaseId getPhaseId()

+    {

+        return PhaseId.ANY_PHASE;

+    }

+

+    @Override

+    public boolean equals(Object o)

+    {

+        if (this == o)

+        {

+            return true;

+        }

+        if (!(o instanceof CrossValidationPhaseListener))

+        {

+            return false;

+        }

+

+        return true;

+    }

+

+    @Override

+    public int hashCode()

+    {

+        return super.hashCode();

+    }

+}

diff --git a/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/crossval/WebXmlParameter.java b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/crossval/WebXmlParameter.java
new file mode 100644
index 0000000..1c40279
--- /dev/null
+++ b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/crossval/WebXmlParameter.java
@@ -0,0 +1,36 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.crossval;

+

+import org.apache.myfaces.extensions.validator.util.WebXmlUtils;

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+

+/**

+ * centralized in order that these information arn't spread over the complete code base

+ *

+ * @author Gerhard Petracek

+ * @since 1.x.1

+ */

+@UsageInformation(UsageCategory.INTERNAL)

+public interface WebXmlParameter

+{

+    static final String DEACTIVATE_CROSSVALIDATION = WebXmlUtils

+            .getInitParameter("DEACTIVATE_CROSSVALIDATION");

+}
\ No newline at end of file
diff --git a/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/crossval/annotation/DateIs.java b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/crossval/annotation/DateIs.java
new file mode 100644
index 0000000..444d2a4
--- /dev/null
+++ b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/crossval/annotation/DateIs.java
@@ -0,0 +1,63 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.crossval.annotation;

+

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+import org.apache.myfaces.extensions.validator.core.validation.parameter.ValidationParameter;

+import org.apache.myfaces.extensions.validator.core.validation.parameter.ViolationSeverity;

+

+import static java.lang.annotation.ElementType.FIELD;

+import static java.lang.annotation.ElementType.METHOD;

+import java.lang.annotation.Retention;

+import static java.lang.annotation.RetentionPolicy.RUNTIME;

+import java.lang.annotation.Target;

+import java.lang.annotation.Documented;

+import java.text.DateFormat;

+

+/**

+ * @author Gerhard Petracek

+ * @since 1.x.1

+ */

+@Target({METHOD, FIELD})

+@Retention(RUNTIME)

+@Documented

+@UsageInformation(UsageCategory.API)

+public @interface DateIs

+{

+    String[] valueOf();

+

+    /*

+     * optional section

+     */

+

+    DateIsType type() default DateIsType.same;

+

+    String validationErrorMsgKey() default "";

+

+    String notBeforeErrorMsgKey() default "wrong_date_not_before";

+

+    String notAfterErrorMsgKey() default "wrong_date_not_after";

+

+    String notEqualErrorMsgKey() default "wrong_date_not_equal";

+

+    int errorMessageDateStyle() default DateFormat.MEDIUM;

+

+    Class<? extends ValidationParameter>[] parameters() default ViolationSeverity.Error.class;

+}
\ No newline at end of file
diff --git a/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/crossval/annotation/DateIsType.java b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/crossval/annotation/DateIsType.java
new file mode 100644
index 0000000..7c5f482
--- /dev/null
+++ b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/crossval/annotation/DateIsType.java
@@ -0,0 +1,35 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.crossval.annotation;

+

+import org.apache.myfaces.extensions.validator.internal.ToDo;

+import org.apache.myfaces.extensions.validator.internal.Priority;

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+

+/**

+ * @author Gerhard Petracek

+ * @since 1.x.1

+ */

+@ToDo(value = Priority.MEDIUM, description = "beforeOrSame, afterOrSame")

+@UsageInformation(UsageCategory.API)

+public enum DateIsType

+{

+    before, after, same

+}

diff --git a/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/crossval/annotation/Equals.java b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/crossval/annotation/Equals.java
new file mode 100644
index 0000000..ffe76b7
--- /dev/null
+++ b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/crossval/annotation/Equals.java
@@ -0,0 +1,48 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.crossval.annotation;

+

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+import org.apache.myfaces.extensions.validator.core.validation.parameter.ValidationParameter;

+import org.apache.myfaces.extensions.validator.core.validation.parameter.ViolationSeverity;

+

+import static java.lang.annotation.ElementType.FIELD;

+import static java.lang.annotation.ElementType.METHOD;

+import java.lang.annotation.Retention;

+import static java.lang.annotation.RetentionPolicy.RUNTIME;

+import java.lang.annotation.Target;

+import java.lang.annotation.Documented;

+

+/**

+ * @author Gerhard Petracek

+ * @since 1.x.1

+ */

+@Target({METHOD, FIELD})

+@Retention(RUNTIME)

+@Documented

+@UsageInformation(UsageCategory.API)

+public @interface Equals

+{

+    String[] value();

+

+    String validationErrorMsgKey() default "duplicated_content_required";

+

+    Class<? extends ValidationParameter>[] parameters() default ViolationSeverity.Error.class;

+}
\ No newline at end of file
diff --git a/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/crossval/annotation/NotEquals.java b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/crossval/annotation/NotEquals.java
new file mode 100644
index 0000000..927bc44
--- /dev/null
+++ b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/crossval/annotation/NotEquals.java
@@ -0,0 +1,48 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.crossval.annotation;

+

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+import org.apache.myfaces.extensions.validator.core.validation.parameter.ValidationParameter;

+import org.apache.myfaces.extensions.validator.core.validation.parameter.ViolationSeverity;

+

+import static java.lang.annotation.ElementType.FIELD;

+import static java.lang.annotation.ElementType.METHOD;

+import java.lang.annotation.Retention;

+import static java.lang.annotation.RetentionPolicy.RUNTIME;

+import java.lang.annotation.Target;

+import java.lang.annotation.Documented;

+

+/**

+ * @author Gerhard Petracek

+ * @since 1.x.1

+ */

+@Target({METHOD, FIELD})

+@Retention(RUNTIME)

+@Documented

+@UsageInformation(UsageCategory.API)

+public @interface NotEquals

+{

+    String[] value();

+

+    String validationErrorMsgKey() default "duplicated_content_denied";

+

+    Class<? extends ValidationParameter>[] parameters() default ViolationSeverity.Error.class;

+}
\ No newline at end of file
diff --git a/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/crossval/annotation/RequiredIf.java b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/crossval/annotation/RequiredIf.java
new file mode 100644
index 0000000..845db24
--- /dev/null
+++ b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/crossval/annotation/RequiredIf.java
@@ -0,0 +1,54 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.crossval.annotation;

+

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+import org.apache.myfaces.extensions.validator.core.validation.parameter.ValidationParameter;

+import org.apache.myfaces.extensions.validator.core.validation.parameter.ViolationSeverity;

+

+import static java.lang.annotation.ElementType.FIELD;

+import static java.lang.annotation.ElementType.METHOD;

+import java.lang.annotation.Retention;

+import static java.lang.annotation.RetentionPolicy.RUNTIME;

+import java.lang.annotation.Target;

+import java.lang.annotation.Documented;

+

+/**

+ * @author Gerhard Petracek

+ * @since 1.x.1

+ */

+@Target({METHOD, FIELD})

+@Retention(RUNTIME)

+@Documented

+@UsageInformation(UsageCategory.API)

+public @interface RequiredIf

+{

+    String[] valueOf();

+

+    /*

+     * optional section

+     */

+

+    RequiredIfType is() default RequiredIfType.not_empty;

+

+    String validationErrorMsgKey() default "empty_field";

+

+    Class<? extends ValidationParameter>[] parameters() default ViolationSeverity.Error.class;

+}
\ No newline at end of file
diff --git a/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/crossval/annotation/RequiredIfType.java b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/crossval/annotation/RequiredIfType.java
new file mode 100644
index 0000000..61c58d9
--- /dev/null
+++ b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/crossval/annotation/RequiredIfType.java
@@ -0,0 +1,32 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.crossval.annotation;

+

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+

+/**

+ * @author Gerhard Petracek

+ * @since 1.x.1

+ */

+@UsageInformation(UsageCategory.API)

+public enum RequiredIfType

+{

+    empty, not_empty

+}
\ No newline at end of file
diff --git a/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/crossval/message/bundle/validation_messages.properties b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/crossval/message/bundle/validation_messages.properties
new file mode 100644
index 0000000..ef60759
--- /dev/null
+++ b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/crossval/message/bundle/validation_messages.properties
@@ -0,0 +1,34 @@
+# Licensed to the Apache Software Foundation (ASF) under one

+# or more contributor license agreements.  See the NOTICE file

+# distributed with this work for additional information

+# regarding copyright ownership.  The ASF licenses this file

+# to you under the Apache License, Version 2.0 (the

+# "License"); you may not use this file except in compliance

+# with the License.  You may obtain a copy of the License at

+#

+#   http://www.apache.org/licenses/LICENSE-2.0

+#

+# Unless required by applicable law or agreed to in writing,

+# software distributed under the License is distributed on an

+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+# KIND, either express or implied.  See the License for the

+# specific language governing permissions and limitations

+# under the License.

+

+duplicated_content_required=Input is different

+duplicated_content_required_detail=Input is different

+

+duplicated_content_denied=Same input isn't allowed

+duplicated_content_denied_detail=Same input isn't allowed

+

+wrong_date=Wrong date

+wrong_date_detail=Wrong date

+

+wrong_date_not_before=Date has to be after {0}

+wrong_date_not_before_detail=Date has to be after {0}

+

+wrong_date_not_after=Date has to be before {0}

+wrong_date_not_after_detail=Date has to be before {0}

+

+wrong_date_not_equal=Date isn't equal to {0}

+wrong_date_not_equal_detail=Date isn't equal to {0}
\ No newline at end of file
diff --git a/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/crossval/message/bundle/validation_messages_ar.properties b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/crossval/message/bundle/validation_messages_ar.properties
new file mode 100644
index 0000000..9ff93c4
--- /dev/null
+++ b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/crossval/message/bundle/validation_messages_ar.properties
@@ -0,0 +1,34 @@
+# Licensed to the Apache Software Foundation (ASF) under one

+# or more contributor license agreements.  See the NOTICE file

+# distributed with this work for additional information

+# regarding copyright ownership.  The ASF licenses this file

+# to you under the Apache License, Version 2.0 (the

+# "License"); you may not use this file except in compliance

+# with the License.  You may obtain a copy of the License at

+#

+#   http://www.apache.org/licenses/LICENSE-2.0

+#

+# Unless required by applicable law or agreed to in writing,

+# software distributed under the License is distributed on an

+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+# KIND, either express or implied.  See the License for the

+# specific language governing permissions and limitations

+# under the License.

+

+duplicated_content_required=\u0627\u0644\u0625\u062f\u062e\u0627\u0644 \u0645\u062e\u062a\u0644\u0641

+duplicated_content_required_detail=\u0627\u0644\u0625\u062f\u062e\u0627\u0644 \u0645\u062e\u062a\u0644\u0641

+

+duplicated_content_denied=\u063a\u064a\u0631 \u0645\u0633\u0645\u0648\u062d \u0628\u0625\u062f\u062e\u0627\u0644 \u0646 \u0641\u0633 \u0642\u064a\u0645\u0629 \u0627\u0644\u0625\u062f\u062e\u0627\u0644

+duplicated_content_denied_detail=\u063a\u064a\u0631 \u0645\u0633\u0645\u0648\u062d \u0628\u0625\u062f\u062e\u0627\u0644  \u0646\u0641\u0633 \u0642\u064a\u0645\u0629 \u0627\u0644\u0625\u062f\u062e\u0627\u0644

+

+wrong_date=\u0627\u0644\u062a\u0627\u0631\u064a\u062e \u062e\u0627\u0637\u0649\u0621

+wrong_date_detail=\u0627\u0644\u062a\u0627\u0631\u064a\u062e \u062e\u0627\u0637\u0649\u0621

+

+wrong_date_not_before=\u0627\u0644\u062a\u0627\u0631\u064a\u062e \u064a\u062c\u0628 \u0623\u0646 \u064a\u0643\u0648 \u0646 \u0628\u0639\u062f {0}

+wrong_date_not_before_detail=\u0627\u0644\u062a\u0627\u0631\u064a\u062e \u064a\u062c\u0628 \u0623\u0646 \u064a\u0643 \u0648\u0646 \u0628\u0639\u062f {0}

+

+wrong_date_not_after=\u0627\u0644\u062a\u0627\u0631\u064a\u062e \u064a\u062c\u0628 \u0623\u0646 \u064a\u0643\u0648 \u0646 \u0642\u0628\u0644 {0}

+wrong_date_not_after_detail=\u0627\u0644\u062a\u0627\u0631\u064a\u062e \u064a\u062c\u0628 \u0623\u0646 \u064a\u0643 \u0648\u0646 \u0642\u0628\u0644 {0}

+

+wrong_date_not_equal=\u0627\u0644\u062a\u0627\u0631\u064a\u062e \u0644\u0627 \u064a\u0633\u0627\u0648\u0649 {0}

+wrong_date_not_equal_detail=\u0627\u0644\u062a\u0627\u0631\u064a\u062e \u0644\u0627 \u064a\u0633\u0627\u0648\u0649 {0}
\ No newline at end of file
diff --git a/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/crossval/message/bundle/validation_messages_ca.properties b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/crossval/message/bundle/validation_messages_ca.properties
new file mode 100644
index 0000000..2854ed2
--- /dev/null
+++ b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/crossval/message/bundle/validation_messages_ca.properties
@@ -0,0 +1,34 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+duplicated_content_required=el valor \u00e9 diferent
+duplicated_content_required_detail=el valor \u00e9 diferent
+
+duplicated_content_denied=no es permet el mateix valor
+duplicated_content_denied_detail=no es permet el mateix valor
+
+wrong_date=data err\u00f2nia
+wrong_date_detail=data err\u00f2nia
+
+wrong_date_not_before=la data ha de ser posterior a {0}
+wrong_date_not_before_detail=la data ha de ser posterior a {0}
+
+wrong_date_not_after=la data ha de ser anterior a {0}
+wrong_date_not_after_detail=la data ha de ser posterior a {0}
+
+wrong_date_not_equal=la data no \u000e9s igual a {0}
+wrong_date_not_equal_detail=la data no \u000e9s igual a {0}
\ No newline at end of file
diff --git a/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/crossval/message/bundle/validation_messages_de.properties b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/crossval/message/bundle/validation_messages_de.properties
new file mode 100644
index 0000000..9d87234
--- /dev/null
+++ b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/crossval/message/bundle/validation_messages_de.properties
@@ -0,0 +1,34 @@
+# Licensed to the Apache Software Foundation (ASF) under one

+# or more contributor license agreements.  See the NOTICE file

+# distributed with this work for additional information

+# regarding copyright ownership.  The ASF licenses this file

+# to you under the Apache License, Version 2.0 (the

+# "License"); you may not use this file except in compliance

+# with the License.  You may obtain a copy of the License at

+#

+#   http://www.apache.org/licenses/LICENSE-2.0

+#

+# Unless required by applicable law or agreed to in writing,

+# software distributed under the License is distributed on an

+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+# KIND, either express or implied.  See the License for the

+# specific language governing permissions and limitations

+# under the License.

+

+duplicated_content_required=Eingabe ist unterschiedlich

+duplicated_content_required_detail=Eingabe ist unterschiedlich

+

+duplicated_content_denied=Der gleiche Wert ist nicht erlaubt

+duplicated_content_denied_detail=Der gleiche Wert ist nicht erlaubt

+

+wrong_date=Datum inkorrekt

+wrong_date_detail=Datum inkorrekt

+

+wrong_date_not_before=Das Datum muss nach dem {0} sein

+wrong_date_not_before_detail=Das Datum muss nach dem {0} sein

+

+wrong_date_not_after=Das Datum muss vor dem {0} sein

+wrong_date_not_after_detail=Das Datum muss vor dem {0} sein

+

+wrong_date_not_equal=Das Datum entspricht nicht dem {0}

+wrong_date_not_equal_detail=Das Datum entspricht nicht dem {0}
\ No newline at end of file
diff --git a/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/crossval/message/bundle/validation_messages_en.properties b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/crossval/message/bundle/validation_messages_en.properties
new file mode 100644
index 0000000..ef60759
--- /dev/null
+++ b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/crossval/message/bundle/validation_messages_en.properties
@@ -0,0 +1,34 @@
+# Licensed to the Apache Software Foundation (ASF) under one

+# or more contributor license agreements.  See the NOTICE file

+# distributed with this work for additional information

+# regarding copyright ownership.  The ASF licenses this file

+# to you under the Apache License, Version 2.0 (the

+# "License"); you may not use this file except in compliance

+# with the License.  You may obtain a copy of the License at

+#

+#   http://www.apache.org/licenses/LICENSE-2.0

+#

+# Unless required by applicable law or agreed to in writing,

+# software distributed under the License is distributed on an

+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+# KIND, either express or implied.  See the License for the

+# specific language governing permissions and limitations

+# under the License.

+

+duplicated_content_required=Input is different

+duplicated_content_required_detail=Input is different

+

+duplicated_content_denied=Same input isn't allowed

+duplicated_content_denied_detail=Same input isn't allowed

+

+wrong_date=Wrong date

+wrong_date_detail=Wrong date

+

+wrong_date_not_before=Date has to be after {0}

+wrong_date_not_before_detail=Date has to be after {0}

+

+wrong_date_not_after=Date has to be before {0}

+wrong_date_not_after_detail=Date has to be before {0}

+

+wrong_date_not_equal=Date isn't equal to {0}

+wrong_date_not_equal_detail=Date isn't equal to {0}
\ No newline at end of file
diff --git a/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/crossval/message/bundle/validation_messages_es.properties b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/crossval/message/bundle/validation_messages_es.properties
new file mode 100644
index 0000000..00a9170
--- /dev/null
+++ b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/crossval/message/bundle/validation_messages_es.properties
@@ -0,0 +1,34 @@
+# Licensed to the Apache Software Foundation (ASF) under one

+# or more contributor license agreements.  See the NOTICE file

+# distributed with this work for additional information

+# regarding copyright ownership.  The ASF licenses this file

+# to you under the Apache License, Version 2.0 (the

+# "License"); you may not use this file except in compliance

+# with the License.  You may obtain a copy of the License at

+#

+#   http://www.apache.org/licenses/LICENSE-2.0

+#

+# Unless required by applicable law or agreed to in writing,

+# software distributed under the License is distributed on an

+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+# KIND, either express or implied.  See the License for the

+# specific language governing permissions and limitations

+# under the License.

+

+duplicated_content_required=la entrada es diferente

+duplicated_content_required_detail=la entrada es diferente

+

+duplicated_content_denied=no se permiten entradas iguales

+duplicated_content_denied_detail=no se permiten entradas iguales

+

+wrong_date=fecha equivocada

+wrong_date_detail=fecha equivocada

+

+wrong_date_not_before=la fecha tiene que ser luego de {0}

+wrong_date_not_before_detail=la fecha tiene que ser luego de {0}

+

+wrong_date_not_after=la fecha tiene que ser antes de {0}

+wrong_date_not_after_detail=la fecha tiene que ser antes de {0}

+

+wrong_date_not_equal=la fecha no es igual a {0}

+wrong_date_not_equal_detail=la fecha no es igual a {0}
\ No newline at end of file
diff --git a/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/crossval/message/bundle/validation_messages_fr.properties b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/crossval/message/bundle/validation_messages_fr.properties
new file mode 100644
index 0000000..c5f0218
--- /dev/null
+++ b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/crossval/message/bundle/validation_messages_fr.properties
@@ -0,0 +1,34 @@
+# Licensed to the Apache Software Foundation (ASF) under one

+# or more contributor license agreements.  See the NOTICE file

+# distributed with this work for additional information

+# regarding copyright ownership.  The ASF licenses this file

+# to you under the Apache License, Version 2.0 (the

+# "License"); you may not use this file except in compliance

+# with the License.  You may obtain a copy of the License at

+#

+#   http://www.apache.org/licenses/LICENSE-2.0

+#

+# Unless required by applicable law or agreed to in writing,

+# software distributed under the License is distributed on an

+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+# KIND, either express or implied.  See the License for the

+# specific language governing permissions and limitations

+# under the License.

+

+duplicated_content_required=Les champs sont diff&eacute;rents

+duplicated_content_required_detail=Les champs sont diff&eacute;rents

+

+duplicated_content_denied=Les champs doivent &ecirc;tre diff&eacute;rents

+duplicated_content_denied_detail=Les champs doivent &ecirc;tre diff&eacute;rents

+

+wrong_date=La date est incorrecte

+wrong_date_detail=La date est incorrecte

+

+wrong_date_not_before=La date doit &ecirc;tre apr&egrave;s {0}

+wrong_date_not_before_detail=La date doit &ecirc;tre apr&egrave;s {0}

+

+wrong_date_not_after=La date doit &ecirc;tre avant {0}

+wrong_date_not_after_detail=La date doit &ecirc;tre avant {0}

+

+wrong_date_not_equal=La date n'est pas &eacute;gale &agrave; {0}

+wrong_date_not_equal_detail=La date n'est pas &eacute;gale &agrave; {0}
\ No newline at end of file
diff --git a/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/crossval/message/bundle/validation_messages_it.properties b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/crossval/message/bundle/validation_messages_it.properties
new file mode 100644
index 0000000..b042801
--- /dev/null
+++ b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/crossval/message/bundle/validation_messages_it.properties
@@ -0,0 +1,34 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+duplicated_content_required=Valori non uguali
+duplicated_content_required_detail=I valori inseriti non coincidono
+
+duplicated_content_denied=Lo stesso valore non &egrave; permesso
+duplicated_content_denied_detail=Lo stesso valore non &egrave; permesso
+
+wrong_date=Data errata
+wrong_date_detail=Data errata
+
+wrong_date_not_before=La data deve essere dopo di {0}
+wrong_date_not_before_detail=La data deve essere dopo di {0}
+
+wrong_date_not_after=La data deve essere prima di {0}
+wrong_date_not_after_detail=La data deve essere prima di {0}
+
+wrong_date_not_equal=La data non &egrave; uguale a {0}
+wrong_date_not_equal_detail=La data non &egrave; uguale a {0}
\ No newline at end of file
diff --git a/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/crossval/message/bundle/validation_messages_tr.properties b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/crossval/message/bundle/validation_messages_tr.properties
new file mode 100644
index 0000000..aaf6a9d
--- /dev/null
+++ b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/crossval/message/bundle/validation_messages_tr.properties
@@ -0,0 +1,35 @@
+# Licensed to the Apache Software Foundation (ASF) under one

+# or more contributor license agreements.  See the NOTICE file

+# distributed with this work for additional information

+# regarding copyright ownership.  The ASF licenses this file

+# to you under the Apache License, Version 2.0 (the

+# "License"); you may not use this file except in compliance

+# with the License.  You may obtain a copy of the License at

+#

+#   http://www.apache.org/licenses/LICENSE-2.0

+#

+# Unless required by applicable law or agreed to in writing,

+# software distributed under the License is distributed on an

+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+# KIND, either express or implied.  See the License for the

+# specific language governing permissions and limitations

+# under the License.

+

+

+duplicated_content_required=girilen de\u011fer farkl\u0131

+duplicated_content_required_detail=girilen de\u011fer farkl\u0131

+

+duplicated_content_denied=ayn\u0131 de\u011fer girilemez

+duplicated_content_denied_detail=ayn\u0131 de\u011fer girilemez

+

+wrong_date=yanl\u0131\u015f tarih

+wrong_date_detail=yanl\u0131\u015f tarih

+

+wrong_date_not_before=tarih {0} de\u011ferinden sonra olmal\u0131d\u0131r

+wrong_date_not_before_detail=tarih {0} de\u011ferinden sonra olmal\u0131d\u0131r

+

+wrong_date_not_after=tarih {0} de\u011ferinden \u00f6nce olmal\u0131d\u0131r

+wrong_date_not_after_detail=tarih {0} de\u011ferinden \u00f6nce olmal\u0131d\u0131r

+

+wrong_date_not_equal=tarih {0} de\u011ferine e\u015fit de\u011fil

+wrong_date_not_equal_detail=tarih {0} de\u011ferine e\u015fit de\u011fil
\ No newline at end of file
diff --git a/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/crossval/message/resolver/DefaultValidationErrorMessageResolver.java b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/crossval/message/resolver/DefaultValidationErrorMessageResolver.java
new file mode 100644
index 0000000..3d7659e
--- /dev/null
+++ b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/crossval/message/resolver/DefaultValidationErrorMessageResolver.java
@@ -0,0 +1,45 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.crossval.message.resolver;

+

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+

+/**

+ * @author Gerhard Petracek

+ * @since 1.x.1

+ */

+@UsageInformation(UsageCategory.INTERNAL)

+public class DefaultValidationErrorMessageResolver

+        extends

+        org.apache.myfaces.extensions.validator.core.validation.message.resolver.DefaultValidationErrorMessageResolver

+{

+    private static String baseName = null;

+

+    @Override

+    protected String getBaseName()

+    {

+        if (baseName == null)

+        {

+            baseName = super.getBaseName();

+        }

+

+        return baseName;

+    }

+}

diff --git a/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/crossval/recorder/CrossValidationUserInputRecorder.java b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/crossval/recorder/CrossValidationUserInputRecorder.java
new file mode 100644
index 0000000..dd3b08d
--- /dev/null
+++ b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/crossval/recorder/CrossValidationUserInputRecorder.java
@@ -0,0 +1,98 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.crossval.recorder;

+

+import org.apache.myfaces.extensions.validator.core.recorder.ProcessedInformationRecorder;

+import org.apache.myfaces.extensions.validator.core.property.PropertyDetails;

+import org.apache.myfaces.extensions.validator.crossval.storage.ProcessedInformationStorageEntry;

+import org.apache.myfaces.extensions.validator.crossval.storage.ProcessedInformationStorage;

+import org.apache.myfaces.extensions.validator.util.CrossValidationUtils;

+import org.apache.myfaces.extensions.validator.util.ExtValUtils;

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+

+import javax.faces.component.UIComponent;

+import javax.faces.component.EditableValueHolder;

+import javax.faces.context.FacesContext;

+import java.util.List;

+import java.util.ArrayList;

+

+/**

+ * @author Gerhard Petracek

+ * @since 1.x.1

+ */

+@UsageInformation(UsageCategory.INTERNAL)

+public class CrossValidationUserInputRecorder implements ProcessedInformationRecorder

+{

+    public void recordUserInput(UIComponent uiComponent, Object value)

+    {

+        if (!(uiComponent instanceof EditableValueHolder))

+        {

+            return;

+        }

+

+        //to support local cross-validation (within the same entity)

+        ProcessedInformationStorage processedInformationStorage = CrossValidationUtils

+            .getOrInitProcessedInformationStorage();

+

+        ProcessedInformationStorageEntry entry;

+

+        PropertyDetails propertyDetails =

+            ExtValUtils.getELHelper().getPropertyDetailsOfValueBinding(uiComponent);

+

+        if(propertyDetails == null)

+        {

+            return;

+        }

+        

+        entry = new ProcessedInformationStorageEntry();

+        entry.setBean(propertyDetails.getBaseObject());

+        entry.setConvertedValue(value);

+        entry.setComponent(uiComponent);

+        entry.setClientId(uiComponent.getClientId(FacesContext.getCurrentInstance()));

+

+        String key = propertyDetails.getKey();

+

+        //for local cross-validation

+        if (processedInformationStorage.containsEntry(key) &&

+            processedInformationStorage.getEntry(key).getBean() != null &&

+            !processedInformationStorage.getEntry(key).getBean().equals(entry.getBean()))

+        {

+            //for the validation within a complex component e.g. a table

+            //don't override existing expression (style: #{entry.property}) - make a special mapping

+

+            List<ProcessedInformationStorageEntry> furtherEntries =

+                processedInformationStorage.getEntry(key).getFurtherEntries();

+

+            if (furtherEntries == null)

+            {

+                furtherEntries = new ArrayList<ProcessedInformationStorageEntry>();

+

+                processedInformationStorage.getEntry(key).setFurtherEntries(furtherEntries);

+            }

+

+            furtherEntries.add(entry);

+        }

+        else

+        {

+            //for normal validation

+            processedInformationStorage.setEntry(key, entry);

+        }

+    }

+}

diff --git a/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/crossval/storage/CrossValidationStorage.java b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/crossval/storage/CrossValidationStorage.java
new file mode 100644
index 0000000..c09fad6
--- /dev/null
+++ b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/crossval/storage/CrossValidationStorage.java
@@ -0,0 +1,38 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.crossval.storage;

+

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+

+import java.util.List;

+

+/**

+ * normally it should be in the storage package - due to backward compatibility it isn't the case

+ *

+ * @author Gerhard Petracek

+ * @since 1.x.1

+ */

+@UsageInformation(UsageCategory.API)

+public interface CrossValidationStorage

+{

+    void add(CrossValidationStorageEntry entry);

+

+    List<CrossValidationStorageEntry> getCrossValidationStorageEntries();

+}

diff --git a/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/crossval/storage/CrossValidationStorageEntry.java b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/crossval/storage/CrossValidationStorageEntry.java
new file mode 100644
index 0000000..c09e1e7
--- /dev/null
+++ b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/crossval/storage/CrossValidationStorageEntry.java
@@ -0,0 +1,94 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.crossval.storage;

+

+import org.apache.myfaces.extensions.validator.core.metadata.MetaDataEntry;

+import org.apache.myfaces.extensions.validator.crossval.strategy.CrossValidationStrategy;

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+

+import javax.faces.component.UIComponent;

+

+/**

+ * normally it should be in the storage package - due to backward compatibility it isn't the case

+ * 

+ * @author Gerhard Petracek

+ * @since 1.x.1

+ */

+@UsageInformation(UsageCategory.API)

+public class CrossValidationStorageEntry

+{

+    private MetaDataEntry metaDataEntry;

+    //for complex components (e.g. a table) stores the object of entry (#{entry.property})

+    private UIComponent component;

+    private Object convertedObject;

+    private CrossValidationStrategy validationStrategy;

+    //just for input components within complex components e.g. dataTable,...

+    private String clientId;

+

+    public MetaDataEntry getMetaDataEntry()

+    {

+        return metaDataEntry;

+    }

+

+    public void setMetaDataEntry(MetaDataEntry metaDataEntry)

+    {

+        this.metaDataEntry = metaDataEntry;

+    }

+

+    public UIComponent getComponent()

+    {

+        return component;

+    }

+

+    public void setComponent(UIComponent component)

+    {

+        this.component = component;

+    }

+

+    public Object getConvertedObject()

+    {

+        return convertedObject;

+    }

+

+    public void setConvertedObject(Object convertedObject)

+    {

+        this.convertedObject = convertedObject;

+    }

+

+    public CrossValidationStrategy getValidationStrategy()

+    {

+        return validationStrategy;

+    }

+

+    public void setValidationStrategy(CrossValidationStrategy validationStrategy)

+    {

+        this.validationStrategy = validationStrategy;

+    }

+

+    public String getClientId()

+    {

+        return clientId;

+    }

+

+    public void setClientId(String clientId)

+    {

+        this.clientId = clientId;

+    }

+}

diff --git a/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/crossval/storage/DefaultCrossValidationStorage.java b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/crossval/storage/DefaultCrossValidationStorage.java
new file mode 100644
index 0000000..ae10a3b
--- /dev/null
+++ b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/crossval/storage/DefaultCrossValidationStorage.java
@@ -0,0 +1,51 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.crossval.storage;

+

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+

+import java.util.ArrayList;

+import java.util.List;

+

+/**

+ * @author Gerhard Petracek

+ * @since x.x.3

+ */

+@UsageInformation(UsageCategory.INTERNAL)

+public class DefaultCrossValidationStorage implements CrossValidationStorage

+{

+    private List<CrossValidationStorageEntry> crossValidationStorageEntries =

+        new ArrayList<CrossValidationStorageEntry>();

+

+    public void add(CrossValidationStorageEntry entry)

+    {

+        this.crossValidationStorageEntries.add(entry);

+    }

+

+    public List<CrossValidationStorageEntry> getCrossValidationStorageEntries()

+    {

+        return crossValidationStorageEntries;

+    }

+

+    public void setCrossValidationStorageEntries(List<CrossValidationStorageEntry> crossValidationStorageEntries)

+    {

+        this.crossValidationStorageEntries = crossValidationStorageEntries;

+    }

+}

diff --git a/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/crossval/storage/DefaultCrossValidationStorageManager.java b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/crossval/storage/DefaultCrossValidationStorageManager.java
new file mode 100644
index 0000000..e041c95d
--- /dev/null
+++ b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/crossval/storage/DefaultCrossValidationStorageManager.java
@@ -0,0 +1,40 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.crossval.storage;

+

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import static org.apache.myfaces.extensions.validator.internal.UsageCategory.INTERNAL;

+import org.apache.myfaces.extensions.validator.core.storage.AbstractRequestScopeAwareStorageManager;

+

+/**

+ * default storage-manager for cross-validation entries

+ *

+ * @author Gerhard Petracek

+ * @since x.x.3

+ */

+@UsageInformation(INTERNAL)

+public class DefaultCrossValidationStorageManager

+    extends AbstractRequestScopeAwareStorageManager<CrossValidationStorage>

+{

+    public String getStorageManagerKey()

+    {

+        //for better backward compatibility

+        return CrossValidationStorage.class.getName();

+    }

+}

diff --git a/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/crossval/storage/DefaultProcessedInformationStorage.java b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/crossval/storage/DefaultProcessedInformationStorage.java
new file mode 100644
index 0000000..c28e187
--- /dev/null
+++ b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/crossval/storage/DefaultProcessedInformationStorage.java
@@ -0,0 +1,51 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.crossval.storage;

+

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+

+import java.util.Map;

+import java.util.HashMap;

+

+/**

+ * @author Gerhard Petracek

+ * @since x.x.3

+ */

+@UsageInformation(UsageCategory.INTERNAL)

+public class DefaultProcessedInformationStorage implements ProcessedInformationStorage

+{

+    private Map<String, ProcessedInformationStorageEntry> processedInformationMap =

+        new HashMap<String, ProcessedInformationStorageEntry>();

+

+    public void setEntry(String key, ProcessedInformationStorageEntry entry)

+    {

+        this.processedInformationMap.put(key, entry);

+    }

+

+    public boolean containsEntry(String key)

+    {

+        return processedInformationMap.containsKey(key);

+    }

+

+    public ProcessedInformationStorageEntry getEntry(String key)

+    {

+        return processedInformationMap.get(key);

+    }

+}
\ No newline at end of file
diff --git a/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/crossval/storage/DefaultProcessedInformationStorageManager.java b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/crossval/storage/DefaultProcessedInformationStorageManager.java
new file mode 100644
index 0000000..66182c8
--- /dev/null
+++ b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/crossval/storage/DefaultProcessedInformationStorageManager.java
@@ -0,0 +1,41 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.crossval.storage;

+

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import static org.apache.myfaces.extensions.validator.internal.UsageCategory.INTERNAL;

+import org.apache.myfaces.extensions.validator.core.storage.AbstractRequestScopeAwareStorageManager;

+import org.apache.myfaces.extensions.validator.util.CrossValidationUtils;

+

+/**

+ * default storage-manager for processed information entries

+ *

+ * @author Gerhard Petracek

+ * @since x.x.3

+ */

+@UsageInformation(INTERNAL)

+public class DefaultProcessedInformationStorageManager

+    extends AbstractRequestScopeAwareStorageManager<CrossValidationStorage>

+{

+    public String getStorageManagerKey()

+    {

+        //for better backward compatibility

+        return CrossValidationUtils.class.getName();

+    }

+}
\ No newline at end of file
diff --git a/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/crossval/storage/ProcessedInformationStorage.java b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/crossval/storage/ProcessedInformationStorage.java
new file mode 100644
index 0000000..a0b156e
--- /dev/null
+++ b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/crossval/storage/ProcessedInformationStorage.java
@@ -0,0 +1,36 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.crossval.storage;

+

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import static org.apache.myfaces.extensions.validator.internal.UsageCategory.INTERNAL;

+

+/**

+ * @author Gerhard Petracek

+ * @since x.x.3

+ */

+@UsageInformation(INTERNAL)

+public interface ProcessedInformationStorage

+{

+    void setEntry(String key, ProcessedInformationStorageEntry entry);

+

+    boolean containsEntry(String key);

+

+    ProcessedInformationStorageEntry getEntry(String key);

+}

diff --git a/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/crossval/storage/ProcessedInformationStorageEntry.java b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/crossval/storage/ProcessedInformationStorageEntry.java
new file mode 100644
index 0000000..3cf789c
--- /dev/null
+++ b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/crossval/storage/ProcessedInformationStorageEntry.java
@@ -0,0 +1,98 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.myfaces.extensions.validator.crossval.storage;
+
+import org.apache.myfaces.extensions.validator.internal.UsageCategory;
+import org.apache.myfaces.extensions.validator.internal.UsageInformation;
+
+import javax.faces.component.UIComponent;
+import java.util.List;
+
+/**
+ * In order to build up a mapping which is used for cross-validation.
+ *
+ * @author Gerhard Petracek
+ * @since 1.x.1
+ */
+@UsageInformation(UsageCategory.INTERNAL)
+public class ProcessedInformationStorageEntry
+{
+    private Object bean;
+    private Object convertedValue;
+    private UIComponent component;
+    //for complex components (e.g. a table there are multiple entries with
+    //the same key (here the el expression #{entry.property})
+    //however, don't override the previous entry - they arn't the same;
+    private List<ProcessedInformationStorageEntry> furtherEntries;
+    //just for input components within complex components e.g. dataTable,...
+    private String clientId;
+
+    /*
+     * generated
+     */
+    public Object getBean()
+    {
+        return bean;
+    }
+
+    public void setBean(Object bean)
+    {
+        this.bean = bean;
+    }
+
+    public Object getConvertedValue()
+    {
+        return convertedValue;
+    }
+
+    public void setConvertedValue(Object convertedValue)
+    {
+        this.convertedValue = convertedValue;
+    }
+
+    public UIComponent getComponent()
+    {
+        return component;
+    }
+
+    public void setComponent(UIComponent component)
+    {
+        this.component = component;
+    }
+
+    public String getClientId()
+    {
+        return clientId;
+    }
+
+    public void setClientId(String clientId)
+    {
+        this.clientId = clientId;
+    }
+
+    public List<ProcessedInformationStorageEntry> getFurtherEntries()
+    {
+        return furtherEntries;
+    }
+
+    public void setFurtherEntries(List<ProcessedInformationStorageEntry> furtherEntries)
+    {
+        this.furtherEntries = furtherEntries;
+    }
+}
diff --git a/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/crossval/storage/mapper/CrossValidationStorageNameMapper.java b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/crossval/storage/mapper/CrossValidationStorageNameMapper.java
new file mode 100644
index 0000000..58ebf3b
--- /dev/null
+++ b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/crossval/storage/mapper/CrossValidationStorageNameMapper.java
@@ -0,0 +1,41 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.crossval.storage.mapper;

+

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import static org.apache.myfaces.extensions.validator.internal.UsageCategory.INTERNAL;

+import org.apache.myfaces.extensions.validator.core.mapper.NameMapper;

+import org.apache.myfaces.extensions.validator.core.InvocationOrder;

+import org.apache.myfaces.extensions.validator.crossval.storage.CrossValidationStorage;

+import org.apache.myfaces.extensions.validator.crossval.storage.DefaultCrossValidationStorage;

+

+/**

+ * @author Gerhard Petracek

+ * @since x.x.3

+ */

+@InvocationOrder(200)

+@UsageInformation(INTERNAL)

+public class CrossValidationStorageNameMapper implements NameMapper<String>

+{

+    public String createName(String key)

+    {

+        return (CrossValidationStorage.class.getName().equals(key)) ?

+                DefaultCrossValidationStorage.class.getName() : null;

+    }

+}

diff --git a/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/crossval/storage/mapper/ProcessedInformationStorageNameMapper.java b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/crossval/storage/mapper/ProcessedInformationStorageNameMapper.java
new file mode 100644
index 0000000..9875303
--- /dev/null
+++ b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/crossval/storage/mapper/ProcessedInformationStorageNameMapper.java
@@ -0,0 +1,41 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.crossval.storage.mapper;

+

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import static org.apache.myfaces.extensions.validator.internal.UsageCategory.INTERNAL;

+import org.apache.myfaces.extensions.validator.core.mapper.NameMapper;

+import org.apache.myfaces.extensions.validator.core.InvocationOrder;

+import org.apache.myfaces.extensions.validator.crossval.storage.ProcessedInformationStorage;

+import org.apache.myfaces.extensions.validator.crossval.storage.DefaultProcessedInformationStorage;

+

+/**

+ * @author Gerhard Petracek

+ * @since x.x.3

+ */

+@InvocationOrder(200)

+@UsageInformation(INTERNAL)

+public class ProcessedInformationStorageNameMapper implements NameMapper<String>

+{

+    public String createName(String key)

+    {

+        return (ProcessedInformationStorage.class.getName().equals(key)) ?

+                DefaultProcessedInformationStorage.class.getName() : null;

+    }

+}
\ No newline at end of file
diff --git a/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/crossval/strategy/AbstractCompareStrategy.java b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/crossval/strategy/AbstractCompareStrategy.java
new file mode 100644
index 0000000..530202b
--- /dev/null
+++ b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/crossval/strategy/AbstractCompareStrategy.java
@@ -0,0 +1,337 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.crossval.strategy;

+

+import java.util.ArrayList;

+import java.util.HashMap;

+import java.util.List;

+import java.util.Map;

+import java.util.MissingResourceException;

+import java.lang.annotation.Annotation;

+

+import javax.faces.application.FacesMessage;

+import javax.faces.validator.ValidatorException;

+

+import org.apache.myfaces.extensions.validator.crossval.storage.CrossValidationStorage;

+import org.apache.myfaces.extensions.validator.crossval.storage.CrossValidationStorageEntry;

+import org.apache.myfaces.extensions.validator.util.ClassUtils;

+import org.apache.myfaces.extensions.validator.util.ExtValUtils;

+import org.apache.myfaces.extensions.validator.core.ExtValContext;

+import org.apache.myfaces.extensions.validator.core.CustomInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+

+/**

+ * @author Gerhard Petracek

+ * @since 1.x.1

+ */

+@SuppressWarnings({"unchecked"})

+@UsageInformation(UsageCategory.INTERNAL)

+public abstract class AbstractCompareStrategy<A extends Annotation> extends AbstractCrossValidationStrategy

+{

+    protected static List<ReferencingStrategy> referencingStrategies;

+    protected Map<Object, Object> violationResultStorage = new HashMap<Object, Object>();

+

+    public AbstractCompareStrategy()

+    {

+        initReferencingStrategies();

+    }

+

+    protected void initReferencingStrategies()

+    {

+        if (referencingStrategies == null)

+        {

+            referencingStrategies = new ArrayList<ReferencingStrategy>();

+

+            String customReferencingStrategyClassName =

+                ExtValContext.getContext().getInformationProviderBean()

+                    .get(CustomInformation.BASE_PACKAGE) + "ReferencingStrategy";

+

+            ReferencingStrategy customReferencingStrategy = (ReferencingStrategy) ClassUtils

+                    .tryToInstantiateClassForName(customReferencingStrategyClassName);

+

+            if (customReferencingStrategy != null)

+            {

+                referencingStrategies.add(customReferencingStrategy);

+            }

+

+            referencingStrategies.add(new ELCompareStrategy());

+            //referencingStrategies.add(new AliasCompareStrategy());

+            referencingStrategies.add(new LocalCompareStrategy());

+            referencingStrategies.add(new LocalPropertyChainCompareStrategy());

+        }

+    }

+

+    public void processCrossValidation(

+            CrossValidationStorageEntry crossValidationStorageEntry,

+            CrossValidationStorage crossValidationStorage) throws ValidatorException

+    {

+        //initCrossValidation is done in the CrossValidationPhaseListener

+

+        String[] validationTargets = getValidationTargets((A)

+            crossValidationStorageEntry.getMetaDataEntry().getValue());

+

+        for (String validationTarget : validationTargets)

+        {

+            validationTarget = validationTarget.trim();

+

+            //select validation method

+            tryToValidate(crossValidationStorageEntry, crossValidationStorage, validationTarget);

+        }

+    }

+

+    private boolean tryToValidate(

+            CrossValidationStorageEntry crossValidationStorageEntry,

+            CrossValidationStorage crossValidationStorage,

+            String validationTarget)

+    {

+        for (ReferencingStrategy referencingStrategy : referencingStrategies)

+        {

+            if (referencingStrategy.evaluateReferenceAndValidate(

+                    crossValidationStorageEntry, crossValidationStorage, validationTarget, this))

+            {

+                return true;

+            }

+        }

+

+        return false;

+    }

+

+    @SuppressWarnings({"ThrowableInstanceNeverThrown"})

+    protected final void processTargetComponentAfterViolation(

+            CrossValidationStorageEntry entryOfSource,

+            CrossValidationStorageEntry entryOfTarget)

+    {

+        if (!handleTargetViolation(entryOfSource, entryOfTarget))

+        {

+            //no target - because there is no target component - value was validated against the model

+            if(entryOfTarget == null)

+            {

+                processTargetComponentAsSourceComponentAfterViolation(entryOfSource);

+                return;

+            }

+

+            return;

+        }

+

+        //get validation error messages for the target component

+        String summary = getErrorMessageSummary((A)entryOfSource.getMetaDataEntry().getValue(), true);

+        String details = getErrorMessageDetail((A)entryOfSource.getMetaDataEntry().getValue(), true);

+

+        //validation target isn't bound to a component withing the current page 

+        //(see validateFoundEntry, tryToValidateLocally and tryToValidateBindingOnly)

+        if (entryOfTarget == null)

+        {

+            entryOfTarget = entryOfSource;

+        }

+

+        FacesMessage message;

+        if (entryOfTarget.getMetaDataEntry() != null)

+        {

+            message = getTargetComponentErrorMessage((A)entryOfTarget.getMetaDataEntry().getValue(), summary, details);

+        }

+        else

+        {

+            //TODO document possible side effects

+            //due to a missing target annotation (see: tryToValidateLocally)

+            message = getTargetComponentErrorMessage((A)entryOfSource.getMetaDataEntry().getValue(), summary, details);

+        }

+

+        if ((message.getSummary() != null || message.getDetail() != null) &&

+            entryOfSource.getClientId() != null && !entryOfSource.getClientId().equals(entryOfTarget.getClientId()))

+        {

+            ValidatorException validatorException = new ValidatorException(message);

+

+            boolean isSourceMetaDataUsed = false;

+

+            if(entryOfTarget.getMetaDataEntry() == null)

+            {

+                prepareTargetMetaDataForSeverityAwareInterception(entryOfSource, entryOfTarget);

+                isSourceMetaDataUsed = true;

+            }

+            

+            if(ExtValUtils.executeAfterThrowingInterceptors(

+                    entryOfTarget.getComponent(), entryOfTarget.getMetaDataEntry(),

+                    entryOfTarget.getConvertedObject(), validatorException, this))

+            {

+                ExtValUtils.tryToAddViolationMessageForComponentId(entryOfTarget.getClientId(),

+                        ExtValUtils.convertFacesMessage(validatorException.getFacesMessage()));

+            }

+

+            if(isSourceMetaDataUsed)

+            {

+                resetTargetMetaData(entryOfTarget);

+            }

+        }

+    }

+

+    private void prepareTargetMetaDataForSeverityAwareInterception(

+            CrossValidationStorageEntry entryOfSource, CrossValidationStorageEntry entryOfTarget)

+    {

+        entryOfTarget.setMetaDataEntry(entryOfSource.getMetaDataEntry());

+    }

+

+    private void resetTargetMetaData(CrossValidationStorageEntry entryOfTarget)

+    {

+        entryOfTarget.setMetaDataEntry(null);

+    }

+

+    @SuppressWarnings({"ThrowableInstanceNeverThrown"})

+    private void processTargetComponentAsSourceComponentAfterViolation(CrossValidationStorageEntry entryOfSource)

+    {

+        //get validation error messages for the current component

+        String summary = getReverseErrorMessageSummary((A)entryOfSource.getMetaDataEntry().getValue());

+        String details = getReverseErrorMessageDetail((A)entryOfSource.getMetaDataEntry().getValue());

+

+        FacesMessage message = getSourceComponentErrorMessage(

+                (A)entryOfSource.getMetaDataEntry().getValue(), summary, details);

+

+        if (message.getSummary() != null || message.getDetail() != null)

+        {

+            //TODO

+            if(ExtValUtils.executeAfterThrowingInterceptors(entryOfSource.getComponent(),

+                    entryOfSource.getMetaDataEntry(),

+                    entryOfSource.getConvertedObject(),

+                    new ValidatorException(message),

+                    this))

+            {

+                ExtValUtils.tryToThrowValidatorExceptionForComponent(entryOfSource.getComponent(), message, null);

+            }

+        }

+        else

+        {

+            //TODO logging

+        }

+    }

+

+    protected final void processSourceComponentAfterViolation(CrossValidationStorageEntry entryOfSource)

+    {

+        if (handleSourceViolation(entryOfSource))

+        {

+            //get validation error messages for the current component

+            String summary = getErrorMessageSummary((A)entryOfSource.getMetaDataEntry().getValue(), false);

+            String details = getErrorMessageDetail((A)entryOfSource.getMetaDataEntry().getValue(), false);

+

+            FacesMessage message = getSourceComponentErrorMessage(

+                (A)entryOfSource.getMetaDataEntry().getValue(), summary, details);

+

+            if (message.getSummary() != null || message.getDetail() != null)

+            {

+                //TODO

+                ExtValUtils.tryToThrowValidatorExceptionForComponent(entryOfSource.getComponent(), message, null);

+            }

+        }

+

+        //just throw a new message - the error message is at the target

+        ExtValUtils.tryToThrowValidatorExceptionForComponent(

+                entryOfSource.getComponent(), new FacesMessage(FacesMessage.SEVERITY_ERROR, null, null), null);

+    }

+

+    protected FacesMessage getSourceComponentErrorMessage(A annotation, String summary, String detail)

+    {

+        return ExtValUtils.createFacesMessage(summary, detail);

+    }

+

+    protected FacesMessage getTargetComponentErrorMessage(A foundAnnotation, String summary, String detail)

+    {

+        return ExtValUtils.createFacesMessage(summary, detail);

+    }

+

+    protected String getErrorMessageSummary(A annotation, boolean isTargetComponent)

+    {

+        return resolveMessage(getValidationErrorMsgKey(annotation, isTargetComponent));

+    }

+

+    protected String getErrorMessageDetail(A annotation, boolean isTargetComponent)

+    {

+        try

+        {

+            String key = getValidationErrorMsgKey(annotation, isTargetComponent);

+            return (key != null) ? resolveMessage(key + DETAIL_MESSAGE_KEY_POSTFIX) : null;

+        }

+        catch (MissingResourceException e)

+        {

+            if(logger.isWarnEnabled())

+            {

+                logger.warn("couldn't find key " + getValidationErrorMsgKey(annotation, isTargetComponent)

+                    + DETAIL_MESSAGE_KEY_POSTFIX, e);

+            }

+        }

+        return null;

+    }

+

+    protected final String getValidationErrorMsgKey(Annotation annotation)

+    {

+        return getValidationErrorMsgKey((A)annotation, false);

+    }

+

+    protected boolean handleTargetViolation(

+            CrossValidationStorageEntry entryOfSource,

+            CrossValidationStorageEntry entryOfTarget)

+    {

+        return entryOfTarget != null && entryOfTarget.getComponent() != null;

+    }

+

+    protected boolean handleSourceViolation(CrossValidationStorageEntry entryOfSource)

+    {

+        return true;

+    }

+

+    protected boolean useTargetComponentToDisplayErrorMsg(CrossValidationStorageEntry crossValidationStorageEntry)

+    {

+        return handleTargetViolation(crossValidationStorageEntry, null);

+    }

+

+    /*

+     * no target component (validation against the model) -> get reverse message for source component

+     */

+    protected String getReverseErrorMessageSummary(A annotation)

+    {

+        //if the message is neutral

+        return getErrorMessageSummary(annotation, true);

+    }

+

+    /*

+     * no target component (validation against the model) -> get reverse message for source component

+     */

+    protected String getReverseErrorMessageDetail(A annotation)

+    {

+        //if the message is neutral

+        return getErrorMessageDetail(annotation, true);

+    }

+

+    /*

+     * abstract methods

+     */

+

+    protected abstract String getValidationErrorMsgKey(A annotation, boolean isTargetComponent);

+

+    /*

+     * implements the specific validation logic

+     */

+

+    public abstract boolean isViolation(Object object1, Object object2, A annotation);

+

+    /*

+     * returns the referenced validation targets of the annotation

+     * e.g. @DateIs(type = DateIsType.before, value = "finalExam")

+     * -> method returns an array with one value ("finalExam")

+     */

+    public abstract String[] getValidationTargets(A annotation);

+}

diff --git a/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/crossval/strategy/AbstractCrossValidationStrategy.java b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/crossval/strategy/AbstractCrossValidationStrategy.java
new file mode 100644
index 0000000..4537612
--- /dev/null
+++ b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/crossval/strategy/AbstractCrossValidationStrategy.java
@@ -0,0 +1,104 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.crossval.strategy;

+

+import org.apache.myfaces.extensions.validator.core.metadata.MetaDataEntry;

+import org.apache.myfaces.extensions.validator.core.validation.strategy.AbstractAnnotationValidationStrategy;

+import org.apache.myfaces.extensions.validator.crossval.storage.CrossValidationStorageEntry;

+import org.apache.myfaces.extensions.validator.util.CrossValidationUtils;

+import org.apache.myfaces.extensions.validator.util.ExtValUtils;

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+

+import javax.faces.component.UIComponent;

+import javax.faces.context.FacesContext;

+import javax.faces.validator.ValidatorException;

+

+/**

+ * @author Gerhard Petracek

+ * @since 1.x.1

+ */

+@UsageInformation(UsageCategory.INTERNAL)

+public abstract class AbstractCrossValidationStrategy extends

+    AbstractAnnotationValidationStrategy implements CrossValidationStrategy

+{

+    //init cross-validation

+    public void processValidation(FacesContext facesContext,

+            UIComponent uiComponent, MetaDataEntry metaDataEntry, Object convertedObject) throws ValidatorException

+    {

+        CrossValidationStorageEntry entry =

+            getCrossValidationStorageEntry(facesContext, uiComponent, metaDataEntry, convertedObject);

+

+        CrossValidationUtils.getOrInitCrossValidationStorage().add(entry);

+    }

+

+    public CrossValidationStorageEntry getCrossValidationStorageEntry(

+            FacesContext facesContext, UIComponent uiComponent,

+            MetaDataEntry metaDataEntry, Object convertedObject)

+    {

+        CrossValidationStorageEntry entry = new CrossValidationStorageEntry();

+

+        entry.setMetaDataEntry(metaDataEntry);

+        entry.setComponent(uiComponent);

+        entry.setClientId(uiComponent.getClientId(facesContext));

+        entry.setConvertedObject(convertedObject);

+        entry.setValidationStrategy(this);

+

+        return entry;

+    }

+

+    @Override

+    protected final boolean processAfterValidatorException(FacesContext facesContext,

+                                                           UIComponent uiComponent,

+                                                           MetaDataEntry metaDataEntry,

+                                                           Object convertedObject,

+                                                           ValidatorException validatorException)

+    {

+        throw new IllegalStateException("not available for cross validation - use processAfterCrossValidatorException");

+    }

+

+    @Override

+    protected final String getLabel(FacesContext facesContext, UIComponent uiComponent, MetaDataEntry metaDataEntry)

+    {

+        throw new IllegalStateException("not available for cross validation");

+    }

+

+    @Override

+    protected final void initValidation(FacesContext facesContext,

+                                        UIComponent uiComponent,

+                                        MetaDataEntry metaDataEntry,

+                                        Object convertedObject)

+    {

+        //not available for cross validation - use initCrossValidation

+    }

+

+    protected void initCrossValidation(CrossValidationStorageEntry crossValidationStorageEntry)

+    {

+        //override if needed

+    }

+

+    //override if needed

+    protected boolean processAfterCrossValidatorException(CrossValidationStorageEntry crossValidationStorageEntry,

+                                                          ValidatorException validatorException)

+    {

+        return ExtValUtils.executeAfterThrowingInterceptors(

+                crossValidationStorageEntry.getComponent(), crossValidationStorageEntry.getMetaDataEntry(),

+                crossValidationStorageEntry.getConvertedObject(), validatorException, this);

+    }

+}

diff --git a/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/crossval/strategy/CrossValidationHelper.java b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/crossval/strategy/CrossValidationHelper.java
new file mode 100644
index 0000000..07d476e
--- /dev/null
+++ b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/crossval/strategy/CrossValidationHelper.java
@@ -0,0 +1,96 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.crossval.strategy;

+

+import org.apache.myfaces.extensions.validator.crossval.storage.ProcessedInformationStorageEntry;

+import org.apache.myfaces.extensions.validator.crossval.storage.CrossValidationStorageEntry;

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+

+import java.lang.annotation.Annotation;

+

+/**

+ * @author Gerhard Petracek

+ * @since 1.x.1

+ */

+@UsageInformation(UsageCategory.INTERNAL)

+class CrossValidationHelper

+{

+    public static void crossValidateCompareStrategy(AbstractCompareStrategy compareStrategy,

+            CrossValidationStorageEntry crossValidationStorageEntry,

+            ProcessedInformationStorageEntry validationTargetEntry,

+            boolean isModelAwareValidation)

+    {

+        if (compareStrategy.isViolation(

+                crossValidationStorageEntry.getConvertedObject(),

+                validationTargetEntry.getConvertedValue(),

+                crossValidationStorageEntry.getMetaDataEntry().getValue(Annotation.class)))

+        {

+            //process after violation

+            //just add messages

+            if(!isModelAwareValidation)

+            {

+                processTargetAfterCrossComponentValidation(

+                        compareStrategy, crossValidationStorageEntry, validationTargetEntry);

+            }

+            else

+            {

+                processTargetAfterModelAwareCrossValidation(

+                        compareStrategy, crossValidationStorageEntry);

+            }

+

+            //thow exception

+            compareStrategy.processSourceComponentAfterViolation(crossValidationStorageEntry);

+        }

+    }

+

+    private static void processTargetAfterCrossComponentValidation(

+            AbstractCompareStrategy compareStrategy,

+            CrossValidationStorageEntry sourceCrossValidationStorageEntry,

+            ProcessedInformationStorageEntry validationTargetEntry)

+    {

+        CrossValidationStorageEntry targetCrossValidationStorageEntry = new CrossValidationStorageEntry();

+

+        if (compareStrategy.useTargetComponentToDisplayErrorMsg(sourceCrossValidationStorageEntry))

+        {

+            targetCrossValidationStorageEntry.setComponent(validationTargetEntry.getComponent());

+            targetCrossValidationStorageEntry.setClientId(validationTargetEntry.getClientId());

+        }

+        else

+        {

+            targetCrossValidationStorageEntry.setComponent(sourceCrossValidationStorageEntry.getComponent());

+            targetCrossValidationStorageEntry.setClientId(sourceCrossValidationStorageEntry.getClientId());

+        }

+

+        targetCrossValidationStorageEntry.setConvertedObject(validationTargetEntry.getConvertedValue());

+        targetCrossValidationStorageEntry.setValidationStrategy(compareStrategy);

+

+        //add message

+        compareStrategy.processTargetComponentAfterViolation(

+                sourceCrossValidationStorageEntry, targetCrossValidationStorageEntry);

+    }

+

+    private static void processTargetAfterModelAwareCrossValidation(

+            AbstractCompareStrategy compareStrategy,

+            CrossValidationStorageEntry crossValidationStorageEntry)

+    {

+        //no target - because there is no target component - value was validated against the model

+        compareStrategy.processTargetComponentAfterViolation(crossValidationStorageEntry, null);

+    }

+}

diff --git a/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/crossval/strategy/CrossValidationStrategy.java b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/crossval/strategy/CrossValidationStrategy.java
new file mode 100644
index 0000000..0c27da5
--- /dev/null
+++ b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/crossval/strategy/CrossValidationStrategy.java
@@ -0,0 +1,47 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.crossval.strategy;

+

+import org.apache.myfaces.extensions.validator.core.metadata.MetaDataEntry;

+import org.apache.myfaces.extensions.validator.core.validation.strategy.ValidationStrategy;

+import org.apache.myfaces.extensions.validator.crossval.storage.CrossValidationStorage;

+import org.apache.myfaces.extensions.validator.crossval.storage.CrossValidationStorageEntry;

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+

+import javax.faces.component.UIComponent;

+import javax.faces.context.FacesContext;

+import javax.faces.validator.ValidatorException;

+

+/**

+ * @author Gerhard Petracek

+ * @since 1.x.1

+ */

+@UsageInformation(UsageCategory.API)

+public interface CrossValidationStrategy extends ValidationStrategy

+{

+    CrossValidationStorageEntry getCrossValidationStorageEntry(

+            FacesContext facesContext, UIComponent uiComponent,

+            MetaDataEntry metaDataEntry, Object convertedObject);

+

+    void processCrossValidation(

+            CrossValidationStorageEntry crossValidationStorageEntry,

+            CrossValidationStorage crossValidationStorage)

+            throws ValidatorException;

+}

diff --git a/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/crossval/strategy/DateIsStrategy.java b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/crossval/strategy/DateIsStrategy.java
new file mode 100644
index 0000000..10afc8f
--- /dev/null
+++ b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/crossval/strategy/DateIsStrategy.java
@@ -0,0 +1,261 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.crossval.strategy;

+

+import org.apache.myfaces.extensions.validator.crossval.storage.CrossValidationStorageEntry;

+import org.apache.myfaces.extensions.validator.crossval.annotation.DateIs;

+import org.apache.myfaces.extensions.validator.crossval.annotation.DateIsType;

+import org.apache.myfaces.extensions.validator.baseval.annotation.SkipValidationSupport;

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+

+import javax.faces.context.FacesContext;

+import java.text.DateFormat;

+import java.util.Date;

+import java.util.MissingResourceException;

+

+/**

+ * @author Gerhard Petracek

+ * @since 1.x.1

+ */

+@SkipValidationSupport

+@UsageInformation(UsageCategory.INTERNAL)

+public class DateIsStrategy extends AbstractCompareStrategy<DateIs>

+{

+    protected static final String TOO_EARLY = "early";

+    protected static final String TOO_LATE = "late";

+    protected static final String NOT_EQUAL_DATE_TIME = "not equal";

+    protected static final String RESULT_KEY = "result";

+    protected static final String COMPARED_VALUE_KEY = "target value";

+    protected static final String REVERSE_COMPARED_VALUE_KEY = "reverse target value";

+

+    @Override

+    public boolean useTargetComponentToDisplayErrorMsg(

+            CrossValidationStorageEntry crossValidationStorageEntry)

+    {

+        return true;

+    }

+

+    //TODO test & remove

+    @Override

+    protected boolean handleSourceViolation(CrossValidationStorageEntry entryOfSource)

+    {

+        return false;

+    }

+

+    public boolean isViolation(Object object1, Object object2, DateIs annotation)

+    {

+        boolean violationFound;

+

+        if (annotation.type().equals(DateIsType.same))

+        {

+            violationFound = object1 != null && !object1.equals(object2);

+

+            if (violationFound)

+            {

+                this.violationResultStorage.put(RESULT_KEY, NOT_EQUAL_DATE_TIME);

+            }

+        }

+        else if (annotation.type().equals(DateIsType.before))

+        {

+            violationFound = object1 != null && object2 != null &&

+                            (!new Date(((Date) object1).getTime()).before((Date) object2) || object1.equals(object2));

+

+            if (violationFound)

+            {

+                this.violationResultStorage.put(RESULT_KEY, TOO_LATE);

+            }

+        }

+        else

+        {

+            violationFound = object1 != null && object2 != null &&

+                            (!new Date(((Date) object1).getTime()).after((Date) object2) || object1.equals(object2));

+

+            if (violationFound)

+            {

+                this.violationResultStorage.put(RESULT_KEY, TOO_EARLY);

+            }

+        }

+

+        if (violationFound)

+        {

+            this.violationResultStorage.put(COMPARED_VALUE_KEY, object1);

+            this.violationResultStorage.put(REVERSE_COMPARED_VALUE_KEY, object2);

+        }

+

+        return violationFound;

+    }

+

+    public String[] getValidationTargets(DateIs annotation)

+    {

+        return annotation.valueOf();

+    }

+

+    /*

+     * protected

+     */

+    protected String getValidationErrorMsgKey(DateIs annotation, boolean isTargetComponent)

+    {

+        String result = (String) this.violationResultStorage.get(RESULT_KEY);

+

+        if (!isTargetComponent)

+        {

+            result = reverseResult(result);

+        }

+

+        if (TOO_EARLY.equals(result))

+        {

+            return getNotAfterErrorMsgKey(annotation);

+        }

+        else if (TOO_LATE.equals(result))

+        {

+            return getNotBeforeErrorMsgKey(annotation);

+        }

+        else

+        {

+            return getNotEqualErrorMsgKey(annotation);

+        }

+    }

+

+    private String reverseResult(String result)

+    {

+        if (TOO_EARLY.equals(result))

+        {

+            return TOO_LATE;

+        }

+        else

+        {

+            return TOO_EARLY;

+        }

+    }

+

+    @Override

+    protected String getErrorMessageSummary(DateIs annotation, boolean isTargetComponent)

+    {

+        if (!isTargetComponent)

+        {

+            return super.getErrorMessageSummary(annotation, isTargetComponent);

+        }

+

+        return getErrorMessage(getValidationErrorMsgKey(annotation, isTargetComponent), annotation, isTargetComponent);

+    }

+

+    @Override

+    protected String getErrorMessageDetail(DateIs annotation, boolean isTargetComponent)

+    {

+        if (!isTargetComponent)

+        {

+            return super.getErrorMessageDetail(annotation, isTargetComponent);

+        }

+

+        try

+        {

+            return getErrorMessage(getValidationErrorMsgKey(annotation, isTargetComponent)

+                    + DETAIL_MESSAGE_KEY_POSTFIX, annotation, isTargetComponent);

+        }

+        catch (MissingResourceException e)

+        {

+            if(logger.isWarnEnabled())

+            {

+                logger.warn("couldn't find key " + getValidationErrorMsgKey(annotation, isTargetComponent)

+                    + DETAIL_MESSAGE_KEY_POSTFIX, e);

+            }

+        }

+        return null;

+    }

+

+    @Override

+    protected String getReverseErrorMessageSummary(DateIs annotation)

+    {

+        return getErrorMessage(getValidationErrorMsgKey(annotation, false), annotation, false);

+    }

+

+    @Override

+    protected String getReverseErrorMessageDetail(DateIs annotation)

+    {

+        try

+        {

+            return getErrorMessage(getValidationErrorMsgKey(annotation, false)

+                    + DETAIL_MESSAGE_KEY_POSTFIX, annotation, false);

+        }

+        catch (MissingResourceException e)

+        {

+            if(logger.isWarnEnabled())

+            {

+                logger.warn("couldn't find key " + getValidationErrorMsgKey(annotation)

+                    + DETAIL_MESSAGE_KEY_POSTFIX, e);

+            }

+        }

+        return null;

+    }

+

+    protected String getErrorMessage(String key, DateIs annotation, boolean isTargetComponent)

+    {

+        String message = resolveMessage(key);

+

+        DateFormat dateFormat = DateFormat.getDateInstance(annotation.errorMessageDateStyle(),

+            FacesContext.getCurrentInstance().getViewRoot().getLocale());

+

+        String result;

+

+        if(isTargetComponent)

+        {

+            result = message.replace("{0}",

+                        dateFormat.format((Date) this.violationResultStorage.get(COMPARED_VALUE_KEY)));

+        }

+        else

+        {

+            result = message.replace("{0}",

+                        dateFormat.format((Date) this.violationResultStorage.get(REVERSE_COMPARED_VALUE_KEY)));

+        }

+

+        //replace placeholder with the value of the other component

+        return result;

+    }

+

+    /*

+     * private

+     */

+    private String getNotAfterErrorMsgKey(DateIs annotation)

+    {

+        if (annotation.validationErrorMsgKey().equals(""))

+        {

+            return annotation.notAfterErrorMsgKey();

+        }

+        return annotation.validationErrorMsgKey();

+    }

+

+    private String getNotBeforeErrorMsgKey(DateIs annotation)

+    {

+        if (annotation.validationErrorMsgKey().equals(""))

+        {

+            return annotation.notBeforeErrorMsgKey();

+        }

+        return annotation.validationErrorMsgKey();

+    }

+

+    private String getNotEqualErrorMsgKey(DateIs annotation)

+    {

+        if (annotation.validationErrorMsgKey().equals(""))

+        {

+            return annotation.notEqualErrorMsgKey();

+        }

+        return annotation.validationErrorMsgKey();

+    }

+}

diff --git a/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/crossval/strategy/ELCompareStrategy.java b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/crossval/strategy/ELCompareStrategy.java
new file mode 100644
index 0000000..56911d5
--- /dev/null
+++ b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/crossval/strategy/ELCompareStrategy.java
@@ -0,0 +1,127 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.crossval.strategy;

+

+import org.apache.myfaces.extensions.validator.crossval.storage.CrossValidationStorageEntry;

+import org.apache.myfaces.extensions.validator.crossval.storage.CrossValidationStorage;

+import org.apache.myfaces.extensions.validator.crossval.storage.ProcessedInformationStorage;

+import org.apache.myfaces.extensions.validator.crossval.storage.ProcessedInformationStorageEntry;

+import org.apache.myfaces.extensions.validator.util.ExtValUtils;

+import org.apache.myfaces.extensions.validator.util.CrossValidationUtils;

+import org.apache.myfaces.extensions.validator.internal.ToDo;

+import org.apache.myfaces.extensions.validator.internal.Priority;

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+import org.apache.myfaces.extensions.validator.core.el.ValueBindingExpression;

+import org.apache.commons.logging.Log;

+import org.apache.commons.logging.LogFactory;

+

+import javax.faces.context.FacesContext;

+

+/**

+ * referencing validation targets - possible formats:

+ * "#{[bean_name].[property_name]}" ... cross-entity validation with value binding

+ *

+ * @author Gerhard Petracek

+ * @since 1.x.1

+ */

+@UsageInformation(UsageCategory.INTERNAL)

+class ELCompareStrategy implements ReferencingStrategy

+{

+    protected final Log logger = LogFactory.getLog(getClass());

+

+    public boolean evaluateReferenceAndValidate(

+            CrossValidationStorageEntry crossValidationStorageEntry,

+            CrossValidationStorage crossValidationStorage,

+            String validationTarget, AbstractCompareStrategy compareStrategy)

+    {

+        if (ExtValUtils.getELHelper().isELTermWellFormed(validationTarget) &&

+            ExtValUtils.getELHelper().isELTermValid(FacesContext.getCurrentInstance(), validationTarget))

+        {

+            tryToValidateValueBinding(

+                    crossValidationStorageEntry,

+                    new ValueBindingExpression(validationTarget), crossValidationStorage, compareStrategy);

+

+            return true;

+        }

+        return false;

+    }

+

+    @ToDo(value = Priority.MEDIUM, description = "test")

+    protected boolean tryToValidateValueBinding(

+            CrossValidationStorageEntry crossValidationStorageEntry,

+            ValueBindingExpression validationTarget,

+            CrossValidationStorage crossValidationStorage,

+            AbstractCompareStrategy compareStrategy)

+    {

+        ProcessedInformationStorageEntry validationTargetEntry =

+                resolveTargetForCrossComponentValidation(crossValidationStorageEntry, validationTarget);

+

+        if(validationTargetEntry != null)

+        {

+            processCrossComponentValidation(compareStrategy, crossValidationStorageEntry, validationTargetEntry);

+        }

+        else

+        {

+            processModelAwareCrossValidation(compareStrategy, crossValidationStorageEntry, validationTarget);

+        }

+

+        return true;

+    }

+

+    private ProcessedInformationStorageEntry resolveTargetForCrossComponentValidation(

+            CrossValidationStorageEntry crossValidationStorageEntry,

+            ValueBindingExpression validationTarget)

+    {

+        ProcessedInformationStorage processedInformationStorage =

+                CrossValidationUtils.getOrInitProcessedInformationStorage();

+

+        return CrossValidationUtils.resolveValidationTargetEntry(

+                processedInformationStorage,

+                CrossValidationUtils.convertValueBindingExpressionToProcessedInformationKey(validationTarget),

+                crossValidationStorageEntry);

+    }

+

+    private void processCrossComponentValidation(

+            AbstractCompareStrategy compareStrategy,

+            CrossValidationStorageEntry crossValidationStorageEntry,

+            ProcessedInformationStorageEntry validationTargetEntry)

+    {

+        CrossValidationHelper

+                .crossValidateCompareStrategy(

+                        compareStrategy, crossValidationStorageEntry, validationTargetEntry, false);

+    }

+

+    private void processModelAwareCrossValidation(

+            AbstractCompareStrategy compareStrategy,

+            CrossValidationStorageEntry crossValidationStorageEntry,

+            ValueBindingExpression validationTarget)

+    {

+        FacesContext facesContext = FacesContext.getCurrentInstance();

+        Object targetValue = ExtValUtils.getELHelper().getValueOfExpression(facesContext, validationTarget);

+

+        ProcessedInformationStorageEntry targetEntry = new ProcessedInformationStorageEntry();

+        targetEntry.setBean(

+                ExtValUtils.getELHelper().getValueOfExpression(facesContext, validationTarget.getBaseExpression()));

+        targetEntry.setConvertedValue(targetValue);

+

+        CrossValidationHelper

+                .crossValidateCompareStrategy(compareStrategy, crossValidationStorageEntry, targetEntry, true);

+    }

+}

diff --git a/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/crossval/strategy/EqualsStrategy.java b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/crossval/strategy/EqualsStrategy.java
new file mode 100644
index 0000000..4edb3f5
--- /dev/null
+++ b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/crossval/strategy/EqualsStrategy.java
@@ -0,0 +1,61 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.crossval.strategy;

+

+import org.apache.myfaces.extensions.validator.crossval.storage.CrossValidationStorageEntry;

+import org.apache.myfaces.extensions.validator.crossval.annotation.Equals;

+import org.apache.myfaces.extensions.validator.baseval.annotation.SkipValidationSupport;

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+import org.apache.myfaces.extensions.validator.core.validation.NullValueAwareValidationStrategy;

+import org.apache.myfaces.extensions.validator.core.validation.EmptyValueAwareValidationStrategy;

+

+import java.lang.annotation.Annotation;

+

+/**

+ * @author Gerhard Petracek

+ * @since 1.x.1

+ */

+@SkipValidationSupport

+@NullValueAwareValidationStrategy

+@EmptyValueAwareValidationStrategy

+@UsageInformation(UsageCategory.INTERNAL)

+public class EqualsStrategy extends AbstractCompareStrategy

+{

+    @Override

+    public boolean useTargetComponentToDisplayErrorMsg(CrossValidationStorageEntry crossValidationStorageEntry)

+    {

+        return true;

+    }

+

+    protected String getValidationErrorMsgKey(Annotation annotation, boolean isTargetComponent)

+    {

+        return ((Equals) annotation).validationErrorMsgKey();

+    }

+

+    public boolean isViolation(Object object1, Object object2, Annotation annotation)

+    {

+        return object1 != null && !object1.equals(object2);

+    }

+

+    public String[] getValidationTargets(Annotation annotation)

+    {

+        return ((Equals) annotation).value();

+    }

+}

diff --git a/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/crossval/strategy/LocalCompareStrategy.java b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/crossval/strategy/LocalCompareStrategy.java
new file mode 100644
index 0000000..9752f3c
--- /dev/null
+++ b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/crossval/strategy/LocalCompareStrategy.java
@@ -0,0 +1,199 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.crossval.strategy;

+

+import org.apache.myfaces.extensions.validator.crossval.storage.CrossValidationStorageEntry;

+import org.apache.myfaces.extensions.validator.crossval.storage.CrossValidationStorage;

+import org.apache.myfaces.extensions.validator.crossval.storage.ProcessedInformationStorage;

+import org.apache.myfaces.extensions.validator.crossval.storage.ProcessedInformationStorageEntry;

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+import org.apache.myfaces.extensions.validator.core.property.PropertyDetails;

+import org.apache.myfaces.extensions.validator.core.el.ValueBindingExpression;

+import org.apache.myfaces.extensions.validator.core.property.PropertyInformationKeys;

+import org.apache.myfaces.extensions.validator.util.CrossValidationUtils;

+import org.apache.myfaces.extensions.validator.util.ReflectionUtils;

+import org.apache.myfaces.extensions.validator.util.ProxyUtils;

+import org.apache.commons.logging.Log;

+import org.apache.commons.logging.LogFactory;

+

+import java.lang.reflect.Method;

+

+/**

+ * "[property_name]" ... local validation -> cross-component, but no cross-entity validation

+ *

+ * @author Gerhard Petracek

+ * @since 1.x.1

+ */

+@UsageInformation(UsageCategory.INTERNAL)

+class LocalCompareStrategy implements ReferencingStrategy

+{

+    protected final Log logger = LogFactory.getLog(getClass());

+

+    public boolean evaluateReferenceAndValidate(

+            CrossValidationStorageEntry crossValidationStorageEntry,

+            CrossValidationStorage crossValidationStorage,

+            String validationTarget, AbstractCompareStrategy compareStrategy)

+    {

+        if(validationTarget.contains("."))

+        {

+            //LocalPropertyChainCompareStrategy will continue

+            return false;

+        }

+

+        return tryToValidateLocally(

+            crossValidationStorageEntry,

+            crossValidationStorage,

+            validationTarget,

+            compareStrategy);

+    }

+

+    protected boolean tryToValidateLocally(

+            CrossValidationStorageEntry crossValidationStorageEntry,

+            CrossValidationStorage crossValidationStorage,

+            String targetKey,

+            AbstractCompareStrategy compareStrategy)

+    {

+        ProcessedInformationStorage processedInformationStorage =

+                CrossValidationUtils.getOrInitProcessedInformationStorage();

+

+        boolean isModelAwareValidation =

+                isModelAwareCrossValidation(crossValidationStorageEntry, processedInformationStorage, targetKey);

+

+        String targetProperty = targetKey;

+

+        String sourceKey = resolveSourceKey(crossValidationStorageEntry);

+        targetKey = sourceKey.substring(0, sourceKey.lastIndexOf(".") + 1) + targetKey;

+

+        ProcessedInformationStorageEntry validationTargetEntry = CrossValidationUtils.resolveValidationTargetEntry(

+                processedInformationStorage, targetKey, crossValidationStorageEntry);

+

+        if (validationTargetEntry != null && validationTargetEntry.getComponent() != null && !isModelAwareValidation)

+        {

+            processCrossComponentValidation(compareStrategy, crossValidationStorageEntry, validationTargetEntry);

+        }

+        //no target - because there is no target component - value was validated against the model

+        else if(isModelAwareValidation)

+        {

+            processModelAwareCrossValidation(compareStrategy, crossValidationStorageEntry, targetProperty);

+        }

+        else

+        {

+            unsupportedCase(crossValidationStorageEntry);

+        }

+

+        return true;

+    }

+

+    protected String createTargetKey(CrossValidationStorageEntry crossValidationStorageEntry, String targetKey)

+    {

+        //no real value binding expression

+        //ValueBindingExpression just hepls to replace the property of the key

+        //here only dot-notation is allowed -> no problem

+        ValueBindingExpression baseExpression =

+            new ValueBindingExpression("#{" + crossValidationStorageEntry.getMetaDataEntry()

+                .getProperty(PropertyInformationKeys.PROPERTY_DETAILS,

+                    PropertyDetails.class).getKey() + "}");

+

+        String result = ValueBindingExpression.replaceOrAddProperty(baseExpression, targetKey)

+            .getExpressionString();

+        return result.substring(2, result.length() -1);

+    }

+

+    protected Object getValueOfProperty(Object base, String property)

+    {

+        property = property.substring(0,1).toUpperCase() + property.substring(1, property.length());

+        Class targetClass = ProxyUtils.getUnproxiedClass(base.getClass());

+        Method targetMethod = ReflectionUtils.tryToGetMethod(targetClass, "get" + property);

+

+        if(targetMethod == null)

+        {

+            targetMethod = ReflectionUtils.tryToGetMethod(targetClass, "is" + property);

+        }

+

+        if(targetMethod == null)

+        {

+            throw new IllegalStateException(

+                "class " + base.getClass() + " has no public get/is " + property.toLowerCase());

+        }

+        return ReflectionUtils.tryToInvokeMethod(base, targetMethod);

+    }

+

+    private boolean isModelAwareCrossValidation(

+            CrossValidationStorageEntry crossValidationStorageEntry,

+            ProcessedInformationStorage keyConvertedValueMapping,

+            String targetKey)

+    {

+        String newKey = createTargetKey(crossValidationStorageEntry, targetKey);

+

+        return !keyConvertedValueMapping.containsEntry(newKey);

+

+    }

+

+    private String resolveSourceKey(CrossValidationStorageEntry crossValidationStorageEntry)

+    {

+        PropertyDetails propertyDetails = crossValidationStorageEntry.getMetaDataEntry()

+                .getProperty(PropertyInformationKeys.PROPERTY_DETAILS, PropertyDetails.class);

+

+        String sourceKey = propertyDetails.getKey();

+

+        if(!sourceKey.contains("."))

+        {

+            throw new IllegalStateException("source path: " + sourceKey + " invalid");

+        }

+

+        return sourceKey;

+    }

+

+    private void unsupportedCase(CrossValidationStorageEntry crossValidationStorageEntry)

+    {

+        if(logger.isWarnEnabled())

+        {

+            logger.warn("couldn't find converted object for " +  crossValidationStorageEntry.getMetaDataEntry()

+            .getProperty(PropertyInformationKeys.PROPERTY_DETAILS, PropertyDetails.class).getKey());

+        }

+    }

+

+    private void processCrossComponentValidation(

+            AbstractCompareStrategy compareStrategy,

+            CrossValidationStorageEntry crossValidationStorageEntry,

+            ProcessedInformationStorageEntry validationTargetEntry)

+    {

+        CrossValidationHelper

+                .crossValidateCompareStrategy(

+                        compareStrategy, crossValidationStorageEntry, validationTargetEntry, false);

+    }

+

+    private void processModelAwareCrossValidation(

+            AbstractCompareStrategy compareStrategy,

+            CrossValidationStorageEntry crossValidationStorageEntry,

+            String targetProperty)

+    {

+        ProcessedInformationStorageEntry targetEntry = new ProcessedInformationStorageEntry();

+

+        targetEntry.setBean(

+                crossValidationStorageEntry.getMetaDataEntry()

+                        .getProperty(PropertyInformationKeys.PROPERTY_DETAILS, PropertyDetails.class).getBaseObject());

+        targetEntry

+                .setConvertedValue(getValueOfProperty(targetEntry.getBean(), targetProperty));

+

+        CrossValidationHelper

+                .crossValidateCompareStrategy(compareStrategy, crossValidationStorageEntry, targetEntry, true);

+    }

+}

diff --git a/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/crossval/strategy/LocalPropertyChainCompareStrategy.java b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/crossval/strategy/LocalPropertyChainCompareStrategy.java
new file mode 100644
index 0000000..0eb656c
--- /dev/null
+++ b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/crossval/strategy/LocalPropertyChainCompareStrategy.java
@@ -0,0 +1,147 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.crossval.strategy;

+

+import org.apache.myfaces.extensions.validator.crossval.storage.CrossValidationStorage;

+import org.apache.myfaces.extensions.validator.crossval.storage.CrossValidationStorageEntry;

+import org.apache.myfaces.extensions.validator.crossval.storage.ProcessedInformationStorageEntry;

+import org.apache.myfaces.extensions.validator.crossval.storage.ProcessedInformationStorage;

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+import org.apache.myfaces.extensions.validator.util.CrossValidationUtils;

+import org.apache.myfaces.extensions.validator.util.ReflectionUtils;

+import org.apache.myfaces.extensions.validator.core.property.PropertyDetails;

+import org.apache.myfaces.extensions.validator.core.property.PropertyInformationKeys;

+

+import java.lang.annotation.Annotation;

+

+/**

+ * "[local_property.property1.property2]"

+ *

+ * @author Gerhard Petracek

+ * @since 1.x.1

+ */

+@UsageInformation(UsageCategory.INTERNAL)

+class LocalPropertyChainCompareStrategy extends LocalCompareStrategy

+{

+    @Override

+    public boolean evaluateReferenceAndValidate(

+            CrossValidationStorageEntry crossValidationStorageEntry,

+            CrossValidationStorage crossValidationStorage,

+            String validationTarget, AbstractCompareStrategy compareStrategy)

+    {

+        if(!validationTarget.contains("."))

+        {

+            //not supported - TODO add logging

+            return false;

+        }

+

+        return tryToValidateLocally(

+            crossValidationStorageEntry,

+            crossValidationStorage,

+            validationTarget,

+            compareStrategy);

+    }

+

+    @Override

+    protected boolean tryToValidateLocally(CrossValidationStorageEntry crossValidationStorageEntry,

+                                           CrossValidationStorage crossValidationStorage,

+                                           String targetKey,

+                                           AbstractCompareStrategy compareStrategy)

+    {

+        ProcessedInformationStorage processedInformationStorage =

+                CrossValidationUtils.getOrInitProcessedInformationStorage();

+

+        String newKey = createTargetKey(crossValidationStorageEntry, targetKey);

+

+        if (processedInformationStorage.containsEntry(newKey))

+        {

+            ProcessedInformationStorageEntry validationTargetEntry = processedInformationStorage.getEntry(newKey);

+

+            processCrossComponentValidation(compareStrategy, crossValidationStorageEntry, validationTargetEntry);

+        }

+        //no target - because there is no target component - value was validated against the model

+        else

+        {

+            processModelAwareCrossValidation(compareStrategy, crossValidationStorageEntry, targetKey);

+        }

+

+        return true;

+    }

+

+    private void processCrossComponentValidation(

+            AbstractCompareStrategy compareStrategy,

+            CrossValidationStorageEntry crossValidationStorageEntry,

+            ProcessedInformationStorageEntry targetInformationEntry)

+    {

+        if (compareStrategy.isViolation(

+                crossValidationStorageEntry.getConvertedObject(),

+                targetInformationEntry.getConvertedValue(),

+                crossValidationStorageEntry.getMetaDataEntry().getValue(Annotation.class)))

+        {

+            CrossValidationStorageEntry tmpCrossValidationStorageEntry = new CrossValidationStorageEntry();

+            tmpCrossValidationStorageEntry.setComponent(crossValidationStorageEntry.getComponent());

+            tmpCrossValidationStorageEntry.setClientId(targetInformationEntry.getClientId());

+            tmpCrossValidationStorageEntry.setConvertedObject(targetInformationEntry.getConvertedValue());

+            tmpCrossValidationStorageEntry.setValidationStrategy(compareStrategy);

+

+            //process after violation

+            //just add messages

+            if(crossValidationStorageEntry.getComponent() != null)

+            {

+                compareStrategy.processTargetComponentAfterViolation(

+                        crossValidationStorageEntry, tmpCrossValidationStorageEntry);

+            }

+            else

+            {

+                compareStrategy.processTargetComponentAfterViolation(crossValidationStorageEntry, null);

+            }

+

+            //thow exception

+            compareStrategy.processSourceComponentAfterViolation(crossValidationStorageEntry);

+        }

+    }

+

+    private void processModelAwareCrossValidation(

+            AbstractCompareStrategy compareStrategy,

+            CrossValidationStorageEntry crossValidationStorageEntry, String targetKey)

+    {

+        PropertyDetails propertyDetails = crossValidationStorageEntry.getMetaDataEntry()

+            .getProperty(PropertyInformationKeys.PROPERTY_DETAILS, PropertyDetails.class);

+

+        Object newBase = ReflectionUtils

+            .getBaseOfPropertyChain(propertyDetails.getBaseObject(), targetKey);

+

+        if(targetKey.contains("."))

+        {

+            //find the last property

+            targetKey = targetKey.substring(targetKey.lastIndexOf(".") + 1, targetKey.length());

+        }

+

+        Object targetValue = getValueOfProperty(newBase, targetKey);

+

+        ProcessedInformationStorageEntry targetEntry = new ProcessedInformationStorageEntry();

+        targetEntry.setBean(newBase);

+        targetEntry.setConvertedValue(targetValue);

+

+        CrossValidationHelper

+                .crossValidateCompareStrategy(

+                        compareStrategy, crossValidationStorageEntry, targetEntry, true);

+    }

+}
\ No newline at end of file
diff --git a/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/crossval/strategy/NotEqualsStrategy.java b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/crossval/strategy/NotEqualsStrategy.java
new file mode 100644
index 0000000..f509e84
--- /dev/null
+++ b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/crossval/strategy/NotEqualsStrategy.java
@@ -0,0 +1,58 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.crossval.strategy;

+

+import org.apache.myfaces.extensions.validator.crossval.annotation.NotEquals;

+import org.apache.myfaces.extensions.validator.baseval.annotation.SkipValidationSupport;

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+import org.apache.myfaces.extensions.validator.core.validation.NullValueAwareValidationStrategy;

+import org.apache.myfaces.extensions.validator.core.validation.EmptyValueAwareValidationStrategy;

+

+import java.lang.annotation.Annotation;

+

+/**

+ * @author Gerhard Petracek

+ * @since 1.x.1

+ */

+@SkipValidationSupport

+@NullValueAwareValidationStrategy

+@EmptyValueAwareValidationStrategy

+@UsageInformation(UsageCategory.INTERNAL)

+public class NotEqualsStrategy extends EqualsStrategy

+{

+    @Override

+    protected String getValidationErrorMsgKey(Annotation annotation, boolean isTargetComponent)

+    {

+        return ((NotEquals) annotation).validationErrorMsgKey();

+    }

+

+    @Override

+    public boolean isViolation(Object object1, Object object2,

+            Annotation annotation)

+    {

+        return !super.isViolation(object1, object2, annotation);

+    }

+

+    @Override

+    public String[] getValidationTargets(Annotation annotation)

+    {

+        return ((NotEquals) annotation).value();

+    }

+}

diff --git a/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/crossval/strategy/ReferencingStrategy.java b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/crossval/strategy/ReferencingStrategy.java
new file mode 100644
index 0000000..9dc5011
--- /dev/null
+++ b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/crossval/strategy/ReferencingStrategy.java
@@ -0,0 +1,40 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.crossval.strategy;

+

+import org.apache.myfaces.extensions.validator.crossval.storage.CrossValidationStorage;

+import org.apache.myfaces.extensions.validator.crossval.storage.CrossValidationStorageEntry;

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+

+/**

+ * Internal interface to allow multiple referencing strategies for cross component validation.

+ *

+ * @author Gerhard Petracek

+ * @since 1.x.1

+ */

+@UsageInformation(UsageCategory.INTERNAL)

+interface ReferencingStrategy

+{

+    boolean evaluateReferenceAndValidate(

+            CrossValidationStorageEntry crossValidationStorageEntry,

+            CrossValidationStorage crossValidationStorage,

+            String validationTarget,

+            AbstractCompareStrategy abstractCompareStrategy);

+}
\ No newline at end of file
diff --git a/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/crossval/strategy/RequiredIfStrategy.java b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/crossval/strategy/RequiredIfStrategy.java
new file mode 100644
index 0000000..98750b3
--- /dev/null
+++ b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/crossval/strategy/RequiredIfStrategy.java
@@ -0,0 +1,119 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.crossval.strategy;

+

+import org.apache.myfaces.extensions.validator.crossval.storage.CrossValidationStorageEntry;

+import org.apache.myfaces.extensions.validator.crossval.annotation.RequiredIf;

+import org.apache.myfaces.extensions.validator.crossval.annotation.RequiredIfType;

+import org.apache.myfaces.extensions.validator.baseval.annotation.SkipValidationSupport;

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+import org.apache.myfaces.extensions.validator.core.validation.message.resolver.AbstractValidationErrorMessageResolver;

+import org.apache.myfaces.extensions.validator.core.validation.NullValueAwareValidationStrategy;

+import org.apache.myfaces.extensions.validator.core.validation.EmptyValueAwareValidationStrategy;

+import org.apache.myfaces.extensions.validator.util.ExtValUtils;

+

+import javax.faces.validator.ValidatorException;

+

+/**

+ * @author Gerhard Petracek

+ * @since 1.x.1

+ */

+@SkipValidationSupport

+@NullValueAwareValidationStrategy

+@EmptyValueAwareValidationStrategy

+@UsageInformation(UsageCategory.INTERNAL)

+public class RequiredIfStrategy extends AbstractCompareStrategy<RequiredIf>

+{

+    private boolean useFacesBundle = false;

+

+    @Override

+    public boolean useTargetComponentToDisplayErrorMsg(CrossValidationStorageEntry crossValidationStorageEntry)

+    {

+        return false;

+    }

+

+    @Override

+    protected String resolveMessage(String key)

+    {

+        String result = super.resolveMessage(key);

+        String marker = AbstractValidationErrorMessageResolver.MISSING_RESOURCE_MARKER;

+

+        if((marker + key + marker).equals(result))

+        {

+            this.useFacesBundle = true;

+        }

+

+        return result;

+    }

+

+    protected String getValidationErrorMsgKey(RequiredIf annotation, boolean isTargetComponent)

+    {

+        return annotation.validationErrorMsgKey();

+    }

+

+    public boolean isViolation(Object source, Object target, RequiredIf annotation)

+    {

+        boolean violationFound = false;

+

+        if (annotation.is().equals(RequiredIfType.empty))

+        {

+            violationFound = (isTargetEmpty(target) || Boolean.FALSE.equals(target)) && isSourceEmpty(source);

+        }

+        else if (annotation.is().equals(RequiredIfType.not_empty))

+        {

+            violationFound = (isTargetNotEmpty(target) && isSourceEmpty(source) && !(target instanceof Boolean)) ||

+                    (Boolean.TRUE.equals(target) && isSourceEmpty(source));

+        }

+

+        return violationFound;

+    }

+

+    private boolean isTargetEmpty(Object target)

+    {

+        return target == null || target.equals("");

+    }

+

+    private boolean isSourceEmpty(Object source)

+    {

+        return source == null || source.equals("");

+    }

+

+    private boolean isTargetNotEmpty(Object target)

+    {

+        return target != null && !target.equals("");

+    }

+

+    public String[] getValidationTargets(RequiredIf annotation)

+    {

+        return annotation.valueOf();

+    }

+

+    @Override

+    protected boolean processAfterCrossValidatorException(

+            CrossValidationStorageEntry crossValidationStorageEntry, ValidatorException validatorException)

+    {

+        if(this.useFacesBundle)

+        {

+            ExtValUtils.replaceWithDefaultRequiredMessage(validatorException.getFacesMessage());

+        }

+

+        return super.processAfterCrossValidatorException(crossValidationStorageEntry, validatorException);

+    }

+}

diff --git a/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/jpa_strategy_mappings.properties b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/jpa_strategy_mappings.properties
new file mode 100644
index 0000000..c7d9929
--- /dev/null
+++ b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/jpa_strategy_mappings.properties
@@ -0,0 +1,22 @@
+# Licensed to the Apache Software Foundation (ASF) under one

+# or more contributor license agreements.  See the NOTICE file

+# distributed with this work for additional information

+# regarding copyright ownership.  The ASF licenses this file

+# to you under the Apache License, Version 2.0 (the

+# "License"); you may not use this file except in compliance

+# with the License.  You may obtain a copy of the License at

+#

+#   http://www.apache.org/licenses/LICENSE-2.0

+#

+# Unless required by applicable law or agreed to in writing,

+# software distributed under the License is distributed on an

+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+# KIND, either express or implied.  See the License for the

+# specific language governing permissions and limitations

+# under the License.

+

+javax.persistence.Column=org.apache.myfaces.extensions.validator.baseval.strategy.JpaValidationStrategy

+javax.persistence.Basic=org.apache.myfaces.extensions.validator.baseval.strategy.JpaValidationStrategy

+javax.persistence.Id=org.apache.myfaces.extensions.validator.baseval.strategy.JpaValidationStrategy

+javax.persistence.OneToOne=org.apache.myfaces.extensions.validator.baseval.strategy.JpaValidationStrategy

+javax.persistence.ManyToOne=org.apache.myfaces.extensions.validator.baseval.strategy.JpaValidationStrategy
\ No newline at end of file
diff --git a/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/util/CrossValidationUtils.java b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/util/CrossValidationUtils.java
new file mode 100644
index 0000000..49f852a
--- /dev/null
+++ b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/util/CrossValidationUtils.java
@@ -0,0 +1,108 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.util;

+

+import org.apache.myfaces.extensions.validator.crossval.storage.CrossValidationStorage;

+import org.apache.myfaces.extensions.validator.crossval.storage.ProcessedInformationStorageEntry;

+import org.apache.myfaces.extensions.validator.crossval.storage.CrossValidationStorageEntry;

+import org.apache.myfaces.extensions.validator.crossval.storage.ProcessedInformationStorage;

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+import org.apache.myfaces.extensions.validator.internal.ToDo;

+import org.apache.myfaces.extensions.validator.internal.Priority;

+import org.apache.myfaces.extensions.validator.core.property.PropertyDetails;

+import org.apache.myfaces.extensions.validator.core.property.PropertyInformationKeys;

+import org.apache.myfaces.extensions.validator.core.el.ValueBindingExpression;

+

+/**

+ * @author Gerhard Petracek

+ * @since 1.x.1

+ */

+@UsageInformation(UsageCategory.INTERNAL)

+public class CrossValidationUtils

+{

+    public static CrossValidationStorage getOrInitCrossValidationStorage()

+    {

+        return ExtValUtils.getStorage(CrossValidationStorage.class, CrossValidationStorage.class.getName());

+    }

+

+    public static void resetCrossValidationStorage()

+    {

+        ExtValUtils.resetStorage(CrossValidationStorage.class, CrossValidationStorage.class.getName());

+    }

+

+    public static ProcessedInformationStorage getOrInitProcessedInformationStorage()

+    {

+        return ExtValUtils.getStorage(

+                ProcessedInformationStorage.class, ProcessedInformationStorage.class.getName());

+    }

+

+    public static void resetKeyToConvertedValueMapping()

+    {

+        ExtValUtils.resetStorage(ProcessedInformationStorage.class, ProcessedInformationStorage.class.getName());

+    }

+

+    public static ProcessedInformationStorageEntry resolveValidationTargetEntry(

+            ProcessedInformationStorage processedInformationStorage,

+            String targetKey, CrossValidationStorageEntry crossValidationStorageEntry)

+    {

+        ProcessedInformationStorageEntry processedInformationEntry =

+            processedInformationStorage.getEntry(targetKey);

+

+        //value not submitted at this request - use model value (validation against the model)

+        if(processedInformationEntry == null)

+        {

+            return null;

+        }

+

+        //simple case

+        if (processedInformationEntry.getFurtherEntries() == null)

+        {

+            return processedInformationEntry;

+        }

+

+        PropertyDetails propertyDetails = crossValidationStorageEntry.getMetaDataEntry()

+                .getProperty(PropertyInformationKeys.PROPERTY_DETAILS, PropertyDetails.class);

+

+        Object targetBean = propertyDetails.getBaseObject();

+

+        //process complex component entries (e.g. a table)

+        //supported: cross-component but no cross-entity validation (= locale validation)

+        if (processedInformationEntry.getBean().equals(targetBean))

+        {

+            return processedInformationEntry;

+        }

+

+        for (ProcessedInformationStorageEntry entry : processedInformationEntry.getFurtherEntries())

+        {

+            if (entry.getBean().equals(targetBean))

+            {

+                return entry;

+            }

+        }

+

+        return null;

+    }

+

+    @ToDo(value = Priority.MEDIUM, description = "support for map syntax")

+    public static String convertValueBindingExpressionToProcessedInformationKey(ValueBindingExpression vbe)

+    {

+        return vbe.getExpressionString().replace("#{", "").replace("}", "");

+    }

+}

diff --git a/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/util/PropertyValidationUtils.java b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/util/PropertyValidationUtils.java
new file mode 100644
index 0000000..1f73a28
--- /dev/null
+++ b/2_0_3_prepare/validation-modules/property-validation/src/main/java/org/apache/myfaces/extensions/validator/util/PropertyValidationUtils.java
@@ -0,0 +1,68 @@
+/*

+ * Licensed to the Apache Software Foundation (ASF) under one

+ * or more contributor license agreements.  See the NOTICE file

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

+ * to you under the Apache License, Version 2.0 (the

+ * "License"); you may not use this file except in compliance

+ * with the License.  You may obtain a copy of the License at

+ *

+ *   http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing,

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY

+ * KIND, either express or implied.  See the License for the

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+package org.apache.myfaces.extensions.validator.util;

+

+import org.apache.myfaces.extensions.validator.internal.UsageInformation;

+import org.apache.myfaces.extensions.validator.internal.UsageCategory;

+import org.apache.myfaces.extensions.validator.core.property.PropertyInformationKeys;

+import org.apache.myfaces.extensions.validator.core.validation.strategy.ValidationStrategy;

+import org.apache.myfaces.extensions.validator.core.metadata.MetaDataEntry;

+import org.apache.myfaces.extensions.validator.baseval.strategy.SkipValidationStrategy;

+import org.apache.commons.logging.Log;

+import org.apache.commons.logging.LogFactory;

+

+import javax.faces.context.FacesContext;

+

+/**

+ * @author Gerhard Petracek

+ * @since 1.x.3

+ */

+@UsageInformation(UsageCategory.INTERNAL)

+public class PropertyValidationUtils

+{

+    private static final Log LOGGER = LogFactory.getLog(PropertyValidationUtils.class);

+

+    public static boolean isValidationSkipped(FacesContext facesContext,

+                                         ValidationStrategy validationStrategy,

+                                         MetaDataEntry metaDataEntry)

+    {

+        if(ExtValUtils.isSkipableValidationStrategy(

+                ProxyUtils.getUnproxiedClass(validationStrategy.getClass(), ValidationStrategy.class)))

+        {

+            Boolean skipValidation = metaDataEntry.getProperty(

+                PropertyInformationKeys.SKIP_VALIDATION, Boolean.class);

+

+            if(Boolean.TRUE.equals(skipValidation))

+            {

+                if(LOGGER.isTraceEnabled())

+                {

+                    LOGGER.trace("validation of " + validationStrategy.getClass().getName() + " canceled");

+                }

+

+                return true;

+            }

+        }

+        else if(validationStrategy instanceof SkipValidationStrategy)

+        {

+            validationStrategy.validate(facesContext, null, metaDataEntry, null);

+            return true;

+        }

+        return false;

+    }

+}

diff --git a/2_0_3_prepare/validation-modules/property-validation/src/main/resources/LICENSE.txt b/2_0_3_prepare/validation-modules/property-validation/src/main/resources/LICENSE.txt
new file mode 100644
index 0000000..c6055ec
--- /dev/null
+++ b/2_0_3_prepare/validation-modules/property-validation/src/main/resources/LICENSE.txt
@@ -0,0 +1,174 @@
+                                 Apache License

+                           Version 2.0, January 2004

+                        http://www.apache.org/licenses/

+

+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

+

+   1. Definitions.

+

+      "License" shall mean the terms and conditions for use, reproduction,

+      and distribution as defined by Sections 1 through 9 of this document.

+

+      "Licensor" shall mean the copyright owner or entity authorized by

+      the copyright owner that is granting the License.

+

+      "Legal Entity" shall mean the union of the acting entity and all

+      other entities that control, are controlled by, or are under common

+      control with that entity. For the purposes of this definition,

+      "control" means (i) the power, direct or indirect, to cause the

+      direction or management of such entity, whether by contract or

+      otherwise, or (ii) ownership of fifty percent (50%) or more of the

+      outstanding shares, or (iii) beneficial ownership of such entity.

+

+      "You" (or "Your") shall mean an individual or Legal Entity

+      exercising permissions granted by this License.

+

+      "Source" form shall mean the preferred form for making modifications,

+      including but not limited to software source code, documentation

+      source, and configuration files.

+

+      "Object" form shall mean any form resulting from mechanical

+      transformation or translation of a Source form, including but

+      not limited to compiled object code, generated documentation,

+      and conversions to other media types.

+

+      "Work" shall mean the work of authorship, whether in Source or

+      Object form, made available under the License, as indicated by a

+      copyright notice that is included in or attached to the work

+      (an example is provided in the Appendix below).

+

+      "Derivative Works" shall mean any work, whether in Source or Object

+      form, that is based on (or derived from) the Work and for which the

+      editorial revisions, annotations, elaborations, or other modifications

+      represent, as a whole, an original work of authorship. For the purposes

+      of this License, Derivative Works shall not include works that remain

+      separable from, or merely link (or bind by name) to the interfaces of,

+      the Work and Derivative Works thereof.

+

+      "Contribution" shall mean any work of authorship, including

+      the original version of the Work and any modifications or additions

+      to that Work or Derivative Works thereof, that is intentionally

+      submitted to Licensor for inclusion in the Work by the copyright owner

+      or by an individual or Legal Entity authorized to submit on behalf of

+      the copyright owner. For the purposes of this definition, "submitted"

+      means any form of electronic, verbal, or written communication sent

+      to the Licensor or its representatives, including but not limited to

+      communication on electronic mailing lists, source code control systems,

+      and issue tracking systems that are managed by, or on behalf of, the

+      Licensor for the purpose of discussing and improving the Work, but

+      excluding communication that is conspicuously marked or otherwise

+      designated in writing by the copyright owner as "Not a Contribution."

+

+      "Contributor" shall mean Licensor and any individual or Legal Entity

+      on behalf of whom a Contribution has been received by Licensor and

+      subsequently incorporated within the Work.

+

+   2. Grant of Copyright License. Subject to the terms and conditions of

+      this License, each Contributor hereby grants to You a perpetual,

+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable

+      copyright license to reproduce, prepare Derivative Works of,

+      publicly display, publicly perform, sublicense, and distribute the

+      Work and such Derivative Works in Source or Object form.

+

+   3. Grant of Patent License. Subject to the terms and conditions of

+      this License, each Contributor hereby grants to You a perpetual,

+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable

+      (except as stated in this section) patent license to make, have made,

+      use, offer to sell, sell, import, and otherwise transfer the Work,

+      where such license applies only to those patent claims licensable

+      by such Contributor that are necessarily infringed by their

+      Contribution(s) alone or by combination of their Contribution(s)

+      with the Work to which such Contribution(s) was submitted. If You

+      institute patent litigation against any entity (including a

+      cross-claim or counterclaim in a lawsuit) alleging that the Work

+      or a Contribution incorporated within the Work constitutes direct

+      or contributory patent infringement, then any patent licenses

+      granted to You under this License for that Work shall terminate

+      as of the date such litigation is filed.

+

+   4. Redistribution. You may reproduce and distribute copies of the

+      Work or Derivative Works thereof in any medium, with or without

+      modifications, and in Source or Object form, provided that You

+      meet the following conditions:

+

+      (a) You must give any other recipients of the Work or

+          Derivative Works a copy of this License; and

+

+      (b) You must cause any modified files to carry prominent notices

+          stating that You changed the files; and

+

+      (c) You must retain, in the Source form of any Derivative Works

+          that You distribute, all copyright, patent, trademark, and

+          attribution notices from the Source form of the Work,

+          excluding those notices that do not pertain to any part of

+          the Derivative Works; and

+

+      (d) If the Work includes a "NOTICE" text file as part of its

+          distribution, then any Derivative Works that You distribute must

+          include a readable copy of the attribution notices contained

+          within such NOTICE file, excluding those notices that do not

+          pertain to any part of the Derivative Works, in at least one

+          of the following places: within a NOTICE text file distributed

+          as part of the Derivative Works; within the Source form or

+          documentation, if provided along with the Derivative Works; or,

+          within a display generated by the Derivative Works, if and

+          wherever such third-party notices normally appear. The contents

+          of the NOTICE file are for informational purposes only and

+          do not modify the License. You may add Your own attribution

+          notices within Derivative Works that You distribute, alongside

+          or as an addendum to the NOTICE text from the Work, provided

+          that such additional attribution notices cannot be construed

+          as modifying the License.

+

+      You may add Your own copyright statement to Your modifications and

+      may provide additional or different license terms and conditions

+      for use, reproduction, or distribution of Your modifications, or

+      for any such Derivative Works as a whole, provided Your use,

+      reproduction, and distribution of the Work otherwise complies with

+      the conditions stated in this License.

+

+   5. Submission of Contributions. Unless You explicitly state otherwise,

+      any Contribution intentionally submitted for inclusion in the Work

+      by You to the Licensor shall be under the terms and conditions of

+      this License, without any additional terms or conditions.

+      Notwithstanding the above, nothing herein shall supersede or modify

+      the terms of any separate license agreement you may have executed

+      with Licensor regarding such Contributions.

+

+   6. Trademarks. This License does not grant permission to use the trade

+      names, trademarks, service marks, or product names of the Licensor,

+      except as required for reasonable and customary use in describing the

+      origin of the Work and reproducing the content of the NOTICE file.

+

+   7. Disclaimer of Warranty. Unless required by applicable law or

+      agreed to in writing, Licensor provides the Work (and each

+      Contributor provides its Contributions) on an "AS IS" BASIS,

+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or

+      implied, including, without limitation, any warranties or conditions

+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A

+      PARTICULAR PURPOSE. You are solely responsible for determining the

+      appropriateness of using or redistributing the Work and assume any

+      risks associated with Your exercise of permissions under this License.

+

+   8. Limitation of Liability. In no event and under no legal theory,

+      whether in tort (including negligence), contract, or otherwise,

+      unless required by applicable law (such as deliberate and grossly

+      negligent acts) or agreed to in writing, shall any Contributor be

+      liable to You for damages, including any direct, indirect, special,

+      incidental, or consequential damages of any character arising as a

+      result of this License or out of the use or inability to use the

+      Work (including but not limited to damages for loss of goodwill,

+      work stoppage, computer failure or malfunction, or any and all

+      other commercial damages or losses), even if such Contributor

+      has been advised of the possibility of such damages.

+

+   9. Accepting Warranty or Additional Liability. While redistributing

+      the Work or Derivative Works thereof, You may choose to offer,

+      and charge a fee for, acceptance of support, warranty, indemnity,

+      or other liability obligations and/or rights consistent with this

+      License. However, in accepting such obligations, You may act only

+      on Your own behalf and on Your sole responsibility, not on behalf

+      of any other Contributor, and only if You agree to indemnify,

+      defend, and hold each Contributor harmless for any liability

+      incurred by, or claims asserted against, such Contributor by reason

+      of your accepting any such warranty or additional liability.

diff --git a/2_0_3_prepare/validation-modules/property-validation/src/main/resources/NOTICE.txt b/2_0_3_prepare/validation-modules/property-validation/src/main/resources/NOTICE.txt
new file mode 100644
index 0000000..4278ef3
--- /dev/null
+++ b/2_0_3_prepare/validation-modules/property-validation/src/main/resources/NOTICE.txt
@@ -0,0 +1,9 @@
+Apache MyFaces Extensions Validator

+Copyright 2007-2008 The Apache Software Foundation

+

+This product includes software developed by

+The Apache Software Foundation (http://www.apache.org/).

+

+------------------------------------------------------------------------

+See the file LICENSE.txt

+------------------------------------------------------------------------
\ No newline at end of file
diff --git a/2_0_3_prepare/validation-modules/property-validation/src/site/apt/index.apt b/2_0_3_prepare/validation-modules/property-validation/src/site/apt/index.apt
new file mode 100644
index 0000000..c339255
--- /dev/null
+++ b/2_0_3_prepare/validation-modules/property-validation/src/site/apt/index.apt
@@ -0,0 +1,10 @@
+ ------

+Apache MyFaces Extensions Property Validation Module

+ ------

+

+Apache MyFaces Extensions Property Validation Module Overview

+

+    MyFaces Extensions Validator Property Validation provides annotation based validation for bean properties.

+    It also provides JPA 1.0 based validation Support.

+  

+    MyFaces Extensions Validator is compatible with JSF 1.1.x and JSF 1.2.x. Both versions require Java 1.5+
\ No newline at end of file