[maven-release-plugin]  copy for tag ruta-2.6.1

git-svn-id: https://svn.apache.org/repos/asf/uima/ruta/tags/ruta-2.6.1@1801480 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/example-projects/ExampleProject/descriptor/uima/ruta/example/AuthorEngine.xml b/example-projects/ExampleProject/descriptor/uima/ruta/example/AuthorEngine.xml
index a5d84f5..cc48daf 100644
--- a/example-projects/ExampleProject/descriptor/uima/ruta/example/AuthorEngine.xml
+++ b/example-projects/ExampleProject/descriptor/uima/ruta/example/AuthorEngine.xml
@@ -1,11 +1,28 @@
 <?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.

+-->

 <analysisEngineDescription xmlns="http://uima.apache.org/resourceSpecifier">

     <frameworkImplementation>org.apache.uima.java</frameworkImplementation>

     <primitive>true</primitive>

     <annotatorImplementationName>org.apache.uima.ruta.engine.RutaEngine</annotatorImplementationName>

     <analysisEngineMetaData>

-        <name>BasicEngine</name>

+        <name>uima.ruta.example.AuthorEngine</name>

         <description/>

         <version>1.0</version>

         <vendor/>

@@ -234,14 +251,14 @@
             <nameValuePair>

                 <name>mainScript</name>

                 <value>

-                    <string>Author</string>

+                    <string>uima.ruta.example.Author</string>

                 </value>

             </nameValuePair>

             <nameValuePair>

                 <name>scriptPaths</name>

                 <value>

                     <array>

-                        <string>D:/work/ws-tutorial/ExampleProject/script</string>

+                        <string>C:/work/ws/ws-uima-ruta-plain/ruta-trunk/example-projects/ExampleProject/script</string>

                     </array>

                 </value>

             </nameValuePair>

@@ -249,7 +266,7 @@
                 <name>descriptorPaths</name>

                 <value>

                     <array>

-                        <string>D:/work/ws-tutorial/ExampleProject/descriptor</string>

+                        <string>C:/work/ws/ws-uima-ruta-plain/ruta-trunk/example-projects/ExampleProject/descriptor</string>

                     </array>

                 </value>

             </nameValuePair>

@@ -257,7 +274,7 @@
                 <name>resourcePaths</name>

                 <value>

                     <array>

-                        <string>D:\work\ws-tutorial\ExampleProject\resources</string>

+                        <string>C:/work/ws/ws-uima-ruta-plain/ruta-trunk/example-projects/ExampleProject/resources</string>

                     </array>

                 </value>

             </nameValuePair>

@@ -283,27 +300,16 @@
                 <name>additionalExtensions</name>

                 <value>

                     <array>

-                        <string>org.apache.uima.ruta.example.extensions.ExampleConditionExtension</string>

-                        <string>org.apache.uima.ruta.example.extensions.ExampleActionExtension</string>

+                        <string>org.apache.uima.ruta.action.MarkReloadExtension</string>

                         <string>org.apache.uima.ruta.string.bool.BooleanOperationsExtension</string>

-                        <string>org.apache.uima.ruta.example.extensions.ExampleBooleanFunctionExtension</string>

-                        <string>org.apache.uima.ruta.example.extensions.ExampleNumberFunctionExtension</string>

                         <string>org.apache.uima.ruta.string.StringOperationsExtension</string>

-                        <string>org.apache.uima.ruta.example.extensions.ExampleStringFunctionExtension</string>

-                        <string>org.apache.uima.ruta.example.extensions.ExampleTypeFunctionExtension</string>

+                        <string>org.apache.uima.ruta.type.TypeFromStringFunctionExtension</string>

                         <string>org.apache.uima.ruta.block.OnlyFirstBlockExtension</string>

                         <string>org.apache.uima.ruta.block.OnlyOnceBlockExtension</string>

                         <string>org.apache.uima.ruta.block.fst.FSTBlockExtension</string>

-                        <string>org.apache.uima.ruta.example.extensions.ExampleBlockExtension</string>

                     </array>

                 </value>

             </nameValuePair>

-            <nameValuePair>

-                <name>additionalEngineLoaders</name>

-                <value>

-                    <array/>

-                </value>

-            </nameValuePair>

         </configurationParameterSettings>

         <typeSystemDescription>

             <imports>

diff --git a/example-projects/ExampleProject/descriptor/uima/ruta/example/AuthorTypeSystem.xml b/example-projects/ExampleProject/descriptor/uima/ruta/example/AuthorTypeSystem.xml
index 35c110b..eb5ad65 100644
--- a/example-projects/ExampleProject/descriptor/uima/ruta/example/AuthorTypeSystem.xml
+++ b/example-projects/ExampleProject/descriptor/uima/ruta/example/AuthorTypeSystem.xml
@@ -1,29 +1,46 @@
 <?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.

+-->

 <typeSystemDescription xmlns="http://uima.apache.org/resourceSpecifier">

-    <name>AuthorTypeSystem</name>

+    <name>uima.ruta.example.AuthorTypeSystem</name>

     <imports>

-        <import location="..\..\..\BasicTypeSystem.xml"/>

-        <import location="..\..\..\types\BibtexTypeSystem.xml"/>

+        <import location="../../../BasicTypeSystem.xml"/>

+        <import location="../../../types/BibtexTypeSystem.xml"/>

     </imports>

     <types>

         <typeDescription>

-            <name>uima.ruta.example.Author.FirstName</name>

-            <description>Type defined in uima.ruta.example.Author</description>

-            <supertypeName>uima.tcas.Annotation</supertypeName>

-        </typeDescription>

-        <typeDescription>

             <name>uima.ruta.example.Author.FirstNameInitial</name>

             <description>Type defined in uima.ruta.example.Author</description>

             <supertypeName>uima.tcas.Annotation</supertypeName>

         </typeDescription>

         <typeDescription>

-            <name>uima.ruta.example.Author.NameListPart</name>

+            <name>uima.ruta.example.Author.Name</name>

             <description>Type defined in uima.ruta.example.Author</description>

             <supertypeName>uima.tcas.Annotation</supertypeName>

         </typeDescription>

         <typeDescription>

-            <name>uima.ruta.example.Author.Name</name>

+            <name>uima.ruta.example.Author.FirstName</name>

+            <description>Type defined in uima.ruta.example.Author</description>

+            <supertypeName>uima.tcas.Annotation</supertypeName>

+        </typeDescription>

+        <typeDescription>

+            <name>uima.ruta.example.Author.NameListPart</name>

             <description>Type defined in uima.ruta.example.Author</description>

             <supertypeName>uima.tcas.Annotation</supertypeName>

         </typeDescription>

diff --git a/example-projects/ExampleProject/descriptor/uima/ruta/example/MainEngine.xml b/example-projects/ExampleProject/descriptor/uima/ruta/example/MainEngine.xml
index b9196b4..b732547 100644
--- a/example-projects/ExampleProject/descriptor/uima/ruta/example/MainEngine.xml
+++ b/example-projects/ExampleProject/descriptor/uima/ruta/example/MainEngine.xml
@@ -1,11 +1,28 @@
 <?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.

+-->

 <analysisEngineDescription xmlns="http://uima.apache.org/resourceSpecifier">

     <frameworkImplementation>org.apache.uima.java</frameworkImplementation>

     <primitive>true</primitive>

     <annotatorImplementationName>org.apache.uima.ruta.engine.RutaEngine</annotatorImplementationName>

     <analysisEngineMetaData>

-        <name>BasicEngine</name>

+        <name>uima.ruta.example.MainEngine</name>

         <description/>

         <version>1.0</version>

         <vendor/>

@@ -234,14 +251,14 @@
             <nameValuePair>

                 <name>mainScript</name>

                 <value>

-                    <string>Main</string>

+                    <string>uima.ruta.example.Main</string>

                 </value>

             </nameValuePair>

             <nameValuePair>

                 <name>scriptPaths</name>

                 <value>

                     <array>

-                        <string>D:/work/ws-tutorial/ExampleProject/script</string>

+                        <string>C:/work/ws/ws-uima-ruta-plain/ruta-trunk/example-projects/ExampleProject/script</string>

                     </array>

                 </value>

             </nameValuePair>

@@ -249,7 +266,7 @@
                 <name>descriptorPaths</name>

                 <value>

                     <array>

-                        <string>D:/work/ws-tutorial/ExampleProject/descriptor</string>

+                        <string>C:/work/ws/ws-uima-ruta-plain/ruta-trunk/example-projects/ExampleProject/descriptor</string>

                     </array>

                 </value>

             </nameValuePair>

@@ -257,7 +274,7 @@
                 <name>resourcePaths</name>

                 <value>

                     <array>

-                        <string>D:\work\ws-tutorial\ExampleProject\resources</string>

+                        <string>C:/work/ws/ws-uima-ruta-plain/ruta-trunk/example-projects/ExampleProject/resources</string>

                     </array>

                 </value>

             </nameValuePair>

@@ -265,9 +282,9 @@
                 <name>additionalScripts</name>

                 <value>

                     <array>

-                        <string>uima.ruta.example.Author</string>

-                        <string>uima.ruta.example.Year</string>

                         <string>uima.ruta.example.Title</string>

+                        <string>uima.ruta.example.Year</string>

+                        <string>uima.ruta.example.Author</string>

                     </array>

                 </value>

             </nameValuePair>

@@ -287,27 +304,16 @@
                 <name>additionalExtensions</name>

                 <value>

                     <array>

-                        <string>org.apache.uima.ruta.example.extensions.ExampleConditionExtension</string>

-                        <string>org.apache.uima.ruta.example.extensions.ExampleActionExtension</string>

+                        <string>org.apache.uima.ruta.action.MarkReloadExtension</string>

                         <string>org.apache.uima.ruta.string.bool.BooleanOperationsExtension</string>

-                        <string>org.apache.uima.ruta.example.extensions.ExampleBooleanFunctionExtension</string>

-                        <string>org.apache.uima.ruta.example.extensions.ExampleNumberFunctionExtension</string>

                         <string>org.apache.uima.ruta.string.StringOperationsExtension</string>

-                        <string>org.apache.uima.ruta.example.extensions.ExampleStringFunctionExtension</string>

-                        <string>org.apache.uima.ruta.example.extensions.ExampleTypeFunctionExtension</string>

+                        <string>org.apache.uima.ruta.type.TypeFromStringFunctionExtension</string>

                         <string>org.apache.uima.ruta.block.OnlyFirstBlockExtension</string>

                         <string>org.apache.uima.ruta.block.OnlyOnceBlockExtension</string>

                         <string>org.apache.uima.ruta.block.fst.FSTBlockExtension</string>

-                        <string>org.apache.uima.ruta.example.extensions.ExampleBlockExtension</string>

                     </array>

                 </value>

             </nameValuePair>

-            <nameValuePair>

-                <name>additionalEngineLoaders</name>

-                <value>

-                    <array/>

-                </value>

-            </nameValuePair>

         </configurationParameterSettings>

         <typeSystemDescription>

             <imports>

diff --git a/example-projects/ExampleProject/descriptor/uima/ruta/example/MainTypeSystem.xml b/example-projects/ExampleProject/descriptor/uima/ruta/example/MainTypeSystem.xml
index 59e6461..a45456c 100644
--- a/example-projects/ExampleProject/descriptor/uima/ruta/example/MainTypeSystem.xml
+++ b/example-projects/ExampleProject/descriptor/uima/ruta/example/MainTypeSystem.xml
@@ -1,12 +1,29 @@
 <?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.

+-->

 <typeSystemDescription xmlns="http://uima.apache.org/resourceSpecifier">

-    <name>MainTypeSystem</name>

+    <name>uima.ruta.example.MainTypeSystem</name>

     <imports>

-        <import location="..\..\..\BasicTypeSystem.xml"/>

-        <import location="..\..\..\types\BibtexTypeSystem.xml"/>

-        <import location="AuthorTypeSystem.xml"/>

-        <import location="YearTypeSystem.xml"/>

+        <import location="../../../BasicTypeSystem.xml"/>

+        <import location="../../../types/BibtexTypeSystem.xml"/>

         <import location="TitleTypeSystem.xml"/>

+        <import location="YearTypeSystem.xml"/>

+        <import location="AuthorTypeSystem.xml"/>

     </imports>

 </typeSystemDescription>

diff --git a/example-projects/ExampleProject/descriptor/uima/ruta/example/TitleEngine.xml b/example-projects/ExampleProject/descriptor/uima/ruta/example/TitleEngine.xml
index 50e5d61..fa6305d 100644
--- a/example-projects/ExampleProject/descriptor/uima/ruta/example/TitleEngine.xml
+++ b/example-projects/ExampleProject/descriptor/uima/ruta/example/TitleEngine.xml
@@ -1,11 +1,28 @@
 <?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.

+-->

 <analysisEngineDescription xmlns="http://uima.apache.org/resourceSpecifier">

     <frameworkImplementation>org.apache.uima.java</frameworkImplementation>

     <primitive>true</primitive>

     <annotatorImplementationName>org.apache.uima.ruta.engine.RutaEngine</annotatorImplementationName>

     <analysisEngineMetaData>

-        <name>BasicEngine</name>

+        <name>uima.ruta.example.TitleEngine</name>

         <description/>

         <version>1.0</version>

         <vendor/>

@@ -234,14 +251,14 @@
             <nameValuePair>

                 <name>mainScript</name>

                 <value>

-                    <string>Title</string>

+                    <string>uima.ruta.example.Title</string>

                 </value>

             </nameValuePair>

             <nameValuePair>

                 <name>scriptPaths</name>

                 <value>

                     <array>

-                        <string>D:/work/ws-tutorial/ExampleProject/script</string>

+                        <string>C:/work/ws/ws-uima-ruta-plain/ruta-trunk/example-projects/ExampleProject/script</string>

                     </array>

                 </value>

             </nameValuePair>

@@ -249,7 +266,7 @@
                 <name>descriptorPaths</name>

                 <value>

                     <array>

-                        <string>D:/work/ws-tutorial/ExampleProject/descriptor</string>

+                        <string>C:/work/ws/ws-uima-ruta-plain/ruta-trunk/example-projects/ExampleProject/descriptor</string>

                     </array>

                 </value>

             </nameValuePair>

@@ -257,7 +274,7 @@
                 <name>resourcePaths</name>

                 <value>

                     <array>

-                        <string>D:\work\ws-tutorial\ExampleProject\resources</string>

+                        <string>C:/work/ws/ws-uima-ruta-plain/ruta-trunk/example-projects/ExampleProject/resources</string>

                     </array>

                 </value>

             </nameValuePair>

@@ -283,27 +300,16 @@
                 <name>additionalExtensions</name>

                 <value>

                     <array>

-                        <string>org.apache.uima.ruta.example.extensions.ExampleConditionExtension</string>

-                        <string>org.apache.uima.ruta.example.extensions.ExampleActionExtension</string>

+                        <string>org.apache.uima.ruta.action.MarkReloadExtension</string>

                         <string>org.apache.uima.ruta.string.bool.BooleanOperationsExtension</string>

-                        <string>org.apache.uima.ruta.example.extensions.ExampleBooleanFunctionExtension</string>

-                        <string>org.apache.uima.ruta.example.extensions.ExampleNumberFunctionExtension</string>

                         <string>org.apache.uima.ruta.string.StringOperationsExtension</string>

-                        <string>org.apache.uima.ruta.example.extensions.ExampleStringFunctionExtension</string>

-                        <string>org.apache.uima.ruta.example.extensions.ExampleTypeFunctionExtension</string>

+                        <string>org.apache.uima.ruta.type.TypeFromStringFunctionExtension</string>

                         <string>org.apache.uima.ruta.block.OnlyFirstBlockExtension</string>

                         <string>org.apache.uima.ruta.block.OnlyOnceBlockExtension</string>

                         <string>org.apache.uima.ruta.block.fst.FSTBlockExtension</string>

-                        <string>org.apache.uima.ruta.example.extensions.ExampleBlockExtension</string>

                     </array>

                 </value>

             </nameValuePair>

-            <nameValuePair>

-                <name>additionalEngineLoaders</name>

-                <value>

-                    <array/>

-                </value>

-            </nameValuePair>

         </configurationParameterSettings>

         <typeSystemDescription>

             <imports>

diff --git a/example-projects/ExampleProject/descriptor/uima/ruta/example/TitleTypeSystem.xml b/example-projects/ExampleProject/descriptor/uima/ruta/example/TitleTypeSystem.xml
index 491efb3..7e562bc 100644
--- a/example-projects/ExampleProject/descriptor/uima/ruta/example/TitleTypeSystem.xml
+++ b/example-projects/ExampleProject/descriptor/uima/ruta/example/TitleTypeSystem.xml
@@ -1,10 +1,27 @@
 <?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.

+-->

 <typeSystemDescription xmlns="http://uima.apache.org/resourceSpecifier">

-    <name>TitleTypeSystem</name>

+    <name>uima.ruta.example.TitleTypeSystem</name>

     <imports>

-        <import location="..\..\..\BasicTypeSystem.xml"/>

-        <import location="..\..\..\types\BibtexTypeSystem.xml"/>

+        <import location="../../../BasicTypeSystem.xml"/>

+        <import location="../../../types/BibtexTypeSystem.xml"/>

     </imports>

     <types>

         <typeDescription>

diff --git a/example-projects/ExampleProject/descriptor/uima/ruta/example/YearEngine.xml b/example-projects/ExampleProject/descriptor/uima/ruta/example/YearEngine.xml
index 57b2d10..07ee9b1 100644
--- a/example-projects/ExampleProject/descriptor/uima/ruta/example/YearEngine.xml
+++ b/example-projects/ExampleProject/descriptor/uima/ruta/example/YearEngine.xml
@@ -1,11 +1,28 @@
 <?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.

+-->

 <analysisEngineDescription xmlns="http://uima.apache.org/resourceSpecifier">

     <frameworkImplementation>org.apache.uima.java</frameworkImplementation>

     <primitive>true</primitive>

     <annotatorImplementationName>org.apache.uima.ruta.engine.RutaEngine</annotatorImplementationName>

     <analysisEngineMetaData>

-        <name>BasicEngine</name>

+        <name>uima.ruta.example.YearEngine</name>

         <description/>

         <version>1.0</version>

         <vendor/>

@@ -234,14 +251,14 @@
             <nameValuePair>

                 <name>mainScript</name>

                 <value>

-                    <string>Year</string>

+                    <string>uima.ruta.example.Year</string>

                 </value>

             </nameValuePair>

             <nameValuePair>

                 <name>scriptPaths</name>

                 <value>

                     <array>

-                        <string>D:/work/ws-tutorial/ExampleProject/script</string>

+                        <string>C:/work/ws/ws-uima-ruta-plain/ruta-trunk/example-projects/ExampleProject/script</string>

                     </array>

                 </value>

             </nameValuePair>

@@ -249,7 +266,7 @@
                 <name>descriptorPaths</name>

                 <value>

                     <array>

-                        <string>D:/work/ws-tutorial/ExampleProject/descriptor</string>

+                        <string>C:/work/ws/ws-uima-ruta-plain/ruta-trunk/example-projects/ExampleProject/descriptor</string>

                     </array>

                 </value>

             </nameValuePair>

@@ -257,7 +274,7 @@
                 <name>resourcePaths</name>

                 <value>

                     <array>

-                        <string>D:\work\ws-tutorial\ExampleProject\resources</string>

+                        <string>C:/work/ws/ws-uima-ruta-plain/ruta-trunk/example-projects/ExampleProject/resources</string>

                     </array>

                 </value>

             </nameValuePair>

@@ -283,27 +300,16 @@
                 <name>additionalExtensions</name>

                 <value>

                     <array>

-                        <string>org.apache.uima.ruta.example.extensions.ExampleConditionExtension</string>

-                        <string>org.apache.uima.ruta.example.extensions.ExampleActionExtension</string>

+                        <string>org.apache.uima.ruta.action.MarkReloadExtension</string>

                         <string>org.apache.uima.ruta.string.bool.BooleanOperationsExtension</string>

-                        <string>org.apache.uima.ruta.example.extensions.ExampleBooleanFunctionExtension</string>

-                        <string>org.apache.uima.ruta.example.extensions.ExampleNumberFunctionExtension</string>

                         <string>org.apache.uima.ruta.string.StringOperationsExtension</string>

-                        <string>org.apache.uima.ruta.example.extensions.ExampleStringFunctionExtension</string>

-                        <string>org.apache.uima.ruta.example.extensions.ExampleTypeFunctionExtension</string>

+                        <string>org.apache.uima.ruta.type.TypeFromStringFunctionExtension</string>

                         <string>org.apache.uima.ruta.block.OnlyFirstBlockExtension</string>

                         <string>org.apache.uima.ruta.block.OnlyOnceBlockExtension</string>

                         <string>org.apache.uima.ruta.block.fst.FSTBlockExtension</string>

-                        <string>org.apache.uima.ruta.example.extensions.ExampleBlockExtension</string>

                     </array>

                 </value>

             </nameValuePair>

-            <nameValuePair>

-                <name>additionalEngineLoaders</name>

-                <value>

-                    <array/>

-                </value>

-            </nameValuePair>

         </configurationParameterSettings>

         <typeSystemDescription>

             <imports>

diff --git a/example-projects/ExampleProject/descriptor/uima/ruta/example/YearTypeSystem.xml b/example-projects/ExampleProject/descriptor/uima/ruta/example/YearTypeSystem.xml
index 921a031..81e830a 100644
--- a/example-projects/ExampleProject/descriptor/uima/ruta/example/YearTypeSystem.xml
+++ b/example-projects/ExampleProject/descriptor/uima/ruta/example/YearTypeSystem.xml
@@ -1,9 +1,26 @@
 <?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.

+-->

 <typeSystemDescription xmlns="http://uima.apache.org/resourceSpecifier">

-    <name>YearTypeSystem</name>

+    <name>uima.ruta.example.YearTypeSystem</name>

     <imports>

-        <import location="..\..\..\BasicTypeSystem.xml"/>

-        <import location="..\..\..\types\BibtexTypeSystem.xml"/>

+        <import location="../../../BasicTypeSystem.xml"/>

+        <import location="../../../types/BibtexTypeSystem.xml"/>

     </imports>

 </typeSystemDescription>

diff --git a/example-projects/ExampleProject/script/uima/ruta/example/Year.ruta b/example-projects/ExampleProject/script/uima/ruta/example/Year.ruta
index 2fa94f1..8d0710c 100644
--- a/example-projects/ExampleProject/script/uima/ruta/example/Year.ruta
+++ b/example-projects/ExampleProject/script/uima/ruta/example/Year.ruta
@@ -24,6 +24,6 @@
 NUM{REGEXP("19..|20..") -> MARK(Year,1,2)} PM?;
 
 // add parentheses if there are some (by removing the old Year annotation and creating a new one)
-SPECIAL{REGEXP("[(]")} Year{ -> SHIFT(Year,1,2,3,4)} SPECIAL{REGEXP("[)]")} PM?;
+SPECIAL{REGEXP("[(]")} Year{ -> SHIFT(Year,1,4)} SPECIAL{REGEXP("[)]")} PM?;
 
 
diff --git a/ruta-core/src/main/antlr3/org/apache/uima/ruta/parser/RutaParser.g b/ruta-core/src/main/antlr3/org/apache/uima/ruta/parser/RutaParser.g
index be9805b..9f6f4a9 100644
--- a/ruta-core/src/main/antlr3/org/apache/uima/ruta/parser/RutaParser.g
+++ b/ruta-core/src/main/antlr3/org/apache/uima/ruta/parser/RutaParser.g
@@ -68,6 +68,7 @@
 import org.apache.uima.ruta.RutaModule;

 import org.apache.uima.ruta.RutaScriptFactory;

 import org.apache.uima.ruta.RutaStatement;

+import org.apache.uima.ruta.block.ForEachBlock;

 import org.apache.uima.ruta.block.RutaBlock;

 import org.apache.uima.ruta.block.RutaScriptBlock;

 import org.apache.uima.ruta.expression.AnnotationTypeExpression;

@@ -519,7 +520,7 @@
 	| stmtAM = macroActionDeclaration {stmt = stmtAM;}

 	| stmtRule = simpleStatement {stmt = stmtRule;}

 	| stmtBlock = blockDeclaration {stmt = stmtBlock;}

-	| stmtBlock = forEachDeclaration {stmt = stmtBlock;}

+	//| stmtBlock = forEachDeclaration {stmt = stmtBlock;}

 	| stmtExternal = externalBlock {stmt = stmtExternal;}

 	)

 	;

@@ -727,6 +728,7 @@
 	RutaBlock env;

 }

 @init{

+Map<String,String> def = new LinkedHashMap<>();

 RutaRuleElement re = null;

 RuleElementIsolator container = null;

 level++;

@@ -736,11 +738,23 @@
 }

 

 	:

-	type = BlockString 

+	((

+	type = (BlockString) 

 	LPAREN

 	id = Identifier 

 	RPAREN

 	{block = factory.createScriptBlock(id, re, body, $blockDeclaration[level - 1]::env);}

+	)

+	|

+	(

+	type = ForEachString 

+	LPAREN

+	id = Identifier (COMMA direction = booleanExpression)?

+	RPAREN

+	{block = factory.createForEachBlock(id, direction, re, body, $blockDeclaration[level - 1]::env);}

+	))

+	

+	

 	{$blockDeclaration::env = block;

 	container = new RuleElementIsolator();}

 	re1 = ruleElementWithCA[container]

@@ -748,13 +762,17 @@
 	{RutaRule rule = factory.createRule(re, block);

 	block.setRule(rule);

 	container.setContainer(rule);

-	}

+	}	

+	{if(block instanceof ForEachBlock) def.put(id.getText(),RutaConstants.RUTA_VARIABLE_ANNOTATION);}

+	{if(block instanceof ForEachBlock) addTemporaryVariables(def);}

 	LCURLY body = statements RCURLY

+	{if(block instanceof ForEachBlock) removeTemporaryVariables(def);}

+	

 	{block.setElements(body);

 	$blockDeclaration::env.getScript().addBlock(id.getText(),block);

 	}	

 	;

-

+/*

 forEachDeclaration returns [RutaBlock block = null]

 options {

 	backtrack = true;

@@ -780,6 +798,8 @@
 	RPAREN

 	{block = factory.createForEachBlock(id, direction, re, body, $blockDeclaration[level - 1]::env);}

 	{$blockDeclaration::env = block;

+	//$blockDeclaration::env = block;

+	

 	container = new RuleElementIsolator();}

 	re1 = ruleElementWithCA[container]

 	 {re = re1;	 }

@@ -795,6 +815,7 @@
 	{$blockDeclaration::env = block.getParent();}

 	}	

 	;

+	*/

 

 externalBlock returns [RutaBlock block = null]

 options {

@@ -2440,7 +2461,7 @@
 	}

 	;

 

-nullExpression returns [IRutaExpression expr = null]

+nullExpression returns [IStringExpression expr = null]

 	:

 	NULL {expr = expressionFactory.createNullExpression();}

 	;

@@ -2790,7 +2811,10 @@
 	:

 	e1 = stringExpression

 	op = (EQUAL | NOTEQUAL)

+	(

 	e2 = stringExpression

+	| e2 = nullExpression

+	)

 	{expr = expressionFactory.createBooleanStringExpression(e1,op,e2);}

 	;

 

diff --git a/ruta-core/src/main/java/org/apache/uima/ruta/RutaStream.java b/ruta-core/src/main/java/org/apache/uima/ruta/RutaStream.java
index 73bdd43..6be4bfc 100644
--- a/ruta-core/src/main/java/org/apache/uima/ruta/RutaStream.java
+++ b/ruta-core/src/main/java/org/apache/uima/ruta/RutaStream.java
@@ -288,18 +288,19 @@
     }

   }

 

-  private Collection<Type> removeSubsumedTypes(Collection<String> typeNames, TypeSystem typeSystem) {

+  private Collection<Type> removeSubsumedTypes(Collection<String> typeNames,

+          TypeSystem typeSystem) {

     Collection<Type> allTypes = new HashSet<>();

     for (String each : typeNames) {

       Type type = typeSystem.getType(each);

-      if(type != null) {

+      if (type != null) {

         allTypes.add(type);

       }

     }

     List<Type> rootTypes = new ArrayList<>(allTypes);

     for (Type type1 : allTypes) {

       for (Type type2 : allTypes) {

-        if(type1!= type2 && typeSystem.subsumes(type1, type2)) {

+        if (type1 != type2 && typeSystem.subsumes(type1, type2)) {

           rootTypes.remove(type2);

         }

       }

@@ -409,8 +410,8 @@
       toSplit.setEnd(anchor);

       RutaBasic newRB = new RutaBasic(getJCas(), anchor, newEnd);

       newRB.setLowMemoryProfile(lowMemoryProfile);

-      newRB.setEndMap(toSplit.getEndMap());

-      newRB.setPartOf(toSplit.getPartOf());

+      newRB.setEndMap(toSplit.getEndMap().clone());

+      newRB.setPartOf(toSplit.getPartOf().clone());

       toSplit.clearEndMap();

       cas.addFsToIndexes(toSplit);

       cas.addFsToIndexes(newRB);

@@ -1231,6 +1232,9 @@
     if (clazz.equals(Double.class) && expression instanceof INumberExpression) {

       double v = ((INumberExpression) expression).getDoubleValue(context, this);

       environment.setVariableValue(var, v);

+    } else if (clazz.equals(Float.class) && expression instanceof INumberExpression) {

+      float v = (float) ((INumberExpression) expression).getDoubleValue(context, this);

+      environment.setVariableValue(var, v);

     } else if (clazz.equals(Integer.class) && expression instanceof INumberExpression) {

       int v = ((INumberExpression) expression).getIntegerValue(context, this);

       environment.setVariableValue(var, v);

diff --git a/ruta-core/src/main/java/org/apache/uima/ruta/engine/Ruta.java b/ruta-core/src/main/java/org/apache/uima/ruta/engine/Ruta.java
index d0bd8ee..5e83a32 100644
--- a/ruta-core/src/main/java/org/apache/uima/ruta/engine/Ruta.java
+++ b/ruta-core/src/main/java/org/apache/uima/ruta/engine/Ruta.java
@@ -96,7 +96,7 @@
 

     File scriptFile = File.createTempFile("Ruta", RutaEngine.SCRIPT_FILE_EXTENSION);

     scriptFile.deleteOnExit();

-    FileUtils.saveString2File(script, scriptFile);

+    FileUtils.saveString2File(script, scriptFile, "UTF-8");

     ae.setConfigParameterValue(RutaEngine.PARAM_SCRIPT_PATHS, new String[] { scriptFile

             .getParentFile().getAbsolutePath() });

     String name = scriptFile.getName().substring(0, scriptFile.getName().length() - 5);

diff --git a/ruta-core/src/main/java/org/apache/uima/ruta/engine/RutaEngine.java b/ruta-core/src/main/java/org/apache/uima/ruta/engine/RutaEngine.java
index 848a22c..a6c01ab 100644
--- a/ruta-core/src/main/java/org/apache/uima/ruta/engine/RutaEngine.java
+++ b/ruta-core/src/main/java/org/apache/uima/ruta/engine/RutaEngine.java
@@ -28,6 +28,7 @@
 import java.util.Arrays;

 import java.util.Collection;

 import java.util.HashMap;

+import java.util.HashSet;

 import java.util.List;

 import java.util.Map;

 import java.util.Map.Entry;

@@ -625,20 +626,29 @@
   }

 

   private void resetEnvironments(CAS cas) {

-    resetEnvironment(script, cas);

-    Collection<RutaModule> scripts = script.getScripts().values();

-    for (RutaModule module : scripts) {

-      resetEnvironment(module, cas);

-    }

+    resetEnvironment(script, cas, new HashSet<RutaModule>());

   }

 

-  private void resetEnvironment(RutaModule module, CAS cas) {

+  private void resetEnvironment(RutaModule module, CAS cas, Collection<RutaModule> alreadyResetted) {

+    if(alreadyResetted.contains(module)) {

+      // avoid loop in recursion

+      return;

+    }

+    alreadyResetted.add(module);

+    

+    // reset all blocks

     RutaBlock block = module.getBlock(null);

     block.getEnvironment().reset(cas);

     Collection<RutaBlock> blocks = module.getBlocks().values();

     for (RutaBlock each : blocks) {

       each.getEnvironment().reset(cas);

     }

+    

+    // reset imported scripts

+    Collection<RutaModule> scripts = module.getScripts().values();

+    for (RutaModule eachModule : scripts) {

+      resetEnvironment(eachModule, cas, alreadyResetted);

+    }

   }

 

   private void initializeTypes(RutaModule script, CAS cas, List<String> initialized) {

diff --git a/ruta-core/src/main/java/org/apache/uima/ruta/engine/RutaTestUtils.java b/ruta-core/src/main/java/org/apache/uima/ruta/engine/RutaTestUtils.java
index 3284bdf..33908d3 100644
--- a/ruta-core/src/main/java/org/apache/uima/ruta/engine/RutaTestUtils.java
+++ b/ruta-core/src/main/java/org/apache/uima/ruta/engine/RutaTestUtils.java
@@ -20,7 +20,9 @@
 package org.apache.uima.ruta.engine;

 

 import java.io.File;

+import java.io.FileOutputStream;

 import java.io.IOException;

+import java.io.OutputStream;

 import java.net.URISyntaxException;

 import java.net.URL;

 import java.util.ArrayList;

@@ -32,11 +34,13 @@
 import java.util.Map.Entry;

 import java.util.Set;

 

+import org.apache.commons.io.IOUtils;

 import org.apache.uima.UIMAFramework;

 import org.apache.uima.analysis_engine.AnalysisEngine;

 import org.apache.uima.analysis_engine.AnalysisEngineDescription;

 import org.apache.uima.analysis_engine.AnalysisEngineProcessException;

 import org.apache.uima.cas.CAS;

+import org.apache.uima.cas.SerialFormat;

 import org.apache.uima.cas.Type;

 import org.apache.uima.cas.text.AnnotationFS;

 import org.apache.uima.cas.text.AnnotationIndex;

@@ -47,6 +51,7 @@
 import org.apache.uima.resource.metadata.TypeDescription;

 import org.apache.uima.resource.metadata.TypeSystemDescription;

 import org.apache.uima.util.CasCreationUtils;

+import org.apache.uima.util.CasIOUtils;

 import org.apache.uima.util.FileUtils;

 import org.apache.uima.util.InvalidXMLException;

 import org.apache.uima.util.XMLInputSource;

@@ -315,4 +320,19 @@
     }

     return cas;

   }

+  

+  

+  public static void storeCas(CAS cas, String name) {

+    File file = new File("input/" + name + ".xmi");

+    file.getParentFile().mkdirs();

+    OutputStream fos = null;

+    try {

+      fos = new FileOutputStream(file);

+      CasIOUtils.save(cas, fos , SerialFormat.XMI);

+    } catch (IOException e) {

+      throw new IllegalArgumentException(e);

+    } finally {

+      IOUtils.closeQuietly(fos);

+    }

+  }

 }

diff --git a/ruta-core/src/main/java/org/apache/uima/ruta/expression/AnnotationTypeExpression.java b/ruta-core/src/main/java/org/apache/uima/ruta/expression/AnnotationTypeExpression.java
index ba460c2..bd42905 100644
--- a/ruta-core/src/main/java/org/apache/uima/ruta/expression/AnnotationTypeExpression.java
+++ b/ruta-core/src/main/java/org/apache/uima/ruta/expression/AnnotationTypeExpression.java
@@ -109,7 +109,7 @@
         if (featureExpression instanceof FeatureMatchExpression) {
           // allow more matches for feature matches
           bestGuessedAnnotations = stream.getAnnotationsByTypeInContext(type, context);
-        } else if(featureExpression != null) {
+        } else if (featureExpression != null) {
           bestGuessedAnnotations = stream.getBestGuessedAnnotationsAt(context.getAnnotation(),
                   type);
         } else {
@@ -207,14 +207,14 @@
         if (featureExpression instanceof FeatureMatchExpression) {
           // allow more matches for feature matches
           bestGuessedAnnotations = stream.getAnnotationsByTypeInContext(type, context);
-        } else if(featureExpression != null) {
+        } else if (featureExpression != null) {
           bestGuessedAnnotations = stream.getBestGuessedAnnotationsAt(context.getAnnotation(),
                   type);
           if (bestGuessedAnnotations.isEmpty()) {
-            bestGuessedAnnotations =stream.getAnnotationsByTypeInContext(type, context);
+            bestGuessedAnnotations = stream.getAnnotationsByTypeInContext(type, context);
           }
         } else {
-            bestGuessedAnnotations =stream.getAnnotationsByTypeInContext(type, context);
+          bestGuessedAnnotations = stream.getAnnotationsByTypeInContext(type, context);
         }
 
         if (featureExpression != null) {
diff --git a/ruta-core/src/main/java/org/apache/uima/ruta/expression/ConditionedAnnotationTypeExpression.java b/ruta-core/src/main/java/org/apache/uima/ruta/expression/ConditionedAnnotationTypeExpression.java
index 4f89cb6..e2617fc 100644
--- a/ruta-core/src/main/java/org/apache/uima/ruta/expression/ConditionedAnnotationTypeExpression.java
+++ b/ruta-core/src/main/java/org/apache/uima/ruta/expression/ConditionedAnnotationTypeExpression.java
@@ -41,11 +41,11 @@
 
   @Override
   public AnnotationFS getAnnotation(MatchContext context, RutaStream stream) {
-   List<AnnotationFS> annotationList = getAnnotationList(context, stream);
-   if(!annotationList.isEmpty()) {
-     return annotationList.get(0);
-   }
-   return null;
+    List<AnnotationFS> annotationList = getAnnotationList(context, stream);
+    if (!annotationList.isEmpty()) {
+      return annotationList.get(0);
+    }
+    return null;
   }
 
   @Override
@@ -53,7 +53,7 @@
     List<AnnotationFS> annotationList = super.getAnnotationList(context, stream);
     List<AnnotationFS> result = new ArrayList<>();
     for (AnnotationFS annotation : annotationList) {
-      if(evalulate(context, stream, annotation)) {
+      if (evalulate(context, stream, annotation)) {
         result.add(annotation);
       }
     }
@@ -61,9 +61,10 @@
   }
 
   private boolean evalulate(MatchContext context, RutaStream stream, AnnotationFS annotation) {
-    MatchContext localContext = new MatchContext(annotation, context.getElement(), context.getRuleMatch(), context.getDirection());
+    MatchContext localContext = new MatchContext(annotation, context.getElement(),
+            context.getRuleMatch(), context.getDirection());
     EvaluatedCondition eval = condition.eval(localContext, stream, InferenceCrowd.emptyCrowd);
     return eval.isValue();
   }
-  
+
 }
diff --git a/ruta-core/src/main/java/org/apache/uima/ruta/expression/ExpressionFactory.java b/ruta-core/src/main/java/org/apache/uima/ruta/expression/ExpressionFactory.java
index 87f328c..c5dbec2 100644
--- a/ruta-core/src/main/java/org/apache/uima/ruta/expression/ExpressionFactory.java
+++ b/ruta-core/src/main/java/org/apache/uima/ruta/expression/ExpressionFactory.java
@@ -304,7 +304,12 @@
   public MatchReference createMatchReference(Token refToken) {

     return createMatchReference(refToken, null, null);

   }

-

+  

+  public MatchReference createMatchReference(String reference) {

+    return createMatchReference(reference, null, null);

+  }

+  

+  

   public MatchReference createMatchReference(Token matchToken, Token comparatorToken,

           IRutaExpression argument) {

     String match = matchToken.getText();

@@ -312,10 +317,15 @@
     if (comparatorToken != null) {

       comparator = comparatorToken.getText();

     }

+    return createMatchReference(match, comparator, argument);

+  }

+  

+  public MatchReference createMatchReference(String matchString, String comparatorString,

+          IRutaExpression argument) {

     if (typeUsage != null) {

-      addPossibleTypeMentions(match);

+      addPossibleTypeMentions(matchString);

     }

-    return new MatchReference(match, comparator, argument);

+    return new MatchReference(matchString, comparatorString, argument);

   }

 

   public MatchReference createMatchReference(ITypeExpression expression) {

@@ -356,7 +366,7 @@
     return new ExternalWordTableExpression(name.getText(), args);

   }

 

-  public IRutaExpression createNullExpression() {

+  public IStringExpression createNullExpression() {

     return new NullExpression();

   }

 

diff --git a/ruta-core/src/main/java/org/apache/uima/ruta/expression/MatchReference.java b/ruta-core/src/main/java/org/apache/uima/ruta/expression/MatchReference.java
index 72cc660..676ce65 100644
--- a/ruta-core/src/main/java/org/apache/uima/ruta/expression/MatchReference.java
+++ b/ruta-core/src/main/java/org/apache/uima/ruta/expression/MatchReference.java
@@ -213,4 +213,12 @@
     return features;

   }

 

+  public IRutaExpression getArgument() {

+    return argument;

+  }

+

+  public String getComparator() {

+    return comparator;

+  }

+

 }

diff --git a/ruta-core/src/main/java/org/apache/uima/ruta/expression/NullExpression.java b/ruta-core/src/main/java/org/apache/uima/ruta/expression/NullExpression.java
index 6a6ffef..9d7699a 100644
--- a/ruta-core/src/main/java/org/apache/uima/ruta/expression/NullExpression.java
+++ b/ruta-core/src/main/java/org/apache/uima/ruta/expression/NullExpression.java
@@ -33,7 +33,8 @@
 import org.apache.uima.ruta.expression.type.ITypeExpression;
 import org.apache.uima.ruta.rule.MatchContext;
 
-public class NullExpression extends FeatureExpression implements IStringExpression, ITypeExpression, IAnnotationExpression {
+public class NullExpression extends FeatureExpression
+        implements IStringExpression, ITypeExpression, IAnnotationExpression {
 
   @Override
   public String getStringValue(MatchContext context, RutaStream stream) {
@@ -41,17 +42,19 @@
   }
 
   @Override
-  public Collection<AnnotationFS> getAnnotations(Collection<? extends FeatureStructure> featureStructures, boolean checkOnFeatureValue,
+  public Collection<AnnotationFS> getAnnotations(
+          Collection<? extends FeatureStructure> featureStructures, boolean checkOnFeatureValue,
           MatchContext context, RutaStream stream) {
     return null;
   }
-  
+
   @Override
-  public Collection<? extends FeatureStructure> getFeatureStructures(Collection<? extends FeatureStructure> featureStructures, boolean checkOnFeatureValue,
+  public Collection<? extends FeatureStructure> getFeatureStructures(
+          Collection<? extends FeatureStructure> featureStructures, boolean checkOnFeatureValue,
           MatchContext context, RutaStream stream) {
     return null;
   }
-  
+
   @Override
   public Type getType(MatchContext context, RutaStream stream) {
     return null;
@@ -87,5 +90,4 @@
     return null;
   }
 
- 
 }
diff --git a/ruta-core/src/main/java/org/apache/uima/ruta/expression/RutaExpression.java b/ruta-core/src/main/java/org/apache/uima/ruta/expression/RutaExpression.java
index f2f4aab..0dba911 100644
--- a/ruta-core/src/main/java/org/apache/uima/ruta/expression/RutaExpression.java
+++ b/ruta-core/src/main/java/org/apache/uima/ruta/expression/RutaExpression.java
@@ -75,9 +75,9 @@
         return result;

       }

     }

-    

+

     return stream.getBestGuessedAnnotationsAt(matchedAnnotation, type);

-    

+

   }

 

 }

diff --git a/ruta-core/src/main/java/org/apache/uima/ruta/expression/bool/BooleanFeatureExpression.java b/ruta-core/src/main/java/org/apache/uima/ruta/expression/bool/BooleanFeatureExpression.java
index bbf02e6..b238451 100644
--- a/ruta-core/src/main/java/org/apache/uima/ruta/expression/bool/BooleanFeatureExpression.java
+++ b/ruta-core/src/main/java/org/apache/uima/ruta/expression/bool/BooleanFeatureExpression.java
@@ -6,9 +6,9 @@
  * to you under the Apache License, Version 2.0 (the

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

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

- * 

+ *

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

- * 

+ *

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

  * software distributed under the License is distributed on an

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

@@ -40,13 +40,18 @@
 

   @Override

   public boolean getBooleanValue(MatchContext context, RutaStream stream) {

+

     AnnotationFS annotation = context.getAnnotation();

-    Feature feature = fe.getFeature(context, stream);

-    List<AnnotationFS> list = getTargetAnnotation(annotation, fe, context, stream);

-    Collection<? extends FeatureStructure> featureStructures = fe.getFeatureStructures(list, false, context,

-            stream);

+    Feature feature = this.fe.getFeature(context, stream);

+    List<AnnotationFS> list = this.getTargetAnnotation(annotation, this.fe, context, stream);

+    Collection<? extends FeatureStructure> featureStructures = this.fe.getFeatureStructures(list,

+            false, context, stream);

     if (!featureStructures.isEmpty()) {

       FeatureStructure next = featureStructures.iterator().next();

+      if (next instanceof AnnotationFS && next != annotation) {

+        feature = this.fe.getFeature(new MatchContext((AnnotationFS) next, context.getElement(),

+                context.getRuleMatch(), context.getDirection()), stream);

+      }

       return next.getBooleanValue(feature);

     }

     return false;

@@ -54,14 +59,17 @@
 

   @Override

   public String getStringValue(MatchContext context, RutaStream stream) {

-    return String.valueOf(getBooleanValue(context, stream));

+

+    return String.valueOf(this.getBooleanValue(context, stream));

   }

 

   public FeatureExpression getFe() {

-    return fe;

+

+    return this.fe;

   }

 

   public void setFe(FeatureExpression fe) {

+

     this.fe = fe;

   }

 

diff --git a/ruta-core/src/main/java/org/apache/uima/ruta/expression/bool/BooleanListFeatureExpression.java b/ruta-core/src/main/java/org/apache/uima/ruta/expression/bool/BooleanListFeatureExpression.java
index e059b2f..bc60d10 100644
--- a/ruta-core/src/main/java/org/apache/uima/ruta/expression/bool/BooleanListFeatureExpression.java
+++ b/ruta-core/src/main/java/org/apache/uima/ruta/expression/bool/BooleanListFeatureExpression.java
@@ -6,9 +6,9 @@
  * to you under the Apache License, Version 2.0 (the
  * "License"); you may not use this file except in compliance
  * with the License.  You may obtain a copy of the License at
- * 
+ *
  * http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  * Unless required by applicable law or agreed to in writing,
  * software distributed under the License is distributed on an
  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
@@ -46,23 +46,29 @@
     super();
     this.fe = fe;
   }
-  
+
   @Override
   public List<Boolean> getList(MatchContext context, RutaStream stream) {
+
     AnnotationFS annotation = context.getAnnotation();
-    Feature feature = fe.getFeature(context, stream);
-    if(feature == null || !feature.getRange().isArray() || !StringUtils.equals(feature.getRange().getName(), CAS.TYPE_NAME_BOOLEAN_ARRAY)) {
+    Feature feature = this.fe.getFeature(context, stream);
+    if (feature == null || !feature.getRange().isArray()
+            || !StringUtils.equals(feature.getRange().getName(), CAS.TYPE_NAME_BOOLEAN_ARRAY)) {
       // throw runtime exception?
       return Collections.emptyList();
     }
-    List<AnnotationFS> list = getTargetAnnotation(annotation, fe, context, stream);
-    Collection<? extends FeatureStructure> featureStructures = fe.getFeatureStructures(list, false, context,
-            stream);
+    List<AnnotationFS> list = this.getTargetAnnotation(annotation, this.fe, context, stream);
+    Collection<? extends FeatureStructure> featureStructures = this.fe.getFeatureStructures(list,
+            false, context, stream);
     List<Boolean> result = new ArrayList<>();
 
     for (FeatureStructure each : featureStructures) {
+      if (each instanceof AnnotationFS && !each.getType().equals(annotation.getType())) {
+        feature = this.fe.getFeature(new MatchContext((AnnotationFS) each, context.getElement(),
+                context.getRuleMatch(), context.getDirection()), stream);
+      }
       FeatureStructure featureValue = each.getFeatureValue(feature);
-      if(featureValue instanceof BooleanArrayFS) {
+      if (featureValue instanceof BooleanArrayFS) {
         BooleanArrayFS array = (BooleanArrayFS) featureValue;
         for (int i = 0; i < array.size(); i++) {
           Boolean b = array.get(i);
@@ -70,21 +76,18 @@
         }
       }
     }
-    
+
     return result;
   }
 
   public FeatureExpression getFeatureExpression() {
-    return fe;
+
+    return this.fe;
   }
 
   public void setFeatureExpression(FeatureExpression fe) {
+
     this.fe = fe;
   }
 
-
-
-  
-  
-
 }
diff --git a/ruta-core/src/main/java/org/apache/uima/ruta/expression/number/NumberFeatureExpression.java b/ruta-core/src/main/java/org/apache/uima/ruta/expression/number/NumberFeatureExpression.java
index 3e370bf..ff28da1 100644
--- a/ruta-core/src/main/java/org/apache/uima/ruta/expression/number/NumberFeatureExpression.java
+++ b/ruta-core/src/main/java/org/apache/uima/ruta/expression/number/NumberFeatureExpression.java
@@ -6,9 +6,9 @@
  * to you under the Apache License, Version 2.0 (the

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

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

- * 

+ *

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

- * 

+ *

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

  * software distributed under the License is distributed on an

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

@@ -42,32 +42,40 @@
 

   @Override

   public int getIntegerValue(MatchContext context, RutaStream stream) {

-    Number v = getNumberValue(context, stream);

+

+    Number v = this.getNumberValue(context, stream);

     return v == null ? 0 : v.intValue();

   }

 

   @Override

   public double getDoubleValue(MatchContext context, RutaStream stream) {

-    Number v = getNumberValue(context, stream);

+

+    Number v = this.getNumberValue(context, stream);

     return v == null ? 0 : v.doubleValue();

   }

 

   @Override

   public float getFloatValue(MatchContext context, RutaStream stream) {

-    Number v = getNumberValue(context, stream);

+

+    Number v = this.getNumberValue(context, stream);

     return v == null ? 0 : v.floatValue();

   }

 

   private Number getNumberValue(MatchContext context, RutaStream stream) {

+

     AnnotationFS annotation = context.getAnnotation();

     Number result = null;

-    List<AnnotationFS> list = getTargetAnnotation(annotation, fe, context, stream);

-    Collection<? extends FeatureStructure> featureStructures = fe.getFeatureStructures(list, false, context,

-            stream);

+    List<AnnotationFS> list = this.getTargetAnnotation(annotation, this.fe, context, stream);

+    Collection<? extends FeatureStructure> featureStructures = this.fe.getFeatureStructures(list,

+            false, context, stream);

     if (!featureStructures.isEmpty()) {

-      Feature feature = fe.getFeature(context, stream);

+      Feature feature = this.fe.getFeature(context, stream);

       Type range = feature.getRange();

       FeatureStructure next = featureStructures.iterator().next();

+      if (next instanceof AnnotationFS && !next.getType().equals(annotation.getType())) {

+        feature = this.fe.getFeature(new MatchContext((AnnotationFS) next, context.getElement(),

+                context.getRuleMatch(), context.getDirection()), stream);

+      }

       if (CAS.TYPE_NAME_BYTE.equals(range.getName())) {

         result = next.getByteValue(feature);

       } else if (CAS.TYPE_NAME_DOUBLE.equals(range.getName())) {

@@ -87,14 +95,17 @@
 

   @Override

   public String getStringValue(MatchContext context, RutaStream stream) {

-    return "" + getNumberValue(context, stream);

+

+    return "" + this.getNumberValue(context, stream);

   }

 

   public FeatureExpression getFe() {

-    return fe;

+

+    return this.fe;

   }

 

   public void setFe(FeatureExpression fe) {

+

     this.fe = fe;

   }

 

diff --git a/ruta-core/src/main/java/org/apache/uima/ruta/expression/number/NumberListFeatureExpression.java b/ruta-core/src/main/java/org/apache/uima/ruta/expression/number/NumberListFeatureExpression.java
index 804859b..aaa44a7 100644
--- a/ruta-core/src/main/java/org/apache/uima/ruta/expression/number/NumberListFeatureExpression.java
+++ b/ruta-core/src/main/java/org/apache/uima/ruta/expression/number/NumberListFeatureExpression.java
@@ -6,9 +6,9 @@
  * to you under the Apache License, Version 2.0 (the
  * "License"); you may not use this file except in compliance
  * with the License.  You may obtain a copy of the License at
- * 
+ *
  * http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  * Unless required by applicable law or agreed to in writing,
  * software distributed under the License is distributed on an
  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
@@ -51,18 +51,23 @@
 
   @Override
   public List<Number> getList(MatchContext context, RutaStream stream) {
+
     AnnotationFS annotation = context.getAnnotation();
-    Feature feature = fe.getFeature(context, stream);
-    if (feature == null || !feature.getRange().isArray() || !validType(feature)) {
+    Feature feature = this.fe.getFeature(context, stream);
+    if (feature == null || !feature.getRange().isArray() || !this.validType(feature)) {
       // throw runtime exception?
       return Collections.emptyList();
     }
-    List<AnnotationFS> list = getTargetAnnotation(annotation, fe, context, stream);
-    Collection<? extends FeatureStructure> featureStructures = fe.getFeatureStructures(list, false, context,
-            stream);
+    List<AnnotationFS> list = this.getTargetAnnotation(annotation, this.fe, context, stream);
+    Collection<? extends FeatureStructure> featureStructures = this.fe.getFeatureStructures(list,
+            false, context, stream);
     List<Number> result = new ArrayList<>();
 
     for (FeatureStructure each : featureStructures) {
+      if (each instanceof AnnotationFS && !each.getType().equals(annotation.getType())) {
+        feature = this.fe.getFeature(new MatchContext((AnnotationFS) each, context.getElement(),
+                context.getRuleMatch(), context.getDirection()), stream);
+      }
       FeatureStructure featureValue = each.getFeatureValue(feature);
       if (featureValue instanceof IntArrayFS) {
         IntArrayFS array = (IntArrayFS) featureValue;
@@ -89,6 +94,7 @@
   }
 
   private boolean validType(Feature feature) {
+
     String name = feature.getRange().getName();
     return StringUtils.equals(name, CAS.TYPE_NAME_INTEGER_ARRAY)
             || StringUtils.equals(name, CAS.TYPE_NAME_DOUBLE_ARRAY)
@@ -96,10 +102,12 @@
   }
 
   public FeatureExpression getFeatureExpression() {
-    return fe;
+
+    return this.fe;
   }
 
   public void setFeatureExpression(FeatureExpression fe) {
+
     this.fe = fe;
   }
 
diff --git a/ruta-core/src/main/java/org/apache/uima/ruta/expression/string/StringFeatureExpression.java b/ruta-core/src/main/java/org/apache/uima/ruta/expression/string/StringFeatureExpression.java
index 682072b..0eb6c31 100644
--- a/ruta-core/src/main/java/org/apache/uima/ruta/expression/string/StringFeatureExpression.java
+++ b/ruta-core/src/main/java/org/apache/uima/ruta/expression/string/StringFeatureExpression.java
@@ -6,9 +6,9 @@
  * to you under the Apache License, Version 2.0 (the

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

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

- * 

+ *

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

- * 

+ *

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

  * software distributed under the License is distributed on an

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

@@ -41,12 +41,18 @@
 

   @Override

   public String getStringValue(MatchContext context, RutaStream stream) {

+

     AnnotationFS annotation = context.getAnnotation();

-    Feature feature = fe.getFeature(context, stream);

-    List<AnnotationFS> list = getTargetAnnotation(annotation, fe, context, stream);

-    Collection<? extends FeatureStructure> featureStructures = fe.getFeatureStructures(list, false, context, stream);

+    Feature feature = this.fe.getFeature(context, stream);

+    List<AnnotationFS> list = this.getTargetAnnotation(annotation, this.fe, context, stream);

+    Collection<? extends FeatureStructure> featureStructures = this.fe.getFeatureStructures(list,

+            false, context, stream);

     if (!featureStructures.isEmpty()) {

       FeatureStructure next = featureStructures.iterator().next();

+      if (next instanceof AnnotationFS && !next.getType().equals(annotation.getType())) {

+        feature = this.fe.getFeature(new MatchContext((AnnotationFS) next, context.getElement(),

+                context.getRuleMatch(), context.getDirection()), stream);

+      }

       if (next instanceof AnnotationFS && feature instanceof CoveredTextFeature) {

         return ((AnnotationFS) next).getCoveredText();

       } else {

@@ -57,10 +63,12 @@
   }

 

   public FeatureExpression getFe() {

-    return fe;

+

+    return this.fe;

   }

 

   public void setFe(FeatureExpression fe) {

+

     this.fe = fe;

   }

 

diff --git a/ruta-core/src/main/java/org/apache/uima/ruta/expression/string/StringListFeatureExpression.java b/ruta-core/src/main/java/org/apache/uima/ruta/expression/string/StringListFeatureExpression.java
index 3d860ea..714e2c3 100644
--- a/ruta-core/src/main/java/org/apache/uima/ruta/expression/string/StringListFeatureExpression.java
+++ b/ruta-core/src/main/java/org/apache/uima/ruta/expression/string/StringListFeatureExpression.java
@@ -6,9 +6,9 @@
  * to you under the Apache License, Version 2.0 (the
  * "License"); you may not use this file except in compliance
  * with the License.  You may obtain a copy of the License at
- * 
+ *
  * http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  * Unless required by applicable law or agreed to in writing,
  * software distributed under the License is distributed on an
  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
@@ -46,45 +46,48 @@
     super();
     this.fe = fe;
   }
-  
+
   @Override
   public List<String> getList(MatchContext context, RutaStream stream) {
+
     AnnotationFS annotation = context.getAnnotation();
-    Feature feature = fe.getFeature(context, stream);
-    if(feature == null || !feature.getRange().isArray() || !StringUtils.equals(feature.getRange().getName(), CAS.TYPE_NAME_STRING_ARRAY)) {
+    Feature feature = this.fe.getFeature(context, stream);
+    if (feature == null || !feature.getRange().isArray()
+            || !StringUtils.equals(feature.getRange().getName(), CAS.TYPE_NAME_STRING_ARRAY)) {
       // throw runtime exception?
       return Collections.emptyList();
     }
-    List<AnnotationFS> list = getTargetAnnotation(annotation, fe, context, stream);
-    Collection<? extends FeatureStructure> featureStructures = fe.getFeatureStructures(list, false, context,
-            stream);
+    List<AnnotationFS> list = this.getTargetAnnotation(annotation, this.fe, context, stream);
+    Collection<? extends FeatureStructure> featureStructures = this.fe.getFeatureStructures(list,
+            false, context, stream);
     List<String> result = new ArrayList<>();
 
     for (FeatureStructure each : featureStructures) {
+      if (each instanceof AnnotationFS && !each.getType().equals(annotation.getType())) {
+        feature = this.fe.getFeature(new MatchContext((AnnotationFS) each, context.getElement(),
+                context.getRuleMatch(), context.getDirection()), stream);
+      }
       FeatureStructure featureValue = each.getFeatureValue(feature);
-      if(featureValue instanceof StringArrayFS) {
+      if (featureValue instanceof StringArrayFS) {
         StringArrayFS array = (StringArrayFS) featureValue;
         for (int i = 0; i < array.size(); i++) {
           String b = array.get(i);
           result.add(b);
         }
-      } 
+      }
     }
-    
+
     return result;
   }
 
   public FeatureExpression getFeatureExpression() {
-    return fe;
+
+    return this.fe;
   }
 
   public void setFeatureExpression(FeatureExpression fe) {
+
     this.fe = fe;
   }
 
-
-
-  
-  
-
 }
diff --git a/ruta-core/src/main/java/org/apache/uima/ruta/expression/type/TypeListVariableExpression.java b/ruta-core/src/main/java/org/apache/uima/ruta/expression/type/TypeListVariableExpression.java
index c75874d..3e6e201 100644
--- a/ruta-core/src/main/java/org/apache/uima/ruta/expression/type/TypeListVariableExpression.java
+++ b/ruta-core/src/main/java/org/apache/uima/ruta/expression/type/TypeListVariableExpression.java
@@ -48,7 +48,12 @@
       } else if (each instanceof Type) {

         result.add((Type) each);

       } else if(each instanceof String) {

-        result.add(parent.getEnvironment().getType((String) each));

+        Type type = parent.getEnvironment().getType((String) each);

+        if(type != null) {

+          result.add(type);

+        } else {

+          throw new IllegalArgumentException("Not able to resolve type: " + each);

+        }

       }

     }

     return result;

diff --git a/ruta-core/src/main/java/org/apache/uima/ruta/resource/TrieXMLEventHandler.java b/ruta-core/src/main/java/org/apache/uima/ruta/resource/TrieXMLEventHandler.java
index 5634bcb..9a31ea4 100644
--- a/ruta-core/src/main/java/org/apache/uima/ruta/resource/TrieXMLEventHandler.java
+++ b/ruta-core/src/main/java/org/apache/uima/ruta/resource/TrieXMLEventHandler.java
@@ -28,17 +28,16 @@
 
   private Stack<MultiTextNode> stack;
 
-  // boolean listeningState;
+  private boolean inContent;
 
-  boolean inContent;
+  private boolean inType;
 
-  boolean inType;
+  private StringBuilder type = new StringBuilder();
 
   public TrieXMLEventHandler(MultiTextNode root) {
     super();
     this.stack = new Stack<MultiTextNode>();
     stack.add(root);
-    // this.listeningState = false;
   }
 
   @Override
@@ -53,11 +52,7 @@
   public void startElement(String namespaceURI, String localName, String qualifiedName,
           Attributes atts) {
     if ("n".equals(localName) || "n".equals(qualifiedName)) {
-      // char c = atts.getValue("c").charAt(0);
-      // boolean e = Boolean.valueOf(atts.getValue("e"));
       MultiTextNode newNode = new MultiTextNode();
-      // newNode.setWordEnd(e);
-      // stack.peek().addChild(newNode);
       stack.add(newNode);
       inContent = false;
       inType = false;
@@ -67,7 +62,6 @@
       inContent = false;
     }
     if ("c".equals(localName) || "c".equals(qualifiedName)) {
-      // listeningState = true;
       inType = false;
       inContent = true;
     }
@@ -80,6 +74,8 @@
       stack.peek().addChild(pop);
     }
     if ("t".equals(localName) || "t".equals(qualifiedName)) {
+      stack.peek().addType(type.toString());
+      type.setLength(0);
       inType = false;
     }
     if ("c".equals(localName) || "c".equals(qualifiedName)) {
@@ -94,11 +90,7 @@
     }
     MultiTextNode peek = stack.peek();
     if (inType) {
-      StringBuilder type = new StringBuilder();
-      for (int i = start; i < start + length; i++) {
-        type.append(String.valueOf(ch[i]));
-      }
-      peek.addType(type.toString());
+      type.append(ch, start, length);
       peek.setWordEnd(true);
     } else if (inContent) {
       if (ch.length > 0) {
diff --git a/ruta-core/src/main/java/org/apache/uima/ruta/rule/ComposedRuleElement.java b/ruta-core/src/main/java/org/apache/uima/ruta/rule/ComposedRuleElement.java
index 2adc318..a663760 100644
--- a/ruta-core/src/main/java/org/apache/uima/ruta/rule/ComposedRuleElement.java
+++ b/ruta-core/src/main/java/org/apache/uima/ruta/rule/ComposedRuleElement.java
@@ -83,8 +83,8 @@
         RuleMatch extendedMatch = ruleMatch.copy(extendedContainerMatch, true);

         ComposedRuleElementMatch composedMatch = createComposedMatch(extendedMatch,

                 extendedContainerMatch, stream);

-        List<RuleMatch> startRuleMatches = each.startMatch(extendedMatch, null, composedMatch,

-                this, stream, crowd);

+        List<RuleMatch> startRuleMatches = each.startMatch(extendedMatch, null, composedMatch, this,

+                stream, crowd);

         for (RuleMatch startRuleMatch : startRuleMatches) {

           ComposedRuleElementMatch startElementMatch = (ComposedRuleElementMatch) startRuleMatch

                   .getLastMatch(this, true);

@@ -223,8 +223,8 @@
         AnnotationFS lastAnnotation = eachRuleMatch.getLastMatchedAnnotation(context, stream);

         boolean failed = !eachComposedMatch.matched();

         List<AnnotationFS> textsMatched = eachRuleMatch.getMatchedAnnotationsOfRoot();

-        if ((!stream.isGreedyAnchoring() && !stream.isOnlyOnce())

-                || (!textsMatched.isEmpty() && !earlyExit(textsMatched.get(0), ruleApply, stream))) {

+        if ((!stream.isGreedyAnchoring() && !stream.isOnlyOnce()) || (!textsMatched.isEmpty()

+                && !earlyExit(textsMatched.get(0), ruleApply, stream))) {

           List<RuleMatch> fallbackContinue = fallbackContinue(after, failed, lastAnnotation,

                   eachRuleMatch, ruleApply, eachComposedMatch, sideStepOrigin, entryPoint, stream,

                   crowd);

@@ -269,8 +269,8 @@
         boolean failed = !eachComposedMatch.matched();

 

         List<AnnotationFS> textsMatched = eachRuleMatch.getMatchedAnnotationsOfRoot();

-        if ((!stream.isGreedyAnchoring() && !stream.isOnlyOnce())

-                || (!textsMatched.isEmpty() && !earlyExit(textsMatched.get(0), ruleApply, stream))) {

+        if ((!stream.isGreedyAnchoring() && !stream.isOnlyOnce()) || (!textsMatched.isEmpty()

+                && !earlyExit(textsMatched.get(0), ruleApply, stream))) {

           List<RuleMatch> fallbackContinue = fallbackContinue(after, failed, lastAnnotation,

                   eachRuleMatch, ruleApply, eachComposedMatch, sideStepOrigin, entryPoint, stream,

                   crowd);

@@ -317,7 +317,8 @@
   }

 

   private Map<RuleMatch, ComposedRuleElementMatch> mergeDisjunctiveRuleMatches(

-          Map<RuleMatch, ComposedRuleElementMatch> ruleMatches, boolean direction, RutaStream stream) {

+          Map<RuleMatch, ComposedRuleElementMatch> ruleMatches, boolean direction,

+          RutaStream stream) {

     // TODO hotfix: this needs a correct implementation

     Map<RuleMatch, ComposedRuleElementMatch> result = new TreeMap<RuleMatch, ComposedRuleElementMatch>(

             ruleMatchComparator);

@@ -336,10 +337,8 @@
           largestEntry = entry;

           largestAnnotation = lastMatchedAnnotation;

         } else {

-          if (lastMatchedAnnotation != null

-                  && largestAnnotation != null

-                  && lastMatchedAnnotation.getCoveredText().length() > largestAnnotation

-                          .getCoveredText().length()) {

+          if (lastMatchedAnnotation != null && largestAnnotation != null && lastMatchedAnnotation

+                  .getCoveredText().length() > largestAnnotation.getCoveredText().length()) {

             largestEntry = entry;

             largestAnnotation = lastMatchedAnnotation;

           }

@@ -448,8 +447,8 @@
             result = nextElement.continueMatch(after, backtrackedAnnotation, ruleMatch, ruleApply,

                     parentContainerMatch, sideStepOrigin, entryPoint, stream, crowd);

           } else {

-            result = fallback(after, failed, annotation, ruleMatch, ruleApply,

-                    parentContainerMatch, sideStepOrigin, entryPoint, stream, crowd);

+            result = fallback(after, failed, annotation, ruleMatch, ruleApply, parentContainerMatch,

+                    sideStepOrigin, entryPoint, stream, crowd);

           }

         } else {

           if (this.equals(entryPoint)) {

@@ -517,10 +516,12 @@
       ComposedRuleElement parentElement = (ComposedRuleElement) parentContainer;

       result = parentElement.fallbackContinue(after, failed, annotation, ruleMatch, ruleApply,

               containerMatch, sideStepOrigin, entryPoint, stream, crowd);

-    } else if (sideStepOrigin != null) {

+    } else if (sideStepOrigin != null && !failed) {

       result = sideStepOrigin.continueSideStep(after, ruleMatch, ruleApply, containerMatch,

               entryPoint, stream, crowd);

     } else {

+      // take care that failed matches wont be applied

+      ruleMatch.setMatched(ruleMatch.matched && !failed);

       result.add(ruleMatch);

       doneMatching(ruleMatch, ruleApply, stream, crowd);

     }

@@ -540,7 +541,8 @@
           RutaStream stream, InferenceCrowd crowd) {

     List<AnnotationFS> textsMatched = match.getTextsMatched();

     if (textsMatched == null || textsMatched.isEmpty()) {

-      getParent().getEnvironment().addMatchToVariable(ruleMatch, this, new MatchContext(getParent()), stream);

+      getParent().getEnvironment().addMatchToVariable(ruleMatch, this,

+              new MatchContext(getParent()), stream);

       match.evaluateInnerMatches(true, stream);

       return;

     }

@@ -551,7 +553,7 @@
 

     MatchContext context = new MatchContext(annotation, this, ruleMatch, after);

     context.getParent().getEnvironment().addMatchToVariable(ruleMatch, this, context, stream);

-    

+

     List<EvaluatedCondition> evaluatedConditions = new ArrayList<EvaluatedCondition>(

             conditions.size());

     for (AbstractRutaCondition condition : conditions) {

@@ -559,7 +561,7 @@
       EvaluatedCondition eval = condition.eval(context, stream, crowd);

       crowd.endVisit(condition, null);

       evaluatedConditions.add(eval);

-      if(!eval.isValue()) {

+      if (!eval.isValue()) {

         break;

       }

     }

diff --git a/ruta-core/src/main/java/org/apache/uima/ruta/rule/RutaRuleElement.java b/ruta-core/src/main/java/org/apache/uima/ruta/rule/RutaRuleElement.java
index 729d679..194c19d 100644
--- a/ruta-core/src/main/java/org/apache/uima/ruta/rule/RutaRuleElement.java
+++ b/ruta-core/src/main/java/org/apache/uima/ruta/rule/RutaRuleElement.java
@@ -276,7 +276,7 @@
     if (matchInfo == null) {

       context.getParent().getEnvironment().addMatchToVariable(ruleMatch, this, context, stream);

       if (quantifier.isOptional(context, stream)) {

-        result = continueMatchSomewhereElse(after, true, annotation, ruleMatch, ruleApply,

+        result = continueMatchSomewhereElse(after, false, annotation, ruleMatch, ruleApply,

                 containerMatch, sideStepOrigin, entryPoint, stream, crowd);

       } else if (getContainer() instanceof ComposedRuleElement) {

         ComposedRuleElement cre = (ComposedRuleElement) getContainer();

diff --git a/ruta-core/src/main/java/org/apache/uima/ruta/verbalize/ExpressionVerbalizer.java b/ruta-core/src/main/java/org/apache/uima/ruta/verbalize/ExpressionVerbalizer.java
index 9c92729..0c48ff0 100644
--- a/ruta-core/src/main/java/org/apache/uima/ruta/verbalize/ExpressionVerbalizer.java
+++ b/ruta-core/src/main/java/org/apache/uima/ruta/verbalize/ExpressionVerbalizer.java
@@ -21,6 +21,8 @@
 

 import java.util.Iterator;

 

+import org.apache.commons.lang3.StringUtils;

+import org.apache.uima.cas.CAS;

 import org.apache.uima.ruta.expression.AnnotationTypeExpression;

 import org.apache.uima.ruta.expression.IRutaExpression;

 import org.apache.uima.ruta.expression.MatchReference;

@@ -299,7 +301,19 @@
   }

   

   public String verbalize(MatchReference expression) {

-    return expression.getMatch();

+    String match = expression.getMatch();

+    if(match == null) {

+      String string = expression.toString();

+      if(StringUtils.equals(string, CAS.TYPE_NAME_DOCUMENT_ANNOTATION)) {

+        return "Document";

+      } else {

+        return string;

+      }

+    }

+    if(expression.getArgument() != null) {

+     return  match + expression.getComparator() + verbalizer.verbalize(expression.getArgument());

+    }

+    return match;

   }

   

   public String verbalize(AnnotationTypeExpression expression) {

diff --git a/ruta-core/src/main/java/org/apache/uima/ruta/verbalize/RutaVerbalizer.java b/ruta-core/src/main/java/org/apache/uima/ruta/verbalize/RutaVerbalizer.java
index 6ce0ad5..1d1c082 100644
--- a/ruta-core/src/main/java/org/apache/uima/ruta/verbalize/RutaVerbalizer.java
+++ b/ruta-core/src/main/java/org/apache/uima/ruta/verbalize/RutaVerbalizer.java
@@ -75,10 +75,10 @@
       return conditionVerbalizer.verbalize((AbstractRutaCondition) element);

     } else if (element instanceof IRutaExpression) {

       return expressionVerbalizer.verbalize((RutaExpression) element);

-    } else if (element instanceof RutaElement) {

-      return scriptVerbalizer.verbalize((RutaElement) element);

     } else if (element instanceof RutaBlock) {

       return verbalize((RutaBlock) element, false);

+    } else if (element instanceof RutaElement) {

+      return scriptVerbalizer.verbalize((RutaElement) element);

     } else {

       return element.getClass().getSimpleName();

     }

diff --git a/ruta-core/src/main/java/org/apache/uima/ruta/verbalize/ScriptVerbalizer.java b/ruta-core/src/main/java/org/apache/uima/ruta/verbalize/ScriptVerbalizer.java
index 4fdc622..f60661b 100644
--- a/ruta-core/src/main/java/org/apache/uima/ruta/verbalize/ScriptVerbalizer.java
+++ b/ruta-core/src/main/java/org/apache/uima/ruta/verbalize/ScriptVerbalizer.java
@@ -154,9 +154,16 @@
       RutaMatcher matcher = tmre.getMatcher();

       // action-only rule

         IRutaExpression expression = matcher.getExpression();

-        if (expression != null) {

-          result.append(verbalizer.verbalize(expression));

-        } else {

+        boolean actionOnlyRule = expression == null;

+        if(expression != null) {

+          String verbalize = verbalizer.verbalize(expression);

+          if(StringUtils.isBlank(verbalize)) {

+            actionOnlyRule = true;

+          } else {

+            result.append(verbalize);

+          }

+        }

+        if (actionOnlyRule) {

           Iterator<AbstractRutaAction> ait = actions.iterator();

           while (ait.hasNext()) {

             AbstractRutaAction each = ait.next();

@@ -165,6 +172,7 @@
               result.append(",");

             }

           }

+          return result.toString();

         }

     } else if (re instanceof WildCardRuleElement) {

       result.append("#");

diff --git a/ruta-core/src/test/java/org/apache/uima/ruta/action/ConfigureTest.java b/ruta-core/src/test/java/org/apache/uima/ruta/action/ConfigureTest.java
new file mode 100644
index 0000000..1065d4e
--- /dev/null
+++ b/ruta-core/src/test/java/org/apache/uima/ruta/action/ConfigureTest.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.uima.ruta.action;
+
+import java.util.Collection;
+
+import org.apache.uima.cas.CAS;
+import org.apache.uima.fit.util.JCasUtil;
+import org.apache.uima.jcas.JCas;
+import org.apache.uima.ruta.engine.Ruta;
+import org.apache.uima.ruta.engine.RutaTestUtils;
+import org.apache.uima.ruta.type.Statistics;
+import org.junit.Assert;
+import org.junit.Test;
+
+
+public class ConfigureTest {
+
+  @Test
+  public void test() throws Exception {
+    
+    String script = "ENGINE org.apache.uima.ruta.engine.CWEngine;";
+    script += "CONFIGURE(CWEngine, \"profile\"= true, \"statistics\"=true);";
+    script +="EXEC(CWEngine);";
+    CAS cas = RutaTestUtils.getCAS("Some test.");
+    Ruta.apply(cas, script);
+    
+    JCas jcas = cas.getJCas();
+    Collection<Statistics> statistics = JCasUtil.select(jcas, Statistics.class);
+    
+    Assert.assertFalse(statistics.isEmpty());
+  }
+  
+  
+}
diff --git a/ruta-core/src/test/java/org/apache/uima/ruta/action/GatherTest.java b/ruta-core/src/test/java/org/apache/uima/ruta/action/GatherTest.java
index 8a6605a..53584e3 100644
--- a/ruta-core/src/test/java/org/apache/uima/ruta/action/GatherTest.java
+++ b/ruta-core/src/test/java/org/apache/uima/ruta/action/GatherTest.java
@@ -88,7 +88,7 @@
   }

 

   @Test

-  public void testOptionalMatch() {

+  public void testOptionalMatch() throws Exception {

     String document = "A X C";

     String script = "";

     script += "W{REGEXP(\"A\")->MARK(T1)};";

@@ -105,13 +105,8 @@
     list.add(new TestFeature(fn1, "", "uima.tcas.Annotation"));

     String fn2 = "b";

     list.add(new TestFeature(fn2, "", "uima.tcas.Annotation"));

-    CAS cas = null;

-    try {

-      cas = RutaTestUtils.getCAS(document, complexTypes, features);

+    CAS cas  = RutaTestUtils.getCAS(document, complexTypes, features);

       Ruta.apply(cas, script);

-    } catch (Exception e) {

-      e.printStackTrace();

-    }

 

     Type t = null;

     AnnotationIndex<AnnotationFS> ai = null;

diff --git a/ruta-core/src/test/java/org/apache/uima/ruta/block/ForEachBlockTest.java b/ruta-core/src/test/java/org/apache/uima/ruta/block/ForEachBlockTest.java
index e36eaf5..887b739 100644
--- a/ruta-core/src/test/java/org/apache/uima/ruta/block/ForEachBlockTest.java
+++ b/ruta-core/src/test/java/org/apache/uima/ruta/block/ForEachBlockTest.java
@@ -208,6 +208,24 @@
     cas.release();
   }
   
+  @Test
+  public void testWithContainingBlock() throws Exception {
+    String script = "";
+    script += "FOREACH(num) NUM{} {\n";
+    script += "BLOCK(onlyNum) num{}{\n";
+    script += "(num NUM){-> T1};\n";
+    script += "num{-> T2};\n";
+    script += "}\n";
+    script += "}\n";
+
+    CAS cas = RutaTestUtils.getCAS("1 22 333");
+    Ruta.apply(cas, script);
+
+    RutaTestUtils.assertAnnotationsEquals(cas, 1, 0);
+    RutaTestUtils.assertAnnotationsEquals(cas, 2, 3, "1", "22", "333");
+    cas.release();
+  }
+  
   
   
 }
diff --git a/ruta-core/src/test/java/org/apache/uima/ruta/block/RutaScriptBlockTest.java b/ruta-core/src/test/java/org/apache/uima/ruta/block/RutaScriptBlockTest.java
index 784cf52..f8af263 100644
--- a/ruta-core/src/test/java/org/apache/uima/ruta/block/RutaScriptBlockTest.java
+++ b/ruta-core/src/test/java/org/apache/uima/ruta/block/RutaScriptBlockTest.java
@@ -87,5 +87,19 @@
     RutaTestUtils.assertAnnotationsEquals(cas, 1, 1, "1");

     cas.release();

   }

-  

+

+  @Test

+  public void testWindow() throws Exception {

+    String script = "NUM{->T1};";

+    script += "BLOCK(num) NUM{} {\n";

+    script += "NUM{-> T2};";

+    script += "}";

+

+    CAS cas = RutaTestUtils.getCAS("1 22 333");

+    Ruta.apply(cas, script);

+

+    RutaTestUtils.assertAnnotationsEquals(cas, 2, 3, "1", "22", "333");

+    cas.release();

+  }

+

 }

diff --git a/ruta-core/src/test/java/org/apache/uima/ruta/condition/ImplicitCondition2Test.java b/ruta-core/src/test/java/org/apache/uima/ruta/condition/ImplicitCondition2Test.java
index 1c7b140..24e7d95 100644
--- a/ruta-core/src/test/java/org/apache/uima/ruta/condition/ImplicitCondition2Test.java
+++ b/ruta-core/src/test/java/org/apache/uima/ruta/condition/ImplicitCondition2Test.java
@@ -63,12 +63,28 @@
   

   @Test

   public void testStringCompare() throws ResourceInitializationException, InvalidXMLException, IOException, AnalysisEngineProcessException, CASException {

-    CAS cas = RutaTestUtils.getCAS("a b. a b.");

+    String document = "a b. a b.";

+    CAS cas = RutaTestUtils.getCAS(document);

     Assert.assertTrue(Ruta.matches(cas.getJCas(), "(w:W # W{W.ct==w.ct}){->T1};"));

     Assert.assertTrue(Ruta.matches(cas.getJCas(), "STRING s1 = \"a\"; (w:W W{s1==w.ct}){->T2};"));

     RutaTestUtils.assertAnnotationsEquals(cas, 1, 2, "a b. a", "b. a b");

     RutaTestUtils.assertAnnotationsEquals(cas, 2, 2, "a b", "a b");

   }

   

+  @Test

+  public void testStringCompareNull() throws ResourceInitializationException, InvalidXMLException, IOException, AnalysisEngineProcessException, CASException {

+    String document = "a b. a b.";

+    CAS cas = RutaTestUtils.getCAS(document);

+    

+    String rules = "STRING s2;\n";

+    rules += "Document{s2 == \"\" -> T10};\n";

+    rules += "Document{s2 == null -> T11};\n";

+    Assert.assertTrue(Ruta.matches(cas.getJCas(), rules));

+    

+    RutaTestUtils.assertAnnotationsEquals(cas, 10, 1, document);

+    RutaTestUtils.assertAnnotationsEquals(cas, 11, 0);

+    

+  }

+  

   

 }

diff --git a/ruta-core/src/test/java/org/apache/uima/ruta/engine/ParamVarTest.java b/ruta-core/src/test/java/org/apache/uima/ruta/engine/ParamVarTest.java
index 7ccdf8e..401c18e 100644
--- a/ruta-core/src/test/java/org/apache/uima/ruta/engine/ParamVarTest.java
+++ b/ruta-core/src/test/java/org/apache/uima/ruta/engine/ParamVarTest.java
@@ -22,6 +22,7 @@
 import java.util.HashMap;
 import java.util.Map;
 
+import org.apache.uima.analysis_engine.AnalysisEngineProcessException;
 import org.apache.uima.cas.CAS;
 import org.apache.uima.ruta.type.CW;
 import org.apache.uima.ruta.type.SW;
@@ -88,10 +89,35 @@
         SW.class.getName() + RutaEngine.SEPARATOR_VAR_VALUES + CW.class.getName() });
 
     CAS cas = RutaTestUtils.getCAS(document);
-      Ruta.apply(cas, script, params);
+    Ruta.apply(cas, script, params);
 
     RutaTestUtils.assertAnnotationsEquals(cas, 1, 2, "Some", "text");
     
     cas.release();
   }
+  
+  @Test(expected = AnalysisEngineProcessException.class)
+  public void testWithStrictImport() throws Exception {
+    String document = "Some text.";
+    String script = "";
+    script += "TYPE t1;";
+    script += "TYPE t2;";
+    script += "TYPELIST tl;";
+    script += "CW{ -> t1};";
+    script += "SW{ -> t2};";
+    script += "ANY{PARTOF(tl) -> T3};";
+    Map<String, Object> params = new HashMap<String, Object>();
+    params.put(RutaEngine.PARAM_STRICT_IMPORTS, true);
+    params.put(RutaEngine.PARAM_VAR_NAMES, new String[] { "t1", "t2", "tl" });
+    params.put(RutaEngine.PARAM_VAR_VALUES, new String[] {"org.apache.uima.T1", "org.apache.uima.T2", 
+        "org.apache.uima.T1,org.apache.uima.T2"  });
+
+    CAS cas = RutaTestUtils.getCAS(document);
+    Ruta.apply(cas, script, params);
+
+    RutaTestUtils.assertAnnotationsEquals(cas, 3, 2, "Some", "text");
+    
+    cas.release();
+  }
+  
 }
diff --git a/ruta-core/src/test/java/org/apache/uima/ruta/engine/RecursiveConfigureTest.java b/ruta-core/src/test/java/org/apache/uima/ruta/engine/RecursiveConfigureTest.java
new file mode 100644
index 0000000..719b5f7
--- /dev/null
+++ b/ruta-core/src/test/java/org/apache/uima/ruta/engine/RecursiveConfigureTest.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.uima.ruta.engine;

+

+import org.apache.uima.analysis_engine.AnalysisEngineDescription;

+import org.apache.uima.fit.factory.AnalysisEngineFactory;

+import org.junit.Ignore;

+import org.junit.Test;

+

+public class RecursiveConfigureTest {

+

+  @Test

+  @Ignore

+  public void test() throws Exception {

+

+    AnalysisEngineDescription aed = AnalysisEngineFactory.createEngineDescriptionFromPath(

+            "src/test/resources/org/apache/uima/ruta/engine/RecursiveConfigureEngine.xml");

+    AnalysisEngineFactory.createEngine(aed);

+  }

+}

diff --git a/ruta-core/src/test/java/org/apache/uima/ruta/engine/RutaEngineTest.java b/ruta-core/src/test/java/org/apache/uima/ruta/engine/RutaEngineTest.java
index da9c827..895f03f 100644
--- a/ruta-core/src/test/java/org/apache/uima/ruta/engine/RutaEngineTest.java
+++ b/ruta-core/src/test/java/org/apache/uima/ruta/engine/RutaEngineTest.java
@@ -73,7 +73,6 @@
     Collection<String> usedTypes = typeUsageInformation.getUsedTypes();
     List<String> usedTypesList = new ArrayList<>(usedTypes);
     Collections.sort(usedTypesList);
-    ;
     Assert.assertEquals(Arrays.asList("org.apache.uima.ruta.type.BREAK",
             "org.apache.uima.ruta.type.COMMA", "org.apache.uima.ruta.type.CW",
             "org.apache.uima.ruta.type.FalseNegative", "org.apache.uima.ruta.type.MARKUP",
diff --git a/ruta-core/src/test/java/org/apache/uima/ruta/engine/ThreeStackedScriptsVariableResetTest.java b/ruta-core/src/test/java/org/apache/uima/ruta/engine/ThreeStackedScriptsVariableResetTest.java
new file mode 100644
index 0000000..00b3a3a
--- /dev/null
+++ b/ruta-core/src/test/java/org/apache/uima/ruta/engine/ThreeStackedScriptsVariableResetTest.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.uima.ruta.engine;
+
+import java.io.File;
+import java.nio.file.Paths;
+
+import org.apache.commons.lang3.tuple.Pair;
+import org.apache.uima.UIMAFramework;
+import org.apache.uima.analysis_engine.AnalysisEngine;
+import org.apache.uima.analysis_engine.AnalysisEngineDescription;
+import org.apache.uima.cas.CAS;
+import org.apache.uima.cas.Feature;
+import org.apache.uima.cas.FeatureStructure;
+import org.apache.uima.cas.Type;
+import org.apache.uima.fit.factory.JCasFactory;
+import org.apache.uima.fit.util.CasUtil;
+import org.apache.uima.jcas.JCas;
+import org.apache.uima.resource.metadata.TypeSystemDescription;
+import org.apache.uima.ruta.descriptor.RutaBuildOptions;
+import org.apache.uima.ruta.descriptor.RutaDescriptorFactory;
+import org.apache.uima.ruta.descriptor.RutaDescriptorInformation;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class ThreeStackedScriptsVariableResetTest {
+
+  @Test
+  public void test() throws Exception {
+    String input1 = "snark";
+    String input2 = "cat";
+    String input3 = "bug";
+
+    String path = "src/test/resources/org/apache/uima/ruta/engine/";
+    RutaDescriptorFactory factory = new RutaDescriptorFactory();
+    RutaBuildOptions options = new RutaBuildOptions();
+    RutaDescriptorInformation rdi = factory
+            .parseDescriptorInformation(new File(path + "script1.ruta"), options);
+    Pair<AnalysisEngineDescription, TypeSystemDescription> descriptions = factory.createDescriptions(null, Paths.get(path).toFile().getAbsolutePath(), rdi, options, new String[] { path }, new String[] { path }, null);
+
+    AnalysisEngine ae = UIMAFramework.produceAnalysisEngine(descriptions.getKey());
+    JCas jcas = JCasFactory.createJCas(descriptions.getValue());
+    
+    jcas.setDocumentText(input1);
+    ae.process(jcas);
+    checkFeatureValue(jcas);
+    
+    jcas.reset();
+    jcas.setDocumentText(input2);
+    ae.process(jcas);
+    checkFeatureValue(jcas);
+    
+    jcas.reset();
+    jcas.setDocumentText(input3);
+    ae.process(jcas);
+    checkFeatureValue(jcas);
+    
+  }
+
+  private void checkFeatureValue(JCas jcas) {
+    CAS cas = jcas.getCas();
+    Type type = cas.getTypeSystem().getType("script3.Value");
+    Feature feature = type.getFeatureByBaseName("value");
+    FeatureStructure fs = CasUtil.selectSingle(cas, type);
+    String stringValue = fs.getStringValue(feature);
+    Assert.assertEquals("", stringValue);
+  }
+
+}
diff --git a/ruta-core/src/test/java/org/apache/uima/ruta/expression/annotation/AnnotationLabelExpressionTest.java b/ruta-core/src/test/java/org/apache/uima/ruta/expression/annotation/AnnotationLabelExpressionTest.java
index 261a3ad..ebcd12b 100644
--- a/ruta-core/src/test/java/org/apache/uima/ruta/expression/annotation/AnnotationLabelExpressionTest.java
+++ b/ruta-core/src/test/java/org/apache/uima/ruta/expression/annotation/AnnotationLabelExpressionTest.java
@@ -6,9 +6,9 @@
  * to you under the Apache License, Version 2.0 (the

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

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

- * 

+ *

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

- * 

+ *

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

  * software distributed under the License is distributed on an

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

@@ -19,9 +19,6 @@
 

 package org.apache.uima.ruta.expression.annotation;

 

-import static org.junit.Assert.assertEquals;

-import static org.junit.Assert.assertNotNull;

-

 import java.io.IOException;

 import java.util.ArrayList;

 import java.util.Collection;

@@ -56,6 +53,7 @@
 

   @Test

   public void testSimple() throws Exception {

+

     String document = "Some text.";

     String script = "a:W W{-> CREATE(Struct, \"a\"=a)};";

 

@@ -80,17 +78,18 @@
     Feature f1 = t.getFeatureByBaseName(fn);

     ai = cas.getAnnotationIndex(t);

 

-    assertEquals(1, ai.size());

+    Assert.assertEquals(1, ai.size());

     iterator = ai.iterator();

     AnnotationFS next = iterator.next();

-    assertEquals("text", next.getCoveredText());

+    Assert.assertEquals("text", next.getCoveredText());

     AnnotationFS a = (AnnotationFS) next.getFeatureValue(f1);

-    assertNotNull("Feature value is null!", a);

-    assertEquals("Some", a.getCoveredText());

+    Assert.assertNotNull("Feature value is null!", a);

+    Assert.assertEquals("Some", a.getCoveredText());

   }

 

   @Test

   public void testMultiple() throws Exception {

+

     String document = "Some text.";

     String script = "b:(a:W)+{-PARTOF(Struct) -> CREATE(Struct, \"a\"=a, \"b\"=b, \"c\"=a, \"d\"=b)};";

     script += "Struct.a{-> T1};";

@@ -121,6 +120,7 @@
 

   @Test

   public void testLayers() throws Exception {

+

     String document = "Some text.";

     String script = "d:(a:W b:W{-> CREATE(Struct, \"a\"=a, \"b\"=b, \"c\"=c, \"d\"=d)} c:PERIOD);";

 

@@ -145,7 +145,7 @@
 

     t = cas.getTypeSystem().getType(typeName);

     ai = cas.getAnnotationIndex(t);

-    assertEquals(1, ai.size());

+    Assert.assertEquals(1, ai.size());

     iterator = ai.iterator();

 

     AnnotationFS a = null;

@@ -153,38 +153,39 @@
     Feature f = null;

 

     next = iterator.next();

-    assertEquals("text", next.getCoveredText());

+    Assert.assertEquals("text", next.getCoveredText());

 

     f = t.getFeatureByBaseName("a");

     a = (AnnotationFS) next.getFeatureValue(f);

-    assertNotNull("Feature value is null!", a);

-    assertEquals("Some", a.getCoveredText());

+    Assert.assertNotNull("Feature value is null!", a);

+    Assert.assertEquals("Some", a.getCoveredText());

 

     f = t.getFeatureByBaseName("b");

     a = (AnnotationFS) next.getFeatureValue(f);

-    assertNotNull("Feature value is null!", a);

-    assertEquals("text", a.getCoveredText());

+    Assert.assertNotNull("Feature value is null!", a);

+    Assert.assertEquals("text", a.getCoveredText());

 

     f = t.getFeatureByBaseName("c");

     a = (AnnotationFS) next.getFeatureValue(f);

-    assertNotNull("Feature value is null!", a);

-    assertEquals(".", a.getCoveredText());

+    Assert.assertNotNull("Feature value is null!", a);

+    Assert.assertEquals(".", a.getCoveredText());

 

     f = t.getFeatureByBaseName("d");

     a = (AnnotationFS) next.getFeatureValue(f);

-    assertNotNull("Feature value is null!", a);

-    assertEquals("Some text.", a.getCoveredText());

+    Assert.assertNotNull("Feature value is null!", a);

+    Assert.assertEquals("Some text.", a.getCoveredText());

 

   }

 

   @Test

   public void testActions() throws Exception {

+

     String script = "a:W W{-> CREATE(Struct1, \"a\"=a)};";

     script += "W W{-> Struct2, Struct3};";

     script += "a:W Struct2{-> SETFEATURE(\"a\", a)};";

     script += "a:W Struct3{-> Struct3.a=a};";

 

-    CAS cas = applyOnStruct4Cas(script);

+    CAS cas = this.applyOnStruct4Cas(script);

 

     Type t = null;

     AnnotationIndex<AnnotationFS> ai = null;

@@ -195,42 +196,43 @@
 

     t = cas.getTypeSystem().getType("Struct1");

     ai = cas.getAnnotationIndex(t);

-    assertEquals(1, ai.size());

+    Assert.assertEquals(1, ai.size());

     iterator = ai.iterator();

     next = iterator.next();

-    assertEquals("text", next.getCoveredText());

+    Assert.assertEquals("text", next.getCoveredText());

     f = t.getFeatureByBaseName("a");

     a = (AnnotationFS) next.getFeatureValue(f);

-    assertNotNull("Feature value is null!", a);

-    assertEquals("Some", a.getCoveredText());

+    Assert.assertNotNull("Feature value is null!", a);

+    Assert.assertEquals("Some", a.getCoveredText());

 

     t = cas.getTypeSystem().getType("Struct2");

     ai = cas.getAnnotationIndex(t);

-    assertEquals(1, ai.size());

+    Assert.assertEquals(1, ai.size());

     iterator = ai.iterator();

     next = iterator.next();

-    assertEquals("text", next.getCoveredText());

+    Assert.assertEquals("text", next.getCoveredText());

     f = t.getFeatureByBaseName("a");

     a = (AnnotationFS) next.getFeatureValue(f);

-    assertNotNull("Feature value is null!", a);

-    assertEquals("Some", a.getCoveredText());

+    Assert.assertNotNull("Feature value is null!", a);

+    Assert.assertEquals("Some", a.getCoveredText());

 

     t = cas.getTypeSystem().getType("Struct3");

     ai = cas.getAnnotationIndex(t);

-    assertEquals(1, ai.size());

+    Assert.assertEquals(1, ai.size());

     iterator = ai.iterator();

     next = iterator.next();

-    assertEquals("text", next.getCoveredText());

+    Assert.assertEquals("text", next.getCoveredText());

     f = t.getFeatureByBaseName("a");

     a = (AnnotationFS) next.getFeatureValue(f);

-    assertNotNull("Feature value is null!", a);

-    assertEquals("Some", a.getCoveredText());

+    Assert.assertNotNull("Feature value is null!", a);

+    Assert.assertEquals("Some", a.getCoveredText());

 

   }

 

   @Test

   @Ignore

   public void testInsideOut() throws Exception {

+

     String document = "Some text.";

     String script = "(a:W{-PARTOF(Struct) -> CREATE(Struct, \"a\"=a, \"c\"=a)})+;";

     script += "Struct.a{-> T1};";

@@ -255,12 +257,13 @@
 

   @Test

   public void testWithinInlined() throws Exception {

+

     String script = "ANNOTATION c;";

     script += "Document{-> Struct1, Struct1.a = c}<-{i:SW{-> c=i} PERIOD;};";

     script += "i:Document{-> c=i}->{PERIOD{-> Struct2, Struct2.a = c};};";

     // script += "i:Document<-{PERIOD{-> Struct2, Struct2.a = i};};";

 

-    CAS cas = applyOnStruct4Cas(script);

+    CAS cas = this.applyOnStruct4Cas(script);

 

     Type t = null;

     AnnotationIndex<AnnotationFS> ai = null;

@@ -271,30 +274,31 @@
 

     t = cas.getTypeSystem().getType("Struct1");

     ai = cas.getAnnotationIndex(t);

-    assertEquals(1, ai.size());

+    Assert.assertEquals(1, ai.size());

     iterator = ai.iterator();

     next = iterator.next();

-    assertEquals("Some text.", next.getCoveredText());

+    Assert.assertEquals("Some text.", next.getCoveredText());

     f = t.getFeatureByBaseName("a");

     a = (AnnotationFS) next.getFeatureValue(f);

-    assertNotNull("Feature value is null!", a);

-    assertEquals("text", a.getCoveredText());

+    Assert.assertNotNull("Feature value is null!", a);

+    Assert.assertEquals("text", a.getCoveredText());

 

     t = cas.getTypeSystem().getType("Struct2");

     ai = cas.getAnnotationIndex(t);

-    assertEquals(1, ai.size());

+    Assert.assertEquals(1, ai.size());

     iterator = ai.iterator();

     next = iterator.next();

-    assertEquals(".", next.getCoveredText());

+    Assert.assertEquals(".", next.getCoveredText());

     f = t.getFeatureByBaseName("a");

     a = (AnnotationFS) next.getFeatureValue(f);

-    assertNotNull("Feature value is null!", a);

-    assertEquals("Some text.", a.getCoveredText());

+    Assert.assertNotNull("Feature value is null!", a);

+    Assert.assertEquals("Some text.", a.getCoveredText());

 

   }

 

   @Test

   public void testFeature() throws Exception {

+

     CAS cas = RutaTestUtils.getCAS("Some text.");

     Assert.assertTrue(Ruta.matches(cas.getJCas(), "a:W b:W{a.end == (b.begin-1)-> T1};"));

     RutaTestUtils.assertAnnotationsEquals(cas, 1, 1, "text");

@@ -302,8 +306,9 @@
 

   @Test

   public void testComplexFeature() throws Exception {

+

     String script = "a:W W{-> CREATE(Struct1, \"a\"=a)};";

-    CAS cas = applyOnStruct4Cas(script);

+    CAS cas = this.applyOnStruct4Cas(script);

     Assert.assertTrue(Ruta.matches(cas.getJCas(), "a:Struct1{a.a.begin == 0 -> T1};"));

     RutaTestUtils.assertAnnotationsEquals(cas, 1, 1, "text");

   }

@@ -311,6 +316,7 @@
   @Test(expected = AnalysisEngineProcessException.class)

   public void testWrongFeature() throws ResourceInitializationException, InvalidXMLException,

           IOException, AnalysisEngineProcessException, CASException {

+

     CAS cas = RutaTestUtils.getCAS("Some text.");

     Ruta.matches(cas.getJCas(), "a:W b:W{a.x == (b.y-1)-> T1};");

   }

@@ -318,12 +324,14 @@
   @Test

   public void testSequentialLabelSelfMatch() throws ResourceInitializationException,

           InvalidXMLException, IOException, AnalysisEngineProcessException, CASException {

+

     CAS cas = RutaTestUtils.getCAS("Some text.");

     Assert.assertFalse(Ruta.matches(cas.getJCas(), "e:CW e;"));

   }

 

   @Test

   public void testSpecialFeatureWithoutContextMatch() throws Exception {

+

     Map<String, String> types = new HashMap<>();

     String type = "Valued";

     types.put(type, "uima.tcas.Annotation");

@@ -342,6 +350,7 @@
 

   @Test

   public void testAcrossInlinedRules() throws Exception {

+

     String script = "(# PERIOD){->T1};\n";

     script += "T1{-> Struct1, Struct1.a = i}<-{i:SW;};\n";

     script += "o:T1<-{SW{->Struct2, Struct2.a = o};};\n";

@@ -349,7 +358,7 @@
     script += "Struct1{Struct1.a.ct==\"text\"->T3};\n";

     script += "Struct2.a{->T4};\n";

     script += "Struct2{Struct2.a.ct==\"Some text.\"->T5};\n";

-    CAS cas = applyOnStruct4Cas(script);

+    CAS cas = this.applyOnStruct4Cas(script);

     RutaTestUtils.assertAnnotationsEquals(cas, 2, 1, "text");

     RutaTestUtils.assertAnnotationsEquals(cas, 3, 1, "Some text.");

     RutaTestUtils.assertAnnotationsEquals(cas, 4, 1, "Some text.");

@@ -358,6 +367,7 @@
 

   @Test

   public void testSameOffset() throws Exception {

+

     String document = "Some text.";

     Map<String, String> typeMap = new TreeMap<String, String>();

     typeMap.put("Struct1", "uima.tcas.Annotation");

@@ -393,6 +403,7 @@
 

   @Test

   public void testFeatureAssignment() throws Exception {

+

     String document = "Some text.";

 

     String script = "CW{-> T1};\n";

@@ -406,7 +417,8 @@
 

   @Test

   public void testLabelWithQuantifier() throws Exception {

-    String script ="";

+

+    String script = "";

     script += "w:(W+) @PERIOD{->Struct1,Struct1.a=w,Struct1.as=w};\n";

     script += "(w:W)+ @PERIOD{->Struct2,Struct2.a=w,Struct2.as=w};\n";

     script += "w:W+ @PERIOD{->Struct3,Struct3.a=w,Struct3.as=w};\n";

@@ -457,7 +469,7 @@
     Assert.assertEquals(1, as.size());

     Assert.assertEquals("Some text", ((AnnotationFS) as.get(0)).getCoveredText());

     Assert.assertEquals("Annotation", as.get(0).getType().getShortName());

-    

+

     type = cas.getTypeSystem().getType("Struct2");

     featureA = type.getFeatureByBaseName("a");

     featureAS = type.getFeatureByBaseName("as");

@@ -480,7 +492,7 @@
     Assert.assertEquals("Some", ((AnnotationFS) as.get(1)).getCoveredText());

     Assert.assertEquals("SW", as.get(0).getType().getShortName());

     Assert.assertEquals("CW", as.get(1).getType().getShortName());

-    

+

     type = cas.getTypeSystem().getType("Struct3");

     featureA = type.getFeatureByBaseName("a");

     featureAS = type.getFeatureByBaseName("as");

@@ -507,79 +519,83 @@
 

   @Test

   public void testLabelReset() throws Exception {

-    String script= "";

+

+    String script = "";

     script += "W{->Struct1, Struct1.a = w} w:W?;";

     script += "W{->Struct2, Struct2.a = c} c:(W ANY)?;";

-    

-    CAS cas = applyOnStruct4Cas(script);

-    

+

+    CAS cas = this.applyOnStruct4Cas(script);

+

     Type type1 = cas.getTypeSystem().getType("Struct1");

     Feature feature1 = type1.getFeatureByBaseName("a");

-    

+

     List<AnnotationFS> select1 = new ArrayList<>(CasUtil.select(cas, type1));

     Assert.assertEquals(2, select1.size());

-    

+

     AnnotationFS a11 = select1.get(0);

     Assert.assertEquals("Some", a11.getCoveredText());

     AnnotationFS featureValue11 = (AnnotationFS) a11.getFeatureValue(feature1);

     Assert.assertEquals("text", featureValue11.getCoveredText());

-    

+

     AnnotationFS a21 = select1.get(1);

     Assert.assertEquals("text", a21.getCoveredText());

     AnnotationFS featureValue21 = (AnnotationFS) a21.getFeatureValue(feature1);

     Assert.assertNull(featureValue21);

-    

+

     Type type2 = cas.getTypeSystem().getType("Struct2");

     Feature feature2 = type2.getFeatureByBaseName("a");

-    

+

     List<AnnotationFS> select2 = new ArrayList<>(CasUtil.select(cas, type2));

     Assert.assertEquals(2, select2.size());

-    

-    AnnotationFS  a12 = select2.get(0);

+

+    AnnotationFS a12 = select2.get(0);

     Assert.assertEquals("Some", a12.getCoveredText());

     AnnotationFS featureValue12 = (AnnotationFS) a12.getFeatureValue(feature2);

     Assert.assertEquals("text.", featureValue12.getCoveredText());

-    

-    AnnotationFS  a22 = select2.get(1);

+

+    AnnotationFS a22 = select2.get(1);

     Assert.assertEquals("text", a22.getCoveredText());

     AnnotationFS featureValue22 = (AnnotationFS) a22.getFeatureValue(feature2);

     Assert.assertNull(featureValue22);

-    

-    

+

   }

-  

+

   @Test(expected = AnalysisEngineProcessException.class)

   public void testInvalidLabelWithQuantifier1() throws Exception {

-    String script= "";

+

+    String script = "";

     script += "w:ANY{->Struct1, Struct1.a = w};";

     script += "s1:Struct1{PARTOF(CW)->T1} s2:Struct1*{s2.a.ct == \"text\"};";

-    applyOnStruct4Cas(script);

+    this.applyOnStruct4Cas(script);

   }

-  

+

   @Test

   public void testInvalidLabelWithQuantifier2() throws Exception {

-    String script= "";

+

+    String script = "";

     script += "w:ANY{->Struct1, Struct1.a = w};";

     script += "PERIOD{s.a.ct==\"text\" ->T2} s:Struct1*{s.a.ct == \"text\"};";

-    CAS cas = applyOnStruct4Cas(script);

+    CAS cas = this.applyOnStruct4Cas(script);

     RutaTestUtils.assertAnnotationsEquals(cas, 2, 0);

   }

-  

+

   @Test

   public void testInvalidLabelWithOptional() throws Exception {

-    String script= "";

+

+    String script = "";

     script += "p:ANY{-> p.begin = a.begin, p.end = a.end} a:ANY;";

     script += "PERIOD{-> T1};";

-    CAS cas = applyOnStruct4Cas(script);

+    CAS cas = this.applyOnStruct4Cas(script);

     RutaTestUtils.assertAnnotationsEquals(cas, 1, 1, ".");

   }

-  

+

   @Test

   public void testInComposedStringExpression() throws Exception {

-    String script= "";

+

+    String script = "";

     script += "c:CW{-> Struct1, Struct1.s = \"<\"+c.ct+\">\" };";

     script += "Struct1.s ==\"<Some>\"{-> T1};";

-    

+

     String document = "Some text.";

     Map<String, String> typeMap = new TreeMap<String, String>();

     typeMap.put("Struct1", "uima.tcas.Annotation");

@@ -593,39 +609,86 @@
     Ruta.apply(cas, script);

     RutaTestUtils.assertAnnotationsEquals(cas, 1, 1, "Some");

   }

-  

+

   @Test

   public void testStackedInCondition() throws Exception {

-    String script= "";

+

+    String script = "";

     script += "w1:W{-> Struct1, Struct1.a = w2} w2:W;";

     script += "s:Struct1{REGEXP(s.a.ct, \"text\") -> T1};";

-    CAS cas = applyOnStruct4Cas(script);

+    CAS cas = this.applyOnStruct4Cas(script);

     RutaTestUtils.assertAnnotationsEquals(cas, 1, 1, "Some");

   }

-  

+

+  @Test

+  public void testStackedReinitLazyFeature() throws Exception {

+

+    String document = "Some text.";

+    Map<String, String> typeMap = new TreeMap<String, String>();

+    typeMap.put("Struct", "uima.tcas.Annotation");

+

+    Map<String, List<TestFeature>> featureMap = new TreeMap<String, List<TestFeature>>();

+    List<TestFeature> list = new ArrayList<RutaTestUtils.TestFeature>();

+    featureMap.put("Struct", list);

+    list.add(new TestFeature("a", "", "uima.tcas.Annotation"));

+    list.add(new TestFeature("s", "", "uima.cas.String"));

+    list.add(new TestFeature("b", "", "uima.cas.Boolean"));

+    list.add(new TestFeature("d", "", "uima.cas.Double"));

+

+    String script = "";

+    script += "SW{-> Struct};";

+    script += "CW{-> Struct, Struct.a=s2} s2:Struct;";

+    script += "s1:Struct{s1.begin==0 -> s1.a.a=CW};";

+    script += "s1:Struct{s1.begin==0 -> s1.a.s=\"s\"};";

+    script += "s1:Struct{s1.begin==0 -> s1.a.d=1.0};";

+    script += "s1:Struct{s1.begin==0 -> s1.a.b=true};";

+    script += "s1:Struct{s1.begin==0, s1.a.a.begin == 0 -> T1};";

+    script += "s1:Struct{s1.begin==0, s1.a.s == \"s\" -> T2};";

+    script += "s1:Struct{s1.begin==0, s1.a.d == 1.0 -> T3};";

+    script += "s1:Struct{s1.begin==0, s1.a.b -> T4};";

+

+    script += "s1:Struct s2:Struct PERIOD{-> CREATE(Struct, \"a\" = s1.a)};";

+    script += "s1:Struct{IS(PERIOD), s1.a.a.begin == 0 -> T5};";

+    script += "s1:Struct{IS(PERIOD), s1.a.s == \"s\" -> T6};";

+    script += "s1:Struct{IS(PERIOD), s1.a.d == 1.0 -> T7};";

+    script += "s1:Struct{IS(PERIOD), s1.a.b -> T8};";

+    CAS cas = RutaTestUtils.getCAS(document, typeMap, featureMap);

+    Ruta.apply(cas, script);

+    RutaTestUtils.assertAnnotationsEquals(cas, 1, 1, "Some");

+    RutaTestUtils.assertAnnotationsEquals(cas, 2, 1, "Some");

+    RutaTestUtils.assertAnnotationsEquals(cas, 3, 1, "Some");

+    RutaTestUtils.assertAnnotationsEquals(cas, 4, 1, "Some");

+    RutaTestUtils.assertAnnotationsEquals(cas, 5, 1, ".");

+    RutaTestUtils.assertAnnotationsEquals(cas, 6, 1, ".");

+    RutaTestUtils.assertAnnotationsEquals(cas, 7, 1, ".");

+    RutaTestUtils.assertAnnotationsEquals(cas, 8, 1, ".");

+  }

+

   @Test

   public void testInUnmark() throws Exception {

-    String script= "";

+

+    String script = "";

     script += "SW{-> T1};";

     script += "w1:W{-> Struct1, Struct1.a = w2} w2:T1;";

     script += "s:Struct1{-> UNMARK(s.a)};";

-    CAS cas = applyOnStruct4Cas(script);

+    CAS cas = this.applyOnStruct4Cas(script);

     RutaTestUtils.assertAnnotationsEquals(cas, 1, 0);

   }

-  

+

   @Test

   public void testInMatchCondition() throws Exception {

-    String script= "";

+

+    String script = "";

     script += "CW{-> Struct1, Struct1.a=sw} sw:SW;\n";

     script += "s:Struct1 s.a{-> T1};\n";

-//    script += "(s:Struct1 SW){->T2}<-{s W{REGEXP(\"text\")};};\n";

-    CAS cas = applyOnStruct4Cas(script);

+    // script += "(s:Struct1 SW){->T2}<-{s W{REGEXP(\"text\")};};\n";

+    CAS cas = this.applyOnStruct4Cas(script);

     RutaTestUtils.assertAnnotationsEquals(cas, 1, 1, "text");

-//    RutaTestUtils.assertAnnotationsEquals(cas, 2, 1, "Some text");

+    // RutaTestUtils.assertAnnotationsEquals(cas, 2, 1, "Some text");

   }

-  

-  

+

   private CAS applyOnStruct4Cas(String script) throws Exception {

+

     String document = "Some text.";

     Map<String, String> typeMap = new TreeMap<String, String>();

     typeMap.put("Struct1", "uima.tcas.Annotation");

diff --git a/ruta-core/src/test/java/org/apache/uima/ruta/expression/number/FloatVariableExpressionTest.java b/ruta-core/src/test/java/org/apache/uima/ruta/expression/number/FloatVariableExpressionTest.java
new file mode 100644
index 0000000..27df260
--- /dev/null
+++ b/ruta-core/src/test/java/org/apache/uima/ruta/expression/number/FloatVariableExpressionTest.java
@@ -0,0 +1,56 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.uima.ruta.expression.number;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.uima.cas.CAS;
+import org.apache.uima.ruta.engine.Ruta;
+import org.apache.uima.ruta.engine.RutaTestUtils;
+import org.apache.uima.ruta.engine.RutaTestUtils.TestFeature;
+import org.junit.Test;
+
+public class FloatVariableExpressionTest {
+
+  @Test
+  public void testAssignOnFloat() throws Exception {
+    String script = "FLOAT a2,a1;";
+    script += "(NUM{PARSE(a1)} \"%\") {-> CREATE (Percent, \"value\" = a1, \"class\" = \"Percent\", \"unit\" = \"%\")};";
+    script += "(NUM{PARSE(a2)} \"‰\") {-> ASSIGN(a2, a2/10), CREATE (Percent, \"value\" = a2, \"class\" = \"Percent\", \"unit\" = \"‰\")};";
+    script += "p:Percent{p.unit == \"%\", p.value==10 -> T1};";
+    script += "p:Percent{p.unit == \"‰\", p.value==1 -> T2};";
+    Map<String, String> complexTypes = new HashMap<>();
+    complexTypes.put("Percent", CAS.TYPE_NAME_ANNOTATION);
+    Map<String, List<TestFeature>> featureMap = new HashMap<>();
+    List<TestFeature> list = new ArrayList<>();
+    list.add(new TestFeature("class", "", CAS.TYPE_NAME_STRING));
+    list.add(new TestFeature("value", "", CAS.TYPE_NAME_FLOAT));
+    list.add(new TestFeature("unit", "", CAS.TYPE_NAME_STRING));
+    featureMap.put("Percent", list);
+    CAS cas = RutaTestUtils.getCAS("10 % , 10 ‰", complexTypes, featureMap);
+    Ruta.apply(cas, script);
+    
+    RutaTestUtils.assertAnnotationsEquals(cas, 1, 1, "10 %");
+    RutaTestUtils.assertAnnotationsEquals(cas, 2, 1, "10 ‰");
+  }
+
+}
diff --git a/ruta-core/src/test/java/org/apache/uima/ruta/rule/RegExpRuleTest.java b/ruta-core/src/test/java/org/apache/uima/ruta/rule/RegExpRuleTest.java
index 8555bf3..b2d78ad 100644
--- a/ruta-core/src/test/java/org/apache/uima/ruta/rule/RegExpRuleTest.java
+++ b/ruta-core/src/test/java/org/apache/uima/ruta/rule/RegExpRuleTest.java
@@ -32,6 +32,7 @@
 import org.apache.uima.cas.Type;

 import org.apache.uima.cas.text.AnnotationFS;

 import org.apache.uima.cas.text.AnnotationIndex;

+import org.apache.uima.ruta.engine.Ruta;

 import org.apache.uima.ruta.engine.RutaEngine;

 import org.apache.uima.ruta.engine.RutaTestUtils;

 import org.apache.uima.ruta.engine.RutaTestUtils.TestFeature;

@@ -40,10 +41,10 @@
 public class RegExpRuleTest {

 

   @Test

-  public void test() {

+  public void test() throws Exception {

     String name = this.getClass().getSimpleName();

     String namespace = this.getClass().getPackage().getName().replaceAll("\\.", "/");

-    CAS cas = null;

+

     Map<String, String> complexTypes = new HashMap<String, String>();

     Map<String, List<TestFeature>> features = new TreeMap<String, List<TestFeature>>();

     String typeName = "org.apache.uima.Complex";

@@ -56,14 +57,9 @@
     list.add(new TestFeature(fn2, "", "uima.cas.Boolean"));

     String fn3 = "s";

     list.add(new TestFeature(fn3, "", "uima.cas.String"));

-    

-    try {

-      cas = RutaTestUtils.process(namespace + "/" + name + RutaEngine.SCRIPT_FILE_EXTENSION, namespace + "/" + name

-              + ".txt", 50, false,false,complexTypes,features, null);

-    } catch (Exception e) {

-      e.printStackTrace();

-      assert (false);

-    }

+

+    CAS cas = RutaTestUtils.process(namespace + "/" + name + RutaEngine.SCRIPT_FILE_EXTENSION,

+            namespace + "/" + name + ".txt", 50, false, false, complexTypes, features, null);

     Type t = null;

     AnnotationIndex<AnnotationFS> ai = null;

     FSIterator<AnnotationFS> iterator = null;

@@ -73,7 +69,7 @@
     assertEquals(1, ai.size());

     iterator = ai.iterator();

     assertEquals(28, iterator.next().getCoveredText().length());

-   

+

     t = RutaTestUtils.getTestType(cas, 2);

     ai = cas.getAnnotationIndex(t);

     iterator = ai.iterator();

@@ -94,7 +90,7 @@
     String stringValue = null;

     Boolean booleanValue = null;

     AnnotationFS afs = null;

-    

+

     next = iterator.next();

     assertEquals("y", next.getCoveredText());

     stringValue = next.getStringValue(t.getFeatureByBaseName(fn3));

@@ -103,7 +99,7 @@
     assertEquals(true, booleanValue);

     afs = (AnnotationFS) next.getFeatureValue(t.getFeatureByBaseName(fn1));

     assertEquals("B", afs.getCoveredText());

-    

+

     next = iterator.next();

     assertEquals("B", next.getCoveredText());

     stringValue = next.getStringValue(t.getFeatureByBaseName(fn3));

@@ -112,7 +108,7 @@
     assertEquals(false, booleanValue);

     afs = (AnnotationFS) next.getFeatureValue(t.getFeatureByBaseName(fn1));

     assertEquals("y", afs.getCoveredText());

-    

+

     next = iterator.next();

     assertEquals("z", next.getCoveredText());

     stringValue = next.getStringValue(t.getFeatureByBaseName(fn3));

@@ -121,7 +117,7 @@
     assertEquals(true, booleanValue);

     afs = (AnnotationFS) next.getFeatureValue(t.getFeatureByBaseName(fn1));

     assertEquals("B", afs.getCoveredText());

-    

+

     next = iterator.next();

     assertEquals("B", next.getCoveredText());

     stringValue = next.getStringValue(t.getFeatureByBaseName(fn3));

@@ -130,7 +126,7 @@
     assertEquals(false, booleanValue);

     afs = (AnnotationFS) next.getFeatureValue(t.getFeatureByBaseName(fn1));

     assertEquals("z", afs.getCoveredText());

-    

+

     next = iterator.next();

     assertEquals("B", next.getCoveredText());

     stringValue = next.getStringValue(t.getFeatureByBaseName(fn3));

@@ -140,4 +136,15 @@
 

     cas.release();

   }

+

+  @Test

+  public void testSegments() throws Exception {

+    String document = "bla concepta bla";

+    String script = "\"(concept)([a-z])\"-> 1 = T1, 2 = T2;\n";

+    script += "T1{-PARTOF(T2)-> T2};";

+    CAS cas = RutaTestUtils.getCAS(document);

+    Ruta.apply(cas, script);

+    RutaTestUtils.assertAnnotationsEquals(cas, 2, 2, "concept", "a");

+  }

+

 }

diff --git a/ruta-core/src/test/java/org/apache/uima/ruta/rule/WildCard2Test.java b/ruta-core/src/test/java/org/apache/uima/ruta/rule/WildCard2Test.java
index fc2b88e..5fe7e8b 100644
--- a/ruta-core/src/test/java/org/apache/uima/ruta/rule/WildCard2Test.java
+++ b/ruta-core/src/test/java/org/apache/uima/ruta/rule/WildCard2Test.java
@@ -19,15 +19,22 @@
 

 package org.apache.uima.ruta.rule;

 

+import java.util.ArrayList;

+import java.util.HashMap;

+import java.util.List;

+import java.util.Map;

+

 import org.apache.uima.cas.CAS;

 import org.apache.uima.ruta.engine.Ruta;

 import org.apache.uima.ruta.engine.RutaTestUtils;

+import org.apache.uima.ruta.engine.RutaTestUtils.TestFeature;

+import org.junit.Assert;

 import org.junit.Test;

 

 public class WildCard2Test {

 

   @Test

-  public void test() {

+  public void test() throws Exception {

     String document = "Ogren, P.V., Wetzler, P.G., Bethard, S.: ClearTK: A UIMA Toolkit for Statistical Natural Language Processing. In: UIMA for NLP workshop at LREC 08. (2008)";

     document += "\n";

     document += "Stephen Soderland, Claire Cardie, and Raymond Mooney. Learning Information Extraction Rules for Semi-Structured and Free Text. In Machine Learning, volume 34, pages 233–272, 1999.";

@@ -42,13 +49,8 @@
     script += "(#{-CONTAINS(COLON)} PERIOD{-PARTOF(T7)}){-> T1} (# PERIOD){-> T2} # NUM{REGEXP(\"....\")-> T3};\n";

     script += "}\n";

 

-    CAS cas = null;

-    try {

-      cas = RutaTestUtils.getCAS(document);

-      Ruta.apply(cas, script);

-    } catch (Exception e) {

-      e.printStackTrace();

-    }

+    CAS cas = RutaTestUtils.getCAS(document);

+    Ruta.apply(cas, script);

 

     RutaTestUtils.assertAnnotationsEquals(cas, 1, 2, "Ogren, P.V., Wetzler, P.G., Bethard, S.:",

             "Stephen Soderland, Claire Cardie, and Raymond Mooney.");

@@ -61,17 +63,12 @@
   }

 

   @Test

-  public void testOptional() {

+  public void testOptional() throws Exception {

     String document = "Cw 1 2 3";

     String script = "(CW #){-> T1} SW?;";

 

-    CAS cas = null;

-    try {

-      cas = RutaTestUtils.getCAS(document);

-      Ruta.apply(cas, script);

-    } catch (Exception e) {

-      e.printStackTrace();

-    }

+    CAS cas = RutaTestUtils.getCAS(document);

+    Ruta.apply(cas, script);

 

     RutaTestUtils.assertAnnotationsEquals(cas, 1, 1, "Cw 1 2 3");

 

@@ -79,17 +76,12 @@
   }

 

   @Test

-  public void testLookaheadInGreedy() {

+  public void testLookaheadInGreedy() throws Exception {

     String document = "Some test. Some test. Some test.";

     String script = "((CW #){-> T1})+;";

     script += "((# PERIOD){-> T2})+;";

-    CAS cas = null;

-    try {

-      cas = RutaTestUtils.getCAS(document);

-      Ruta.apply(cas, script);

-    } catch (Exception e) {

-      e.printStackTrace();

-    }

+    CAS cas = RutaTestUtils.getCAS(document);

+    Ruta.apply(cas, script);

 

     // UIMA-4715: should be

     // RutaTestUtils.assertAnnotationsEquals(cas, 1, 3, "Some test.", "Some test.", "Some test.");

@@ -99,15 +91,15 @@
 

     cas.release();

   }

-  

+

   @Test

-  public void testMatchAtDocumentBegin() throws Exception{

+  public void testMatchAtDocumentBegin() throws Exception {

     String document = "First test. Some test. Last test.";

     String script = "# CW{-> T1};";

     script += "CW{-> T2};";

     script += "T1 # (T2 #){->T3};";

     script += "T3->{# CW{->T4};};";

-    CAS cas =  RutaTestUtils.getCAS(document);

+    CAS cas = RutaTestUtils.getCAS(document);

     Ruta.apply(cas, script);

     RutaTestUtils.assertAnnotationsEquals(cas, 1, 1, "First");

     RutaTestUtils.assertAnnotationsEquals(cas, 2, 3, "First", "Some", "Last");

@@ -116,4 +108,67 @@
     cas.release();

   }

 

+  @Test

+  public void testInReverseForEachWithAnalysisEngineAndFiltering() throws Exception {

+    String document = "a b (A) a . c (1 C) a . d (a C) .";

+    String script = "UIMAFIT org.apache.uima.ruta.engine.UimaFitAnalysisEngineWithManditoryParameter (type, "

+            + RutaTestUtils.TYPE + "10);";

+    script += "EXEC(UimaFitAnalysisEngineWithManditoryParameter);";

+    script += "ADDFILTERTYPE(PERIOD);";

+    script += "FOREACH(cw,false) CW {}{\n";

+    script += "(SPECIAL==\"(\" # cw SPECIAL.ct==\"]\"){->T1};";

+    script += "(SPECIAL==\"(\" # cw SPECIAL.ct==\")\"){->T2};";

+    script += "}";

+

+    CAS cas = RutaTestUtils.getCAS(document);

+    Ruta.apply(cas, script);

+

+    RutaTestUtils.assertAnnotationsEquals(cas, 1, 0);

+    RutaTestUtils.assertAnnotationsEquals(cas, 2, 3, "(A)", "(1 C)", "(a C)");

+    cas.release();

+  }

+

+  @Test

+  public void testMultipleAndQuantifier() throws Exception {

+    String document = "1 A ...... 1 X 2 B ...... 2";

+    String script = "";

+    script += "PM{->T1};\n";

+    // optional elements are not optional after wildcard UIMA-5484

+    script += "NUM #{-> T2} T1* NUM;\n";

+    script += "PM{->T1};\n";

+    script += "NUM #{-> T3} T1* NUM;\n";

+

+    CAS cas = RutaTestUtils.getCAS(document);

+    Ruta.apply(cas, script);

+

+    RutaTestUtils.assertAnnotationsEquals(cas, 2, 3, "A", "X 2 B", "B");

+    Assert.assertEquals(1008,

+            cas.getAnnotationIndex(cas.getTypeSystem().getType(RutaTestUtils.TYPE + "3")).size());

+    cas.release();

+  }

+

+  @Test

+  public void testCheckInIterator() throws Exception {

+    String document = "1 a b c 2 d e f 3";

+    String script = "";

+    script += "NUM #{-> T1} NUM;\n";

+    script += "SW{-> Struct};\n";

+    script += "T1->{# s2:Struct.a==null{-> s2.a=SW};};\n";

+    script += "T1->{s1:Struct.a!=null # s2:@Struct.a==null{-> s2.a=s1.a};};\n";

+    script += "s:Struct{REGEXP(s.a.ct, \"[ad]\") -> T2};\n";

+

+    Map<String, String> complexType = new HashMap<>();

+    complexType.put("Struct", CAS.TYPE_NAME_ANNOTATION);

+    Map<String, List<TestFeature>> featureMap = new HashMap<>();

+    List<TestFeature> list = new ArrayList<>();

+    list.add(new TestFeature("a", "", CAS.TYPE_NAME_ANNOTATION));

+    featureMap.put("Struct", list);

+    CAS cas = RutaTestUtils.getCAS(document, complexType, featureMap);

+    Ruta.apply(cas, script);

+

+    RutaTestUtils.assertAnnotationsEquals(cas, 1, 2, "a b c", "d e f");

+    RutaTestUtils.assertAnnotationsEquals(cas, 2, 6, "a", "b", "c", "d", "e", "f");

+    cas.release();

+  }

+

 }

diff --git a/ruta-core/src/test/java/org/apache/uima/ruta/rule/quantifier/MinMaxQuantifierTest.java b/ruta-core/src/test/java/org/apache/uima/ruta/rule/quantifier/MinMaxQuantifierTest.java
new file mode 100644
index 0000000..425ee0e
--- /dev/null
+++ b/ruta-core/src/test/java/org/apache/uima/ruta/rule/quantifier/MinMaxQuantifierTest.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.uima.ruta.rule.quantifier;
+
+import org.apache.uima.cas.CAS;
+import org.apache.uima.ruta.engine.Ruta;
+import org.apache.uima.ruta.engine.RutaTestUtils;
+import org.junit.Test;
+
+public class MinMaxQuantifierTest {
+
+  @Test
+  public void test() throws Exception {
+    String document = "A, A. B, B, B";
+    String script = "";
+    script += "(CW{-PARTOF(TruePositive)} (COMMA CW)[2,5]){-> TruePositive};\n";
+    script += "TruePositive{-> T1};\n";
+
+    CAS cas = RutaTestUtils.getCAS(document);
+    Ruta.apply(cas, script);
+
+    RutaTestUtils.assertAnnotationsEquals(cas, 1, 1, "B, B, B");
+    cas.release();
+  }
+}
diff --git a/ruta-core/src/test/java/org/apache/uima/ruta/verbalizer/RutaVerbalizerTest.java b/ruta-core/src/test/java/org/apache/uima/ruta/verbalizer/RutaVerbalizerTest.java
new file mode 100644
index 0000000..69b3b07
--- /dev/null
+++ b/ruta-core/src/test/java/org/apache/uima/ruta/verbalizer/RutaVerbalizerTest.java
@@ -0,0 +1,56 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.uima.ruta.verbalizer;
+
+import java.util.List;
+
+import org.apache.commons.lang3.reflect.FieldUtils;
+import org.apache.uima.analysis_engine.AnalysisEngine;
+import org.apache.uima.fit.factory.AnalysisEngineFactory;
+import org.apache.uima.ruta.RutaModule;
+import org.apache.uima.ruta.RutaStatement;
+import org.apache.uima.ruta.block.ForEachBlock;
+import org.apache.uima.ruta.block.RutaScriptBlock;
+import org.apache.uima.ruta.engine.RutaEngine;
+import org.apache.uima.ruta.verbalize.RutaVerbalizer;
+import org.junit.Assert;
+import org.junit.Test;
+
+
+public class RutaVerbalizerTest {
+  
+  @Test
+  public void testSimpleScriptVerbalization() throws Exception{
+    
+    AnalysisEngine analysisEngine = AnalysisEngineFactory.createEngine(RutaEngine.class, RutaEngine.PARAM_MAIN_SCRIPT, "org.apache.uima.ruta.Verbalize");
+    RutaEngine rutaEngine = (RutaEngine) FieldUtils.readField(analysisEngine, "mAnalysisComponent", true);
+    RutaModule module = (RutaModule) FieldUtils.readField(rutaEngine, "script", true);
+    RutaVerbalizer verbalizer = new RutaVerbalizer();
+    Assert.assertNull(verbalizer.verbalize(module));
+    Assert.assertEquals("BLOCK(Verbalize) Document;", verbalizer.verbalize(module.getRootBlock()));
+    List<RutaStatement> elements = module.getRootBlock().getElements();
+    Assert.assertEquals("Document{->CALL(Additional)};", verbalizer.verbalize(elements.get(1)));
+    Assert.assertEquals("CW.ct==\"A\"{->TruePositive};", verbalizer.verbalize(elements.get(2)));
+    RutaScriptBlock block = (RutaScriptBlock) elements.get(3);
+    Assert.assertEquals("BLOCK(block) CW;", verbalizer.verbalize(block));
+    ForEachBlock foreach = (ForEachBlock) elements.get(4);
+    Assert.assertEquals("FOREACH(sw) SW;", verbalizer.verbalize(foreach));
+  }
+}
diff --git a/ruta-core/src/test/java/org/apache/uima/ruta/verbalizer/ScriptVerbalizerTest.java b/ruta-core/src/test/java/org/apache/uima/ruta/verbalizer/ScriptVerbalizerTest.java
index 9c1c79a..50f12c7 100644
--- a/ruta-core/src/test/java/org/apache/uima/ruta/verbalizer/ScriptVerbalizerTest.java
+++ b/ruta-core/src/test/java/org/apache/uima/ruta/verbalizer/ScriptVerbalizerTest.java
@@ -40,13 +40,14 @@
   public void testRuleVerbalization() throws Exception{
     JCas jcas = RutaTestUtils.getCAS("Some text.").getJCas();
     
-//    assertRuleVerbalization(jcas, "W{->T1} W{->T2};");
-//    assertRuleVerbalization(jcas, "MARK(T1);", "Document{->MARK(T1)};");
-//    assertRuleVerbalization(jcas, "T1<-{W PERIOD;};");
-//    assertRuleVerbalization(jcas, "T1->{W{->T1} PERIOD;};");
-//    assertRuleVerbalization(jcas, "T1<-{W PERIOD;}->{W{->T1} PERIOD;};");
-//    assertRuleVerbalization(jcas, "W W? W?? W+ W+? W* W*? W[1,2] W[1,2]? #;");
+    assertRuleVerbalization(jcas, "Document{->MARK(T1)};");
+    assertRuleVerbalization(jcas, "W{->T1} W{->T2};");
+    assertRuleVerbalization(jcas, "T1<-{W PERIOD;};");
+    assertRuleVerbalization(jcas, "T1->{W{->T1} PERIOD;};");
+    assertRuleVerbalization(jcas, "T1<-{W PERIOD;}->{W{->T1} PERIOD;};");
+    assertRuleVerbalization(jcas, "W W? W?? W+ W+? W* W*? W[1,2] W[1,2]? #;");
     assertRuleVerbalization(jcas, "Document{CONTAINS(T1)->T2};");
+    assertRuleVerbalization(jcas, "Document{->ADDFILTERTYPE(CW)};");
     
     jcas.release();
   }
@@ -65,4 +66,6 @@
     Assert.assertEquals(expected, ruleApply.getElement());
     Ruta.removeDebugInformation(jcas);
   }
+  
+  
 }
diff --git a/ruta-core/src/test/resources/org/apache/uima/ruta/Verbalize.ruta b/ruta-core/src/test/resources/org/apache/uima/ruta/Verbalize.ruta
new file mode 100644
index 0000000..3c010ee
--- /dev/null
+++ b/ruta-core/src/test/resources/org/apache/uima/ruta/Verbalize.ruta
@@ -0,0 +1,12 @@
+PACKAGE org.apache.uima.ruta;

+SCRIPT org.apache.uima.ruta.Additional;

+CALL(Additional);

+CW.ct=="A"{-> TruePositive};

+

+BLOCK(block) CW{}{

+    SW;

+}

+

+FOREACH(sw) SW{}{

+    sw.ct=="a";

+}

diff --git a/ruta-core/src/test/resources/org/apache/uima/ruta/engine/RecursiveConfigure.ruta b/ruta-core/src/test/resources/org/apache/uima/ruta/engine/RecursiveConfigure.ruta
new file mode 100644
index 0000000..44df1bc
--- /dev/null
+++ b/ruta-core/src/test/resources/org/apache/uima/ruta/engine/RecursiveConfigure.ruta
@@ -0,0 +1,3 @@
+ENGINE org.apache.uima.ruta.engine.RecursiveConfigureEngine;

+CONFIGURE(RecursiveConfigureEngine, "statistics" = true);

+EXEC(RecursiveConfigureEngine);
\ No newline at end of file
diff --git a/ruta-core/src/test/resources/org/apache/uima/ruta/engine/RecursiveConfigureEngine.xml b/ruta-core/src/test/resources/org/apache/uima/ruta/engine/RecursiveConfigureEngine.xml
new file mode 100644
index 0000000..d77f483
--- /dev/null
+++ b/ruta-core/src/test/resources/org/apache/uima/ruta/engine/RecursiveConfigureEngine.xml
@@ -0,0 +1,318 @@
+<?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.

+-->

+

+<analysisEngineDescription xmlns="http://uima.apache.org/resourceSpecifier">

+    <frameworkImplementation>org.apache.uima.java</frameworkImplementation>

+    <primitive>true</primitive>

+    <annotatorImplementationName>org.apache.uima.ruta.engine.RutaEngine</annotatorImplementationName>

+    <analysisEngineMetaData>

+        <name>BasicEngine</name>

+        <description/>

+        <version>1.0</version>

+        <vendor/>

+        <configurationParameters searchStrategy="language_fallback">

+            <configurationParameter>

+                <name>seeders</name>

+                <type>String</type>

+                <multiValued>true</multiValued>

+                <mandatory>false</mandatory>

+            </configurationParameter>

+            <configurationParameter>

+                <name>debug</name>

+                <type>Boolean</type>

+                <multiValued>false</multiValued>

+                <mandatory>false</mandatory>

+            </configurationParameter>

+            <configurationParameter>

+                <name>additionalScripts</name>

+                <type>String</type>

+                <multiValued>true</multiValued>

+                <mandatory>false</mandatory>

+            </configurationParameter>

+            <configurationParameter>

+                <name>profile</name>

+                <type>Boolean</type>

+                <multiValued>false</multiValued>

+                <mandatory>false</mandatory>

+            </configurationParameter>

+            <configurationParameter>

+                <name>debugWithMatches</name>

+                <type>Boolean</type>

+                <multiValued>false</multiValued>

+                <mandatory>false</mandatory>

+            </configurationParameter>

+            <configurationParameter>

+                <name>statistics</name>

+                <type>Boolean</type>

+                <multiValued>false</multiValued>

+                <mandatory>false</mandatory>

+            </configurationParameter>

+            <configurationParameter>

+                <name>additionalEngines</name>

+                <type>String</type>

+                <multiValued>true</multiValued>

+                <mandatory>false</mandatory>

+            </configurationParameter>

+            <configurationParameter>

+                <name>additionalExtensions</name>

+                <type>String</type>

+                <multiValued>true</multiValued>

+                <mandatory>false</mandatory>

+            </configurationParameter>

+            <configurationParameter>

+                <name>debugOnlyFor</name>

+                <type>String</type>

+                <multiValued>true</multiValued>

+                <mandatory>false</mandatory>

+            </configurationParameter>

+            <configurationParameter>

+                <name>scriptEncoding</name>

+                <type>String</type>

+                <multiValued>false</multiValued>

+                <mandatory>false</mandatory>

+            </configurationParameter>

+            <configurationParameter>

+                <name>additionalEngineLoaders</name>

+                <type>String</type>

+                <multiValued>true</multiValued>

+                <mandatory>false</mandatory>

+            </configurationParameter>

+            <configurationParameter>

+                <name>resourcePaths</name>

+                <type>String</type>

+                <multiValued>true</multiValued>

+                <mandatory>false</mandatory>

+            </configurationParameter>

+            <configurationParameter>

+                <name>defaultFilteredTypes</name>

+                <type>String</type>

+                <multiValued>true</multiValued>

+                <mandatory>false</mandatory>

+            </configurationParameter>

+            <configurationParameter>

+                <name>mainScript</name>

+                <type>String</type>

+                <multiValued>false</multiValued>

+                <mandatory>false</mandatory>

+            </configurationParameter>

+            <configurationParameter>

+                <name>scriptPaths</name>

+                <type>String</type>

+                <multiValued>true</multiValued>

+                <mandatory>false</mandatory>

+            </configurationParameter>

+            <configurationParameter>

+                <name>descriptorPaths</name>

+                <type>String</type>

+                <multiValued>true</multiValued>

+                <mandatory>false</mandatory>

+            </configurationParameter>

+            <configurationParameter>

+                <name>removeBasics</name>

+                <type>Boolean</type>

+                <multiValued>false</multiValued>

+                <mandatory>false</mandatory>

+            </configurationParameter>

+            <configurationParameter>

+                <name>dynamicAnchoring</name>

+                <description>Activates dynamic anchoring (possible speed up).</description>

+                <type>Boolean</type>

+                <multiValued>false</multiValued>

+                <mandatory>false</mandatory>

+            </configurationParameter>

+            <configurationParameter>

+                <name>greedyRuleElement</name>

+                <description>Activates greedy anchoring for rule elements.</description>

+                <type>Boolean</type>

+                <multiValued>false</multiValued>

+                <mandatory>false</mandatory>

+            </configurationParameter>

+            <configurationParameter>

+                <name>greedyRule</name>

+                <description>Activates greedy anchoring for complete rules.</description>

+                <type>Boolean</type>

+                <multiValued>false</multiValued>

+                <mandatory>false</mandatory>

+            </configurationParameter>

+            <configurationParameter>

+                <name>lowMemoryProfile</name>

+                <type>Boolean</type>

+                <multiValued>false</multiValued>

+                <mandatory>false</mandatory>

+            </configurationParameter>

+            <configurationParameter>

+                <name>createdBy</name>

+                <type>Boolean</type>

+                <multiValued>false</multiValued>

+                <mandatory>false</mandatory>

+            </configurationParameter>

+            <configurationParameter>

+                <name>simpleGreedyForComposed</name>

+                <type>Boolean</type>

+                <multiValued>false</multiValued>

+                <mandatory>false</mandatory>

+            </configurationParameter>

+            <configurationParameter>

+                <name>additionalUimafitEngines</name>

+                <type>String</type>

+                <multiValued>true</multiValued>

+                <mandatory>false</mandatory>

+            </configurationParameter>

+            <configurationParameter>

+                <name>strictImports</name>

+                <type>Boolean</type>

+                <multiValued>false</multiValued>

+                <mandatory>false</mandatory>

+            </configurationParameter>

+        </configurationParameters>

+        <configurationParameterSettings>

+            <nameValuePair>

+                <name>debug</name>

+                <value>

+                    <boolean>false</boolean>

+                </value>

+            </nameValuePair>

+            <nameValuePair>

+                <name>profile</name>

+                <value>

+                    <boolean>false</boolean>

+                </value>

+            </nameValuePair>

+            <nameValuePair>

+                <name>debugWithMatches</name>

+                <value>

+                    <boolean>true</boolean>

+                </value>

+            </nameValuePair>

+            <nameValuePair>

+                <name>defaultFilteredTypes</name>

+                <value>

+                    <array>

+                        <string>org.apache.uima.ruta.type.SPACE</string>

+                        <string>org.apache.uima.ruta.type.BREAK</string>

+                        <string>org.apache.uima.ruta.type.MARKUP</string>

+                    </array>

+                </value>

+            </nameValuePair>

+            <nameValuePair>

+                <name>removeBasics</name>

+                <value>

+                    <boolean>false</boolean>

+                </value>

+            </nameValuePair>

+            <nameValuePair>

+                <name>seeders</name>

+                <value>

+                    <array>

+                        <string>org.apache.uima.ruta.seed.DefaultSeeder</string>

+                    </array>

+                </value>

+            </nameValuePair>

+            <nameValuePair>

+                <name>createdBy</name>

+                <value>

+                    <boolean>false</boolean>

+                </value>

+            </nameValuePair>

+            <nameValuePair>

+                <name>mainScript</name>

+                <value>

+                    <string>org.apache.uima.ruta.engine.RecursiveConfigure</string>

+                </value>

+            </nameValuePair>

+            <nameValuePair>

+                <name>scriptPaths</name>

+                <value>

+                    <array>

+                        <string></string>

+                    </array>

+                </value>

+            </nameValuePair>

+            <nameValuePair>

+                <name>descriptorPaths</name>

+                <value>

+                    <array>

+                        <string></string>

+                    </array>

+                </value>

+            </nameValuePair>

+            <nameValuePair>

+                <name>resourcePaths</name>

+                <value>

+                    <array>

+                        <string></string>

+                    </array>

+                </value>

+            </nameValuePair>

+            <nameValuePair>

+                <name>additionalScripts</name>

+                <value>

+                    <array/>

+                </value>

+            </nameValuePair>

+            <nameValuePair>

+                <name>additionalEngines</name>

+                <value>

+                    <array/>

+                </value>

+            </nameValuePair>

+            <nameValuePair>

+                <name>additionalUimafitEngines</name>

+                <value>

+                    <array/>

+                </value>

+            </nameValuePair>

+            <nameValuePair>

+                <name>additionalEngineLoaders</name>

+                <value>

+                    <array/>

+                </value>

+            </nameValuePair>

+        </configurationParameterSettings>

+        <typeSystemDescription>

+            <name>CWTypeSystem</name>

+            <imports>

+                <import name="org.apache.uima.ruta.engine.BasicTypeSystem"/>

+            </imports>

+        </typeSystemDescription>

+        <typePriorities>

+            <priorityList>

+                <type>org.apache.uima.ruta.type.RutaFrame</type>

+                <type>uima.tcas.Annotation</type>

+                <type>org.apache.uima.ruta.type.RutaBasic</type>

+            </priorityList>

+        </typePriorities>

+        <fsIndexCollection/>

+        <capabilities>

+            <capability>

+                <inputs/>

+                <outputs/>

+                <languagesSupported/>

+            </capability>

+        </capabilities>

+        <operationalProperties>

+            <modifiesCas>true</modifiesCas>

+            <multipleDeploymentAllowed>true</multipleDeploymentAllowed>

+            <outputsNewCASes>true</outputsNewCASes>

+        </operationalProperties>

+    </analysisEngineMetaData>

+    <resourceManagerConfiguration/>

+</analysisEngineDescription>

diff --git a/ruta-core/src/test/resources/org/apache/uima/ruta/engine/script1.ruta b/ruta-core/src/test/resources/org/apache/uima/ruta/engine/script1.ruta
new file mode 100644
index 0000000..6f3e28a
--- /dev/null
+++ b/ruta-core/src/test/resources/org/apache/uima/ruta/engine/script1.ruta
@@ -0,0 +1,3 @@
+SCRIPT script2;

+

+Document{->CALL(script2)};

diff --git a/ruta-core/src/test/resources/org/apache/uima/ruta/engine/script1TypeSystem.xml b/ruta-core/src/test/resources/org/apache/uima/ruta/engine/script1TypeSystem.xml
new file mode 100644
index 0000000..b8ee2d2
--- /dev/null
+++ b/ruta-core/src/test/resources/org/apache/uima/ruta/engine/script1TypeSystem.xml
@@ -0,0 +1,30 @@
+<?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.
+-->
+
+<typeSystemDescription xmlns="http://uima.apache.org/resourceSpecifier">
+    <name>script1TypeSystem</name>
+    <imports>
+        <import name="org.apache.uima.ruta.engine.BasicTypeSystem"/>
+        <import location="script2TypeSystem.xml"/>
+    </imports>
+    <types>
+    </types>
+</typeSystemDescription>
diff --git a/ruta-core/src/test/resources/org/apache/uima/ruta/engine/script2.ruta b/ruta-core/src/test/resources/org/apache/uima/ruta/engine/script2.ruta
new file mode 100644
index 0000000..c46c705
--- /dev/null
+++ b/ruta-core/src/test/resources/org/apache/uima/ruta/engine/script2.ruta
@@ -0,0 +1,3 @@
+SCRIPT script3;

+

+Document{->CALL(script3)};

diff --git a/ruta-core/src/test/resources/org/apache/uima/ruta/engine/script2TypeSystem.xml b/ruta-core/src/test/resources/org/apache/uima/ruta/engine/script2TypeSystem.xml
new file mode 100644
index 0000000..7a171c8
--- /dev/null
+++ b/ruta-core/src/test/resources/org/apache/uima/ruta/engine/script2TypeSystem.xml
@@ -0,0 +1,30 @@
+<?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.
+-->
+
+<typeSystemDescription xmlns="http://uima.apache.org/resourceSpecifier">
+    <name>script2TypeSystem</name>
+    <imports>
+        <import name="org.apache.uima.ruta.engine.BasicTypeSystem"/>
+        <import location="script3TypeSystem.xml"/>
+    </imports>
+    <types>
+    </types>
+</typeSystemDescription>
diff --git a/ruta-core/src/test/resources/org/apache/uima/ruta/engine/script3.ruta b/ruta-core/src/test/resources/org/apache/uima/ruta/engine/script3.ruta
new file mode 100644
index 0000000..e6372e1
--- /dev/null
+++ b/ruta-core/src/test/resources/org/apache/uima/ruta/engine/script3.ruta
@@ -0,0 +1,5 @@
+DECLARE Value(STRING value);

+

+STRING value; // or = "dog";

+

+W{-> CREATE(Value, "value" = value), ASSIGN(value, W.ct)};

diff --git a/ruta-core/src/test/resources/org/apache/uima/ruta/engine/script3TypeSystem.xml b/ruta-core/src/test/resources/org/apache/uima/ruta/engine/script3TypeSystem.xml
new file mode 100644
index 0000000..44efd8d
--- /dev/null
+++ b/ruta-core/src/test/resources/org/apache/uima/ruta/engine/script3TypeSystem.xml
@@ -0,0 +1,41 @@
+<?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.
+-->
+
+<typeSystemDescription xmlns="http://uima.apache.org/resourceSpecifier">
+    <name>script2TypeSystem</name>
+    <imports>
+        <import name="org.apache.uima.ruta.engine.BasicTypeSystem"/>
+    </imports>
+    <types>
+       <typeDescription>
+            <name>script3.Value</name>
+            <description/>
+            <supertypeName>uima.tcas.Annotation</supertypeName>
+            <features>
+              <featureDescription>
+                <name>value</name>
+                <description/>
+                <rangeTypeName>uima.cas.String</rangeTypeName>
+              </featureDescription>
+            </features>
+        </typeDescription>
+    </types>
+</typeSystemDescription>
diff --git a/ruta-docbook/src/docbook/tools.ruta.language.xml b/ruta-docbook/src/docbook/tools.ruta.language.xml
index 63df653..60aff38 100644
--- a/ruta-docbook/src/docbook/tools.ruta.language.xml
+++ b/ruta-docbook/src/docbook/tools.ruta.language.xml
@@ -135,8 +135,64 @@
     </para>

 

   </section>

+

+  <section id="ugr.tools.ruta.language.wildcard">

+    <title>Wildcard #</title>

+    <para>

+      The wildcard <code>#</code> is a special matching condition of a rule element, 

+      which does not match itself but uses the next rule element to determine its match.

+      It's behavior is similar to a generic rule element with a reluctant, not restricted quantifier like

+      <code>ANY+?</code> but it much more efficient since no additional annotations have to be matched.

+      The functionality of the wildcard is illustrated with following examples:

+      

+      <programlisting><![CDATA[PERIOD #{-> Sentence} PERIOD;]]></programlisting>

+      

+      In this example, everything in beteen two periods is annotated with an annotation of the type

+      <code>Sentence</code>. This rule is much more efficient than a rule like 

+      <code>PERIOD ANY+{-PARTOF(PERIOD)} PERIOD;</code> since it only navigated in the index of PERIOD annotations 

+      and does not match on all tokens.

+      

+      The wildcard is a normal matching condition and can be used as any other matching condition. If the sentence 

+      should include the period, the rule would look like:

+      

+      <programlisting><![CDATA[PERIOD (# PERIOD){-> Sentence};]]></programlisting>

+      

+      This rule creates only annotations after a period. If the wildcard is used as an anchor of the rule, 

+      e.g., is the first rule element and no manual anchor is specified, then it starts to match at the beginning 

+      of the doucment or current window.

+      

+      <programlisting><![CDATA[(# PERIOD){-> Sentence};]]></programlisting>

+      

+      This rule creates a Sentence annotation starting at the begin of the document ending with the first period.

+      If the rule lements are swicthed, the result is quite different because of the starting anchor of the rule:

+      

+      <programlisting><![CDATA[(PERIOD #){-> Sentence};]]></programlisting>

+      

+      Here, one annotation of the type Sentence is create for each PERIOD annotation starting with the period and 

+      ending at the end of the document.

+      

+      Currently, optional rule elements after wildcards are not optional.

+    </para>

+  </section>

   

-  

+  <section id="ugr.tools.ruta.language.labels">

+    <title>Label expressions</title>

+    <para>

+      Rule elements can be extended with labels, which introduce a new local variable storing one or 

+      multiple annotations - the annotations matched by the matching condition of the rule element. 

+      The name of the variable is the short identifier before the colon in front of the matching condition, e.g., 

+      in <code>sw:SW</code>, <code>SW</code> is the matching condition and <code>sw</code> is the name of the local variable.

+      The variable will be assigned when the rule element tries to match (also when it fails afterall) 

+      and can be utilzed in all other language elements afterwards.

+      The functionality of the label expressions is illustrated with following examples:

+      

+      <programlisting><![CDATA[sw1:SW sw2:SW{sw1.end=sw2.begin};]]></programlisting>

+      

+      This rule matches on two consecutive small-written words, but matches only if there is no space inbetween them.

+      

+      Label expression can also be used across <xref linkend='ugr.tools.ruta.language.inlined' />.

+    </para>

+  </section>

   

   <section id="ugr.tools.ruta.language.blocks">

     <title>Blocks</title>

@@ -1104,12 +1160,7 @@
       <section>

         <title>contains(IStringExpression expr,IStringExpression contains)

         </title>

-        <programlisting><![CDATA[STRING s;

-BOOLEAN a ;

-BLOCK(forEACH) W{}{

-    W{->MATCHEDTEXT(s), ASSIGN(a,contains(s,"er"))};

-    W{a ->Test};

-}]]></programlisting>

+        <programlisting><![CDATA[w:W{contains(w.ct, "er")-> Test};]]></programlisting>

         <para>

           If you want to find all words that contain a given charactersequence.

           Assume again you

@@ -1126,14 +1177,9 @@
       <section>

         <title>endsWith(IStringExpression expr,IStringExpression expr)

         </title>

-        <programlisting><![CDATA[STRING s;

-BOOLEAN a;

-BLOCK(forEACH) W{}{

-    W{->MATCHEDTEXT(s), ASSIGN(a,endsWith(s,"str."))};

-    W{a ->Test};

-}]]></programlisting>

+        <programlisting><![CDATA[w:W{endsWith(w.ct, "str")-> Test};]]></programlisting>

         <para>

-          Assume you found the suffix "str." as a strong indicator whether a given

+          Assume you found the suffix "str" as a strong indicator whether a given

           token

           represents

           location (a street) by using this function you can now easily identify all

@@ -1146,18 +1192,12 @@
       <section>

         <title>startsWith(IStringExpression expr,IStringExpression expr)

         </title>

-        <programlisting><![CDATA[STRING s;

-BOOLEAN a ;

-BLOCK(forEACH) W{}{

-    W{->MATCHEDTEXT(s), ASSIGN(a,startsWith(s,"sprech"))};

-    W{a ->Test};

-}]]></programlisting>

+        <programlisting><![CDATA[w:W{startsWith(w.ct, "sprech")-> Test};]]></programlisting>

         <para>

           Given a stem of a word you want to mark every instance that was possibly derived from that stem.

           If you decide to use that function you can detect all those words in 1 line and in a next step

           mark all

           of them as an Annotationtype of choice.

-

         </para>

       </section>

 

diff --git a/ruta-maven-archetype/src/main/resources/archetype-resources/pom.xml b/ruta-maven-archetype/src/main/resources/archetype-resources/pom.xml
index 59e0f35..0f76fb6 100644
--- a/ruta-maven-archetype/src/main/resources/archetype-resources/pom.xml
+++ b/ruta-maven-archetype/src/main/resources/archetype-resources/pom.xml
@@ -36,7 +36,7 @@
 
   <properties>
     <junit-version>4.11</junit-version>
-    <uima-version>2.8.1</uima-version>
+    <uima-version>2.10.0</uima-version>
     <ruta-version>${archetypeVersion}</ruta-version>
   </properties>