Merge branch 'master-v2' into feature/UIMA-6227-Upgrade-to-xmlunit-2

* master-v2: (21 commits)
  [UIMA-6275] InitializableFactory is not smart enough to find a suitable classloader
  [UIMA-6275] InitializableFactory is not smart enough to find a suitable classloader
  [UIMA-6275] InitializableFactory is not smart enough to find a suitable classloader
  [UIMA-6263] CAS validation support
  [UIMA-6263] CAS validation support
  [UIMA-6263] CAS validation support
  [UIMA-6263] CAS validation support
  [UIMA-6263] CAS validation support
  [UIMA-6263] CAS validation support
  [UIMA-6263] CAS validation support
  [UIMA-6263] CAS validation support
  [UIMA-6263] CAS validation support
  [UIMA-6263] CAS validation support
  [UIMA-6263] CAS validation support
  [UIMA-6264] Switch from DocBook to Asciidoc
  [UIMA-6263] CAS validation support
  [UIMA-6257] Jenkinsfile for uimaFIT
  [UIMA-6257] Jenkinsfile for uimaFIT
  [UIMA-6242] uimaFIT Maven plugin should fail on error by default
  [UIMA-6240] Failure to resolve type system imports when generating descriptors
  ...
diff --git a/Jenkinsfile b/Jenkinsfile
new file mode 100644
index 0000000..5bd0abc
--- /dev/null
+++ b/Jenkinsfile
@@ -0,0 +1,91 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+// 
+// http://www.apache.org/licenses/LICENSE-2.0
+// 
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+  
+pipeline {
+  agent {
+    label '!Windows'
+  }
+
+  tools { 
+    maven 'Maven (latest)' 
+    jdk 'JDK 1.8 (latest)' 
+  }
+
+  options {
+    buildDiscarder(logRotator(
+      numToKeepStr: '25', 
+      artifactNumToKeepStr: '5'
+    ))
+    
+    // Seems not to be working reliably yet: https://issues.jenkins-ci.org/browse/JENKINS-48556
+    // timestamps()
+  }
+  
+  parameters {
+    string(
+      name: 'extraMavenArguments',
+      defaultValue: "",
+      description: "Extra arguments to be passed to maven (for testing)")
+  }
+
+  stages {
+    // Display information about the build environemnt. This can be useful for debugging
+    // build issues.
+    stage("Build info") {
+      steps {
+        echo '=== Environment variables ==='
+        sh 'printenv'
+      }
+    }
+        
+    // Perform a merge request build. This is a conditional stage executed with the GitLab
+    // sources plugin triggers a build for a merge request. To avoid conflicts with other
+    // builds, this stage should not deploy artifacts to the Maven repository server and
+    // also not install them locally.
+    stage("Pull request build") {
+      when { branch 'PR-*' }
+    
+      steps {
+        script {
+          currentBuild.description = 'Triggered by: <a href="' + CHANGE_URL + '">' + BRANCH_NAME +
+            ': ' + env.CHANGE_BRANCH + '</a> (' +  env.CHANGE_AUTHOR_DISPLAY_NAME + ')'
+        }
+
+        withMaven() {
+          sh script: 'mvn ' +
+            params.extraMavenArguments +
+            ' -U -Dmaven.test.failure.ignore=true clean verify'
+        }
+      }
+    }
+    
+    // Perform a SNAPSHOT build of a main branch. This stage is typically executed after a
+    // merge request has been merged. On success, it deploys the generated artifacts to the
+    // Maven repository server.
+    stage("SNAPSHOT build") {
+      when { branch pattern: "master|master-v2", comparator: "REGEXP" }
+      
+      steps {
+        withMaven() {
+          sh script: 'mvn ' +
+            params.extraMavenArguments +
+            ' -U -Dmaven.test.failure.ignore=true clean deploy'
+        }
+      }
+    }
+  }
+}
diff --git a/README b/README
index 30a74d7..59e67fb 100644
--- a/README
+++ b/README
@@ -95,6 +95,9 @@
 uimafit-cpe            - support for the Collection Processing Engine (multi-threaded pipelines)
 uimafit-maven          - a Maven plugin to automatically enhance UIMA components with uimaFIT
                          metadata and to generate XML descriptors for uimaFIT-enabled components.
+uimafit-junit          - convenience code facilitating the implementation of UIMA/uimaFIT tests
+                         in JUnit tests
+uimafit-assertj        - adds assertions for UIMA/uimaFIT types via the AssertJ framework
 uimafit-legacy-support - allows uimaFIT 2.x.0 to use uimaFIT 1.4.x meta data like Java annotations
                          and META-INF/org.uimafit/types.txt files. Pipelines mixing uimaFIT 1.4.x
                          and 2.x components MUST be created using the 2.x factories, because the
diff --git a/pom.xml b/pom.xml
index ea84744..d098714 100644
--- a/pom.xml
+++ b/pom.xml
@@ -60,6 +60,16 @@
     </dependency>
     <dependency>
       <groupId>org.apache.uima</groupId>
+      <artifactId>uimafit-junit</artifactId>
+      <version>2.5.1-SNAPSHOT</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.uima</groupId>
+      <artifactId>uimafit-assertj</artifactId>
+      <version>2.5.1-SNAPSHOT</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.uima</groupId>
       <artifactId>uimafit-legacy-support</artifactId>
       <version>2.5.1-SNAPSHOT</version>
     </dependency>
@@ -124,11 +134,13 @@
 
   <modules>
     <module>uimafit-core</module>
+    <module>uimafit-junit</module>
+    <module>uimafit-assertj</module>
     <module>uimafit-examples</module>
     <module>uimafit-spring</module>
     <module>uimafit-maven-plugin</module>
     <module>uimafit-legacy-support</module>
-    <module>uimafit-docbook</module>
+    <module>uimafit-doc</module>
     <module>uimafit-cpe</module>
     <module>uimafit-benchmark</module>
     <module>uimafit-parent</module>
diff --git a/src/main/assembly/bin.xml b/src/main/assembly/bin.xml
index fa4aa47..066cb11 100644
--- a/src/main/assembly/bin.xml
+++ b/src/main/assembly/bin.xml
@@ -129,9 +129,9 @@
       <directoryMode>755</directoryMode>        
     </fileSet>
 
-    <!-- docbooks -->
+    <!-- manuals -->
     <fileSet>
-      <directory>uimafit-docbook/target/site/</directory>
+      <directory>uimafit-doc/target/site/</directory>
       <outputDirectory>docs</outputDirectory>
       <fileMode>644</fileMode>
       <directoryMode>755</directoryMode>        
diff --git a/uimafit-assertj/pom.xml b/uimafit-assertj/pom.xml
new file mode 100644
index 0000000..eab3ac3
--- /dev/null
+++ b/uimafit-assertj/pom.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements. See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership. The ASF licenses this file
+  to you under the Apache License, Version 2.0 (the
+  "License"); you may not use this file except in compliance
+  with the License. You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing,
+  software distributed under the License is distributed on an
+  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  KIND, either express or implied. See the License for the
+  specific language governing permissions and limitations
+  under the License.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <groupId>org.apache.uima</groupId>
+    <artifactId>uimafit-parent</artifactId>
+    <version>2.5.1-SNAPSHOT</version>
+    <relativePath>../uimafit-parent</relativePath>
+  </parent>
+  <artifactId>uimafit-assertj</artifactId>
+  <name>Apache UIMA uimaFIT - AssertJ support</name>
+  <dependencies>
+    <dependency>
+      <groupId>org.apache.uima</groupId>
+      <artifactId>uimafit-core</artifactId>
+      <version>2.5.1-SNAPSHOT</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.uima</groupId>
+      <artifactId>uimaj-core</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.assertj</groupId>
+      <artifactId>assertj-core</artifactId>
+    </dependency>
+  </dependencies>
+</project>
\ No newline at end of file
diff --git a/uimafit-assertj/src/main/java/org/apache/uima/fit/testing/assertj/CasAssert.java b/uimafit-assertj/src/main/java/org/apache/uima/fit/testing/assertj/CasAssert.java
new file mode 100644
index 0000000..8b320ff
--- /dev/null
+++ b/uimafit-assertj/src/main/java/org/apache/uima/fit/testing/assertj/CasAssert.java
@@ -0,0 +1,38 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.uima.fit.testing.assertj;
+
+import org.apache.uima.cas.CAS;
+
+/**
+ * Asserts related to the {@link CAS}.
+ */
+public class CasAssert
+    extends CasAssert_ImplBase<CasAssert, CAS>
+{
+    public CasAssert(CAS actual)
+    {
+        super(actual, CasAssert.class);
+    }
+
+    public static CasAssert assertThat(CAS actual)
+    {
+        return new CasAssert(actual);
+    }
+}
\ No newline at end of file
diff --git a/uimafit-assertj/src/main/java/org/apache/uima/fit/testing/assertj/CasAssert_ImplBase.java b/uimafit-assertj/src/main/java/org/apache/uima/fit/testing/assertj/CasAssert_ImplBase.java
new file mode 100644
index 0000000..3a22e1f
--- /dev/null
+++ b/uimafit-assertj/src/main/java/org/apache/uima/fit/testing/assertj/CasAssert_ImplBase.java
@@ -0,0 +1,90 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.uima.fit.testing.assertj;
+
+import static java.lang.String.format;
+import static java.util.stream.Collectors.joining;
+import static org.apache.uima.fit.validation.ValidationResult.Severity.ERROR;
+
+import org.apache.uima.cas.CAS;
+import org.apache.uima.fit.validation.ValidationException;
+import org.apache.uima.fit.validation.ValidationSummary;
+import org.apache.uima.fit.validation.Validator;
+import org.apache.uima.jcas.JCas;
+import org.assertj.core.api.AbstractAssert;
+import org.assertj.core.api.Fail;
+
+/**
+ * Asserts related to the {@link CAS}.
+ */
+public class CasAssert_ImplBase<SELF extends CasAssert_ImplBase<SELF, ACTUAL>, ACTUAL>
+    extends AbstractAssert<SELF, ACTUAL>
+{
+    public CasAssert_ImplBase(ACTUAL aActual, Class<?> aSelfType)
+    {
+        super(aActual, aSelfType);
+    }
+    
+    protected ValidationSummary validate(Validator aValidator) throws ValidationException
+    {
+        if (actual instanceof CAS) {
+            return aValidator.check((CAS) actual);
+        }
+        if (actual instanceof JCas) {
+            return aValidator.check((JCas) actual);
+        }
+        
+        throw new IllegalArgumentException(
+                "Unsupported CAS implementation [" + actual.getClass().getName() + "]");
+    }
+
+    /**
+     * Checks that CAS is valid using the auto-detected validation checks.
+     */
+    public SELF isValid()
+    {
+        return isValidUsing(new Validator.Builder().build());
+    }
+    
+    /**
+     * Checks that CAS is valid using the given validator.
+     */
+    public SELF isValidUsing(Validator aValidator)
+    {
+        isNotNull();
+
+        try {
+            ValidationSummary summary = validate(aValidator);
+
+            String messageBuffer = summary.getResults().stream()
+                    .filter(r -> r.getSeverity().isEquallyOrMoreSevereThan(ERROR))
+                    .map(r -> format("[%s] %s", r.getSource(), r.getMessage()))
+                    .collect(joining("\n"));
+
+            if (messageBuffer.length() > 0) {
+                Fail.fail(messageBuffer);
+            }
+        }
+        catch (ValidationException e) {
+            Fail.fail("Unable to validate CAS", e);
+        }
+
+        return myself;
+    }
+}
\ No newline at end of file
diff --git a/uimafit-assertj/src/main/java/org/apache/uima/fit/testing/assertj/JCasAssert.java b/uimafit-assertj/src/main/java/org/apache/uima/fit/testing/assertj/JCasAssert.java
new file mode 100644
index 0000000..de1b60c
--- /dev/null
+++ b/uimafit-assertj/src/main/java/org/apache/uima/fit/testing/assertj/JCasAssert.java
@@ -0,0 +1,38 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.uima.fit.testing.assertj;
+
+import org.apache.uima.jcas.JCas;
+
+/**
+ * Asserts related to the {@link JCas}.
+ */
+public class JCasAssert
+    extends CasAssert_ImplBase<JCasAssert, JCas>
+{
+    public JCasAssert(JCas actual)
+    {
+        super(actual, JCasAssert.class);
+    }
+
+    public static JCasAssert assertThat(JCas actual)
+    {
+        return new JCasAssert(actual);
+    }
+}
\ No newline at end of file
diff --git a/uimafit-assertj/src/main/java/org/apache/uima/fit/testing/assertj/ValidationCheckAssert.java b/uimafit-assertj/src/main/java/org/apache/uima/fit/testing/assertj/ValidationCheckAssert.java
new file mode 100644
index 0000000..8ef8e8b
--- /dev/null
+++ b/uimafit-assertj/src/main/java/org/apache/uima/fit/testing/assertj/ValidationCheckAssert.java
@@ -0,0 +1,60 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.uima.fit.testing.assertj;
+
+import static java.util.ServiceLoader.load;
+import static java.util.stream.StreamSupport.stream;
+
+import java.util.ServiceLoader;
+
+import org.apache.uima.fit.validation.ValidationCheck;
+import org.assertj.core.api.AbstractAssert;
+
+/**
+ * Asserts related to {@link ValidationCheck} implementations.
+ */
+public class ValidationCheckAssert
+        extends AbstractAssert<ValidationCheckAssert, ValidationCheck> {
+  public ValidationCheckAssert(ValidationCheck actual) {
+    super(actual, ValidationCheckAssert.class);
+  }
+
+  public static ValidationCheckAssert assertThat(ValidationCheck actual) {
+    return new ValidationCheckAssert(actual);
+  }
+
+  /**
+   * Checks that the check is correctly registered and available to the Java Service Locator.
+   */
+  public ValidationCheckAssert isAvailableToServiceLoader() {
+    isNotNull();
+
+    ServiceLoader<ValidationCheck> loader = load(ValidationCheck.class);
+    boolean found = stream(loader.spliterator(), false)
+            .anyMatch(check -> check.getClass().equals(actual.getClass()));
+
+    if (!found) {
+      failWithMessage(
+              "[%s] cannot be found by the service loader. Ensure it is registered in [META-INF/services/%s]",
+              actual.getClass(), ValidationCheck.class.getName());
+    }
+
+    return this;
+  }
+}
\ No newline at end of file
diff --git a/uimafit-core/.settings/org.eclipse.jdt.core.prefs b/uimafit-core/.settings/org.eclipse.jdt.core.prefs
index be382b6..4ff91b1 100644
--- a/uimafit-core/.settings/org.eclipse.jdt.core.prefs
+++ b/uimafit-core/.settings/org.eclipse.jdt.core.prefs
@@ -10,7 +10,12 @@
 org.eclipse.jdt.core.compiler.processAnnotations=disabled
 org.eclipse.jdt.core.compiler.release=disabled
 org.eclipse.jdt.core.compiler.source=1.8
+org.eclipse.jdt.core.formatter.align_assignment_statements_on_columns=false
+org.eclipse.jdt.core.formatter.align_fields_grouping_blank_lines=2147483647
 org.eclipse.jdt.core.formatter.align_type_members_on_columns=false
+org.eclipse.jdt.core.formatter.align_variable_declarations_on_columns=false
+org.eclipse.jdt.core.formatter.align_with_spaces=false
+org.eclipse.jdt.core.formatter.alignment_for_additive_operator=16
 org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16
 org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=0
 org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16
@@ -19,24 +24,41 @@
 org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16
 org.eclipse.jdt.core.formatter.alignment_for_assignment=0
 org.eclipse.jdt.core.formatter.alignment_for_binary_expression=16
+org.eclipse.jdt.core.formatter.alignment_for_bitwise_operator=16
 org.eclipse.jdt.core.formatter.alignment_for_compact_if=16
+org.eclipse.jdt.core.formatter.alignment_for_compact_loops=16
 org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=80
+org.eclipse.jdt.core.formatter.alignment_for_conditional_expression_chain=0
 org.eclipse.jdt.core.formatter.alignment_for_enum_constants=0
 org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16
+org.eclipse.jdt.core.formatter.alignment_for_expressions_in_for_loop_header=0
+org.eclipse.jdt.core.formatter.alignment_for_logical_operator=16
 org.eclipse.jdt.core.formatter.alignment_for_method_declaration=0
+org.eclipse.jdt.core.formatter.alignment_for_module_statements=16
 org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16
+org.eclipse.jdt.core.formatter.alignment_for_multiplicative_operator=16
+org.eclipse.jdt.core.formatter.alignment_for_parameterized_type_references=0
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_record_components=16
+org.eclipse.jdt.core.formatter.alignment_for_relational_operator=0
 org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=80
 org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=16
+org.eclipse.jdt.core.formatter.alignment_for_shift_operator=0
+org.eclipse.jdt.core.formatter.alignment_for_string_concatenation=16
 org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_record_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16
 org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16
+org.eclipse.jdt.core.formatter.alignment_for_type_arguments=0
+org.eclipse.jdt.core.formatter.alignment_for_type_parameters=0
 org.eclipse.jdt.core.formatter.alignment_for_union_type_in_multicatch=16
 org.eclipse.jdt.core.formatter.blank_lines_after_imports=1
+org.eclipse.jdt.core.formatter.blank_lines_after_last_class_body_declaration=0
 org.eclipse.jdt.core.formatter.blank_lines_after_package=1
+org.eclipse.jdt.core.formatter.blank_lines_before_abstract_method=1
 org.eclipse.jdt.core.formatter.blank_lines_before_field=1
 org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=0
 org.eclipse.jdt.core.formatter.blank_lines_before_imports=1
@@ -45,6 +67,7 @@
 org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=1
 org.eclipse.jdt.core.formatter.blank_lines_before_package=0
 org.eclipse.jdt.core.formatter.blank_lines_between_import_groups=1
+org.eclipse.jdt.core.formatter.blank_lines_between_statement_group_in_switch=0
 org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=1
 org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=end_of_line
 org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=end_of_line
@@ -54,11 +77,17 @@
 org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=end_of_line
 org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=end_of_line
 org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_lambda_body=end_of_line
 org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_record_constructor=end_of_line
+org.eclipse.jdt.core.formatter.brace_position_for_record_declaration=end_of_line
 org.eclipse.jdt.core.formatter.brace_position_for_switch=end_of_line
 org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=end_of_line
+org.eclipse.jdt.core.formatter.comment.align_tags_descriptions_grouped=false
+org.eclipse.jdt.core.formatter.comment.align_tags_names_descriptions=false
 org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment=false
 org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=false
+org.eclipse.jdt.core.formatter.comment.count_line_length_from_starting_position=false
 org.eclipse.jdt.core.formatter.comment.format_block_comments=true
 org.eclipse.jdt.core.formatter.comment.format_header=false
 org.eclipse.jdt.core.formatter.comment.format_html=true
@@ -67,7 +96,9 @@
 org.eclipse.jdt.core.formatter.comment.format_source_code=true
 org.eclipse.jdt.core.formatter.comment.indent_parameter_description=true
 org.eclipse.jdt.core.formatter.comment.indent_root_tags=true
+org.eclipse.jdt.core.formatter.comment.indent_tag_description=false
 org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=insert
+org.eclipse.jdt.core.formatter.comment.insert_new_line_between_different_tags=do not insert
 org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=insert
 org.eclipse.jdt.core.formatter.comment.line_length=100
 org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries=true
@@ -79,10 +110,11 @@
 org.eclipse.jdt.core.formatter.disabling_tag=@formatter\:off
 org.eclipse.jdt.core.formatter.enabling_tag=@formatter\:on
 org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=false
-org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column=true
+org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column=false
 org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true
 org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true
 org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true
+org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_record_header=true
 org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=true
 org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=true
 org.eclipse.jdt.core.formatter.indent_empty_lines=false
@@ -91,6 +123,7 @@
 org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true
 org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=true
 org.eclipse.jdt.core.formatter.indentation.size=2
+org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_enum_constant=insert
 org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field=insert
 org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=insert
 org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method=insert
@@ -99,6 +132,7 @@
 org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type=insert
 org.eclipse.jdt.core.formatter.insert_new_line_after_label=do not insert
 org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert
+org.eclipse.jdt.core.formatter.insert_new_line_after_type_annotation=do not insert
 org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=do not insert
 org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=do not insert
 org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert
@@ -112,11 +146,15 @@
 org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration=insert
 org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=insert
 org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_after_additive_operator=insert
 org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert
+org.eclipse.jdt.core.formatter.insert_space_after_arrow_in_switch_case=insert
+org.eclipse.jdt.core.formatter.insert_space_after_arrow_in_switch_default=insert
 org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert
 org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert
 org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert
 org.eclipse.jdt.core.formatter.insert_space_after_binary_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_after_bitwise_operator=insert
 org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=insert
 org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert
 org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert
@@ -142,10 +180,16 @@
 org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert
 org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert
 org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_record_components=insert
 org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=insert
+org.eclipse.jdt.core.formatter.insert_space_after_comma_in_switch_case_expressions=insert
 org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert
 org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert
 org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert
+org.eclipse.jdt.core.formatter.insert_space_after_lambda_arrow=insert
+org.eclipse.jdt.core.formatter.insert_space_after_logical_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_after_multiplicative_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_after_not_operator=do not insert
 org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert
 org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert
 org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert
@@ -162,6 +206,7 @@
 org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert
 org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert
 org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_record_declaration=do not insert
 org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert
 org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=do not insert
 org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_try=do not insert
@@ -170,13 +215,20 @@
 org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert
 org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert
 org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=do not insert
+org.eclipse.jdt.core.formatter.insert_space_after_relational_operator=insert
 org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert
 org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_try_resources=insert
+org.eclipse.jdt.core.formatter.insert_space_after_shift_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_after_string_concatenation=insert
 org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_additive_operator=insert
 org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert
+org.eclipse.jdt.core.formatter.insert_space_before_arrow_in_switch_case=insert
+org.eclipse.jdt.core.formatter.insert_space_before_arrow_in_switch_default=insert
 org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert
 org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert
 org.eclipse.jdt.core.formatter.insert_space_before_binary_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_before_bitwise_operator=insert
 org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert
 org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert
 org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert
@@ -193,6 +245,7 @@
 org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert
 org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert
 org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_record_declaration=do not insert
 org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert
 org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized=do not insert
 org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_try=do not insert
@@ -219,10 +272,15 @@
 org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=do not insert
 org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=do not insert
 org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_record_components=do not insert
 org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_comma_in_switch_case_expressions=do not insert
 org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert
 org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert
 org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_lambda_arrow=insert
+org.eclipse.jdt.core.formatter.insert_space_before_logical_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_before_multiplicative_operator=insert
 org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert
 org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert
 org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert
@@ -234,6 +292,8 @@
 org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=insert
 org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert
 org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_record_constructor=insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_record_declaration=insert
 org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch=insert
 org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert
 org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=do not insert
@@ -249,6 +309,7 @@
 org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert
 org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert
 org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_record_declaration=do not insert
 org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=insert
 org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=insert
 org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_try=insert
@@ -259,9 +320,12 @@
 org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=do not insert
 org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert
 org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_relational_operator=insert
 org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert
 org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert
 org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_try_resources=do not insert
+org.eclipse.jdt.core.formatter.insert_space_before_shift_operator=insert
+org.eclipse.jdt.core.formatter.insert_space_before_string_concatenation=insert
 org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert
 org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert
 org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert
@@ -273,20 +337,63 @@
 org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert
 org.eclipse.jdt.core.formatter.join_lines_in_comments=true
 org.eclipse.jdt.core.formatter.join_wrapped_lines=true
+org.eclipse.jdt.core.formatter.keep_annotation_declaration_on_one_line=one_line_never
+org.eclipse.jdt.core.formatter.keep_anonymous_type_declaration_on_one_line=one_line_never
+org.eclipse.jdt.core.formatter.keep_code_block_on_one_line=one_line_never
 org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=false
 org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=false
+org.eclipse.jdt.core.formatter.keep_enum_constant_declaration_on_one_line=one_line_never
+org.eclipse.jdt.core.formatter.keep_enum_declaration_on_one_line=one_line_never
+org.eclipse.jdt.core.formatter.keep_if_then_body_block_on_one_line=one_line_never
 org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=false
+org.eclipse.jdt.core.formatter.keep_lambda_body_block_on_one_line=one_line_never
+org.eclipse.jdt.core.formatter.keep_loop_body_block_on_one_line=one_line_never
+org.eclipse.jdt.core.formatter.keep_method_body_on_one_line=one_line_never
+org.eclipse.jdt.core.formatter.keep_record_constructor_on_one_line=one_line_never
+org.eclipse.jdt.core.formatter.keep_record_declaration_on_one_line=one_line_never
+org.eclipse.jdt.core.formatter.keep_simple_do_while_body_on_same_line=false
+org.eclipse.jdt.core.formatter.keep_simple_for_body_on_same_line=false
+org.eclipse.jdt.core.formatter.keep_simple_getter_setter_on_one_line=false
+org.eclipse.jdt.core.formatter.keep_simple_while_body_on_same_line=false
 org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false
+org.eclipse.jdt.core.formatter.keep_type_declaration_on_one_line=one_line_never
 org.eclipse.jdt.core.formatter.lineSplit=100
 org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column=false
 org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=false
+org.eclipse.jdt.core.formatter.number_of_blank_lines_after_code_block=0
+org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_code_block=0
 org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0
+org.eclipse.jdt.core.formatter.number_of_blank_lines_at_end_of_code_block=0
+org.eclipse.jdt.core.formatter.number_of_blank_lines_at_end_of_method_body=0
+org.eclipse.jdt.core.formatter.number_of_blank_lines_before_code_block=0
 org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=1
+org.eclipse.jdt.core.formatter.parentheses_positions_in_annotation=common_lines
+org.eclipse.jdt.core.formatter.parentheses_positions_in_catch_clause=common_lines
+org.eclipse.jdt.core.formatter.parentheses_positions_in_enum_constant_declaration=common_lines
+org.eclipse.jdt.core.formatter.parentheses_positions_in_for_statment=common_lines
+org.eclipse.jdt.core.formatter.parentheses_positions_in_if_while_statement=common_lines
+org.eclipse.jdt.core.formatter.parentheses_positions_in_lambda_declaration=common_lines
+org.eclipse.jdt.core.formatter.parentheses_positions_in_method_delcaration=common_lines
+org.eclipse.jdt.core.formatter.parentheses_positions_in_method_invocation=common_lines
+org.eclipse.jdt.core.formatter.parentheses_positions_in_record_declaration=common_lines
+org.eclipse.jdt.core.formatter.parentheses_positions_in_switch_statement=common_lines
+org.eclipse.jdt.core.formatter.parentheses_positions_in_try_clause=common_lines
 org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=true
 org.eclipse.jdt.core.formatter.tabulation.char=space
 org.eclipse.jdt.core.formatter.tabulation.size=2
+org.eclipse.jdt.core.formatter.text_block_indentation=0
 org.eclipse.jdt.core.formatter.use_on_off_tags=false
 org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false
+org.eclipse.jdt.core.formatter.wrap_before_additive_operator=true
+org.eclipse.jdt.core.formatter.wrap_before_assignment_operator=false
 org.eclipse.jdt.core.formatter.wrap_before_binary_operator=true
+org.eclipse.jdt.core.formatter.wrap_before_bitwise_operator=true
+org.eclipse.jdt.core.formatter.wrap_before_conditional_operator=true
+org.eclipse.jdt.core.formatter.wrap_before_logical_operator=true
+org.eclipse.jdt.core.formatter.wrap_before_multiplicative_operator=true
 org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch=true
+org.eclipse.jdt.core.formatter.wrap_before_relational_operator=true
+org.eclipse.jdt.core.formatter.wrap_before_shift_operator=true
+org.eclipse.jdt.core.formatter.wrap_before_string_concatenation=true
 org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested=true
+org.eclipse.jdt.core.javaFormatter=org.eclipse.jdt.core.defaultJavaFormatter
diff --git a/uimafit-core/.settings/org.eclipse.jdt.ui.prefs b/uimafit-core/.settings/org.eclipse.jdt.ui.prefs
index adc6b5a..eb8a428 100644
--- a/uimafit-core/.settings/org.eclipse.jdt.ui.prefs
+++ b/uimafit-core/.settings/org.eclipse.jdt.ui.prefs
@@ -1,3 +1,4 @@
 eclipse.preferences.version=1
 formatter_profile=_Apache UIMA Code Conventions
-formatter_settings_version=12
+formatter_settings_version=19
+org.eclipse.jdt.ui.text.custom_code_templates=
diff --git a/uimafit-core/pom.xml b/uimafit-core/pom.xml
index b6e8e03..6f11dc6 100644
--- a/uimafit-core/pom.xml
+++ b/uimafit-core/pom.xml
@@ -179,10 +179,12 @@
                   <exclude>src/test/resources/data/reference/JCasBuilderTest.dump</exclude>
                   <exclude>src/test/resources/data/reference/test.xmi.dump</exclude>
                   <exclude>src/test/resources/data/reference/SerializationTestAnnotator.xml</exclude>
+                  <exclude>src/test/resources/pear/DateTime.pear</exclude>
                   <!-- These configuration files cannot bear a license header -->
                   <exclude>src/test/resources/META-INF/org.apache.uima.fit/fsindexes.txt</exclude>
                   <exclude>src/test/resources/META-INF/org.apache.uima.fit/typepriorities.txt</exclude>
                   <exclude>src/test/resources/META-INF/org.apache.uima.fit/types.txt</exclude>
+                  <exclude>src/test/resources/META-INF/services/org.apache.uima.fit.validation.ValidationCheck</exclude>
                 </excludes>
               </configuration>
             </execution>
diff --git a/uimafit-core/src/main/java/org/apache/uima/fit/factory/FsIndexFactory.java b/uimafit-core/src/main/java/org/apache/uima/fit/factory/FsIndexFactory.java
index ad2bf14..33c717b 100644
--- a/uimafit-core/src/main/java/org/apache/uima/fit/factory/FsIndexFactory.java
+++ b/uimafit-core/src/main/java/org/apache/uima/fit/factory/FsIndexFactory.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
@@ -26,10 +26,12 @@
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.WeakHashMap;
 
 import org.apache.commons.logging.LogFactory;
 import org.apache.uima.fit.descriptor.FsIndex;
 import org.apache.uima.fit.descriptor.FsIndexKey;
+import org.apache.uima.fit.internal.ClassLoaderUtils;
 import org.apache.uima.fit.internal.MetaDataType;
 import org.apache.uima.resource.ResourceInitializationException;
 import org.apache.uima.resource.metadata.FsIndexCollection;
@@ -61,6 +63,17 @@
 
   private static final Object SCAN_LOCK = new Object();
 
+  private static final Object CREATE_LOCK = new Object();
+
+  private static WeakHashMap<ClassLoader, String[]> fsIndexLocationsByClassloader;
+
+  private static WeakHashMap<ClassLoader, FsIndexCollection> fsIndexCollectionsByClassloader;
+
+  static {
+    fsIndexLocationsByClassloader = new WeakHashMap<>();
+    fsIndexCollectionsByClassloader = new WeakHashMap<>();
+  }
+
   private FsIndexFactory() {
     // Factory class
   }
@@ -68,13 +81,13 @@
   /**
    * Create index configuration data for a given class definition using reflection and the
    * configuration parameter annotation.
-   * 
+   *
    * @param componentClass
    *          the class to analyze
    * @return the index collection
    */
   public static FsIndexCollection createFsIndexCollection(Class<?> componentClass) {
-    List<FsIndex> anFsIndexList = new ArrayList<FsIndex>();
+    List<FsIndex> anFsIndexList = new ArrayList<>();
 
     // Check FsIndexCollection annotation
     org.apache.uima.fit.descriptor.FsIndexCollection anIndexCollection = getInheritableAnnotation(
@@ -88,10 +101,10 @@
             componentClass);
     if (anFsIndex != null) {
       if (anIndexCollection != null) {
-        throw new IllegalStateException("Class [" + componentClass.getName() + "] must not "
-                + "declare "
-                + org.apache.uima.fit.descriptor.FsIndexCollection.class.getSimpleName() + " and "
-                + FsIndex.class.getSimpleName() + " at the same time.");
+        throw new IllegalStateException(
+                "Class [" + componentClass.getName() + "] must not " + "declare "
+                        + org.apache.uima.fit.descriptor.FsIndexCollection.class.getSimpleName()
+                        + " and " + FsIndex.class.getSimpleName() + " at the same time.");
       }
 
       anFsIndexList.add(anFsIndex);
@@ -102,7 +115,7 @@
     // Process collected FsIndex annotations
     for (FsIndex anIdx : anFsIndexList) {
       // Collect index keys
-      List<FsIndexKeyDescription> keys = new ArrayList<FsIndexKeyDescription>();
+      List<FsIndexKeyDescription> keys = new ArrayList<>();
       for (FsIndexKey anIndexKey : anIdx.keys()) {
         keys.add(createFsIndexKeyDescription(anIndexKey.featureName(), anIndexKey.comparator()));
       }
@@ -158,7 +171,7 @@
 
   /**
    * Create a index collection from a set of descriptions.
-   * 
+   *
    * @param descriptions
    *          the index descriptions
    * @return the index collection
@@ -185,7 +198,8 @@
    *          the index comparator
    * @return the index key description
    */
-  public static FsIndexKeyDescription createFsIndexKeyDescription(String featureName, int comparator) {
+  public static FsIndexKeyDescription createFsIndexKeyDescription(String featureName,
+          int comparator) {
     FsIndexKeyDescription_impl key = new FsIndexKeyDescription_impl();
     key.setFeatureName(featureName);
     key.setComparator(comparator);
@@ -193,17 +207,15 @@
     return key;
   }
 
-  private static String[] indexDescriptorLocations;
-
   /**
    * Creates a {@link FsIndexCollection} from descriptor names.
-   * 
+   *
    * @param descriptorNames
    *          The fully qualified, Java-style, dotted descriptor names.
    * @return a {@link FsIndexCollection} that includes the indexes from all of the specified files.
    */
   public static FsIndexCollection createFsIndexCollection(String... descriptorNames) {
-    List<Import> imports = new ArrayList<Import>();
+    List<Import> imports = new ArrayList<>();
     for (String descriptorName : descriptorNames) {
       Import imp = new Import_impl();
       imp.setName(descriptorName);
@@ -218,13 +230,13 @@
 
   /**
    * Creates a {@link FsIndexCollection} from a descriptor file
-   * 
+   *
    * @param descriptorURIs
    *          The descriptor file paths.
    * @return A {@link FsIndexCollection} that includes the indexes from all of the specified files.
    */
   public static FsIndexCollection createTypeSystemDescriptionFromPath(String... descriptorURIs) {
-    List<Import> imports = new ArrayList<Import>();
+    List<Import> imports = new ArrayList<>();
     for (String descriptorURI : descriptorURIs) {
       Import imp = new Import_impl();
       imp.setLocation(descriptorURI);
@@ -241,46 +253,59 @@
    * Creates a {@link FsIndexCollection} from all index descriptions that can be found via the
    * pattern specified in the system property {@code org.apache.uima.fit.fsindex.import_pattern} or
    * via the {@code META-INF/org.apache.uima.fit/fsindexes.txt} files in the classpath.
-   * 
+   *
    * @return the auto-scanned indexes.
    * @throws ResourceInitializationException
    *           if the index collection could not be assembled
    */
   public static FsIndexCollection createFsIndexCollection() throws ResourceInitializationException {
-    List<FsIndexDescription> fsIndexList = new ArrayList<FsIndexDescription>();
-    for (String location : scanIndexDescriptors()) {
-      try {
-        XMLInputSource xmlInput = new XMLInputSource(location);
-        FsIndexCollection fsIdxCol = getXMLParser().parseFsIndexCollection(xmlInput);
-        fsIdxCol.resolveImports();
-        fsIndexList.addAll(asList(fsIdxCol.getFsIndexes()));
-        LogFactory.getLog(FsIndexFactory.class).debug("Detected index at [" + location + "]");
-      } catch (IOException e) {
-        throw new ResourceInitializationException(e);
-      } catch (InvalidXMLException e) {
-        LogFactory.getLog(FsIndexFactory.class).warn(
-                "[" + location + "] is not a index descriptor file. Ignoring.", e);
+    ClassLoader cl = ClassLoaderUtils.findClassloader();
+    FsIndexCollection aggFsIdxCol = fsIndexCollectionsByClassloader.get(cl);
+    if (aggFsIdxCol == null) {
+      synchronized (CREATE_LOCK) {
+        List<FsIndexDescription> fsIndexList = new ArrayList<>();
+        for (String location : scanIndexDescriptors()) {
+          try {
+            XMLInputSource xmlInput = new XMLInputSource(location);
+            FsIndexCollection fsIdxCol = getXMLParser().parseFsIndexCollection(xmlInput);
+            fsIdxCol.resolveImports();
+            fsIndexList.addAll(asList(fsIdxCol.getFsIndexes()));
+            LogFactory.getLog(FsIndexFactory.class).debug("Detected index at [" + location + "]");
+          } catch (IOException e) {
+            throw new ResourceInitializationException(e);
+          } catch (InvalidXMLException e) {
+            LogFactory.getLog(FsIndexFactory.class)
+            .warn("[" + location + "] is not a index descriptor file. Ignoring.", e);
+          }
+        }
+
+        aggFsIdxCol = createFsIndexCollection(
+                fsIndexList.toArray(new FsIndexDescription[fsIndexList.size()]));
+        fsIndexCollectionsByClassloader.put(cl, aggFsIdxCol);
       }
     }
 
-    return createFsIndexCollection(fsIndexList.toArray(new FsIndexDescription[fsIndexList.size()]));
+    return (FsIndexCollection) aggFsIdxCol.clone();
   }
 
   /**
    * Get all currently accessible index descriptor locations. A scan is actually only performed on
    * the first call and the locations are cached. To force a re-scan use
    * {@link #forceIndexDescriptorsScan()}.
-   * 
+   *
    * @return an array of locations.
    * @throws ResourceInitializationException
    *           if the locations could not be resolved.
    */
   public static String[] scanIndexDescriptors() throws ResourceInitializationException {
     synchronized (SCAN_LOCK) {
-      if (indexDescriptorLocations == null) {
-        indexDescriptorLocations = scanDescriptors(MetaDataType.FS_INDEX);
+      ClassLoader cl = ClassLoaderUtils.findClassloader();
+      String[] indexLocations = fsIndexLocationsByClassloader.get(cl);
+      if (indexLocations == null) {
+        indexLocations = scanDescriptors(MetaDataType.FS_INDEX);
+        fsIndexLocationsByClassloader.put(cl, indexLocations);
       }
-      return indexDescriptorLocations;
+      return indexLocations;
     }
   }
 
@@ -289,6 +314,9 @@
    * all auto-import locations.
    */
   public static void forceIndexDescriptorsScan() {
-    indexDescriptorLocations = null;
+    synchronized (SCAN_LOCK) {
+      fsIndexLocationsByClassloader.clear();
+      fsIndexCollectionsByClassloader.clear();
+    }
   }
 }
diff --git a/uimafit-core/src/main/java/org/apache/uima/fit/factory/TypePrioritiesFactory.java b/uimafit-core/src/main/java/org/apache/uima/fit/factory/TypePrioritiesFactory.java
index 907c0c7..e01eb3d 100644
--- a/uimafit-core/src/main/java/org/apache/uima/fit/factory/TypePrioritiesFactory.java
+++ b/uimafit-core/src/main/java/org/apache/uima/fit/factory/TypePrioritiesFactory.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
@@ -25,8 +25,10 @@
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.WeakHashMap;
 
 import org.apache.commons.logging.LogFactory;
+import org.apache.uima.fit.internal.ClassLoaderUtils;
 import org.apache.uima.fit.internal.MetaDataType;
 import org.apache.uima.fit.internal.ResourceManagerFactory;
 import org.apache.uima.resource.ResourceInitializationException;
@@ -38,13 +40,19 @@
 import org.apache.uima.util.InvalidXMLException;
 import org.apache.uima.util.XMLInputSource;
 
-/**
- */
-
 public final class TypePrioritiesFactory {
   private static final Object SCAN_LOCK = new Object();
 
-  private static String[] typePriorityDescriptorLocations;
+  private static final Object CREATE_LOCK = new Object();
+
+  private static WeakHashMap<ClassLoader, String[]> typePrioritesLocationsByClassloader;
+
+  private static WeakHashMap<ClassLoader, TypePriorities> typePrioritiesByClassloader;
+
+  static {
+    typePrioritesLocationsByClassloader = new WeakHashMap<>();
+    typePrioritiesByClassloader = new WeakHashMap<>();
+  }
 
   private TypePrioritiesFactory() {
     // This class is not meant to be instantiated
@@ -52,7 +60,7 @@
 
   /**
    * Create a TypePriorities given a sequence of ordered type classes
-   * 
+   *
    * @param prioritizedTypes
    *          a sequence of ordered type classes
    * @return type priorities created from the ordered JCas classes
@@ -71,8 +79,8 @@
   }
 
   /**
-   * Create a TypePriorities given a sequence of ordered type names
-   * 
+   * Create a {@link TypePriorities} given a sequence of ordered type names
+   *
    * @param prioritizedTypeNames
    *          a sequence of ordered type names
    * @return type priorities created from the ordered type names
@@ -91,51 +99,60 @@
    * the pattern specified in the system property
    * {@code org.apache.uima.fit.typepriorities.import_pattern} or via the
    * {@code META-INF/org.apache.uima.fit/typepriorities.txt} files in the classpath.
-   * 
+   *
    * @return the auto-scanned type priorities.
    * @throws ResourceInitializationException
    *           if the collected type priorities cannot be merged.
    */
   public static TypePriorities createTypePriorities() throws ResourceInitializationException {
-    List<TypePriorities> typePrioritiesList = new ArrayList<TypePriorities>();
-    for (String location : scanTypePrioritiesDescriptors()) {
-      try {
-        XMLInputSource xmlInput = new XMLInputSource(location);
-        TypePriorities typePriorities = getXMLParser().parseTypePriorities(xmlInput);
-        typePriorities.resolveImports();
-        typePrioritiesList.add(typePriorities);
-        LogFactory.getLog(TypePrioritiesFactory.class).debug(
-                "Detected type priorities at [" + location + "]");
-      } catch (IOException e) {
-        throw new ResourceInitializationException(e);
-      } catch (InvalidXMLException e) {
-        LogFactory.getLog(TypePrioritiesFactory.class).warn(
-                "[" + location + "] is not a type priorities descriptor file. Ignoring.", e);
+    ClassLoader cl = ClassLoaderUtils.findClassloader();
+    TypePriorities aggTypePriorities = typePrioritiesByClassloader.get(cl);
+    if (aggTypePriorities == null) {
+      synchronized (CREATE_LOCK) {
+        List<TypePriorities> typePrioritiesList = new ArrayList<>();
+        for (String location : scanTypePrioritiesDescriptors()) {
+          try {
+            XMLInputSource xmlInput = new XMLInputSource(location);
+            TypePriorities typePriorities = getXMLParser().parseTypePriorities(xmlInput);
+            typePriorities.resolveImports();
+            typePrioritiesList.add(typePriorities);
+            LogFactory.getLog(TypePrioritiesFactory.class)
+            .debug("Detected type priorities at [" + location + "]");
+          } catch (IOException e) {
+            throw new ResourceInitializationException(e);
+          } catch (InvalidXMLException e) {
+            LogFactory.getLog(TypePrioritiesFactory.class).warn(
+                    "[" + location + "] is not a type priorities descriptor file. Ignoring.", e);
+          }
+        }
+
+        ResourceManager resMgr = ResourceManagerFactory.newResourceManager();
+        aggTypePriorities = CasCreationUtils.mergeTypePriorities(typePrioritiesList, resMgr);
+        typePrioritiesByClassloader.put(cl, aggTypePriorities);
       }
     }
 
-    ResourceManager resMgr = ResourceManagerFactory.newResourceManager();
-    TypePriorities aggTypePriorities = CasCreationUtils.mergeTypePriorities(typePrioritiesList,
-            resMgr);
-
-    return aggTypePriorities;
+    return (TypePriorities) aggTypePriorities.clone();
   }
 
   /**
    * Get all currently accessible type priorities descriptor locations. A scan is actually only
    * performed on the first call and the locations are cached. To force a re-scan use
    * {@link #forceTypePrioritiesDescriptorsScan()}.
-   * 
+   *
    * @return an array of locations.
    * @throws ResourceInitializationException
    *           if the locations could not be resolved.
    */
   public static String[] scanTypePrioritiesDescriptors() throws ResourceInitializationException {
     synchronized (SCAN_LOCK) {
-      if (typePriorityDescriptorLocations == null) {
-        typePriorityDescriptorLocations = scanDescriptors(MetaDataType.TYPE_PRIORITIES);
+      ClassLoader cl = ClassLoaderUtils.findClassloader();
+      String[] typePrioritesLocations = typePrioritesLocationsByClassloader.get(cl);
+      if (typePrioritesLocations == null) {
+        typePrioritesLocations = scanDescriptors(MetaDataType.TYPE_PRIORITIES);
+        typePrioritesLocationsByClassloader.put(cl, typePrioritesLocations);
       }
-      return typePriorityDescriptorLocations;
+      return typePrioritesLocations;
     }
   }
 
@@ -144,6 +161,9 @@
    * {@link #scanTypePrioritiesDescriptors()} will rescan all auto-import locations.
    */
   public static void forceTypePrioritiesDescriptorsScan() {
-    typePriorityDescriptorLocations = null;
+    synchronized (SCAN_LOCK) {
+      typePrioritesLocationsByClassloader.clear();
+      typePrioritiesByClassloader.clear();
+    }
   }
 }
diff --git a/uimafit-core/src/main/java/org/apache/uima/fit/factory/TypeSystemDescriptionFactory.java b/uimafit-core/src/main/java/org/apache/uima/fit/factory/TypeSystemDescriptionFactory.java
index 16be4ab..e3b2d99 100644
--- a/uimafit-core/src/main/java/org/apache/uima/fit/factory/TypeSystemDescriptionFactory.java
+++ b/uimafit-core/src/main/java/org/apache/uima/fit/factory/TypeSystemDescriptionFactory.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
@@ -25,8 +25,10 @@
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.WeakHashMap;
 
 import org.apache.commons.logging.LogFactory;
+import org.apache.uima.fit.internal.ClassLoaderUtils;
 import org.apache.uima.fit.internal.MetaDataType;
 import org.apache.uima.fit.internal.ResourceManagerFactory;
 import org.apache.uima.resource.ResourceInitializationException;
@@ -38,12 +40,19 @@
 import org.apache.uima.util.InvalidXMLException;
 import org.apache.uima.util.XMLInputSource;
 
-/**
- */
 public final class TypeSystemDescriptionFactory {
   private static final Object SCAN_LOCK = new Object();
 
-  private static String[] typeDescriptorLocations;
+  private static final Object CREATE_LOCK = new Object();
+
+  private static WeakHashMap<ClassLoader, String[]> typeDescriptorLocationsByClassloader;
+
+  private static WeakHashMap<ClassLoader, TypeSystemDescription> typeDescriptorByClassloader;
+
+  static {
+    typeDescriptorLocationsByClassloader = new WeakHashMap<>();
+    typeDescriptorByClassloader = new WeakHashMap<>();
+  }
 
   private TypeSystemDescriptionFactory() {
     // This class is not meant to be instantiated
@@ -51,14 +60,14 @@
 
   /**
    * Creates a TypeSystemDescription from descriptor names.
-   * 
+   *
    * @param descriptorNames
    *          The fully qualified, Java-style, dotted descriptor names.
    * @return A TypeSystemDescription that includes the types from all of the specified files.
    */
   public static TypeSystemDescription createTypeSystemDescription(String... descriptorNames) {
     TypeSystemDescription typeSystem = new TypeSystemDescription_impl();
-    List<Import> imports = new ArrayList<Import>();
+    List<Import> imports = new ArrayList<>();
     for (String descriptorName : descriptorNames) {
       Import imp = new Import_impl();
       imp.setName(descriptorName);
@@ -70,15 +79,16 @@
   }
 
   /**
-   * Creates a TypeSystemDescription from a descriptor file
-   * 
+   * Creates a {@link TypeSystemDescription} from a descriptor file
+   *
    * @param descriptorURIs
    *          The descriptor file paths.
    * @return A TypeSystemDescription that includes the types from all of the specified files.
    */
-  public static TypeSystemDescription createTypeSystemDescriptionFromPath(String... descriptorURIs) {
+  public static TypeSystemDescription createTypeSystemDescriptionFromPath(
+          String... descriptorURIs) {
     TypeSystemDescription typeSystem = new TypeSystemDescription_impl();
-    List<Import> imports = new ArrayList<Import>();
+    List<Import> imports = new ArrayList<>();
     for (String descriptorURI : descriptorURIs) {
       Import imp = new Import_impl();
       imp.setLocation(descriptorURI);
@@ -93,45 +103,56 @@
    * Creates a {@link TypeSystemDescription} from all type descriptions that can be found via the
    * default import pattern or via the {@code META-INF/org.apache.uima.fit/types.txt} files in the
    * classpath.
-   * 
+   *
    * @return the auto-scanned type system.
    * @throws ResourceInitializationException
    *           if the collected type system descriptions cannot be merged.
    */
   public static TypeSystemDescription createTypeSystemDescription()
           throws ResourceInitializationException {
-    List<TypeSystemDescription> tsdList = new ArrayList<TypeSystemDescription>();
-    for (String location : scanTypeDescriptors()) {
-      try {
-        XMLInputSource xmlInputType1 = new XMLInputSource(location);
-        tsdList.add(getXMLParser().parseTypeSystemDescription(xmlInputType1));
-        LogFactory.getLog(TypeSystemDescription.class).debug(
-                "Detected type system at [" + location + "]");
-      } catch (IOException e) {
-        throw new ResourceInitializationException(e);
-      } catch (InvalidXMLException e) {
-        LogFactory.getLog(TypeSystemDescription.class).warn(
-                "[" + location + "] is not a type file. Ignoring.", e);
+    ClassLoader cl = ClassLoaderUtils.findClassloader();
+    TypeSystemDescription tsd = typeDescriptorByClassloader.get(cl);
+    if (tsd == null) {
+      synchronized (CREATE_LOCK) {
+        List<TypeSystemDescription> tsdList = new ArrayList<>();
+        for (String location : scanTypeDescriptors()) {
+          try {
+            XMLInputSource xmlInputType1 = new XMLInputSource(location);
+            tsdList.add(getXMLParser().parseTypeSystemDescription(xmlInputType1));
+            LogFactory.getLog(TypeSystemDescription.class)
+            .debug("Detected type system at [" + location + "]");
+          } catch (IOException e) {
+            throw new ResourceInitializationException(e);
+          } catch (InvalidXMLException e) {
+            LogFactory.getLog(TypeSystemDescription.class)
+            .warn("[" + location + "] is not a type file. Ignoring.", e);
+          }
+        }
+
+        ResourceManager resMgr = ResourceManagerFactory.newResourceManager();
+        tsd = mergeTypeSystems(tsdList, resMgr);
+        typeDescriptorByClassloader.put(cl, tsd);
       }
     }
-
-    ResourceManager resMgr = ResourceManagerFactory.newResourceManager();
-    return mergeTypeSystems(tsdList, resMgr);
+    return (TypeSystemDescription) tsd.clone();
   }
 
   /**
    * Get all currently accessible type system descriptor locations. A scan is actually only
    * performed on the first call and the locations are cached. To force a re-scan use
    * {@link #forceTypeDescriptorsScan()}.
-   * 
+   *
    * @return an array of locations.
    * @throws ResourceInitializationException
    *           if the locations could not be resolved.
    */
   public static String[] scanTypeDescriptors() throws ResourceInitializationException {
     synchronized (SCAN_LOCK) {
+      ClassLoader cl = ClassLoaderUtils.findClassloader();
+      String[] typeDescriptorLocations = typeDescriptorLocationsByClassloader.get(cl);
       if (typeDescriptorLocations == null) {
         typeDescriptorLocations = scanDescriptors(MetaDataType.TYPE_SYSTEM);
+        typeDescriptorLocationsByClassloader.put(cl, typeDescriptorLocations);
       }
       return typeDescriptorLocations;
     }
@@ -142,6 +163,9 @@
    * all auto-import locations.
    */
   public static void forceTypeDescriptorsScan() {
-    typeDescriptorLocations = null;
+    synchronized (SCAN_LOCK) {
+      typeDescriptorLocationsByClassloader.clear();
+      typeDescriptorByClassloader.clear();
+    }
   }
 }
diff --git a/uimafit-core/src/main/java/org/apache/uima/fit/factory/initializable/InitializableFactory.java b/uimafit-core/src/main/java/org/apache/uima/fit/factory/initializable/InitializableFactory.java
index e0c54e6..535782d 100644
--- a/uimafit-core/src/main/java/org/apache/uima/fit/factory/initializable/InitializableFactory.java
+++ b/uimafit-core/src/main/java/org/apache/uima/fit/factory/initializable/InitializableFactory.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,11 +19,12 @@
 package org.apache.uima.fit.factory.initializable;
 
 import org.apache.uima.UimaContext;
+import org.apache.uima.fit.internal.ClassLoaderUtils;
 import org.apache.uima.resource.ResourceInitializationException;
 
 /**
  * Please see {@link Initializable} for a description of how this class is intended to be used.
- * 
+ *
  * @see Initializable
  */
 public final class InitializableFactory {
@@ -35,7 +36,7 @@
    * Provides a way to create an instance of T. If the class specified by className implements
    * {@link Initializable}, then the UimaContext provided here will be passed to its initialize
    * method.
-   * 
+   *
    * @param <T>
    *          the interface type
    * @param context
@@ -50,7 +51,14 @@
    */
   public static <T> T create(UimaContext context, String className, Class<T> superClass)
           throws ResourceInitializationException {
-    Class<? extends T> cls = getClass(className, superClass);
+    Class<? extends T> cls;
+    try {
+      ClassLoader cl = ClassLoaderUtils.findClassloader(context);
+      cls = Class.forName(className, true, cl).asSubclass(superClass);
+    } catch (Exception e) {
+      throw new ResourceInitializationException(new IllegalStateException("classname = "
+              + className + " superClass = " + superClass.getName(), e));
+    }
     return create(context, cls);
   }
 
@@ -68,7 +76,8 @@
   public static <T> Class<? extends T> getClass(String className, Class<T> superClass)
           throws ResourceInitializationException {
     try {
-      return Class.forName(className).asSubclass(superClass);
+      ClassLoader cl = ClassLoaderUtils.findClassloader();
+      return Class.forName(className, true, cl).asSubclass(superClass);
     } catch (Exception e) {
       throw new ResourceInitializationException(new IllegalStateException("classname = "
               + className + " superClass = " + superClass.getName(), e));
diff --git a/uimafit-core/src/main/java/org/apache/uima/fit/internal/ClassLoaderUtils.java b/uimafit-core/src/main/java/org/apache/uima/fit/internal/ClassLoaderUtils.java
new file mode 100644
index 0000000..f498264
--- /dev/null
+++ b/uimafit-core/src/main/java/org/apache/uima/fit/internal/ClassLoaderUtils.java
@@ -0,0 +1,123 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.uima.fit.internal;
+
+import org.apache.uima.UimaContext;
+import org.apache.uima.UimaContextAdmin;
+import org.apache.uima.UimaContextHolder;
+import org.apache.uima.resource.ResourceManager;
+import org.springframework.util.ClassUtils;
+
+/**
+ * INTERNAL API - Helper functions to obtain a suitable classloader.
+ */
+public final class ClassLoaderUtils {
+  private ClassLoaderUtils() {
+    // No instances
+  }
+
+  /**
+   * Looks up a suitable classloader in the following order:
+   * <ol>
+   * <li>The {@link UimaContext} in the {@link UimaContextHolder} of the current thread(if any)</li>
+   * <li>The current thread-context classloader (if any)</li>
+   * <li>The classloader through which uimaFIT (i.e. this class) was loaded.</li>
+   * <li>For backwards compatibility then delegates to {@link ClassUtils#getDefaultClassLoader()}</li>
+   * </ol>
+   *
+   * @return a classloader or {@code null} if no suitable classloader could be found.
+   */
+  public static ClassLoader findClassloader() {
+    ClassLoader uimaThreadContextClassLoader = getExtensionClassloader(
+            UimaContextHolder.getContext());
+    if (uimaThreadContextClassLoader != null) {
+      return uimaThreadContextClassLoader;
+    }
+
+    ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
+    if (contextClassLoader != null) {
+      return contextClassLoader;
+    }
+
+    ClassLoader uimaFITClassLoader = ClassLoaderUtils.class.getClassLoader();
+    if (uimaFITClassLoader != null) {
+      return uimaFITClassLoader;
+    }
+
+    return ClassUtils.getDefaultClassLoader();
+  }
+
+  /**
+   * Looks up a suitable classloader in the following order:
+   * <ol>
+   * <li>The extension classloader of the given {@link ResourceManager}</li>
+   * <li>See {@link #findClassloader()}</li>
+   * </ol>
+   *
+   * @return a classloader or {@code null} if no suitable classloader could be found.
+   */
+  public static ClassLoader findClassloader(ResourceManager aResMgr) {
+    ClassLoader resourceManagerExtensionClassloader = getExtensionClassloader(aResMgr);
+    if (resourceManagerExtensionClassloader != null) {
+      return resourceManagerExtensionClassloader;
+    }
+
+    return findClassloader();
+  }
+
+  /**
+   * Looks up a suitable classloader in the following order:
+   * <ol>
+   * <li>The extension classloader of the {@link ResourceManager} associated with the given
+   * {@link UimaContext} (if any)</li>
+   * <li>See {@link #findClassloader(ResourceManager)}</li>
+   * </ol>
+   *
+   * @return a classloader or {@code null} if no suitable classloader could be found.
+   */
+  public static ClassLoader findClassloader(UimaContext aContext) {
+    ClassLoader uimaContextExtensionClassloader = getExtensionClassloader(aContext);
+    if (uimaContextExtensionClassloader != null) {
+      return uimaContextExtensionClassloader;
+    }
+
+    return findClassloader((ResourceManager) null);
+  }
+
+  private static ClassLoader getExtensionClassloader(UimaContext aContext) {
+    if (aContext instanceof UimaContextAdmin) {
+      return getExtensionClassloader(((UimaContextAdmin) aContext).getResourceManager());
+    }
+
+    return null;
+  }
+
+  private static ClassLoader getExtensionClassloader(ResourceManager aResMgr) {
+    if (aResMgr == null) {
+      return null;
+    }
+
+    ClassLoader cl = aResMgr.getExtensionClassLoader();
+    if (cl != null) {
+      return aResMgr.getExtensionClassLoader();
+    }
+
+    return null;
+  }
+}
diff --git a/uimafit-core/src/main/java/org/apache/uima/fit/internal/MetaDataUtil.java b/uimafit-core/src/main/java/org/apache/uima/fit/internal/MetaDataUtil.java
index 112b78c..814f6aa 100644
--- a/uimafit-core/src/main/java/org/apache/uima/fit/internal/MetaDataUtil.java
+++ b/uimafit-core/src/main/java/org/apache/uima/fit/internal/MetaDataUtil.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
@@ -45,7 +45,7 @@
 
   /**
    * Scan patterns from manifest files and from the specified system property.
-   * 
+   *
    * @param aType
    *          the type of metadata to scan for
    * @return array or all patterns found.
@@ -54,7 +54,7 @@
    */
   public static String[] scanImportsAndManifests(MetaDataType aType)
           throws ResourceInitializationException {
-    ArrayList<String> patterns = new ArrayList<String>();
+    ArrayList<String> patterns = new ArrayList<>();
 
     // Scan auto-import locations
     for (String property : getImportProperties(aType)) {
@@ -80,7 +80,7 @@
 
   /**
    * Resolve a list of patterns to a set of URLs.
-   * 
+   *
    * @param patterns
    *          the patterns to resolve
    * @return an array of locations.
@@ -88,11 +88,11 @@
    *           if the locations could not be resolved.
    */
   public static String[] resolve(String... patterns) throws ResourceInitializationException {
-    Set<String> locations = new HashSet<String>();
+    Set<String> locations = new HashSet<>();
     PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
     try {
       // Scan auto-import locations. Using a set to avoid scanning a pattern twice.
-      for (String pattern : new TreeSet<String>(Arrays.asList(patterns))) {
+      for (String pattern : new TreeSet<>(Arrays.asList(patterns))) {
         String p = pattern.trim();
         if (p.length() == 0) {
           continue;
@@ -109,13 +109,13 @@
 
   /**
    * Get manifest locations for the specified type.
-   * 
+   *
    * @param aType
    *          the type of metadata to scan for
    * @return the manifest locations for this kind of metadata to scan
    */
   public static String[] getManifestLocations(MetaDataType aType) {
-    List<String> locations = new ArrayList<String>();
+    List<String> locations = new ArrayList<>();
     switch (aType) {
       case FS_INDEX:
         locations.add("classpath*:META-INF/org.apache.uima.fit/fsindexes.txt");
@@ -125,7 +125,7 @@
         break;
       case TYPE_PRIORITIES:
         locations.add("classpath*:META-INF/org.apache.uima.fit/typepriorities.txt");
-        break;        
+        break;
     }
 
     return locations.toArray(new String[locations.size()]);
@@ -134,13 +134,13 @@
   /**
    * Get system properties indicating which locations to scan for descriptions of the given type. A
    * list of locations may be given separated by ";".
-   * 
+   *
    * @param aType
    *          the type of metadata to scan for
    * @return the locations for this kind of metadata to scan
    */
   public static String[] getImportProperties(MetaDataType aType) {
-    List<String> locations = new ArrayList<String>();
+    List<String> locations = new ArrayList<>();
     switch (aType) {
       case FS_INDEX:
         locations.add("org.apache.uima.fit.fsindex.import_pattern");
@@ -150,18 +150,18 @@
         break;
       case TYPE_PRIORITIES:
         locations.add("org.apache.uima.fit.typepriorities.import_pattern");
-        break;        
+        break;
     }
 
     return locations.toArray(new String[locations.size()]);
   }
-  
+
   /**
    * Get all currently accessible descriptor locations for the given type.
-   * 
+   *
    * @param aType
    *          the type of metadata to scan for
-      * @return an array of locations.
+   * @return an array of locations.
    * @throws ResourceInitializationException
    *           if the locations could not be resolved.
    */
diff --git a/uimafit-core/src/main/java/org/apache/uima/fit/internal/ResourceManagerFactory.java b/uimafit-core/src/main/java/org/apache/uima/fit/internal/ResourceManagerFactory.java
index 4905564..b62dc86 100644
--- a/uimafit-core/src/main/java/org/apache/uima/fit/internal/ResourceManagerFactory.java
+++ b/uimafit-core/src/main/java/org/apache/uima/fit/internal/ResourceManagerFactory.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
@@ -27,16 +27,16 @@
 import org.apache.uima.impl.UimaVersion;
 import org.apache.uima.resource.ResourceInitializationException;
 import org.apache.uima.resource.ResourceManager;
-import org.springframework.util.ClassUtils;
+import org.apache.uima.resource.impl.ResourceManager_impl;
 
 /**
  * INTERNAL API - Helper functions for dealing with resource managers and classloading
- * 
- * This API is experimental and is very likely to be removed or changed in future versions. 
+ *
+ * This API is experimental and is very likely to be removed or changed in future versions.
  */
 public class ResourceManagerFactory {
   private static ResourceManagerCreator resourceManagerCreator = new DefaultResourceManagerCreator();
-  
+
   private ResourceManagerFactory() {
     // No instances
   }
@@ -45,7 +45,7 @@
   {
     return resourceManagerCreator.newResourceManager();
   }
-  
+
   /**
    * Mind that returning a singleton resource manager from {@link ResourceManagerFactory} is
    * generally a bad idea because it gets destroyed on a regular basis. For this reason, it is
@@ -56,15 +56,15 @@
           ResourceManagerCreator resourceManagerCreator) {
     ResourceManagerFactory.resourceManagerCreator = resourceManagerCreator;
   }
-  
+
   public static ResourceManagerCreator getResourceManagerCreator() {
     return resourceManagerCreator;
   }
-  
-  public static interface ResourceManagerCreator {
+
+  public interface ResourceManagerCreator {
     ResourceManager newResourceManager() throws ResourceInitializationException;
   }
-  
+
   public static class DefaultResourceManagerCreator implements ResourceManagerCreator {
     @Override
     public ResourceManager newResourceManager() throws ResourceInitializationException {
@@ -77,27 +77,35 @@
           // See https://issues.apache.org/jira/browse/UIMA-5056
           return ((UimaContextAdmin) activeContext).getResourceManager();
         }
-        else {
-          // If there is no UIMA context, then we create a new resource manager
-          // UIMA core still does not fall back to the context classloader in all cases.
-          // This was the default behavior until uimaFIT 2.2.0.
-          ResourceManager resMgr = UIMAFramework.newDefaultResourceManager();
-          
-          // Since UIMA Core version 2.10.3 and 3.0.1 the thread context classloader is taken
-          // into account by the core framework. Thus, we no longer have to explicitly set a
-          // classloader these or more recent versions. (cf. UIMA-5802)
-          short maj = UimaVersion.getMajorVersion();
-          short min = UimaVersion.getMinorVersion();
-          short rev = UimaVersion.getBuildRevision();
-          boolean uimaCoreIgnoresContextClassloader = 
-                  (maj == 2 && (min < 10 || (min == 10 && rev < 3))) || // version < 2.10.3
-                  (maj == 3 && ((min == 0 && rev < 1)));                // version < 3.0.1
-          if (uimaCoreIgnoresContextClassloader) {
-            resMgr.setExtensionClassPath(ClassUtils.getDefaultClassLoader(), "", true);
-          }
-          
-          return resMgr;
+
+        // If there is no UIMA context, then we create a new resource manager
+        // UIMA core still does not fall back to the context classloader in all cases.
+        // This was the default behavior until uimaFIT 2.2.0.
+        ResourceManager resMgr;
+        if (Thread.currentThread().getContextClassLoader() != null) {
+          // If the context classloader is set, then we want the resource manager to fallb
+          // back to it. However, it may not reliably do that that unless we explictly pass
+          // null here. See. UIMA-6239.
+          resMgr = new ResourceManager_impl(null);
         }
+        else {
+          resMgr = UIMAFramework.newDefaultResourceManager();
+        }
+
+        // Since UIMA Core version 2.10.3 and 3.0.1 the thread context classloader is taken
+        // into account by the core framework. Thus, we no longer have to explicitly set a
+        // classloader these or more recent versions. (cf. UIMA-5802)
+        short maj = UimaVersion.getMajorVersion();
+        short min = UimaVersion.getMinorVersion();
+        short rev = UimaVersion.getBuildRevision();
+        boolean uimaCoreIgnoresContextClassloader =
+                (maj == 2 && (min < 10 || (min == 10 && rev < 3))) || // version < 2.10.3
+                (maj == 3 && ((min == 0 && rev < 1)));                // version < 3.0.1
+        if (uimaCoreIgnoresContextClassloader) {
+          resMgr.setExtensionClassPath(ClassLoaderUtils.findClassloader(), "", true);
+        }
+
+        return resMgr;
       }
       catch (MalformedURLException e) {
         throw new ResourceInitializationException(e);
diff --git a/uimafit-core/src/main/java/org/apache/uima/fit/validation/CasValidationCheck.java b/uimafit-core/src/main/java/org/apache/uima/fit/validation/CasValidationCheck.java
new file mode 100644
index 0000000..c16f96e
--- /dev/null
+++ b/uimafit-core/src/main/java/org/apache/uima/fit/validation/CasValidationCheck.java
@@ -0,0 +1,44 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.uima.fit.validation;
+
+import java.util.List;
+
+import org.apache.uima.cas.CAS;
+
+/**
+ * CAS validation check.
+ * <p>
+ * <b>Note:</b> Implementations of this class are typically singletons which are obtained through
+ * the Java Service Locator mechanism. This means that the implementations must be stateless to
+ * ensure that they can be used by multiple threads concurrently.
+ */
+@FunctionalInterface
+public interface CasValidationCheck extends ValidationCheck {
+  /**
+   * Apply this check to the given CAS.
+   * 
+   * @param cas
+   *          the CAS to check.
+   * @return the results of the check.
+   * @throws ValidationCheckException
+   *           if there was a problem performing the validation.
+   */
+  List<ValidationResult> validate(CAS cas) throws ValidationCheckException;
+}
diff --git a/uimafit-core/src/main/java/org/apache/uima/fit/validation/JCasValidationCheck.java b/uimafit-core/src/main/java/org/apache/uima/fit/validation/JCasValidationCheck.java
new file mode 100644
index 0000000..4fe123a
--- /dev/null
+++ b/uimafit-core/src/main/java/org/apache/uima/fit/validation/JCasValidationCheck.java
@@ -0,0 +1,44 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.uima.fit.validation;
+
+import java.util.List;
+
+import org.apache.uima.jcas.JCas;
+
+/**
+ * JCas validation check.
+ * <p>
+ * <b>Note:</b> Implementations of this class are typically singletons which are obtained through
+ * the Java Service Locator mechanism. This means that the implementations must be stateless to
+ * ensure that they can be used by multiple threads concurrently.
+ */
+@FunctionalInterface
+public interface JCasValidationCheck extends ValidationCheck {
+  /**
+   * Apply this check to the given CAS.
+   * 
+   * @param cas
+   *          the CAS to check.
+   * @return the results of the check.
+   * @throws ValidationCheckException
+   *           if there was a problem performing the validation.
+   */
+  List<ValidationResult> validate(JCas cas) throws ValidationCheckException;
+}
diff --git a/uimafit-core/src/main/java/org/apache/uima/fit/validation/ValidationCheck.java b/uimafit-core/src/main/java/org/apache/uima/fit/validation/ValidationCheck.java
new file mode 100644
index 0000000..26ac388
--- /dev/null
+++ b/uimafit-core/src/main/java/org/apache/uima/fit/validation/ValidationCheck.java
@@ -0,0 +1,48 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.uima.fit.validation;
+
+/**
+ * Interface identifying validation checks that can be located via the Java Service Locator
+ * mechanism.
+ */
+public interface ValidationCheck {
+  
+  /**
+   * Fail the check with the given message.
+   * 
+   * @param aMessage the failure message.
+   * @throws ValidationCheckFailedException an exception carrying the failure message.
+   */
+  default void fail(String aMessage) throws ValidationCheckFailedException
+  {
+    throw new ValidationCheckFailedException(aMessage);
+  }
+
+  /**
+   * Skip the check with the given reason.
+   * 
+   * @param aMessage the skip reason.
+   * @throws ValidationCheckSkippedException an exception carrying the failure message.
+   */
+  default void skip(String aMessage) throws ValidationCheckSkippedException
+  {
+    throw new ValidationCheckSkippedException(aMessage);
+  }
+}
diff --git a/uimafit-core/src/main/java/org/apache/uima/fit/validation/ValidationCheckException.java b/uimafit-core/src/main/java/org/apache/uima/fit/validation/ValidationCheckException.java
new file mode 100644
index 0000000..c9b6b9b
--- /dev/null
+++ b/uimafit-core/src/main/java/org/apache/uima/fit/validation/ValidationCheckException.java
@@ -0,0 +1,48 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.uima.fit.validation;
+
+/**
+ * Exception by a particular validation check. These exceptions should not abort the validation
+ * but rather be rendered as results for the particular check.
+ */
+public abstract class ValidationCheckException extends ValidationException {
+  private static final long serialVersionUID = -5685006985598972648L;
+
+  public ValidationCheckException() {
+    super();
+  }
+
+  public ValidationCheckException(String aMessage, Throwable aCause, boolean aEnableSuppression,
+          boolean aWritableStackTrace) {
+    super(aMessage, aCause, aEnableSuppression, aWritableStackTrace);
+  }
+
+  public ValidationCheckException(String aMessage, Throwable aCause) {
+    super(aMessage, aCause);
+  }
+
+  public ValidationCheckException(String aMessage) {
+    super(aMessage);
+  }
+
+  public ValidationCheckException(Throwable aCause) {
+    super(aCause);
+  }
+}
diff --git a/uimafit-core/src/main/java/org/apache/uima/fit/validation/ValidationCheckFailedException.java b/uimafit-core/src/main/java/org/apache/uima/fit/validation/ValidationCheckFailedException.java
new file mode 100644
index 0000000..0c7a7cd
--- /dev/null
+++ b/uimafit-core/src/main/java/org/apache/uima/fit/validation/ValidationCheckFailedException.java
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.uima.fit.validation;
+
+/**
+ * Fail the current check.
+ */
+public class ValidationCheckFailedException extends ValidationCheckException {
+  private static final long serialVersionUID = 7135158265431902494L;
+
+  public ValidationCheckFailedException() {
+    super();
+  }
+
+  public ValidationCheckFailedException(String aMessage, Throwable aCause, boolean aEnableSuppression,
+          boolean aWritableStackTrace) {
+    super(aMessage, aCause, aEnableSuppression, aWritableStackTrace);
+  }
+
+  public ValidationCheckFailedException(String aMessage, Throwable aCause) {
+    super(aMessage, aCause);
+  }
+
+  public ValidationCheckFailedException(String aMessage) {
+    super(aMessage);
+  }
+
+  public ValidationCheckFailedException(Throwable aCause) {
+    super(aCause);
+  }
+}
diff --git a/uimafit-core/src/main/java/org/apache/uima/fit/validation/ValidationCheckSkippedException.java b/uimafit-core/src/main/java/org/apache/uima/fit/validation/ValidationCheckSkippedException.java
new file mode 100644
index 0000000..540d184
--- /dev/null
+++ b/uimafit-core/src/main/java/org/apache/uima/fit/validation/ValidationCheckSkippedException.java
@@ -0,0 +1,38 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.uima.fit.validation;
+
+/**
+ * Skip the current check.
+ */
+public class ValidationCheckSkippedException extends ValidationCheckException {
+  private static final long serialVersionUID = 486560734913688851L;
+
+  public ValidationCheckSkippedException() {
+    super();
+  }
+
+  public ValidationCheckSkippedException(String aMessage, Throwable aCause) {
+    super(aMessage, aCause);
+  }
+
+  public ValidationCheckSkippedException(String aMessage) {
+    super(aMessage);
+  }
+}
diff --git a/uimafit-core/src/main/java/org/apache/uima/fit/validation/ValidationException.java b/uimafit-core/src/main/java/org/apache/uima/fit/validation/ValidationException.java
new file mode 100644
index 0000000..1dad48e
--- /dev/null
+++ b/uimafit-core/src/main/java/org/apache/uima/fit/validation/ValidationException.java
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.uima.fit.validation;
+
+/**
+ * Exception generated while validating a CAS.
+ */
+public class ValidationException extends Exception {
+  private static final long serialVersionUID = 3797439484561980758L;
+
+  public ValidationException() {
+    super();
+  }
+
+  public ValidationException(String aMessage, Throwable aCause, boolean aEnableSuppression,
+          boolean aWritableStackTrace) {
+    super(aMessage, aCause, aEnableSuppression, aWritableStackTrace);
+  }
+
+  public ValidationException(String aMessage, Throwable aCause) {
+    super(aMessage, aCause);
+  }
+
+  public ValidationException(String aMessage) {
+    super(aMessage);
+  }
+
+  public ValidationException(Throwable aCause) {
+    super(aCause);
+  }
+}
diff --git a/uimafit-core/src/main/java/org/apache/uima/fit/validation/ValidationResult.java b/uimafit-core/src/main/java/org/apache/uima/fit/validation/ValidationResult.java
new file mode 100644
index 0000000..9951956
--- /dev/null
+++ b/uimafit-core/src/main/java/org/apache/uima/fit/validation/ValidationResult.java
@@ -0,0 +1,121 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS 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.fit.validation;
+
+import static java.lang.String.format;
+import static org.apache.uima.fit.validation.ValidationResult.Severity.DEBUG;
+import static org.apache.uima.fit.validation.ValidationResult.Severity.ERROR;
+import static org.apache.uima.fit.validation.ValidationResult.Severity.INFO;
+import static org.apache.uima.fit.validation.ValidationResult.Severity.TRACE;
+import static org.apache.uima.fit.validation.ValidationResult.Severity.WARN;
+
+import java.util.Objects;
+
+/**
+ * Individual result from a CAS validation check.
+ */
+public class ValidationResult {
+
+  public enum Severity {
+
+    ERROR(5), WARN(4), INFO(3), DEBUG(2), TRACE(1);
+
+    private final int level;
+
+    private Severity(int level) {
+      this.level = level;
+    }
+
+    public boolean isEquallyOrMoreSevereThan(Severity other) {
+      return level >= other.level;
+    }
+  }
+
+  private final Severity severity;
+  private final String source;
+  private final String message;
+
+  public ValidationResult(Object source, Severity severity, String format, Object... args) {
+
+    super();
+
+    if (source instanceof String) {
+      this.source = (String) source;
+    } else if (source instanceof Class) {
+      this.source = ((Class<?>) source).getSimpleName();
+    } else {
+      this.source = source != null ? source.getClass().getSimpleName() : null;
+    }
+
+    this.severity = severity;
+    message = format(format, args);
+  }
+
+  public String getSource() {
+    return source;
+  }
+
+  public String getMessage() {
+    return message;
+  }
+
+  public Severity getSeverity() {
+    return severity;
+  }
+
+  public static ValidationResult error(Object source, String format, Object... args) {
+    return new ValidationResult(source, ERROR, format, args);
+  }
+
+  public static ValidationResult warn(Object source, String format, Object... args) {
+    return new ValidationResult(source, WARN, format, args);
+  }
+
+  public static ValidationResult info(Object source, String format, Object... args) {
+    return new ValidationResult(source, INFO, format, args);
+  }
+
+  public static ValidationResult debug(Object source, String format, Object... args) {
+    return new ValidationResult(source, DEBUG, format, args);
+  }
+
+  public static ValidationResult trace(Object source, String format, Object... args) {
+    return new ValidationResult(source, TRACE, format, args);
+  }
+
+  @Override
+  public boolean equals(final Object other) {
+    if (!(other instanceof ValidationResult)) {
+      return false;
+    }
+    ValidationResult castOther = (ValidationResult) other;
+    return Objects.equals(severity, castOther.severity) && Objects.equals(source, castOther.source)
+            && Objects.equals(message, castOther.message);
+  }
+
+  @Override
+  public int hashCode() {
+    return Objects.hash(severity, source, message);
+  }
+
+  @Override
+  public String toString() {
+    return String.format("[%s] %s", source != null ? source : "<unknown>", message);
+  }
+}
diff --git a/uimafit-core/src/main/java/org/apache/uima/fit/validation/ValidationSummary.java b/uimafit-core/src/main/java/org/apache/uima/fit/validation/ValidationSummary.java
new file mode 100644
index 0000000..75ff05d
--- /dev/null
+++ b/uimafit-core/src/main/java/org/apache/uima/fit/validation/ValidationSummary.java
@@ -0,0 +1,54 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.uima.fit.validation;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import org.apache.uima.fit.validation.ValidationResult.Severity;
+
+/**
+ * Container for {@link ValidationResult CasValidationResults}.
+ */
+public class ValidationSummary {
+
+  private List<ValidationResult> results;
+
+  public ValidationSummary() {
+    results = new ArrayList<>();
+  }
+
+  public void add(ValidationResult result) {
+    results.add(result);
+  }
+
+  public void addAll(Collection<ValidationResult> moreResults) {
+    results.addAll(moreResults);
+  }
+
+  public List<ValidationResult> getResults() {
+    return results;
+  }
+
+  public boolean containsResultsEquallyOrMoreSevereThan(Severity threshold) {
+    return results.stream()
+            .anyMatch(result -> result.getSeverity().isEquallyOrMoreSevereThan(threshold));
+  }
+}
diff --git a/uimafit-core/src/main/java/org/apache/uima/fit/validation/Validator.java b/uimafit-core/src/main/java/org/apache/uima/fit/validation/Validator.java
new file mode 100644
index 0000000..ca69888
--- /dev/null
+++ b/uimafit-core/src/main/java/org/apache/uima/fit/validation/Validator.java
@@ -0,0 +1,263 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS 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.fit.validation;
+
+import static java.util.Arrays.stream;
+import static java.util.ServiceLoader.load;
+import static java.util.stream.StreamSupport.stream;
+
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.LinkedHashSet;
+import java.util.Set;
+import java.util.regex.Pattern;
+
+import org.apache.uima.cas.CAS;
+import org.apache.uima.cas.CASException;
+import org.apache.uima.jcas.JCas;
+
+/**
+ * Validate a (J)CAS.
+ */
+public class Validator {
+  private Collection<ValidationCheck> checks;
+
+  public Validator(Collection<ValidationCheck> checks) {
+    this.checks = checks;
+  }
+
+  public ValidationSummary check(JCas aJCas) throws ValidationException {
+    ValidationSummary summary = new ValidationSummary();
+
+    for (ValidationCheck check : checks) {
+      try {
+        if (check instanceof CasValidationCheck) {
+          summary.addAll(((CasValidationCheck) check).validate(aJCas.getCas()));
+        } else if (check instanceof JCasValidationCheck) {
+          summary.addAll(((JCasValidationCheck) check).validate(aJCas));
+        } else {
+          throw new IllegalArgumentException(
+                  "Unknown ValidationCheck type: [" + check.getClass().getName() + "]");
+        }
+      } catch (ValidationCheckSkippedException e) {
+        summary.add(ValidationResult.info(check, "Skipped: %s", e.getMessage()));
+      } catch (ValidationCheckException e) {
+        summary.add(ValidationResult.error(check, "%s", e.getMessage()));
+      }
+    }
+
+    return summary;
+  }
+  
+  public ValidationSummary check(CAS cas) throws ValidationException {
+    ValidationSummary summary = new ValidationSummary();
+
+    for (ValidationCheck check : checks) {
+      try {
+        if (check instanceof CasValidationCheck) {
+          summary.addAll(((CasValidationCheck) check).validate(cas));
+        } else if (check instanceof JCasValidationCheck) {
+          try {
+            summary.addAll(((JCasValidationCheck) check).validate(cas.getJCas()));
+          } catch (CASException e) {
+            throw new ValidationException(e);
+          }
+        } else {
+          throw new IllegalArgumentException(
+                  "Unknown ValidationCheck type: [" + check.getClass().getName() + "]");
+        }
+      } catch (ValidationCheckSkippedException e) {
+        summary.add(ValidationResult.info(check, "Skipped: %s", e.getMessage()));
+      } catch (ValidationCheckException e) {
+        summary.add(ValidationResult.error(check, "%s", e.getMessage()));
+      }
+    }
+
+    return summary;
+  }
+  
+  public Collection<ValidationCheck> getChecks() {
+    return checks;
+  }
+
+  public static class Builder {
+
+    private final Set<ValidationCheck> checks = new LinkedHashSet<>();
+    private final Set<Pattern> includePatterns = new HashSet<>();
+    private final Set<Class<?>> includeTypes = new HashSet<>();
+    private final Set<Pattern> excludePatterns = new HashSet<>();
+    private final Set<Class<?>> excludeTypes = new HashSet<>();
+    private boolean skipAutoDetection = false;
+
+    /**
+     * Add the given check instance to the validator. This allows even adding checks which are not
+     * available via the Java Service Locator, which take parameters or which are otherwise stateful
+     * (assuming that the resulting validator is not shared between threads).
+     * <p>
+     * <b>Note:</b> Includes/excludes do also apply do checks added via this method.
+     * 
+     * @param check
+     *          a check instance to use.
+     */
+    public Validator.Builder withCheck(CasValidationCheck check) {
+      checks.add(check);
+      return this;
+    }
+
+    /**
+     * Disable auto-detection of checks.
+     */
+    public Validator.Builder withoutAutoDetectedChecks() {
+      skipAutoDetection = true;
+      return this;
+    }
+
+    /**
+     * Enable auto-detection of checks (the default behavior).
+     */
+    public Validator.Builder withAutoDetectedChecks() {
+      skipAutoDetection = false;
+      return this;
+    }
+
+    /**
+     * Skip any checks with the given names. Subtypes of the given classes are not skipped.
+     * <p>
+     * <b>Note:</b> Excludes are applied after includes.
+     * 
+     * @param className
+     *          names of check classes to be excluded.
+     */
+    public Validator.Builder excludingByName(String... className) {
+      stream(className)
+          .map(Pattern::quote)
+          .map(Pattern::compile)
+          .forEach(excludePatterns::add);
+      return this;
+    }
+
+    /**
+     * Skip any checks with names matching the given regular expressions.
+     * <p>
+     * <b>Note:</b> Excludes are applied after includes.
+     * 
+     * @param patterns
+     *          regular expressions matching check class names to be excluded.
+     */
+    public Validator.Builder excludingByPattern(String... patterns) {
+      stream(patterns)
+          .map(Pattern::compile)
+          .forEach(excludePatterns::add);
+      return this;
+    }
+
+    /**
+     * Skips any checks of the given types (includes checks that are subclasses or implementations
+     * of the given types).
+     * <p>
+     * <b>Note:</b> Excludes are applied after includes.
+     * 
+     * @param types
+     *          check type names to be excluded.
+     */
+    public Validator.Builder excludingByType(Class<?>... types) {
+      stream(types).forEach(excludeTypes::add);
+      return this;
+    }
+    
+    /**
+     * Retain only checks with the given names. Subtypes of the given classes are not retained.
+     * <p>
+     * <b>Note:</b> Excludes are applied after includes.
+     * 
+     * @param className
+     *          names of check classes to be included.
+     */
+    public Validator.Builder includingByName(String... className) {
+      stream(className)
+          .map(Pattern::quote)
+          .map(Pattern::compile)
+          .forEach(includePatterns::add);
+      return this;
+    }
+
+    /**
+     * Retain any checks with names matching the given regular expressions.
+     * <p>
+     * <b>Note:</b> Excludes are applied after includes.
+     * 
+     * @param patterns
+     *          regular expressions matching check class names to be included.
+     */
+    public Validator.Builder includingByPattern(String... patterns) {
+      stream(patterns)
+          .map(Pattern::compile)
+          .forEach(includePatterns::add);
+      return this;
+    }
+
+    /**
+     * Retain any checks of the given types (includes checks that are subclasses or implementations
+     * of the given types).
+     * <p>
+     * <b>Note:</b> Excludes are applied after includes.
+     * 
+     * @param types
+     *          check type names to be included.
+     */
+    public Validator.Builder includingByType(Class<?>... types) {
+      stream(types).forEach(includeTypes::add);
+      return this;
+    }
+
+    private Validator.Builder autoDetectChecks() {
+      stream(load(ValidationCheck.class).spliterator(), false)
+              .forEachOrdered(checks::add);
+      return this;
+    }
+
+    public Validator build() {
+      if (!skipAutoDetection) {
+        autoDetectChecks();
+      }
+      
+      if (!includePatterns.isEmpty()) {
+        checks.removeIf(check -> includePatterns.stream()
+                .noneMatch(p -> p.matcher(check.getClass().getName()).matches()));
+      }
+      
+      if (!includeTypes.isEmpty()) {
+        checks.removeIf(check -> includeTypes.stream()
+                .noneMatch(t -> t.isAssignableFrom(check.getClass())));
+      }
+      
+      if (!excludePatterns.isEmpty()) {
+        checks.removeIf(check -> excludePatterns.stream()
+                .anyMatch(p -> p.matcher(check.getClass().getName()).matches()));
+      }
+      
+      if (!excludeTypes.isEmpty()) {
+        checks.removeIf(check -> excludeTypes.stream()
+                .anyMatch(t -> t.isAssignableFrom(check.getClass())));
+      }
+
+      return new Validator(checks);
+    }
+  }
+}
diff --git a/uimafit-core/src/test/java/org/apache/uima/fit/component/initialize/ConfigurationParameterInitializerTest.java b/uimafit-core/src/test/java/org/apache/uima/fit/component/initialize/ConfigurationParameterInitializerTest.java
index 8de2de4..fc7d86d 100644
--- a/uimafit-core/src/test/java/org/apache/uima/fit/component/initialize/ConfigurationParameterInitializerTest.java
+++ b/uimafit-core/src/test/java/org/apache/uima/fit/component/initialize/ConfigurationParameterInitializerTest.java
@@ -425,7 +425,7 @@
     
     assertThat(target.customFromString)
             .extracting(CustomClassWithStringConstructor::getValue)
-            .containsExactly("test");
+            .isEqualTo("test");
     assertThat(target.customArrayFromString)
             .extracting(CustomClassWithStringConstructor::getValue)
             .containsExactly("test1", "test2", "test3");
diff --git a/uimafit-core/src/test/java/org/apache/uima/fit/validation/CasValidatorBuilderTest.java b/uimafit-core/src/test/java/org/apache/uima/fit/validation/CasValidatorBuilderTest.java
new file mode 100644
index 0000000..1533fa4
--- /dev/null
+++ b/uimafit-core/src/test/java/org/apache/uima/fit/validation/CasValidatorBuilderTest.java
@@ -0,0 +1,60 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.uima.fit.validation;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import org.apache.uima.fit.validation.checks.EndAfterBeginCheckForTesting;
+import org.apache.uima.fit.validation.checks.EndSameAsBeginCheckForTesting;
+import org.junit.Before;
+import org.junit.Test;
+
+public class CasValidatorBuilderTest {
+
+  private Validator.Builder sut;
+
+  @Before
+  public void setup() {
+    sut = new Validator.Builder();
+  }
+
+  @Test
+  @SuppressWarnings({ "unchecked", "rawtypes" })
+  public void thatExcludeByNameWorks() {
+    sut.excludingByName(EndAfterBeginCheckForTesting.class.getName());
+
+    Validator validator = sut.build();
+
+    assertThat(validator.getChecks())
+            .extracting(Object::getClass)
+            .containsExactly((Class) EndSameAsBeginCheckForTesting.class);
+  }
+
+  @Test
+  @SuppressWarnings({ "unchecked", "rawtypes" })
+  public void thatExcludeByTypeWorks() {
+    sut.excludingByType(EndAfterBeginCheckForTesting.class);
+
+    Validator validator = sut.build();
+
+    assertThat(validator.getChecks())
+            .extracting(Object::getClass)
+            .containsExactly((Class) EndSameAsBeginCheckForTesting.class);
+  }
+}
diff --git a/uimafit-core/src/test/java/org/apache/uima/fit/validation/checks/EndAfterBeginCheckForTesting.java b/uimafit-core/src/test/java/org/apache/uima/fit/validation/checks/EndAfterBeginCheckForTesting.java
new file mode 100644
index 0000000..142bca9
--- /dev/null
+++ b/uimafit-core/src/test/java/org/apache/uima/fit/validation/checks/EndAfterBeginCheckForTesting.java
@@ -0,0 +1,51 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.uima.fit.validation.checks;
+
+import static org.apache.uima.fit.util.CasUtil.selectAll;
+import static org.apache.uima.fit.validation.ValidationResult.error;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.uima.cas.CAS;
+import org.apache.uima.cas.text.AnnotationFS;
+import org.apache.uima.fit.validation.CasValidationCheck;
+import org.apache.uima.fit.validation.ValidationResult;
+
+/**
+ * Simple CAS validation check ensuring that annotations do not end before they start.
+ * <p>
+ * <b>Note:</b> This is used for testing in uimaFIT. It is not meant for general use!
+ */
+public class EndAfterBeginCheckForTesting implements CasValidationCheck {
+  @Override
+  public List<ValidationResult> validate(CAS cas) {
+    List<ValidationResult> results = new ArrayList<>();
+
+    for (AnnotationFS anno : selectAll(cas)) {
+      if (anno.getEnd() < anno.getBegin()) {
+        results.add(error(this, "%s ends (%d) before it begins (%d)", anno.getType().getShortName(),
+                anno.getEnd(), anno.getBegin()));
+      }
+    }
+
+    return results;
+  }
+}
diff --git a/uimafit-core/src/test/java/org/apache/uima/fit/validation/checks/EndSameAsBeginCheckForTesting.java b/uimafit-core/src/test/java/org/apache/uima/fit/validation/checks/EndSameAsBeginCheckForTesting.java
new file mode 100644
index 0000000..c8abfe5
--- /dev/null
+++ b/uimafit-core/src/test/java/org/apache/uima/fit/validation/checks/EndSameAsBeginCheckForTesting.java
@@ -0,0 +1,51 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.uima.fit.validation.checks;
+
+import static org.apache.uima.fit.util.JCasUtil.select;
+import static org.apache.uima.fit.validation.ValidationResult.error;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.uima.fit.validation.ValidationResult;
+import org.apache.uima.fit.validation.JCasValidationCheck;
+import org.apache.uima.jcas.JCas;
+import org.apache.uima.jcas.tcas.Annotation;
+
+/**
+ * Simple JCas validation check ensuring that annotations do not have the same start/end position.
+ * <p>
+ * <b>Note:</b> This is used for testing in uimaFIT. It is not meant for general use!
+ */
+public class EndSameAsBeginCheckForTesting implements JCasValidationCheck {
+  @Override
+  public List<ValidationResult> validate(JCas aJCas) {
+    List<ValidationResult> results = new ArrayList<>();
+
+    for (Annotation anno : select(aJCas, Annotation.class)) {
+      if (anno.getEnd() == anno.getBegin()) {
+        results.add(error(this, "%s starts and ends at the same position (%d)",
+                anno.getType().getShortName(), anno.getBegin()));
+      }
+    }
+
+    return results;
+  }
+}
diff --git a/uimafit-core/src/test/resources/META-INF/services/org.apache.uima.fit.validation.ValidationCheck b/uimafit-core/src/test/resources/META-INF/services/org.apache.uima.fit.validation.ValidationCheck
new file mode 100644
index 0000000..f52edea
--- /dev/null
+++ b/uimafit-core/src/test/resources/META-INF/services/org.apache.uima.fit.validation.ValidationCheck
@@ -0,0 +1,2 @@
+org.apache.uima.fit.validation.checks.EndAfterBeginCheckForTesting
+org.apache.uima.fit.validation.checks.EndSameAsBeginCheckForTesting
diff --git a/uimafit-doc/pom.xml b/uimafit-doc/pom.xml
new file mode 100644
index 0000000..e044c7a
--- /dev/null
+++ b/uimafit-doc/pom.xml
@@ -0,0 +1,150 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements. See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership. The ASF licenses this file
+  to you under the Apache License, Version 2.0 (the
+  "License"); you may not use this file except in compliance
+  with the License. You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing,
+  software distributed under the License is distributed on an
+  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  KIND, either express or implied. See the License for the
+  specific language governing permissions and limitations
+  under the License.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <groupId>org.apache.uima</groupId>
+    <artifactId>uimafit-parent</artifactId>
+    <version>2.5.1-SNAPSHOT</version>
+    <relativePath>../uimafit-parent</relativePath>
+  </parent>
+  <artifactId>uimafit-doc</artifactId>
+  <name>Apache UIMA uimaFIT - Documentation</name>
+  <packaging>pom</packaging>
+  <properties>
+    <asciidoctor.plugin.version>1.6.0</asciidoctor.plugin.version>
+    <asciidoctor.version>1.6.2</asciidoctor.version>
+    <asciidoctor.pdf.version>1.5.3</asciidoctor.pdf.version>
+    <maven.deploy.skip>true</maven.deploy.skip>
+  </properties>
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.asciidoctor</groupId>
+        <artifactId>asciidoctor-maven-plugin</artifactId>
+        <version>${asciidoctor.plugin.version}</version>
+        <executions>
+          <execution>
+            <id>user-guide-html</id>
+            <phase>generate-resources</phase>
+            <goals>
+              <goal>process-asciidoc</goal>
+            </goals>
+            <configuration>
+              <backend>html5</backend>
+              <attributes>
+                <toc>left</toc>
+              </attributes>
+            </configuration>
+          </execution>
+          <execution>
+            <id>user-guide-pdf</id>
+            <phase>generate-resources</phase>
+            <goals>
+              <goal>process-asciidoc</goal>
+            </goals>
+            <configuration>
+              <backend>pdf</backend>
+              <attributes>
+                <toc>preamble</toc>
+              </attributes>
+            </configuration>
+          </execution>
+        </executions>
+        <configuration>
+          <sourceDocumentName>tools.uimafit.book.adoc</sourceDocumentName>
+          <outputDirectory>${project.build.directory}/site/d</outputDirectory>
+          <attributes>
+            <doctype>book</doctype>
+            <toclevels>8</toclevels>
+            <sectanchors>true</sectanchors>
+            <docinfo1>true</docinfo1>
+            <project-version>${project.version}</project-version>
+            <revnumber>${project.version}</revnumber>
+            <product-name>Apache UIMA uimaFIT</product-name>
+            <product-website-url>https://uima.apache.org/uimafit.html</product-website-url>
+            <icons>font</icons>
+          </attributes>
+          <requires>
+            <require>asciidoctor-pdf</require>
+          </requires>
+        </configuration>
+        <dependencies>
+          <dependency>
+            <groupId>org.asciidoctor</groupId>
+            <artifactId>asciidoctorj</artifactId>
+            <version>${asciidoctor.version}</version>
+          </dependency>
+          <dependency>
+            <groupId>org.asciidoctor</groupId>
+            <artifactId>asciidoctorj-pdf</artifactId>
+            <version>${asciidoctor.pdf.version}</version>
+          </dependency>
+        </dependencies>
+      </plugin>
+    </plugins>
+  </build>
+  <profiles>
+    <profile>
+      <id>m2e</id>
+      <activation>
+        <property>
+          <name>m2e.version</name>
+        </property>
+      </activation>
+      <build>
+        <pluginManagement>
+          <plugins>
+            <!--
+              - This plugin's configuration is used to store Eclipse m2e settings only.
+              - It has no influence on the Maven build itself.
+            -->
+            <plugin>
+              <groupId>org.eclipse.m2e</groupId>
+              <artifactId>lifecycle-mapping</artifactId>
+              <version>1.0.0</version>
+              <configuration>
+                <lifecycleMappingMetadata>
+                  <pluginExecutions>
+                    <pluginExecution>
+                      <pluginExecutionFilter>
+                        <groupId>org.asciidoctor</groupId>
+                        <artifactId>asciidoctor-maven-plugin</artifactId>
+                        <versionRange>[1.0,)</versionRange>
+                        <goals>
+                          <goal>process-asciidoc</goal>
+                        </goals>
+                      </pluginExecutionFilter>
+                      <action>
+                        <execute />
+                      </action>
+                    </pluginExecution>
+                  </pluginExecutions>
+                </lifecycleMappingMetadata>
+              </configuration>
+            </plugin>
+          </plugins>
+        </pluginManagement>
+      </build>
+    </profile>
+  </profiles>  
+</project>
\ No newline at end of file
diff --git a/uimafit-doc/src/main/asciidoc/common_book_info.adoc b/uimafit-doc/src/main/asciidoc/common_book_info.adoc
new file mode 100644
index 0000000..14737ee
--- /dev/null
+++ b/uimafit-doc/src/main/asciidoc/common_book_info.adoc
@@ -0,0 +1,38 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+[discrete]
+=== License and Disclaimer
+
+The ASF licenses this documentation to you under the Apache License, Version 2.0 (the "License"); 
+you may not use this documentation except in compliance with the License.  You may obtain a copy of
+the License at
+
+[.text-center]
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, this documentation and its contents are
+distributed under the License on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
+either express or implied.  See the License for the specific language governing permissions and
+limitations under the License.
+
+[discrete]
+=== Trademarks
+
+All terms mentioned in the text that are known to be trademarks or service marks have been 
+appropriately capitalized.  Use of such terms in this book should not be regarded as affecting the
+validity of the the trademark or service mark.
\ No newline at end of file
diff --git a/uimafit-doc/src/main/asciidoc/tools.uimafit.book.adoc b/uimafit-doc/src/main/asciidoc/tools.uimafit.book.adoc
new file mode 100644
index 0000000..2320da4
--- /dev/null
+++ b/uimafit-doc/src/main/asciidoc/tools.uimafit.book.adoc
@@ -0,0 +1,50 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+= Apache uimaFIT™
+:Author: Apache UIMA™ Development Community
+:toc-title: User Guide
+
+The document is a manual for users of uimaFIT, a friendly API to the Apache UIMA framework.
+
+include::common_book_info.adoc[leveloffset=+1]
+
+include::tools.uimafit.introduction.adoc[leveloffset=+1]
+
+include::tools.uimafit.gettingstarted.adoc[leveloffset=+1]
+
+include::tools.uimafit.pipelines.adoc[leveloffset=+1]
+
+include::tools.uimafit.testing.adoc[leveloffset=+1]
+
+include::tools.uimafit.validation.adoc[leveloffset=+1]
+
+include::tools.uimafit.experiments.adoc[leveloffset=+1]
+
+include::tools.uimafit.casutil.adoc[leveloffset=+1]
+
+include::tools.uimafit.configurationparameters.adoc[leveloffset=+1]
+
+include::tools.uimafit.externalresources.adoc[leveloffset=+1]
+
+include::tools.uimafit.typesystem.adoc[leveloffset=+1]
+
+include::tools.uimafit.packaging.adoc[leveloffset=+1]
+
+include::tools.uimafit.maven.adoc[leveloffset=+1]
+
+include::tools.uimafit.migration.adoc[leveloffset=+1]
diff --git a/uimafit-doc/src/main/asciidoc/tools.uimafit.casutil.adoc b/uimafit-doc/src/main/asciidoc/tools.uimafit.casutil.adoc
new file mode 100644
index 0000000..ad9d4cb
--- /dev/null
+++ b/uimafit-doc/src/main/asciidoc/tools.uimafit.casutil.adoc
@@ -0,0 +1,83 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+[[_ugr.tools.uimafit.casutil]]
+= CAS Utilities
+
+uimaFIT facilitates working with the CAS and JCas by offering various convenient methods for accessing and navigating annotations and feature structures.
+Additionally, the the convenience methods for JCas access are fully type-safe and return the JCas type or a collection of the JCas type which you wanted to access.
+
+== Access methods
+
+uimaFIT supports the following convenience methods for accessing CAS and JCas structures.
+All methods respect the UIMA index definitions and return annotations or feature structures in the order defined by the indexes.
+Unless the default UIMA index for annotations has been overwritten, annotations are returned sorted by begin (increasing) and end (decreasing).
+
+* `select(cas, type)` - fetch all annotations of the given type from the CAS/JCas. Variants of this method also exist to fetch annotations from a [type]``FSList`` or [type]``FSArray``.
+* `selectAll(cas)` - fetch all annotations from the CAS or fetch all feature structures from the JCas.
+* ``selectBetween(type, annotation1, annotation2)``* - fetch all annotations between the given two annotations.
+* ``selectCovered(type, annotation)``* - fetch all annotations covered by the given annotation. If this operation is used intensively, `indexCovered(...)` should be used to pre-calculate annotation covering information.
+* `selectCovering(type, annotation)*` - fetch all annotations covering the given annotation. If this operation is used intensively, `indexCovering(...)` should be used to pre-calculate annotation covering information.
+* `selectByIndex(cas, type, n)` - fetch the n-th feature structure of the given type.
+* `selectSingle(cas, type)` - fetch the single feature structure of the given type. An exception is thrown if there is not exactly one feature structure of the type. 
+* `selectSingleRelative(type, annotation, n)`* - fetch a single annotation relative to the given annotation. A positive [parameter]``n`` fetches the n-th annotation right of the specified annotation, while the a negative [parameter]``n`` fetches to the left.
+* `selectPreceding(type, annotation, n)`* - fetch the n annotations preceding the given annotation. If there are less then n preceding annotations, all preceding annotations are returned.
+* `selectFollowing(type, annotation, n)`* - fetch the n annotations following the given annotation. If there are less then n following annotations, all following annotations are returned.
+
+
+[NOTE]
+====
+For historical reasons, the method marked with * also exist in a version that accepts a CAS/JCas as the first argument.
+These may not work as expected when the annoation arguments provided to the method are from a different CAS/JCas/view.
+Also, for any method accepting two annotations, these should come from the same CAS/JCas/view.
+In future, the potentially problematic signatures may be deprecated, removed, or throw exeptions if these conditions are not met.
+====
+
+[NOTE]
+====
+You should expect the structures returned by these methods to be backed by the CAS/JCas contents.
+In particular, if you remove any feature structures from the CAS while iterating over these structures may cause failures.
+For this reason, you should also not hold on to these structures longer than necessary, as is the case for UIMA ``FSIterator``s as well.
+====
+
+Depending on whether one works with a CAS or JCas, the respective methods are available from the JCasUtil or CasUtil classes. 
+
+JCasUtil expect a JCas wrapper class for the [parameter]``type`` argument, e.g. `select(jcas, Token.class)` and return this type or a collection using this generic type.
+Any subtypes of the specified type are returned as well.
+CasUtil expects a UIMA [type]``Type`` instance.
+For conveniently getting these, CasUtil offers the methods `getType(CAS, Class<?>)` or `getType(CAS, String)` which fetch a type either by its JCas wrapper class or by its name.
+
+Unless annotations are specifically required, e.g.
+because begin/end offsets are required, the JCasUtil methods can be used to access any feature structure inheriting from [type]``TOP``, not only annotations.
+The CasUtil methods generally work only on annotations.
+Alternative methods ending in "FS" are provided for accessing arbitrary feature structures, e.g. ``selectFS``.
+
+Examples:
+
+[source,java]
+----
+// CAS version
+Type tokenType = CasUtil.getType(cas, "my.Token");
+for (AnnotationFS token : CasUtil.select(cas, tokenType)) {
+  ...
+}
+
+// JCas version
+for (Token token : JCasUtil.select(jcas, Token.class)) {
+  ...
+}
+----
\ No newline at end of file
diff --git a/uimafit-doc/src/main/asciidoc/tools.uimafit.configurationparameters.adoc b/uimafit-doc/src/main/asciidoc/tools.uimafit.configurationparameters.adoc
new file mode 100644
index 0000000..d36eb07
--- /dev/null
+++ b/uimafit-doc/src/main/asciidoc/tools.uimafit.configurationparameters.adoc
@@ -0,0 +1,141 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+[[_ugr.tools.uimafit.configurationparameters]]
+= Configuration Parameters
+
+uimaFIT defines the `@ConfigurationParameter` annotation which can be used to annotate the fields of an analysis engine or collection reader.
+The purpose of this annotation is twofold:
+
+* injection of parameters from the UIMA context into fields
+* declaration of parameter metadata (mandatory, default value, description) which can be used to generate XML descriptors
+
+In a regular UIMA component, parameters need to be manually extracted from the UIMA context, typically requiring a type cast. 
+
+[source,java]
+----
+class MyAnalysisEngine extends CasAnnotator_ImplBase {
+  public static final String PARAM_SOURCE_DIRECTORY = "sourceDirectory";
+  private File sourceDirectory;
+
+  public void initialize(UimaContext context) 
+      throws ResourceInitializationException {
+
+    sourceDirectory = new File((String) context.getConfigParameterValue(
+      PARAM_SOURCE_DIRECTORY));
+  }
+}
+----
+
+The component has no way to declare a default value or to declare if a parameter is optional or mandatory.
+In addition, any documentation needs to be maintained in !JavaDoc and in the XML descriptor for the component.
+
+With uimaFIT, all this information can be declared in the component using the [class]``@ConfigurationParameter`` annotation.
+
+.`@ConfigurationParameter` annotation
+[cols="1,1,1", frame="all", options="header"]
+|===
+| Parameter
+| Description
+| Default
+
+|name
+|parameter name
+|name of annotated field
+
+|description
+|description of the parameter
+|
+
+|mandatory
+|whether a non-null value must be specified 
+|true
+
+|defaultValue
+|the default value if no value is specified
+|
+|===
+
+[source,java]
+----
+class MyAnalysisEngine 
+    extends org.apache.uima.fit.component.CasAnnotator_ImplBase {
+
+  /**
+   * Directory to read the data from.
+   */
+  public static final String PARAM_SOURCE_DIRECTORY = "sourceDirectory";
+  @ConfigurationParameter(name=PARAM_SOURCE_DIRECTORY, defaultValue=".")
+  private File sourceDirectory;
+}
+----
+
+Note, that it is no longer necessary to implement the [method]``initialize()`` method.
+uimaFIT takes care of locating the parameter [parameter]``sourceDirectory`` in the UIMA context.
+It recognizes that the [class]``File`` class has a [class]``String`` constructor and uses that to instantiate a new [class]``File`` object from the parameter.
+A parameter is mandatory unless specified otherwise.
+If a mandatory parameter is not specified in the context, an exception is thrown.
+
+The `defaultValue` is used when generating an UIMA component description from the class.
+It should be pointed out in particular, that uimaFIT does not make use of the default value when injecting parameters into fields.
+For this reason, it is possible to have a parameter that is mandatory but does have a default value.
+The default value is used as a parameter value when a component description is generated via the uimaFIT factories unless a parameter is specified in the factory call.
+If a component description in created manually without specifying a value for a mandatory parameter, uimaFIT will generate an exception.
+
+[NOTE]
+====
+You can use the _enhance_ goal of the uimaFIT Maven plugin to pick up the parameter description from the JavaDoc and post it to the [parameter]``description`` field of the [class]``@ConfigurationParameter`` annotation.
+This should be preferred to specifying the description explicitly as part of the annotation.
+====
+
+The parameter injection mechanism is implemented in the `ConfigurationParameterInitializer` class.
+uimaFIT provides several base classes that already come with an `initialize()` method using the initializer:
+
+* `CasAnnotator_ImplBase`
+* `CasCollectionReader_ImplBase`
+* `CasConsumer_ImplBase`
+* `CasFlowController_ImplBase`
+* `CasMultiplier_ImplBase`
+* `JCasAnnotator_ImplBase`
+* `JCasCollectionReader_ImplBase`
+* `JCasConsumer_ImplBase`
+* `JCasFlowController_ImplBase`
+* `JCasMultiplier_ImplBase`
+* `Resource_ImplBase`
+
+The `ConfigurationParameterInitializer` can also be used with shared resources:
+
+[source,java]
+----
+class MySharedResourceObject implements SharedResourceObject {
+  public static final String PARAM_VALUE = "Value";
+  @ConfigurationParameter(name = PARAM_VALUE, mandatory = true)
+  private String value;
+
+  public void load(DataResource aData)
+      throws ResourceInitializationException {
+
+    ConfigurationParameterInitializer.initialize(this, aData);
+  }
+}
+----
+
+Fields that can be annotated with the `@ConfigurationParameter` annotation are any array or collection types (including if they are only typed via interfaces such as `List` or `Set`) of primitive types (`int`, `boolean`, `float`, `double`). Enum types, as well as, fields of the types `Charset`, `File`, `Locale`, `Pattern`, `URI`, and `URL` can also be used.
+These can be initialized either using an object value (e.g. `StandardChartsets.UTF_8``) or a string value (e.g. `"UTF-8"`). Additionally it is possible to inject any fields of types that define a constructor accepting a single `String`.
+These must be initialized from a string value.
+
+Multi-valued parameters can be initialized from single values without having to wrap these into a container.
\ No newline at end of file
diff --git a/uimafit-doc/src/main/asciidoc/tools.uimafit.experiments.adoc b/uimafit-doc/src/main/asciidoc/tools.uimafit.experiments.adoc
new file mode 100644
index 0000000..6968a8e
--- /dev/null
+++ b/uimafit-doc/src/main/asciidoc/tools.uimafit.experiments.adoc
@@ -0,0 +1,41 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+[[_ugr.tools.uimafit.experiments]]
+= Running Experiments
+
+The _uimafit-examples_ module contains a package [package]#org.apache.uima.fit.examples.experiment.pos# which demonstrates a very simple experimental setup for testing a part-of-speech tagger.
+You may find this example more accessible if you check out the code from subversion and build it in your own environment.
+
+The documentation for this example can be found in the code itself.
+Please refer to [class]``RunExperiment`` as a starting point.
+The following is copied from the javadoc comments of that file:
+
+[quote]
+`RunExperiment` demonstrates a very common (though simplified) experimental setup in which gold 
+standard data is available for some task and you want to evaluate how well your analysis engine 
+works against that data. Here we are evaluating `BaselineTagger` which is a (ridiculously)
+simple part-of-speech tagger against the part-of-speech tags found in 
+`src/main/resources/org/apache/uima/fit/examples/pos/sample-gold.txt`
+
+The basic strategy is as follows:
+
+* post the data _as is_ into the default view,
+* parse the gold-standard tokens and part-of-speech tags and put the results into another view we will call __GOLD_VIEW__,
+* create another view called _SYSTEM_VIEW_ and copy the text and [class]``Token`` annotations from the _GOLD_VIEW_ into this view,
+* run the [class]``BaselineTagger`` on the _SYSTEM_VIEW_ over the copied [class]``Token`` annoations,
+* evaluate the part-of-speech tags found in the _SYSTEM_VIEW_ with those in the _GOLD_VIEW._
diff --git a/uimafit-doc/src/main/asciidoc/tools.uimafit.externalresources.adoc b/uimafit-doc/src/main/asciidoc/tools.uimafit.externalresources.adoc
new file mode 100644
index 0000000..3edc63a
--- /dev/null
+++ b/uimafit-doc/src/main/asciidoc/tools.uimafit.externalresources.adoc
@@ -0,0 +1,288 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+[[_ugr.tools.uimafit.externalresources]]
+= External Resources
+
+An analysis engine often uses some data model.
+This may be as simple as word frequency counts or as complex as the model of a parser.
+Often these models can become quite large.
+If an analysis engine is deployed multiple times in the same pipeline or runs on multiple CPU cores, memory can be saved by using a shared instance of the data model.
+UIMA supports such a scenario by so-called external resources.
+The following sections illustrates how external resources can be used with uimaFIT.
+
+First create a class for the shared data model.
+Usually this class would load its data from some URI and then expose it via its methods.
+An example would be to load word frequency counts and to provide a `getFrequency()` method.
+In our simple example we do not load anything from the provided URI - we just offer a method to get the URI from which data be loaded.
+
+[source,java]
+----
+// Simple model that only stores the URI it was loaded from. Normally data
+// would be loaded from the URI instead and made accessible through methods
+// in this class. This simple example only allows accessing the URI.
+public static final class SharedModel implements SharedResourceObject {
+  private String uri;
+
+  public void load(DataResource aData) 
+      throws ResourceInitializationException {
+
+    uri = aData.getUri().toString();
+  }
+
+  public String getUri() { return uri; }
+}
+----
+
+== Resource injection
+
+=== Regular UIMA components
+
+When an external resource is used in a regular UIMA component, it is usually fetched from the context, cast and copied to a class member variable.
+
+[source,java]
+----
+class MyAnalysisEngine extends CasAnnotator_ImplBase {
+  final static String MODEL_KEY = "Model";
+  private SharedModel model;
+
+  public void initialize(UimaContext context) 
+      throws ResourceInitializationException {
+
+    configuredResource = (SharedModel) 
+      getContext().getResourceObject(MODEL_KEY);
+  }
+}
+----
+
+uimaFIT can be used to inject external resources into such traditional components using the `createDependencyAndBind()` method.
+To show that this works with any off-the-shelf UIMA component, the following example uses uimaFIT to configure the OpenNLP Tokenizer:
+
+[source,java]
+----
+// Create descriptor
+AnalysisEngineDescription tokenizer = createEngineDescription(
+  Tokenizer.class,
+  UimaUtil.TOKEN_TYPE_PARAMETER, Token.class.getName(),
+  UimaUtil.SENTENCE_TYPE_PARAMETER, Sentence.class.getName());
+
+// Create the external resource dependency for the model and bind it
+createDependencyAndBind(tokenizer, UimaUtil.MODEL_PARAMETER,
+  TokenizerModelResourceImpl.class,
+  "http://opennlp.sourceforge.net/models-1.5/en-token.bin");
+----
+
+[NOTE]
+====
+We recommend declaring parameter constants in the classes that use them, e.g.
+here in `Tokenizer`.
+This way, the parameters for a class can be found easily.
+However, OpenNLP declares parameters centrally in `UimaUtil`.
+Thus, the example above is correct, although unconventional.
+====
+
+[NOTE]
+====
+Note that uimaFIT is unable to perform type-coercion on parameters if a descriptor is created from a class that does not contain `@ConfigurationParameter` annotations, such as the OpenNLP `Tokenizer`.
+Such a descriptor does not contain any parameter declarations! However, it is still possible to configure such a component using uimaFIT by passing exactly the expected types as parameter values.
+Thus, we need use the `getName()` method  to get the class name as a string, instead of simply passing the class itself.
+Also, setting multi-valued parameter from a list or single value does not work here.
+Multi-values parameters must be passed as an array of the required type.
+Only the default UIMA types are possible: `String`, `boolean`, `int`, and `float`.
+====
+
+=== uimaFIT-aware components
+
+uimaFIT provides the `@ExternalResource` annotation to inject external resources directly into class member variables.
+
+.`@ExternalResource` annotation
+[cols="1,1,1", frame="all", options="header"]
+|===
+| Parameter
+| Description
+| Default
+
+|key
+|Resource key
+|field name
+
+|api
+|Used when the external resource type is different from the field type, e.g.
+                when using an ExternalResourceLocator
+|field type
+
+|mandatory
+|Whether a value must be specified
+|true
+|===
+
+[source,java]
+----
+// Example annotator that uses the SharedModel. In the process() we only
+// test if the model was properly initialized by uimaFIT
+public static class Annotator 
+    extends org.apache.uima.fit.component.JCasAnnotator_ImplBase {
+
+  final static String MODEL_KEY = "Model";
+  @ExternalResource(key = MODEL_KEY)
+  private SharedModel model;
+
+  public void process(JCas aJCas) throws AnalysisEngineProcessException {
+    assertTrue(model.getUri().endsWith("gene_model_v02.bin"));
+    // Prints the instance ID to the console - this proves the same
+    // instance of the SharedModel is used in both Annotator instances.
+    System.out.println(model);
+  }
+}
+----
+
+Note, that it is no longer necessary to implement the `initialize()` method.
+uimaFIT takes care of locating the external resource `Model` in the UIMA context and assigns it to the field `model`.
+If a mandatory resource is not present in the context, an exception is thrown.
+
+The resource injection mechanism is implemented in the `ExternalResourceInitializer` class.
+uimaFIT provides several base classes that already come with an `initialize()` method using the initializer:
+
+* `CasAnnotator_ImplBase`
+* `CasCollectionReader_ImplBase`
+* `CasConsumer_ImplBase`
+* `CasFlowController_ImplBase`
+* `CasMultiplier_ImplBase`
+* `JCasAnnotator_ImplBase`
+* `JCasCollectionReader_ImplBase`
+* `JCasConsumer_ImplBase`
+* `JCasFlowController_ImplBase`
+* `JCasMultiplier_ImplBase`
+* `Resource_ImplBase`
+
+When building a pipeline, external resources can be set of a component just like configuration parameters.
+External resources and configuration parameters can be mixed and appear in any order when creating a component description.
+
+Note that in the following example, we create only one external resource description and use it to configure two different analysis engines.
+Because we only use a single description, also only a single instance of the external resource is created and shared between the two engines. 
+[source,java]
+----
+ExternalResourceDescription extDesc = createExternalResourceDescription(
+  SharedModel.class, new File("somemodel.bin"));
+		
+// Binding external resource to each Annotator individually
+AnalysisEngineDescription aed1 = createEngineDescription(
+  Annotator.class,
+  Annotator.MODEL_KEY, extDesc);
+
+AnalysisEngineDescription aed2 = createEngineDescription(
+  Annotator.class,
+  Annotator.MODEL_KEY, extDesc);
+
+// Check the external resource was injected
+AnalysisEngineDescription aaed = createEngineDescription(aed1, aed2);
+AnalysisEngine ae = createEngine(aaed);
+ae.process(ae.newJCas());
+----
+
+This example is given as a full JUnit-based example in the the _uimaFIT-examples_ project.
+
+=== Resources extending Resource_ImplBase
+
+One kind of resources extend `Resource_ImplBase`.
+These are the easiest to handle, because uimaFIT's version of `Resource_ImplBase` already implements the necessary logic.
+Just be sure to call `super.initialize()` when overriding `initialize()`.
+Also mind that external resources are not available yet when `initialize()` is called.
+For any initialization logic that requires resources, override and implement `afterResourcesInitialized()`.
+Other than that, injection of external resources works as usual.
+
+[source,java]
+----
+public static class ChainableResource extends Resource_ImplBase {
+  public final static String PARAM_CHAINED_RESOURCE = "chainedResource";
+  @ExternalResource(key = PARAM_CHAINED_RESOURCE)
+  private ChainableResource chainedResource;
+
+  public void afterResourcesInitialized() {
+    // init logic that requires external resources
+  }
+}
+----
+
+=== Resources implementing SharedResourceObject
+
+The other kind of resources implement `SharedResourceObject``.
+Since this is an interface, uimaFIT cannot provide the initialization logic, so you have to implement a couple of things in the resource:
+
+* implement `ExternalResourceAware`
+* declare a configuration parameter `ExternalResourceFactory.PARAM_RESOURCE_NAME` and return its value in `getResourceName()`
+* invoke `ConfigurationParameterInitializer.initialize()` in the `load()` method.
+
+Again, mind that external resource not properly initialized until uimaFIT invokes `afterResourcesInitialized()`.
+
+[source,java]
+----
+public class TestSharedResourceObject implements 
+    SharedResourceObject, ExternalResourceAware {
+
+  @ConfigurationParameter(name=ExternalResourceFactory.PARAM_RESOURCE_NAME)
+  private String resourceName;
+
+  public final static String PARAM_CHAINED_RESOURCE = "chainedResource";
+  @ExternalResource(key = PARAM_CHAINED_RESOURCE)
+  private ChainableResource chainedResource;
+
+  public String getResourceName() {
+    return resourceName;
+  }
+
+  public void load(DataResource aData) 
+      throws ResourceInitializationException {
+
+    ConfigurationParameterInitializer.initialize(this, aData);
+    // rest of the init logic that does not require external resources
+  }
+
+  public void afterResourcesInitialized() {
+   // init logic that requires external resources
+  }
+}
+----
+
+=== Note on injecting resources into resources
+
+Nested resources are only initialized if they are used in a pipeline which contains at least one component that calls `ConfigurationParameterInitializer.initialize()`.
+Any component extending uimaFIT's component base classes qualifies.
+If you use nested resources in a pipeline without any uimaFIT-aware components, you can just add uimaFIT's `NoopAnnotator` to the pipeline.
+
+== Resource locators
+
+Normally, in UIMA an external resource needs to implement either `SharedResourceObject` or `Resource`.
+In order to inject arbitrary objects, uimaFIT has the concept of `ExternalResourceLocator`.
+When a resource implements this interface, not the resource itself is injected, but the method `getResource()` is called on the resource and the result is injected.
+The following example illustrates how to inject an object from JNDI into a UIMA component:
+
+[source,java]
+----
+class MyAnalysisEngine2 extends JCasAnnotator_ImplBase {
+  static final String RES_DICTIONARY = "dictionary";
+  @ExternalResource(key = RES_DICTIONARY)
+  Dictionary dictionary;
+}
+
+AnalysisEngineDescription desc = createEngineDescription(
+  MyAnalysisEngine2.class);
+
+bindResource(desc, MyAnalysisEngine2.RES_DICTIONARY, 
+  JndiResourceLocator.class,
+  JndiResourceLocator.PARAM_NAME, "dictionaries/german");
+----
\ No newline at end of file
diff --git a/uimafit-doc/src/main/asciidoc/tools.uimafit.gettingstarted.adoc b/uimafit-doc/src/main/asciidoc/tools.uimafit.gettingstarted.adoc
new file mode 100644
index 0000000..e2f9eba
--- /dev/null
+++ b/uimafit-doc/src/main/asciidoc/tools.uimafit.gettingstarted.adoc
@@ -0,0 +1,147 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+[[_ugr.tools.uimafit.gettingstarted]]
+= Getting Started
+
+This quick start tutorial demonstrates how to use uimaFIT to define and set a configuration parameter in an analysis engine, run it, and generate a descriptor file for it.
+The complete code for this example can be found in the _uimaFIT-examples_ module.
+
+== Adding uimaFIT to your project
+
+The following instructions describe how to add uimaFIT to your project's classpath.
+
+=== Maven users
+
+If you use Maven, then uimaFIT can be added to your project by simply adding uimaFIT as a project dependency by adding the following snippet of XML to your pom.xml file:
+
+[source,xml,subs="+attributes"]
+----
+<dependency>
+  <groupId>org.apache.uima</groupId>
+  <artifactId>uimafit-core</artifactId>
+  <version>{revnumber}</version>
+</dependency>
+----
+
+uimaFIT distributions are hosted by Maven Central and so no repository needs to be added to your pom.xml file. 
+
+=== Non-Maven users
+
+If you do not build with Maven, then download uimaFIT from the http://uima.apache.org/downloads.cgi[Apache UIMA downloads page].
+The file name should be uimafit--bin.zip.
+Download and unpack this file.
+The contents of the resulting upacked directory will contain a directory called [path]_lib_.
+Add all of the files in this directory to your classpath.
+
+== A simple analysis engine implementation
+
+Here is the complete analysis engine implementation for this example.
+
+[source,java]
+----
+public class GetStartedQuickAE 
+    extends org.apache.uima.fit.component.JCasAnnotator_ImplBase {
+  
+  public static final String PARAM_STRING = "stringParam";
+  @ConfigurationParameter(name = PARAM_STRING)
+  private String stringParam;
+  
+  @Override
+  public void process(JCas jCas) throws AnalysisEngineProcessException {
+    System.out.println("Hello world!  Say 'hi' to " + stringParam);
+  }
+}
+----
+
+The first thing to note is that the member variable [var]``stringParam`` is annotated with [class]``@ConfigurationParameter`` which tells uimaFIT that this is an analysis engine configuration parameter.
+It is best practice to create a public constant for the parameter name, here `PARAM_STRING` The second thing to note is that we extend uimaFIT's version of the [class]``JCasAnnotator_ImplBase``.
+The initialize method of this super class calls:
+
+[source,java]
+----
+ConfigurationParameterInitializer.initializeConfigurationParameters(
+  Object, UimaContext)
+----
+
+which populates the configuration parameters with the appropriate contents of the [interface]``UimaContext``.
+If you do not want to extend uimaFIT's [class]``JCasAnnotator_ImplBase``, then you can call this method directly in the [method]``initialize`` method of your analysis engine or any class that implements [interface]``Initializable``.
+You can call this method for an instance of any class that has configuration parameters.
+
+== Running the analysis engine
+
+The following lines of code demonstrate how to instantiate and run the analysis engine from a main method:
+
+[source,java]
+----
+JCas jCas = JCasFactory.createJCas();
+  
+AnalysisEngine analysisEngine = AnalysisEngineFactory.createEngine(
+  GetStartedQuickAE.class,
+  GetStartedQuickAE.PARAM_STRING, "uimaFIT");
+  
+analysisEngine.process(jCas);
+----
+
+In a more involved example, we would probably instantiate a collection reader and run this analysis engine over a collection of documents.
+Here, it suffices to simply create a [interface]``JCas``.
+Line 3 instantiates the analysis engine using [class]``AnalysisEngineFactory`` and sets the string parameter named [parameter]``stringParam`` to the value ``uimaFIT``.
+Running this simple program sends the following output to the console: 
+
+[source]
+----
+Hello world!  Say 'hi' to uimaFIT
+----
+
+Normally you would be using a type system with your analysis components.
+When using uimaFIT, it is easiest to keep your type system descriptors in your source folders and make them known to uimaFIT.
+To do so, create a file [path]_META-INF/org.apache.uima.fit/types.txt_ in a source folder and add references to all your type descriptors to the file, one per line.
+You can also use wildcards.
+For example: 
+
+[source]
+----
+classpath*:org/apache/uima/fit/examples/type/Token.xml
+classpath*:org/apache/uima/fit/examples/type/Sentence.xml
+classpath*:org/apache/uima/fit/examples/tutorial/type/*.xml
+----
+
+== Generate a descriptor file
+
+The following lines of code demonstrate how a descriptor file can be generated using the class definition:
+
+[source,java]
+----
+AnalysisEngine analysisEngine = AnalysisEngineFactory.createEngine(
+  GetStartedQuickAE.class,
+  GetStartedQuickAE.PARAM_STRING, "uimaFIT");
+
+analysisEngineDescription.toXML(
+  new FileOutputStream("GetStartedQuickAE.xml"));
+----
+
+If you open the resulting descriptor file you will see that the configuration parameter [parameter]``stringParam`` is defined with the value set to ``uimaFIT``.
+We could now instantiate an analysis engine using this descriptor file with a line of code like this:
+
+[source,java]
+----
+AnalysisEngineFactory.createEngine("GetStartedQuickAE");
+----
+
+But, of course, we really wouldn't want to do that now that we can instantiate analysis engines using the class definition as was done above!
+
+This chapter, of course, did not demonstrate every feature of uimaFIT which provides support for annotating external resources, creating aggregate engines, running pipelines, testing components, among others.
\ No newline at end of file
diff --git a/uimafit-doc/src/main/asciidoc/tools.uimafit.introduction.adoc b/uimafit-doc/src/main/asciidoc/tools.uimafit.introduction.adoc
new file mode 100644
index 0000000..a84671e
--- /dev/null
+++ b/uimafit-doc/src/main/asciidoc/tools.uimafit.introduction.adoc
@@ -0,0 +1,122 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+[[_ugr.tools.uimafit.introduction]]
+= Introduction
+
+While uimaFIT provides many features for a UIMA developer, there are two overarching themes that most features fall under.
+These two sides of uimaFIT are,while complementary, largely independent of each other.
+One of the beauties of uimaFIT is that a developer that uses one side of uimaFIT extensively is not required to use the other side at all. 
+
+== Simplify Component Implementation
+
+The first broad theme of uimaFIT provides features that __simplify component
+        implementation__.
+Our favorite example of this is the [class]``@ConfigurationParameter`` annotation which allows you to annotate a member variable as a configuration parameter.
+This annotation in combination with the method [method]``ConfigurationParameterInitializer.initialize()`` completely automates the process of initializing member variables with values from the [interface]``UimaContext`` passed into your analysis engine's initialize method.
+Similarly, the annotation [class]``@ExternalResource`` annotation in combination with the method [method]``ExternalResourceInitializer.initialize()`` completely automates the binding of an external resource as defined in the [interface]``UimaContext`` to a member variable.
+Dispensing with manually writing the code that performs these two tasks reduces effort, eliminates verbose and potentially buggy boiler-plate code, and makes implementing a UIMA component more enjoyable.
+Consider, for example, a member variable that is of type [class]``Locale``.
+With uimaFIT you can simply annotate the member variable with [class]``@ConfigurationParameter`` and have your initialize method automatically initialize the variable correctly with a string value in the [interface]``UimaContext`` such as ``en_US``. 
+
+== Simplify Component Instantiation
+
+The second broad theme of uimaFIT provides features that __simplify component
+        instantiation__.
+Working with UIMA, have you ever said to yourself "`but I
+        just want to tag some text!?`" What does it take to "`just tag some text?`" Here's a list of things you must do with the traditional approach:
+
+* wrap your tagger as a UIMA analysis engine
+* write a descriptor file for your analysis engine
+* write a CAS consumer that produces the desired output
+* write another descriptor file for the CAS consumer
+* write a descriptor file for a collection reader
+* write a descriptor file that describes a pipeline
+* invoke the Collection Processing Manager with your pipeline descriptor file
+
+
+=== From a class
+
+Each of these steps has its own pitfalls and can be rather time consuming.
+This is a rather unsatisfying answer to our simple desire to just tag some text.
+With uimaFIT you can literally eliminate all of these steps. 
+
+Here's a simple snippet of Java code that illustrates "`tagging some text`" with uimaFIT:
+
+[source,java]
+----
+import static org.apache.uima.fit.factory.JCasFactory.createJCas;
+import static org.apache.uima.fit.pipeline.SimplePipeline.runPipeline;
+import static 
+ org.apache.uima.fit.factory.AnalysisEngineFactory.createEngineDescription;
+      
+JCas jCas = createJCas();
+
+jCas.setDocumentText("some text");
+
+runPipeline(jCas, 
+    createEngineDescription(MyTokenizer.class), 
+    createEngineDescription(MyTagger.class));
+
+for (Token token : iterate(jCas, Token.class)){
+    System.out.println(token.getTag());
+}
+----
+
+This code uses several static method imports for brevity.
+And while the terseness of this code won't make a Python programmer blush - it is certainly much easier than the seven steps outlined above! 
+
+=== From an XML descriptor
+
+uimaFIT provides mechanisms to instantiate and run UIMA components programmatically with or without descriptor files.
+For example, if you have a descriptor file for your analysis engine defined by [class]``MyTagger`` (as shown above), then you can instead instantiate the analysis engine with:
+
+[source,java]
+----
+AnalysisEngineDescription tagger = createEngineDescription(
+    "mypackage.MyTagger");
+----
+
+This will find the descriptor file [path]_mypackage/MyTagger.xml_ by name.
+Similarly, you can find a descriptor file by location with [method]``createEngineDescriptionFromPath()``.
+However, if you want to dispense with XML descriptor files altogether (and you probably do), you can use the method [method]``createEngineDescription()`` as shown above.
+One of the driving motivations for creating the second side of uimaFIT is our frustration with descriptor files and our desire to eliminate them.
+Descriptor files are difficult to maintain because they are generally tightly coupled with java code, they decay without warning, they are wearisome to test, and they proliferate, among other reasons.
+
+== Is this cheating?
+
+One question that is often raised by new uimaFIT users is whether or not it breaks the __UIMA way__.
+That is, does adopting uimaFIT lead me down a path of creating UIMA components and systems that are incompatible with the traditional UIMA approach? The answer to this question is __no__.
+For starters, uimaFIT does not skirt the UIMA mechanism of describing components - it only skips the XML part of it.
+For example, when the method [method]``createEngineDescription()`` is called (as shown above) an [interface]``AnalysisEngineDescription`` is created for the analysis engine.
+This is the same object type that is instantiated when a descriptor file is used.
+So, instead of parsing XML to instantiate an analysis engine description from XML, uimaFIT uses a factory method to instantiate it from method parameters.
+One of the happy benefits of this approach is that for a given [interface]``AnalysisEnginedDescription`` you can generate an XML descriptor file using [method]``AnalysisEngineDescription.toXML()``.
+So, uimaFIT actually provides a very simple and direct path for _generating_ XML descriptor files rather than manually creating and maintaining them! 
+
+It is also useful to clarify that if you only want to use one side or the other of uimaFIT, then you are free to do so.
+This is possible precisely because uimaFIT does not workaround UIMA's mechanisms for describing components but rather uses them directly.
+For example, if the only thing you want to use in uimaFIT is the [class]``@ConfigurationParameter``, then you can do so without worrying about what effect this will have on your descriptor files.
+This is because your analysis engine will be initialized with exactly the same [interface]``UimaContext`` regardless of whether you instantiate your analysis engine in the _UIMA way_ or use one of uimaFIT's factory methods.
+Similarly, a UIMA component does not need to be annotated with [class]``@ConfiguratioParameter`` for you to make use of the [method]``createEngineDescription()`` method.
+This is because when you pass configuration parameter values in to the [method]``createEngineDescription()`` method, they are added to an [interface]``AnalysisEngineDescription`` which is used by UIMA to populate a [interface]``UimaContext`` - just as it would if you used a descriptor file. 
+
+== Conclusion
+
+Because uimaFIT can be used to simplify component implementation and instantiation it is easy to assume that you can't do one without the other.
+This page has demonstrated that while these two sides of uimaFIT complement each other, they are not coupled together and each can be effectively used without the other.
+Similarly, by understanding how uimaFIT uses the UIMA component description mechanisms directly, one can be assured that uimaFIT enables UIMA development that is compatible and consistent with the UIMA standard and APIs. 
\ No newline at end of file
diff --git a/uimafit-doc/src/main/asciidoc/tools.uimafit.maven.adoc b/uimafit-doc/src/main/asciidoc/tools.uimafit.maven.adoc
new file mode 100644
index 0000000..c404d80
--- /dev/null
+++ b/uimafit-doc/src/main/asciidoc/tools.uimafit.maven.adoc
@@ -0,0 +1,195 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+[[_tools.uimafit.maven]]
+= uimaFIT Maven Plugin
+
+uimaFIT dynamically generates UIMA component descriptions from annotations in the Java source code.
+The uimaFIT Maven plugin provides the ability to automatically create such annotations in already compiled classes and to automatically generate XML descriptors from the annotated classes.
+
+== enhance goal
+
+The goal enhance allows automatically augmenting compiled classes with uimaFIT annotations.
+Information like vendor, copyright, or version can be obtained from the Maven POM.
+Additionally, descriptions for parameters and components can be generated from Javadoc comments.
+Existing annotations are not overwritten unless forced. 
+
+[source,xml]
+----
+<plugin>
+  <groupId>org.apache.uima</groupId>
+  <artifactId>uimafit-maven-plugin</artifactId>
+  <version></version> <!-- change to latest version -->
+  <configuration>
+    <!-- OPTIONAL -->
+    <!-- Override component description in generated descriptors. -->
+    <overrideComponentDescription>false</overrideComponentDescription>
+
+    <!-- OPTIONAL -->
+    <!-- Override version in generated descriptors. -->
+    <overrideComponentVersion>false</overrideComponentVersion>
+
+    <!-- OPTIONAL -->
+    <!-- Override vendor in generated descriptors. -->
+    <overrideComponentVendor>false</overrideComponentVendor>
+
+    <!-- OPTIONAL -->
+    <!-- Override copyright in generated descriptors. -->
+    <overrideComponentCopyright>false</overrideComponentCopyright>
+
+    <!-- OPTIONAL -->
+    <!-- Version to use in generated descriptors. -->
+    <componentVersion>${project.version}</componentVersion>
+
+    <!-- OPTIONAL -->
+    <!-- Vendor to use in generated descriptors. -->
+    <componentVendor>Apache Foundation</componentVendor>
+
+    <!-- OPTIONAL -->
+    <!-- Copyright to use in generated descriptors. -->
+    <componentCopyright>Apache Foundation 2013</componentCopyright>
+
+    <!-- OPTIONAL -->
+    <!-- Source file encoding. -->
+    <encoding>${project.build.sourceEncoding}</encoding>
+
+    <!-- OPTIONAL -->
+    <!-- Generate a report of missing meta data in 
+         $project.build.directory/uimafit-missing-meta-data-report.txt -->
+    <generateMissingMetaDataReport>true</generateMissingMetaDataReport>
+
+    <!-- OPTIONAL -->
+    <!-- Fail on missing meta data. This setting has no effect unless
+         generateMissingMetaDataReport is enabled. -->
+    <failOnMissingMetaData>false</failOnMissingMetaData>
+
+    <!-- OPTIONAL -->
+    <!-- Constant name prefixes used for parameters and external resources,
+         e.g. "PARAM_". -->
+    <parameterNameConstantPrefixes>
+      <prefix>PARAM_<prefix/>
+    </parameterNameConstantPrefixes>
+    
+    <!-- OPTIONAL -->
+    <!-- Fail on missing meta data. This setting has no effect unless
+         generateMissingMetaDataReport is enabled. -->
+    <externalResourceNameConstantPrefixes>
+      <prefix>KEY_<prefix/>
+      <prefix>RES_<prefix/>
+    </externalResourceNameConstantPrefixes>
+    
+    <!-- OPTIONAL -->
+    <!-- Mode of adding type systems found on the classpath via the
+         uimaFIT detection mechanism at compile time to the generated
+         descriptor. By default, no type systems are added. -->
+    <addTypeSystemDescriptions>NONE</addTypeSystemDescriptions>
+    
+  </configuration>
+  <executions>
+    <execution>
+      <id>default</id>
+      <phase>process-classes</phase>
+      <goals>
+        <goal>enhance</goal>
+      </goals>
+    </execution>
+  </executions>
+</plugin>
+----
+
+When generating descriptions for configuration parameters or external resources, the plugin supports a common practice of placing the Javadoc on a constant field instead of the parameter or external resource field.
+Per default, parameter name constants must be prefixed with `PARAM_` and external resource key constants must be prefixed with `RES_ ` or `KEY_`.
+
+[source,java]
+----
+/**
+ * Enable or disable my feature.
+ */
+public static final String PARAM_ENABLE_FEATURE = "enableFeature";
+@ConfigurationParameter(name=PARAM_ENABLE_FEATURE)
+private boolean enableFeature;
+
+/**
+ * My external resource.
+ */
+public static final String RES_MY_RESOURCE = "resource";
+@ExternalResource(key=RES_MY_RESOURCE)
+private MyResource resource;
+----
+
+By enabling `generateMissingMetaDataReport`, the build can be made to fail if meta data such as parameter descriptions are missing.
+A report about the missing data is generated in [path]_uimafit-missing-meta-data-report.txt_ in the project build directory.
+
+== generate goal
+
+The generate goal generates XML component descriptors for UIMA components. 
+
+[source,xml]
+----
+<plugin>
+  <groupId>org.apache.uima</groupId>
+  <artifactId>uimafit-maven-plugin</artifactId>
+  <version></version> <!-- change to latest version -->
+  <configuration>
+    <!-- OPTIONAL -->
+    <!-- Path where the generated resources are written. -->
+    <outputDirectory>
+      ${project.build.directory}/generated-sources/uimafit
+    </outputDirectory>
+
+    <!-- OPTIONAL -->
+    <!-- Skip generation of META-INF/org.apache.uima.fit/components.txt -->
+    <skipComponentsManifest>false</skipComponentsManifest>
+
+    <!-- OPTIONAL -->
+    <!-- Source file encoding. -->
+    <encoding>${project.build.sourceEncoding}</encoding>
+  </configuration>
+  <executions>
+    <execution>
+      <id>default</id>
+      <phase>process-classes</phase>
+      <goals>
+        <goal>generate</goal>
+      </goals>
+    </execution>
+  </executions>
+</plugin>
+----
+
+In addition to the XML descriptors, a manifest file is written to `META-INF/org.apache.uima.fit/components.txt`.
+This file can be used to conveniently locate the XML descriptors, which are written in the packages next to the classes they describe.
+
+[source]
+----
+classpath*:org/apache/uima/fit/examples/ExampleComponent.xml
+----
+
+It is recommended to use both, the enhance and the generate goal.
+Both goals should be specified in the same execution, first enhance, then generate:
+
+[source,xml]
+----
+<execution>
+  <id>default</id>
+  <phase>process-classes</phase>
+  <goals>
+    <goal>enhance</goal>
+    <goal>generate</goal>
+  </goals>
+</execution>
+----
\ No newline at end of file
diff --git a/uimafit-doc/src/main/asciidoc/tools.uimafit.migration.adoc b/uimafit-doc/src/main/asciidoc/tools.uimafit.migration.adoc
new file mode 100644
index 0000000..e4e87cd
--- /dev/null
+++ b/uimafit-doc/src/main/asciidoc/tools.uimafit.migration.adoc
@@ -0,0 +1,189 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+[[_ugr.tools.uimafit.migration]]
+= Migration Guide
+
+This section provides helpful information on incompatible changes between versions.
+
+== Version 2.3.0 to 2.4.0
+
+.Version requirements
+Depends on UIMA 2.10.2, Spring Framework 3.2.16 and Java 7.
+
+Mind the updated version requirements.
+There should be no other potentially problematic changes in this upgrade.
+
+== Version 2.2.0 to 2.3.0
+
+.CasIOUtil deprecated
+The functionality of the uimaFIT CasIOUtil class has been superseded by the core UIMA class CasIOUtils added in UIMA 2.9.0.
+The method signatures in the new class are not the same, but provide more functionality.
+CasIOUtil has been deprecated and documentation has been added which of the CasIOUtils methods should be used instead.
+
+.Version requirements
+Depends on UIMA 2.9.1, Spring Framework 3.2.16 and Java 7.
+
+Mind the updated version requirements.
+There should be no other potentially problematic changes in this upgrade.
+
+== Version 2.1.0 to 2.2.0
+
+.Version requirements
+Depends on UIMA 2.8.1, Spring Framework 3.2.16 and Java 7.
+
+Mind the updated version requirements.
+There should be no other potentially problematic changes in this upgrade.
+
+== Version 2.0.0 to 2.1.0
+
+.Version requirements
+Depends on UIMA 2.6.0 and Java 6.
+
+.AnnotationFactory.createAnnotation()
+No longer throws ``UIMAExcption``.
+If this exception was cought, some IDEs may complain here after upgrading to uimaFIT 2.1.0. 
+
+== Version 1.4.0 to 2.0.0
+
+.Version requirements
+Depends on UIMA 2.4.2.
+
+.Backwards compatibility
+Compatibility with legacy annotation is provided by the Legacy support module.
+
+.Change of Maven groupId and artifactId
+The Maven group ID has changed from `org.uimafit` to ``org.apache.uima``.
+
+The artifact ID of the main uimaFIT artifact has been changed from `uimafit` to ``uimafit-core``.
+
+.Change of package names
+The base package has been renamed from `org.uimafit` to ``org.apache.uima.fit``.
+A global search/replace on Java files with for lines starting with `import org.uimafit` and replacing that with `import org.apache.uima.fit` should work.
+
+.@ConfigurationParameter
+The default value for the mandatory attribute now is ``true``.
+The default name of configuration parameters is now the name of the annotated field only.
+The classname is no longer prefixed.
+The method `ConfigurationParameterFactory.createConfigurationParameterName()` that was used to generate the prefixed name has been removed.
+
+.Type detection: META-INF/org.uimafit folder
+The `META-INF/org.uimafit` was renamed to ``META-INF/org.apache.uima.fit``.
+
+.JCasUtil
+The deprecated `JCasUtil.iterate()` methods have been removed. `JCasUtil.select()` should be used instead.
+
+.AnalysisEngineFactory
+All `createAggregateXXX` and `createPrimitiveXXX` methods have been renamed to ``createEngineXXX``.
+The old names are deprecated and will be removed in future versions.
+
+All `createAnalysisEngineXXX` methods have been renamed to ``createEngineXXX``.
+The old names are deprecated and will be removed in future versions.
+
+.CollectionReaderFactory
+All `createDescriptionXXX` methods have been renamed to ``createReaderDescriptionXXX``.
+The old names are deprecated and will be removed in future versions.
+
+All `createCollectionReaderXXX` methods have been renamed to ``createReaderXXX``.
+The old names are deprecated and will be removed in future versions.
+
+.JCasIterable
+`JCasIterable` now only accepts reader and engine descriptions (no instances) and no longer implements the `Iterator` interface.
+Instead, new `JCasIterator` has been added, which replaces `JCasIterable` in that respect.
+
+.CasDumpWriter
+`org.uimafit.component.xwriter.CASDumpWriter` has been renamed to ``org.apache.uima.fit.component.CasDumpWriter``.
+
+.CpePipeline
+`CpePipeline` has been moved to a separate module with the artifact ID `uimafit-cpe` to reduce the dependencies incurred by the main uimaFIT artifact.
+
+.XWriter removed
+The `XWriter` and associated file namers have been removed as they were much more complex then acutally needed.
+As an alternative, `CasIOUtil` has been introduced providing several convenience methods to read/write JCas/CAS data. 
+
+.JCasFactory
+Methods only loading JCas data have been removed from ``JCasFactory``.
+The new methods in `CasIOUtil` can be used instead.
+
+== Legacy support module
+
+The compatibility layer should allow you to migrate to uimaFIT without breaking anything.
+You should then be able to gradually change the codebase to be compatible with uimaFIT .
+As far as my tests go, uimaFIT 1.x and can coexist peacefully on the classpath (and indeed both need to be on the classpath in order to use the legacy support module).
+
+To enable the legacy support, make sure that you have a dependency on uimaFIT 1.x and then just add a dependency on the legacy module:
+
+[source]
+----
+<dependency>
+  <groupId>org.uimafit</groupId>
+  <artifactId>uimafit</artifactId>
+  <version>1.4.0</version>
+</dependency>
+<dependency>
+  <groupId>org.apache.uima</groupId>
+  <artifactId>uimafit-legacy-support</artifactId>
+  <version></version>
+</dependency>
+----
+
+uimaFIT automatically detects the presence of the legacy module and uses it - no additional configuration is necessary.
+
+The following bash script may help to partially automatize the source code migration process.
+Please observe that it does not cover all of the necessary changes!
+
+[NOTE]
+====
+The script recursively changes all files under the current working directory! Make sure you are in the right directory before running it! _Use the script at your own 
+      risk!_
+====
+
+[source,bash]
+----
+#!/bin/sh
+
+############################################
+# MAKE SURE TO BACKUP YOUR FILES FIRST!
+# SCRIPT RECURSIVELY CHANGES ALL JAVA FILES!
+# USE AT YOUR OWN RISK!
+############################################
+
+# Change of package names
+find . -name '*.java' -print | 
+xargs perl -p -i -e 's/org.uimafit/org.apache.uima.fit/g'
+
+find . -name '*.java' -print | 
+xargs perl -p -i -e 's/org.uimafit.component.xwriter.CASDumpWriter/\
+org.apache.uima.fit.component.CasDumpWriter/g'
+
+# AnalysisEngineFactory
+find . -name '*.java' -print | 
+xargs perl -p -i -e 's/createAggregate/createEngine/g'
+
+find . -name '*.java' -print | 
+xargs perl -p -i -e 's/createPrimitive/createEngine/g'
+
+find . -name '*.java' -print | 
+xargs perl -p -i -e 's/createAnalysisEngine/createEngine/g'
+
+# Readers
+find . -name '*.java' -print | 
+xargs perl -p -i -e 's/createDescription/createReaderDescription/g'
+
+find . -name '*.java' -print | 
+xargs perl -p -i -e 's/createCollectionReader/createReader/g'
+----
\ No newline at end of file
diff --git a/uimafit-doc/src/main/asciidoc/tools.uimafit.packaging.adoc b/uimafit-doc/src/main/asciidoc/tools.uimafit.packaging.adoc
new file mode 100644
index 0000000..1cc2065
--- /dev/null
+++ b/uimafit-doc/src/main/asciidoc/tools.uimafit.packaging.adoc
@@ -0,0 +1,106 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+[[_ugr.tools.uimafit.packaging]]
+= Building an executable JAR
+
+Building an executable JAR including uimaFIT components typically requires extra care.
+Per convention, uimaFIT expects certain information in specific locations on the classpath, e.g.
+the [path]_types.txt_ file that controls the <<_ugr.tools.uimafit.packaging,automatic type system detection>> mechanism must reside at [path]_META-INF/org.apache.uima.fit/types.txt_.
+It often occurs that a project has several dependencies, each supplying its own configuration files at these standard locations.
+However, this causes a problem with naive approaches to creating an executable _fat-jar_ merging all dependencies into a single JAR file.
+Without extra care, the files supplied by the different dependencies overwrite each other during the packaging process and only one file _wins_ in the end.
+As a consequence, the types configured in the other files cannot be detected at runtime.
+Such a native approach is taken, for example, by the Maven Assembly Plugin.
+
+The Maven Shade Plugin provides a convenient alternative for the creation of executable fat-jars, as it provides a mechanism to concatenate the configuration files from different dependencies while creating the fat-jar.
+To use the Maven Shade Plugin with uimaFIT, use the following configuration section in your POM file and make sure to change the `mainClass` as required for your project:
+
+[source,xml]
+----
+<build>
+  <plugins>
+    <plugin>
+      <groupId>org.apache.maven.plugins</groupId>
+      <artifactId>maven-shade-plugin</artifactId>
+      <version>2.2</version>
+      <executions>
+        <execution>
+          <phase>package</phase>
+          <goals><goal>shade</goal></goals>
+          <configuration>
+            <transformers>
+              <!-- Set the main class of the executable JAR -->
+              <transformer
+                implementation="org.apache.maven.plugins.shade.\
+                                resource.ManifestResourceTransformer">
+                <mainClass>org.apache.uima.fit.example.Main</mainClass>
+              </transformer>
+              <!-- Merge the uimaFIT configuration files -->
+              <transformer
+                implementation="org.apache.maven.plugins.shade.\
+                                resource.AppendingTransformer">
+                <resource>\
+                  META-INF/org.apache.uima.fit/fsindexes.txt\
+                </resource>
+              </transformer>
+              <transformer
+                implementation="org.apache.maven.plugins.shade.\
+                                resource.AppendingTransformer">
+                <resource>\
+                  META-INF/org.apache.uima.fit/types.txt\
+                </resource>
+              </transformer>
+              <transformer
+                implementation="org.apache.maven.plugins.shade.\
+                                resource.AppendingTransformer">
+                <resource>\
+                  META-INF/org.apache.uima.fit/typepriorities.txt\
+                </resource>
+              </transformer>
+              <!-- Merge CAS validation check registrations -->
+              <transformer 
+                implementation="org.apache.maven.plugins.shade.\
+                                resource.ServicesResourceTransformer"/>
+            </transformers>
+            <!-- 
+              Prevent huge shaded artifacts from being deployed
+              to a Maven repository (remove if not desired) 
+            -->
+            <outputFile>\
+              ${project.build.directory}/\
+              ${artifactId}-${version}-standalone.jar\
+            </outputFile>
+          </configuration>
+        </execution>
+      </executions>
+    </plugin>
+  </plugins>
+</build>
+----
+
+[NOTE]
+====
+Due to formatting constraints in the PDF version of this manual, the example above uses `\` to indicate a line continuation.
+Remove these and join the lines when you copy/paste this example.
+====
+
+[NOTE]
+====
+You might want to consider also merging additional files, such as LICENSE, NOTICE, or DEPENDENCY files,  configuration files for the Java Service Locator API, or  files used by other frameworks that uses similar conventions for configuration file locations.
+Check the documentation of the Maven Shade Plugin, as different kinds of configuration files require different specialized transformers.
+====
\ No newline at end of file
diff --git a/uimafit-doc/src/main/asciidoc/tools.uimafit.pipelines.adoc b/uimafit-doc/src/main/asciidoc/tools.uimafit.pipelines.adoc
new file mode 100644
index 0000000..7596e1f
--- /dev/null
+++ b/uimafit-doc/src/main/asciidoc/tools.uimafit.pipelines.adoc
@@ -0,0 +1,72 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+[[_ugr.tools.uimafit.pipelines]]
+= Pipelines
+
+UIMA is a component-based architecture that allows composing various processing components into a complex processing pipeline.
+A pipeline typically involves a _collection
+      reader_ which ingests documents and _analysis engines_ that do the actual processing.
+
+Normally, you would run a pipeline using a UIMA Collection Processing Engine or using UIMA AS.
+uimaFIT offers a third alternative that is much simpler to use and well suited for embedding UIMA pipelines into applications or for writing tests.
+
+As uimaFIT does not supply any readers or processing components, we just assume that we have written three components:
+
+* [class]``TextReader`` - reads text files from a directory
+* [class]``Tokenizer`` - annotates tokens
+* [class]``TokenFrequencyWriter`` - writes a list of tokens and their frequency to a file
+
+We create descriptors for all components and run them as a pipeline:
+
+[source,java]
+----
+CollectionReaderDescription reader = 
+  CollectionReaderFactory.createReaderDescription(
+    TextReader.class, 
+    TextReader.PARAM_INPUT, "/home/uimafit/documents");
+
+AnalysisEngineDescription tokenizer = 
+  AnalysisEngineFactory.createEngineDescription(
+    Tokenizer.class);
+
+AnalysisEngineDescription tokenFrequencyWriter = 
+  AnalysisEngineFactory.createEngineDescription(
+    TokenFrequencyWriter.class, 
+    TokenFrequencyWriter.PARAM_OUTPUT, "counts.txt");
+
+SimplePipeline.runPipeline(reader, tokenizer, writer);
+----
+
+Instead of running the full pipeline end-to-end, we can also process one document at a time and inspect the analysis results:
+
+[source,java]
+----
+CollectionReaderDescription reader = 
+  CollectionReaderFactory.createReaderDescription(
+    TextReader.class, 
+    TextReader.PARAM_INPUT, "/home/uimafit/documents");
+
+AnalysisEngineDescription tokenizer = 
+  AnalysisEngineFactory.createEngineDescription(
+    Tokenizer.class);
+
+for (JCas jcas : SimplePipeline.iteratePipeline(reader, tokenizer)) {
+  System.out.printf("Found %d tokens%n", 
+    JCasUtil.select(jcas, Token.class).size());
+}
+----
\ No newline at end of file
diff --git a/uimafit-doc/src/main/asciidoc/tools.uimafit.testing.adoc b/uimafit-doc/src/main/asciidoc/tools.uimafit.testing.adoc
new file mode 100644
index 0000000..99f9414
--- /dev/null
+++ b/uimafit-doc/src/main/asciidoc/tools.uimafit.testing.adoc
@@ -0,0 +1,49 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+[[_ugr.tools.uimafit.testing"]]
+= Testing UIMA components
+
+Writing tests without uimaFIT can be a laborious process that results in fragile tests that are very verbose and break easily when code is refactored. This page demonstrates how you can write tests that are both concise and robust. Here is an outline of how you might create a test for a UIMA component _without_ uimaFIT:
+
+* write a descriptor file that configures your component appropriately for the test. This requires a minimum of 30-50 lines of XML.
+* begin a test with 5-10 lines of code that instantiate the e.g. analysis engine.
+* run the analysis engine against some text and test the contents of the CAS.
+* repeat steps 1-3 for your next test usually by copying the descriptor file, renaming it, and changing e.g. configuration parameters.</para>
+
+If you have gone through the pain of creating tests like these and then decided you should refactor your code, then you know how tedious it is to maintain them.
+
+Instead of pasting variants of the setup code (see step 2) into other tests we began to create a library of utility methods that we could call which helped shorten our code. We extended these methods so that we could instantiate our components directly without a descriptor file. These utility methods became the initial core of uimaFIT.
+
+
+== Examples
+
+There are several examples that can be found in the _uimafit-examples_ module.
+
+* There are a number of examples of unit tests in both the test suite for the _uimafit-core_ module and the _uimafit-examples_ module. In particular, there are some well-documented unit tests in the latter which can be found in `RoomNumberAnnotator1Test`.
+* You can improve your testing strategy by introducing a `TestBase` class such as the one found in `ExamplesTestBase`. This class is intended as a super class for your other test classes and sets up a `JCas` that is always ready to use along with a `TypeSystemDescription` and a `TypePriorities`. An example test that subclasses from `ExamplesTestBase` is `RoomNumberAnnotator2Test`.
+* Most analysis engines that you want to test will generally be downstream of many other components that add annotations to the CAS. These annotations will likely need to be in the CAS so that a downstream analysis engine will do something sensible. This poses a problem for tests because it may be undesirable to set up and run an entire pipeline every time you want to test a downstream analysis engine. Furthermore, such tests can become fragile in the face of behavior changes to upstream components. For this reason, it can be advantageous to serialize a CAS as an XMI file and use this as a starting point rather than running an entire pipeline. An example of this approach can be found in `XmiTest`. 
+
+
+== Tips & Tricks
+
+The package <package>org.apache.uima.fit.testing</package> provides some utility classes that can be handy when writing tests for UIMA components. You may find the following suggestions useful:
+
+* add a `TokenBuilder` to your `TestBase` class. An example of this can be found in `ComponentTestBase`. This makes it easy to add tokens and sentences to the CAS you are testing which is a common task for many tests.
+* use a `JCasBuilder` to add text and annotations incrementally to a JCas instead of first setting the text and then adding all annotations.
+* use a `CasDumpWriter` to write the CAS contents is a human readable format to a file or to the console. Compare this with a previously written and manually verified file to see if changes in the component result in changes of the components output.
+
diff --git a/uimafit-doc/src/main/asciidoc/tools.uimafit.typesystem.adoc b/uimafit-doc/src/main/asciidoc/tools.uimafit.typesystem.adoc
new file mode 100644
index 0000000..d32028e
--- /dev/null
+++ b/uimafit-doc/src/main/asciidoc/tools.uimafit.typesystem.adoc
@@ -0,0 +1,174 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+[[_ugr.tools.uimafit.typesystem]]
+= Type System Detection
+
+UIMA requires that types that are used in the CAS are defined in XML files - so-called _type system descriptions_ (TSD). Whenever a UIMA component is created, it must be associated with such a type system.
+While it is possible to manually load the type system descriptors and pass them to each UIMA component and to each created CAS, it is quite inconvenient to do so.
+For this reason, uimaFIT supports the automatic detection of such files in the classpath.
+Thus is becomes possible for a UIMA component provider to have component's type automatically detected and thus the components becomes immediately usable by adding it to the classpath.
+
+== Making types auto-detectable
+
+The provider of a type system should create a file [path]_META-INF/org.apache.uima.fit/types.txt_ in the classpath.
+This file should define the locations of the type system descriptions.
+Assume that a type `org.apache.uima.fit.type.Token` is specified in the TSD [path]_org/apache/uima/fit/type/Token.xml_, then the file should have the following contents:
+
+[source]
+----
+classpath*:org/apache/uima/fit/type/Token.xml
+----
+
+[NOTE]
+====
+Mind that the file [path]_types.txt_ is must be located in [path]_META-INF/org.apache.uima.fit_ where [path]_org.apache.uima.fit_ is the name of a sub-directory inside [path]_META-INF_. _We are not using the Java package notation
+          here!_
+====
+
+To specify multiple TSDs, add additional lines to the file.
+If you have a large number of TSDs, you may prefer to add a pattern.
+Assume that we have a large number of TSDs under [path]_org/apache/uima/fit/type_, we can use the following pattern which recursively scans the package [package]#org.apache.uima.fit.type# and all sub-packages for XML files and tries to load them as TSDs.
+
+[source]
+----
+classpath*:org/apache/uima/fit/type/**/*.xml
+----
+
+Try to design your packages structure in a way that TSDs and JCas wrapper classes generated from them are separate from the rest of your code.
+
+If it is not possible or inconvenient to add the `types.txt` file, patterns can also be specified using the system property [parameter]``org.apache.uima.fit.type.import_pattern``.
+Multiple patterns may be specified separated by semicolon:
+
+[source]
+----
+-Dorg.apache.uima.fit.type.import_pattern=\
+  classpath*:org/apache/uima/fit/type/**/*.xml
+----
+
+[NOTE]
+====
+The `\` in the example is used as a line-continuation indicator.
+It and all spaces following it should be ommitted.
+====
+
+== Making index definitions and type priorities auto-detectable
+
+Auto-detection also works for index definitions and type priority definitions.
+For index definitions, the respective file where to register the index definition XML files is [path]_META-INF/org.apache.uima.fit/fsindexes.txt_ and for type priorities, it is [path]_META-INF/org.apache.uima.fit/typepriorities.txt_.
+
+== Using type auto-detection 
+
+The auto-detected type system can be obtained from the `TypeSystemDescriptionFactory`:
+
+[source,java]
+----
+TypeSystemDescription tsd = 
+  TypeSystemDescriptionFactory.createTypeSystemDescription()
+----
+
+Popular factory methods also support auto-detection:
+
+[source,java]
+----
+AnalysisEngine ae = createEngine(MyEngine.class);
+----
+
+== Multiple META-INF/org.apache.uima.fit/types.txt files
+
+uimaFIT supports multiple [path]_types.txt_ files in the classpath (e.g.
+in differnt JARs). The [path]_types.txt_ files are located via Spring using the classpath search pattern: 
+
+[source,java]
+----
+TYPE_MANIFEST_PATTERN = "classpath*:META-INF/org.apache.uima.fit/types.txt"
+----
+
+This resolves to a list URLs pointing to ALL [path]_types.txt_ files.
+The resolved URLs are unique and will point either to a specific point in the file system or into a specific JAR.
+These URLs can be handled by the standard Java URL loading mechanism.
+Example:
+
+[source,java]
+----
+jar:/path/to/syntax-types.jar!/META-INF/org.apache.uima.fit/types.txt 
+jar:/path/to/token-types.jar!/META-INF/org.apache.uima.fit/types.txt
+----
+
+uimaFIT then reads all patters from all of these URLs and uses these to search the classpath again.
+The patterns now resolve to a list of URLs pointing to the individual type system XML descriptors.
+All of these URLs are collected in a set to avoid duplicate loading (for performance optimization - not strictly necessary because the UIMA type system merger can handle compatible duplicates). Then the descriptors are loaded into memory and merged using the standard UIMA type system merger (`CasCreationUtils.mergeTypeSystems()`). Example:
+
+[source]
+----
+jar:/path/to/syntax-types.jar!/desc/types/Syntax.xml 
+jar:/path/to/token-types.jar!/org/foobar/typesystems/Tokens.xml
+----
+
+Voilá, the result is a type system covering all types could be found in the classpath.
+
+It is recommended 
+
+. to put type system descriptors into packages resembling a namespace you "own" and to use a package-scoped wildcard search
++
+[source]
+----
+classpath*:org/apache/uima/fit/type/**/*.xml`
+----
+. or when putting descriptors into a "well-known" package like [package]#desc.type#, that [path]_types.txt_ file should explicitly list all type system descriptors instead of using a wildcard search
++
+[source]
+----
+classpath*:desc/type/Token.xml 
+classpath*:desc/type/Syntax.xml
+----
+
+Method 1 should be preferred.
+Both methods can be mixed. 
+
+== Performance note and caching
+
+Currently uimaFIT evaluates the patterns for TSDs once and caches the locations, but not the actual merged type system description.
+A rescan can be forced using `TypeSystemDescriptionFactory.forceTypeDescriptorsScan()`.
+This may change in future.
+
+== Potential problems
+
+The mechanism works fine.
+However, there are specific issues with Java in general that one should be aware of.
+
+=== m2eclipse fails to copy descriptors to target/classes
+
+There seems to be a bug in some older versions of m2eclipse that causes resources not always to be copied to [path]_target/classes_.
+If UIMA complains about type definitions missing at runtime, try to _clean/rebuild_ your project and carefully check the m2eclipse console in the console view for error messages that might cause m2eclipse to abort.
+
+=== Class version conflicts
+
+A problem can occur if you end up having multiple incompatible versions of the same type system in the classpath.
+This is a general problem and not related to the auto-detection feature.
+It is the same as when you have incompatible version of a particular class (e.g. `JCas` wrapper or some third-party-library) in the classpath.
+The behavior of the Java Classloader is undefined in that case.
+The detection will do its best to try and load everything it can find, but the UIMA type system merger may barf or you may end up with undefined behavior at runtime because one of the class versions is used at random. 
+
+=== Classes and resources in the default package
+
+It is bad practice to place classes into the default (unnamed) package.
+In fact it is not possible to import classes from the default package in another class.
+Similarly it is a bad idea to put resources at the root of the classpath.
+The Spring documentation on resources http://static.springsource.org/spring/docs/3.0.x/reference/resources.html#resources-app-ctx-wildcards-in-resource-paths[explains this in detail].
+
+For this reason the [path]_types.txt_ resides in [path]_/META-INF/org.apache.uima.fit_ and it is suggest that type system descriptors reside either in a proper package like [path]_/org/foobar/typesystems/XXX.xml_ or in [path]_/desc/types/XXX.xml_. 
\ No newline at end of file
diff --git a/uimafit-doc/src/main/asciidoc/tools.uimafit.validation.adoc b/uimafit-doc/src/main/asciidoc/tools.uimafit.validation.adoc
new file mode 100644
index 0000000..41c0c8b
--- /dev/null
+++ b/uimafit-doc/src/main/asciidoc/tools.uimafit.validation.adoc
@@ -0,0 +1,101 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+[[_ugr.tools.uimafit.validation]]
+= Validating CASes
+
+The uimaFIT CAS validation feature allows you to define consistency rules for your type system and
+to automatically check that CASes comply with these rules.
+
+== Example use case
+
+Imagine a system which uses machine learning to automatically identify persons in a text. Such a
+system might define an annotation type called `Person` having a feature called `confidence` of type
+`float`. However, a requirement of the system should be that the confidence score must be within
+range from 0 to 1. Any value outside that range would probably be a bug in the systems
+implementation. Now imagine that you want to implement not only one, but a bunch of different UIMA analysis engines,
+each based on a different machine learning approach and plug these into the system. Instead of
+repeating the test code that checks the range of the confidence feature with each implementation, it
+would be much nicer if the range check could be included with the type system that all these
+implementations share. The unit tests should be able to pick this check (any any other consistency
+checks) up automatically and use them.
+
+
+== Defining a validation check
+
+To define a validation check, all you need to do is to create a class implementing the 
+`org.apache.uima.fit.validation.CasValidationCheck` interface. This interfaces defines a single
+method `List<CasValidationResult> check(CAS cas)`. Or if you prefer working against the JCas API, 
+you can implement the `org.apache.uima.fit.validation.JCasValidationCheck` interface.
+Implementations of both interfaces (`CasValidationCheck` and `JCasValidationCheck`) can be applied
+to CAS as well as JCas instances - so it does not matter against which interface you build your
+check.
+
+[source,java]
+----
+public class ConfidenceRangeCheck implements JCasValidationCheck {
+  @Override
+  public List<ValidationResult> validate(JCas aJCas) throws ValidationException {
+    List<ValidationResult> results = new ArrayList<>();
+    for (Person person : JCasUtil.select(aJCas, Person.class)) {
+      if (person.getConfidence() < 0.0d || person.getConfidence() > 1.0d) {
+        results.add(ValidationResult.error(this, "Invalid confidence score (%f) on %s at [%d,%d]",
+                person.getConfidence(), person.getType().getName(), 
+                person.getBegin(), person.getEnd()));
+      }
+    }
+    return results;
+  }
+}
+----
+
+[NOTE]
+====
+Checks are instantiated by the system as singletons. This means that their implementations must be
+stateless and must have a zero-argument constructor (or no constructor at all). 
+====
+
+
+== Registering the check for auto-detection
+
+uimaFIT uses the Java Service Locator mechanism to locate validation check implementations. So to
+make a check available for auto-detection, its fully-qualified class name must be added to a file 
+`META-INF/services/org.apache.uima.fit.validation.ValidationCheck`. Multiple checks can be added by
+putting each class name on separate lines.
+
+== Validating a CAS
+
+The `org.apache.uima.fit.validation.Validator` class can be used to validate your (J)CASes. This
+class is typically constructed using a builder:
+
+[source,java]
+----
+CAS cas = ...
+
+// By default, the builder auto-detects all registered checks
+Validator validator = new Validator.Builder().build();
+
+// You could also pass in a JCas here instead of a CAS
+ValidationSummary summary = validator.check(cas);
+----
+
+The output of a check is a `ValidationSummary` which contains a bunch of `ValidationResult` items.
+A `ValidationResult` essentially is a message with a severity level. When a summary contains any
+result with an error-level severity, the validation should be considered as failed.
+
+The `Validator.Builder` can be configured, e.g. to exclude certain checks or to entirely disable the
+auto-detection of checks and instead work with only a set of explicitly specified checks.
diff --git a/uimafit-docbook/pom.xml b/uimafit-docbook/pom.xml
deleted file mode 100644
index a9a4b33..0000000
--- a/uimafit-docbook/pom.xml
+++ /dev/null
@@ -1,36 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-	Licensed to the Apache Software Foundation (ASF) under one
-	or more contributor license agreements. See the NOTICE file
-	distributed with this work for additional information
-	regarding copyright ownership. The ASF licenses this file
-	to you under the Apache License, Version 2.0 (the
-	"License"); you may not use this file except in compliance
-	with the License. You may obtain a copy of the License at
-
-	http://www.apache.org/licenses/LICENSE-2.0
-
-	Unless required by applicable law or agreed to in writing,
-	software distributed under the License is distributed on an
-	"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-	KIND, either express or implied. See the License for the
-	specific language governing permissions and limitations
-	under the License.
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-	<modelVersion>4.0.0</modelVersion>
-	<parent>
-		<groupId>org.apache.uima</groupId>
-		<artifactId>uimafit-parent</artifactId>
-		<version>2.5.1-SNAPSHOT</version>
-		<relativePath>../uimafit-parent</relativePath>
-	</parent>
-	<artifactId>uimafit-docbook</artifactId>
-	<name>Apache UIMA uimaFIT - Documentation</name>
-	<packaging>pom</packaging>
-	<properties>
-		<uimaScmProject>${project.artifactId}</uimaScmProject>
-        <bookNameRoot>tools.uimafit.book</bookNameRoot>
-        <maven.deploy.skip>true</maven.deploy.skip>
-	</properties>
-</project>
\ No newline at end of file
diff --git a/uimafit-docbook/src/docbook/common_book_info.xml b/uimafit-docbook/src/docbook/common_book_info.xml
deleted file mode 100644
index 69264a8..0000000
--- a/uimafit-docbook/src/docbook/common_book_info.xml
+++ /dev/null
@@ -1,79 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE bookinfo PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN"
-"http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd">
-<!--
-Licensed to the Apache Software Foundation (ASF) under one
-or more contributor license agreements.  See the NOTICE file
-distributed with this work for additional information
-regarding copyright ownership.  The ASF licenses this file
-to you under the Apache License, Version 2.0 (the
-"License"); you may not use this file except in compliance
-with the License.  You may obtain a copy of the License at
-
-   http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing,
-software distributed under the License is distributed on an
-"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-KIND, either express or implied.  See the License for the
-specific language governing permissions and limitations
-under the License.
--->  
-<bookinfo>
-
-    <releaseinfo>Version <?eval ${project.version}?></releaseinfo>
-
-    <productname>Apache uimaFIT&#8482;</productname>
-
-    <authorgroup>
-      <corpauthor>Written and maintained by the Apache UIMA&#8482; Development Community</corpauthor>
-    </authorgroup>
-
- <!--
-    <mediaobject>
-      <imageobject>
-        <imagedata fileref="images/UIMAlogoLarge.png"/>
-      </imageobject>
-    </mediaobject>
- -->
-    <legalnotice>
-      <para> </para>
-      <formalpara>
-        <title>License and Disclaimer</title>
-
-        <para>The ASF licenses this documentation
-           to you under the Apache License, Version 2.0 (the
-           "License"); you may not use this documentation except in compliance
-           with the License.  You may obtain a copy of the License at
-         
-         <blockquote>
-           <para><ulink url="http://www.apache.org/licenses/LICENSE-2.0"/></para>
-         </blockquote>
-         
-           Unless required by applicable law or agreed to in writing,
-           this documentation and its contents are distributed under the License 
-           on an 
-           "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-           KIND, either express or implied.  See the License for the
-           specific language governing permissions and limitations
-           under the License.
-         </para>
-      </formalpara>
-      <para> </para>
-      <para> </para>
-      <formalpara>
-        <title>Trademarks</title>
-        <para>All terms mentioned in the text that are known to be trademarks or 
-        service marks have been appropriately capitalized.  Use of such terms
-        in this book should not be regarded as affecting the validity of the
-        the trademark or service mark.
-        </para>
-      </formalpara>
-    </legalnotice>
-    <copyright>
-      <year><?eval ${project.inceptionYear}?></year>
-      <year><?eval ${project.properties.buildYear}?></year>
-      <holder>The Apache Software Foundation</holder>
-    </copyright>
-    <pubdate><?eval ${project.properties.buildMonth}?>, <?eval ${project.properties.buildYear}?></pubdate>
-  </bookinfo>
\ No newline at end of file
diff --git a/uimafit-docbook/src/docbook/tools.uimafit.book.xml b/uimafit-docbook/src/docbook/tools.uimafit.book.xml
deleted file mode 100644
index 3e9b5e6..0000000
--- a/uimafit-docbook/src/docbook/tools.uimafit.book.xml
+++ /dev/null
@@ -1,49 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN"
-"http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd">
-<!--
-Licensed to the Apache Software Foundation (ASF) under one
-or more contributor license agreements.  See the NOTICE file
-distributed with this work for additional information
-regarding copyright ownership.  The ASF licenses this file
-to you under the Apache License, Version 2.0 (the
-"License"); you may not use this file except in compliance
-with the License.  You may obtain a copy of the License at
-
-   http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing,
-software distributed under the License is distributed on an
-"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-KIND, either express or implied.  See the License for the
-specific language governing permissions and limitations
-under the License.
--->
-<book lang="en">
-  <title>Apache uimaFIT&#8482; Guide and Reference</title>
-  <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="common_book_info.xml"/>
-    
-  <toc/>
-
-  <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="tools.uimafit.introduction.xml"/>
-  
-  <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="tools.uimafit.gettingstarted.xml"/>
-
-  <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="tools.uimafit.pipelines.xml"/>
-
-  <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="tools.uimafit.experiments.xml"/>
-
-  <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="tools.uimafit.casutil.xml"/>
-  
-  <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="tools.uimafit.configurationparameters.xml"/>
-
-  <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="tools.uimafit.externalresources.xml"/>
-
-  <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="tools.uimafit.typesystem.xml"/>
-
-  <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="tools.uimafit.packaging.xml"/>
-
-  <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="tools.uimafit.maven.xml"/>
-
-  <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="tools.uimafit.migration.xml"/>
-</book>
diff --git a/uimafit-docbook/src/docbook/tools.uimafit.casutil.xml b/uimafit-docbook/src/docbook/tools.uimafit.casutil.xml
deleted file mode 100644
index 746cffb..0000000
--- a/uimafit-docbook/src/docbook/tools.uimafit.casutil.xml
+++ /dev/null
@@ -1,122 +0,0 @@
-<!--
-	Licensed to the Apache Software Foundation (ASF) under one
-	or more contributor license agreements. See the NOTICE file
-	distributed with this work for additional information
-	regarding copyright ownership. The ASF licenses this file
-	to you under the Apache License, Version 2.0 (the
-	"License"); you may not use this file except in compliance
-	with the License. You may obtain a copy of the License at
-
-	http://www.apache.org/licenses/LICENSE-2.0
-
-	Unless required by applicable law or agreed to in writing,
-	software distributed under the License is distributed on an
-	"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-	KIND, either express or implied. See the License for the
-	specific language governing permissions and limitations
-	under the License.
--->
-<chapter id="ugr.tools.uimafit.casutil">
-  <title>CAS Utilities</title>
-  <para>uimaFIT facilitates working with the CAS and JCas by offering various convenient methods for
-    accessing and navigating annotations and feature structures. Additionally, the the convenience
-    methods for JCas access are fully type-safe and return the JCas type or a collection of the JCas
-    type which you wanted to access.</para>
-  <section>
-    <title>Access methods</title>
-    <para>uimaFIT supports the following convenience methods for accessing CAS and JCas structures.
-      All methods respect the UIMA index definitions and return annotations or feature structures in
-      the order defined by the indexes. Unless the default UIMA index for annotations has been
-      overwritten, annotations are returned sorted by begin (increasing) and end
-      (decreasing).</para>
-    <itemizedlist>
-      <listitem>
-        <para><code>select(cas, type)</code> - fetch all annotations of the given type from the
-          CAS/JCas. Variants of this method also exist to fetch annotations from a
-            <type>FSList</type> or <type>FSArray</type>.</para>
-      </listitem>
-      <listitem>
-        <para><code>selectAll(cas)</code> - fetch all annotations from the CAS or fetch all feature
-          structures from the JCas.</para>
-      </listitem>
-      <listitem>
-        <para><code>selectBetween(type, annotation1, annotation2)</code>* - fetch all annotations
-          between the given two annotations.</para>
-      </listitem>
-      <listitem>
-        <para><code>selectCovered(type, annotation)</code>* - fetch all annotations covered by the
-          given annotation. If this operation is used intensively, <code>indexCovered(...)</code>
-          should be used to pre-calculate annotation covering information.</para>
-      </listitem>
-      <listitem>
-        <para><code>selectCovering(type, annotation)*</code> - fetch all annotations covering the
-          given annotation. If this operation is used intensively, <code>indexCovering(...)</code>
-          should be used to pre-calculate annotation covering information.</para>
-      </listitem>
-      <listitem>
-        <para><code>selectByIndex(cas, type, n)</code> - fetch the n-th feature structure of the
-          given type.</para>
-      </listitem>
-      <listitem>
-        <para><code>selectSingle(cas, type)</code> - fetch the single feature structure of the given
-          type. An exception is thrown if there is not exactly one feature structure of the type.
-        </para>
-      </listitem>
-      <listitem>
-        <para><code>selectSingleRelative(type, annotation, n)</code>* - fetch a single annotation
-          relative to the given annotation. A positive <parameter>n</parameter> fetches the n-th
-          annotation right of the specified annotation, while the a negative
-            <parameter>n</parameter> fetches to the left.</para>
-      </listitem>
-      <listitem>
-        <para><code>selectPreceding(type, annotation, n)</code>* - fetch the n annotations preceding
-          the given annotation. If there are less then n preceding annotations, all preceding
-          annotations are returned.</para>
-      </listitem>
-      <listitem>
-        <para><code>selectFollowing(type, annotation, n)</code>* - fetch the n annotations following
-          the given annotation. If there are less then n following annotations, all following
-          annotations are returned.</para>
-      </listitem>
-    </itemizedlist>
-    <note>
-      <para>For historical reasons, the method marked with * also exist in a version that accepts a
-        CAS/JCas as the first argument. These may not work as expected when the annoation arguments
-        provided to the method are from a different CAS/JCas/view. Also, for any method accepting
-        two annotations, these should come from the same CAS/JCas/view. In future, the potentially
-        problematic signatures may be deprecated, removed, or throw exeptions if these conditions
-        are not met.</para>
-    </note>
-    <note>
-      <para>You should expect the structures returned by these methods to be backed by the CAS/JCas
-        contents. In particular, if you remove any feature structures from the CAS while iterating
-        over these structures may cause failures. For this reason, you should also not hold on to
-        these structures longer than necessary, as is the case for UIMA <code>FSIterator</code>s as
-        well.</para>
-    </note>
-    <para>Depending on whether one works with a CAS or JCas, the respective methods are available
-      from the JCasUtil or CasUtil classes. </para>
-    <para>JCasUtil expect a JCas wrapper class for the <parameter>type</parameter> argument, e.g.
-        <code>select(jcas, Token.class)</code> and return this type or a collection using this
-      generic type. Any subtypes of the specified type are returned as well. CasUtil expects a UIMA
-        <type>Type</type> instance. For conveniently getting these, CasUtil offers the methods
-        <code>getType(CAS, Class&lt;?>)</code> or <code>getType(CAS, String)</code> which fetch a
-      type either by its JCas wrapper class or by its name.</para>
-    <para>Unless annotations are specifically required, e.g. because begin/end offsets are required,
-      the JCasUtil methods can be used to access any feature structure inheriting from
-        <type>TOP</type>, not only annotations. The CasUtil methods generally work only on
-      annotations. Alternative methods ending in "FS" are provided for accessing arbitrary feature
-      structures, e.g. <code>selectFS</code>.</para>
-    <para>Examples:</para>
-    <programlisting>// CAS version
-Type tokenType = CasUtil.getType(cas, "my.Token");
-for (AnnotationFS token : CasUtil.select(cas, tokenType)) {
-  ...
-}
-
-// JCas version
-for (Token token : JCasUtil.select(jcas, Token.class)) {
-  ...
-}</programlisting>
-  </section>
-</chapter>
diff --git a/uimafit-docbook/src/docbook/tools.uimafit.configurationparameters.xml b/uimafit-docbook/src/docbook/tools.uimafit.configurationparameters.xml
deleted file mode 100644
index fd277e4..0000000
--- a/uimafit-docbook/src/docbook/tools.uimafit.configurationparameters.xml
+++ /dev/null
@@ -1,185 +0,0 @@
-<!--
-	Licensed to the Apache Software Foundation (ASF) under one
-	or more contributor license agreements. See the NOTICE file
-	distributed with this work for additional information
-	regarding copyright ownership. The ASF licenses this file
-	to you under the Apache License, Version 2.0 (the
-	"License"); you may not use this file except in compliance
-	with the License. You may obtain a copy of the License at
-
-	http://www.apache.org/licenses/LICENSE-2.0
-
-	Unless required by applicable law or agreed to in writing,
-	software distributed under the License is distributed on an
-	"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-	KIND, either express or implied. See the License for the
-	specific language governing permissions and limitations
-	under the License.
--->
-<chapter id="ugr.tools.uimafit.configurationparameters">
-  <title>Configuration Parameters</title>
-  <para>uimaFIT defines the <classname>@ConfigurationParameter</classname> annotation which can be
-    used to annotate the fields of an analysis engine or collection reader. The purpose of this
-    annotation is twofold:<itemizedlist>
-      <listitem>
-        <para>injection of parameters from the UIMA context into fields</para>
-      </listitem>
-      <listitem>
-        <para>declaration of parameter metadata (mandatory, default value, description) which can be
-          used to generate XML descriptors</para>
-      </listitem>
-    </itemizedlist>In a regular UIMA component, parameters need to be manually extracted from the
-    UIMA context, typically requiring a type cast. </para>
-  <programlisting format="linespecific">class MyAnalysisEngine extends CasAnnotator_ImplBase {
-  public static final String PARAM_SOURCE_DIRECTORY = "sourceDirectory";
-  private File sourceDirectory;
-
-  public void initialize(UimaContext context) 
-      throws ResourceInitializationException {
-
-    sourceDirectory = new File((String) context.getConfigParameterValue(
-      PARAM_SOURCE_DIRECTORY));
-  }
-}</programlisting>
-  <para>The component has no way to declare a default value or to declare if a parameter is optional
-    or mandatory. In addition, any documentation needs to be maintained in !JavaDoc and in the XML
-    descriptor for the component.</para>
-  <para>With uimaFIT, all this information can be declared in the component using the
-      <classname>@ConfigurationParameter</classname> annotation.<table frame="all">
-      <title><classname>@ConfigurationParameter</classname> annotation</title>
-      <tgroup cols="3">
-        <colspec colname="c1" colnum="1" colwidth="1.0*"/>
-        <colspec colname="c2" colnum="2" colwidth="1*"/>
-        <colspec colname="c3" colnum="3" colwidth="1.0*"/>
-        <thead>
-          <row>
-            <entry>Parameter</entry>
-            <entry>Description</entry>
-            <entry>Default</entry>
-          </row>
-        </thead>
-        <tbody>
-          <row>
-            <entry>name</entry>
-            <entry>parameter name</entry>
-            <entry>name of annotated field</entry>
-          </row>
-          <row>
-            <entry>description</entry>
-            <entry>description of the parameter</entry>
-            <entry/>
-          </row>
-          <row>
-            <entry>mandatory</entry>
-            <entry>whether a non-null value must be specified </entry>
-            <entry>true</entry>
-          </row>
-          <row>
-            <entry>defaultValue</entry>
-            <entry>the default value if no value is specified</entry>
-            <entry/>
-          </row>
-        </tbody>
-      </tgroup>
-    </table></para>
-  <programlisting>class MyAnalysisEngine 
-    extends org.apache.uima.fit.component.CasAnnotator_ImplBase {
-
-  /**
-   * Directory to read the data from.
-   */
-  public static final String PARAM_SOURCE_DIRECTORY = "sourceDirectory";
-  @ConfigurationParameter(name=PARAM_SOURCE_DIRECTORY, defaultValue=".")
-  private File sourceDirectory;
-}</programlisting>
-  <para>Note, that it is no longer necessary to implement the <methodname>initialize()</methodname>
-    method. uimaFIT takes care of locating the parameter <parameter>sourceDirectory</parameter> in
-    the UIMA context. It recognizes that the <classname>File</classname> class has a
-      <classname>String</classname> constructor and uses that to instantiate a new
-      <classname>File</classname> object from the parameter. A parameter is mandatory unless
-    specified otherwise. If a mandatory parameter is not specified in the context, an exception is
-    thrown.</para>
-  <para>The <parameter>defaultValue</parameter> is used when generating an UIMA component
-    description from the class. It should be pointed out in particular, that uimaFIT does not make
-    use of the default value when injecting parameters into fields. For this reason, it is possible
-    to have a parameter that is mandatory but does have a default value. The default value is used
-    as a parameter value when a component description is generated via the uimaFIT factories unless
-    a parameter is specified in the factory call. If a component description in created manually
-    without specifying a value for a mandatory parameter, uimaFIT will generate an exception.</para>
-  <note>
-    <para>You can use the <emphasis>enhance</emphasis> goal of the uimaFIT Maven plugin to pick up
-      the parameter description from the JavaDoc and post it to the
-        <parameter>description</parameter> field of the
-        <classname>@ConfigurationParameter</classname> annotation. This should be preferred to
-      specifying the description explicitly as part of the annotation.</para>
-  </note>
-  <para>The parameter injection mechanism is implemented in the
-      <classname>ConfigurationParameterInitializer</classname> class. uimaFIT provides several base
-    classes that already come with an <methodname>initialize()</methodname> method using the
-    initializer:</para>
-  <itemizedlist>
-    <listitem>
-      <para><classname>CasAnnotator_ImplBase</classname>`</para>
-    </listitem>
-    <listitem>
-      <para><classname>CasCollectionReader_ImplBase</classname></para>
-    </listitem>
-    <listitem>
-      <para><classname>CasConsumer_ImplBase</classname></para>
-    </listitem>
-    <listitem>
-      <para><classname>CasFlowController_ImplBase</classname></para>
-    </listitem>
-    <listitem>
-      <para><classname>CasMultiplier_ImplBase</classname></para>
-    </listitem>
-    <listitem>
-      <para><classname>JCasAnnotator_ImplBase</classname></para>
-    </listitem>
-    <listitem>
-      <para><classname>JCasCollectionReader_ImplBase</classname></para>
-    </listitem>
-    <listitem>
-      <para><classname>JCasConsumer_ImplBase</classname></para>
-    </listitem>
-    <listitem>
-      <para><classname>JCasFlowController_ImplBase</classname></para>
-    </listitem>
-    <listitem>
-      <para><classname>JCasMultiplier_ImplBase</classname></para>
-    </listitem>
-    <listitem>
-      <para><classname>Resource_ImplBase</classname></para>
-    </listitem>
-  </itemizedlist>
-  <para>The <classname>ConfigurationParameterInitializer</classname> can also be used with shared
-    resources:</para>
-  <programlisting>class MySharedResourceObject implements SharedResourceObject {
-  public static final String PARAM_VALUE = "Value";
-  @ConfigurationParameter(name = PARAM_VALUE, mandatory = true)
-  private String value;
-
-  public void load(DataResource aData)
-      throws ResourceInitializationException {
-
-    ConfigurationParameterInitializer.initialize(this, aData);
-  }
-}</programlisting>
-  <para>Fields that can be annotated with the <classname>@ConfigurationParameter</classname>
-    annotation are any array or collection types (including if they are only typed via interfaces
-    such as <type>List</type> or <type>Set</type>) of primitive types (<type>int</type>,
-      <type>boolean</type>, <type>float</type>, <type>double</type>). Enum types, as well as, 
-      fields of the types 
-      <classname>Charset</classname>, 
-      <classname>File</classname>, 
-      <classname>Locale</classname>, 
-      <classname>Pattern</classname>,
-      <classname>URI</classname>, and
-      <classname>URL</classname> can also be used. 
-      These can be initialized either using an object value (e.g. <code>StandardChartsets.UTF_8</code>)
-      or a string value (e.g. <code>"UTF-8"</code>).
-      Additionally it is possible to inject any fields of types that define a constructor accepting
-      a single <classname>String</classname>. These must be initialized from a string value.</para>
-  <para>Multi-valued parameters can be initialized from single values without having to wrap these
-      into a container.</para>
-</chapter>
diff --git a/uimafit-docbook/src/docbook/tools.uimafit.experiments.xml b/uimafit-docbook/src/docbook/tools.uimafit.experiments.xml
deleted file mode 100644
index e01c151..0000000
--- a/uimafit-docbook/src/docbook/tools.uimafit.experiments.xml
+++ /dev/null
@@ -1,60 +0,0 @@
-<!--
-	Licensed to the Apache Software Foundation (ASF) under one
-	or more contributor license agreements. See the NOTICE file
-	distributed with this work for additional information
-	regarding copyright ownership. The ASF licenses this file
-	to you under the Apache License, Version 2.0 (the
-	"License"); you may not use this file except in compliance
-	with the License. You may obtain a copy of the License at
-
-	http://www.apache.org/licenses/LICENSE-2.0
-
-	Unless required by applicable law or agreed to in writing,
-	software distributed under the License is distributed on an
-	"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-	KIND, either express or implied. See the License for the
-	specific language governing permissions and limitations
-	under the License.
--->
-<chapter id="ugr.tools.uimafit.experiments">
-  <title>Running Experiments</title>
-  <para>The <emphasis>uimafit-examples</emphasis> module contains a package
-      <package>org.apache.uima.fit.examples.experiment.pos</package> which demonstrates a very simple
-    experimental setup for testing a part-of-speech tagger. You may find this example more
-    accessible if you check out the code from subversion and build it in your own
-    environment.</para>
-  <para>The documentation for this example can be found in the code itself. Please refer to
-      <classname>RunExperiment</classname> as a starting point. The following is copied from the
-    javadoc comments of that file:</para>
-  <blockquote>
-    <para><classname>RunExperiment</classname> demonstrates a very common (though simplified)
-      experimental setup in which gold standard data is available for some task and you want to
-      evaluate how well your analysis engine works against that data. Here we are evaluating
-        <classname>BaselineTagger</classname> which is a (ridiculously) simple part-of-speech tagger
-      against the part-of-speech tags found in
-        <filename>src/main/resources/org/apache/uima/fit/examples/pos/sample-gold.txt</filename></para>
-  </blockquote>
-  <para>The basic strategy is as follows:</para>
-  <itemizedlist>
-    <listitem>
-      <para>post the data <emphasis>as is</emphasis> into the default view,</para>
-    </listitem>
-    <listitem>
-      <para>parse the gold-standard tokens and part-of-speech tags and put the results into another
-        view we will call <emphasis>GOLD_VIEW</emphasis>,</para>
-    </listitem>
-    <listitem>
-      <para>create another view called <emphasis>SYSTEM_VIEW</emphasis> and copy the text and
-          <classname>Token</classname> annotations from the <emphasis>GOLD_VIEW</emphasis> into this
-        view,</para>
-    </listitem>
-    <listitem>
-      <para>run the <classname>BaselineTagger</classname> on the <emphasis>SYSTEM_VIEW</emphasis>
-        over the copied <classname>Token</classname> annoations,</para>
-    </listitem>
-    <listitem>
-      <para>evaluate the part-of-speech tags found in the <emphasis>SYSTEM_VIEW</emphasis> with
-        those in the <emphasis>GOLD_VIEW.</emphasis></para>
-    </listitem>
-  </itemizedlist>
-</chapter>
diff --git a/uimafit-docbook/src/docbook/tools.uimafit.externalresources.xml b/uimafit-docbook/src/docbook/tools.uimafit.externalresources.xml
deleted file mode 100644
index 970f0ae..0000000
--- a/uimafit-docbook/src/docbook/tools.uimafit.externalresources.xml
+++ /dev/null
@@ -1,321 +0,0 @@
-<!--
-	Licensed to the Apache Software Foundation (ASF) under one
-	or more contributor license agreements. See the NOTICE file
-	distributed with this work for additional information
-	regarding copyright ownership. The ASF licenses this file
-	to you under the Apache License, Version 2.0 (the
-	"License"); you may not use this file except in compliance
-	with the License. You may obtain a copy of the License at
-
-	http://www.apache.org/licenses/LICENSE-2.0
-
-	Unless required by applicable law or agreed to in writing,
-	software distributed under the License is distributed on an
-	"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-	KIND, either express or implied. See the License for the
-	specific language governing permissions and limitations
-	under the License.
--->
-<chapter id="ugr.tools.uimafit.externalresources">
-  <title>External Resources</title>
-  <para>An analysis engine often uses some data model. This may be as simple as word frequency
-    counts or as complex as the model of a parser. Often these models can become quite large. If an
-    analysis engine is deployed multiple times in the same pipeline or runs on multiple CPU cores,
-    memory can be saved by using a shared instance of the data model. UIMA supports such a scenario
-    by so-called external resources. The following sections illustrates how external resources can
-    be used with uimaFIT.</para>
-  <para>First create a class for the shared data model. Usually this class would load its data from
-    some URI and then expose it via its methods. An example would be to load word frequency counts
-    and to provide a <methodname>getFrequency()</methodname> method. In our simple example we do not
-    load anything from the provided URI - we just offer a method to get the URI from which data be
-    loaded.</para>
-  <programlisting>// Simple model that only stores the URI it was loaded from. Normally data
-// would be loaded from the URI instead and made accessible through methods
-// in this class. This simple example only allows accessing the URI.
-public static final class SharedModel implements SharedResourceObject {
-  private String uri;
-
-  public void load(DataResource aData) 
-      throws ResourceInitializationException {
-
-    uri = aData.getUri().toString();
-  }
-
-  public String getUri() { return uri; }
-}</programlisting>
-  <section>
-    <title>Resource injection</title>
-    <section>
-      <title>Regular UIMA components</title>
-      <para>When an external resource is used in a regular UIMA component, it is usually fetched
-        from the context, cast and copied to a class member variable.</para>
-      <programlisting>class MyAnalysisEngine extends CasAnnotator_ImplBase {
-  final static String MODEL_KEY = "Model";
-  private SharedModel model;
-
-  public void initialize(UimaContext context) 
-      throws ResourceInitializationException {
-
-    configuredResource = (SharedModel) 
-      getContext().getResourceObject(MODEL_KEY);
-  }
-}</programlisting>
-      <para>uimaFIT can be used to inject external resources into such traditional components using
-        the <methodname>createDependencyAndBind()</methodname> method. To show that this works with
-        any off-the-shelf UIMA component, the following example uses uimaFIT to configure the
-        OpenNLP Tokenizer:</para>
-      <programlisting>// Create descriptor
-AnalysisEngineDescription tokenizer = createEngineDescription(
-  Tokenizer.class,
-  UimaUtil.TOKEN_TYPE_PARAMETER, Token.class.getName(),
-  UimaUtil.SENTENCE_TYPE_PARAMETER, Sentence.class.getName());
-
-// Create the external resource dependency for the model and bind it
-createDependencyAndBind(tokenizer, UimaUtil.MODEL_PARAMETER,
-  TokenizerModelResourceImpl.class,
-  "http://opennlp.sourceforge.net/models-1.5/en-token.bin");</programlisting>
-      <note>
-        <para>We recommend declaring parameter constants in the classes that use them, e.g. here
-        in  <classname>Tokenizer</classname>. This way, the parameters for a class can be found
-        easily. However, OpenNLP declares parameters centrally in <classname>UimaUtil</classname>.
-        Thus, the example above is correct, although unconvential.</para>
-      </note>
-      <note>
-        <para>Note that uimaFIT is unable to perform type-coercion on parameters if a descriptor
-          is created from a class that does not contain <classname>@ConfigurationParameter</classname>
-          annotations, such as the OpenNLP <classname>Tokenizer</classname>. Such a descriptor does
-          not contain any parameter declarations! However, it is
-          still possible to configure such a component using uimaFIT by passing exactly the expected
-          types as parameter values. Thus, we need use the <methodname>getName()</methodname> method 
-          to get the class name as a string, instead of simply passing the class itself. Also, setting
-          multi-valued parameter from a list or single value does not work here. Multi-values parameters
-          must be passed as an array of the required type. Only the default UIMA types are possible:
-          <type>String</type>, <type>boolean</type>, <type>int</type>, and <type>float</type>.</para>
-      </note>
-    </section>
-    <section>
-      <title>uimaFIT-aware components</title>
-      <para>uimaFIT provides the <classname>@ExternalResource</classname> annotation to inject
-        external resources directly into class member variables.</para>
-      <table frame="all">
-        <title><classname>@ExternalResource</classname> annotation</title>
-        <tgroup cols="3">
-          <colspec colname="c1" colnum="1" colwidth="1.0*"/>
-          <colspec colname="c2" colnum="2" colwidth="1.0*"/>
-          <colspec colname="c3" colnum="3" colwidth="1.0*"/>
-          <thead>
-            <row>
-              <entry>Parameter</entry>
-              <entry>Description</entry>
-              <entry>Default</entry>
-            </row>
-          </thead>
-          <tbody>
-            <row>
-              <entry>key</entry>
-              <entry>Resource key</entry>
-              <entry>field name</entry>
-            </row>
-            <row>
-              <entry>api</entry>
-              <entry>Used when the external resource type is different from the field type, e.g.
-                when using an ExternalResourceLocator</entry>
-              <entry>field type</entry>
-            </row>
-            <row>
-              <entry>mandatory</entry>
-              <entry>Whether a value must be specified</entry>
-              <entry>true</entry>
-            </row>
-          </tbody>
-        </tgroup>
-      </table>
-      <programlisting>// Example annotator that uses the SharedModel. In the process() we only
-// test if the model was properly initialized by uimaFIT
-public static class Annotator 
-    extends org.apache.uima.fit.component.JCasAnnotator_ImplBase {
-
-  final static String MODEL_KEY = "Model";
-  @ExternalResource(key = MODEL_KEY)
-  private SharedModel model;
-
-  public void process(JCas aJCas) throws AnalysisEngineProcessException {
-    assertTrue(model.getUri().endsWith("gene_model_v02.bin"));
-    // Prints the instance ID to the console - this proves the same
-    // instance of the SharedModel is used in both Annotator instances.
-    System.out.println(model);
-  }
-}</programlisting>
-      <para>Note, that it is no longer necessary to implement the
-          <methodname>initialize()</methodname> method. uimaFIT takes care of locating the external
-        resource <parameter>Model</parameter> in the UIMA context and assigns it to the field
-          <varname>model</varname>. If a mandatory resource is not present in the context, an
-        exception is thrown.</para>
-      <para>The resource injection mechanism is implemented in the
-          <classname>ExternalResourceInitializer</classname> class. uimaFIT provides several base
-        classes that already come with an <methodname>initialize()</methodname> method using the
-        initializer:</para>
-      <itemizedlist>
-        <listitem>
-          <para><classname>CasAnnotator_ImplBase</classname></para>
-        </listitem>
-        <listitem>
-          <para><classname>CasCollectionReader_ImplBase</classname></para>
-        </listitem>
-        <listitem>
-          <para><classname>CasConsumer_ImplBase</classname></para>
-        </listitem>
-        <listitem>
-          <para><classname>CasFlowController_ImplBase</classname></para>
-        </listitem>
-        <listitem>
-          <para><classname>CasMultiplier_ImplBase</classname></para>
-        </listitem>
-        <listitem>
-          <para><classname>JCasAnnotator_ImplBase</classname></para>
-        </listitem>
-        <listitem>
-          <para><classname>JCasCollectionReader_ImplBase</classname></para>
-        </listitem>
-        <listitem>
-          <para><classname>JCasConsumer_ImplBase</classname></para>
-        </listitem>
-        <listitem>
-          <para><classname>JCasFlowController_ImplBase</classname></para>
-        </listitem>
-        <listitem>
-          <para><classname>JCasMultiplier_ImplBase</classname></para>
-        </listitem>
-        <listitem>
-          <para><classname>Resource_ImplBase</classname></para>
-        </listitem>
-      </itemizedlist>
-      <para>When building a pipeline, external resources can be set of a component just like
-        configuration parameters. External resources and configuration parameters can be mixed and
-        appear in any order when creating a component description.</para>
-      <para>Note that in the following example, we create only one external resource description and
-        use it to configure two different analysis engines. Because we only use a single
-        description, also only a single instance of the external resource is created and shared
-        between the two engines.
-        <programlisting>ExternalResourceDescription extDesc = createExternalResourceDescription(
-  SharedModel.class, new File("somemodel.bin"));
-		
-// Binding external resource to each Annotator individually
-AnalysisEngineDescription aed1 = createEngineDescription(
-  Annotator.class,
-  Annotator.MODEL_KEY, extDesc);
-
-AnalysisEngineDescription aed2 = createEngineDescription(
-  Annotator.class,
-  Annotator.MODEL_KEY, extDesc);
-
-// Check the external resource was injected
-AnalysisEngineDescription aaed = createEngineDescription(aed1, aed2);
-AnalysisEngine ae = createEngine(aaed);
-ae.process(ae.newJCas());</programlisting></para>
-      <para>This example is given as a full JUnit-based example in the the
-          <emphasis>uimaFIT-examples</emphasis> project.</para>
-    </section>
-    <section>
-      <title>Resources extending Resource_ImplBase</title>
-      <para>One kind of resources extend <classname>Resource_ImplBase</classname>. These are the
-        easiest to handle, because uimaFIT's version of <classname>Resource_ImplBase</classname>
-        already implements the necessary logic. Just be sure to call
-          <methodname>super.initialize()</methodname> when overriding
-          <methodname>initialize()</methodname>. Also mind that external resources are not available
-        yet when <methodname>initialize()</methodname> is called. For any initialization logic that
-        requires resources, override and implement
-          <methodname>afterResourcesInitialized()</methodname>. Other than that, injection of
-        external resources works as usual.</para>
-      <programlisting>public static class ChainableResource extends Resource_ImplBase {
-  public final static String PARAM_CHAINED_RESOURCE = "chainedResource";
-  @ExternalResource(key = PARAM_CHAINED_RESOURCE)
-  private ChainableResource chainedResource;
-
-  public void afterResourcesInitialized() {
-    // init logic that requires external resources
-  }
-}</programlisting>
-    </section>
-    <section>
-      <title>Resources implementing SharedResourceObject</title>
-      <para>The other kind of resources implement
-          <interfacename>SharedResourceObject</interfacename>. Since this is an interface, uimaFIT
-        cannot provide the initialization logic, so you have to implement a couple of things in the
-        resource:</para>
-      <itemizedlist>
-        <listitem>
-          <para>implement <interfacename>ExternalResourceAware</interfacename></para>
-        </listitem>
-        <listitem>
-          <para>declare a configuration parameter
-              <constant>ExternalResourceFactory.PARAM_RESOURCE_NAME</constant> and return its value
-            in <methodname>getResourceName()</methodname></para>
-        </listitem>
-        <listitem>
-          <para>invoke <methodname>ConfigurationParameterInitializer.initialize()</methodname> in
-            the <methodname>load()</methodname> method.</para>
-        </listitem>
-      </itemizedlist>
-      <para>Again, mind that external resource not properly initialized until uimaFIT invokes
-          <methodname>afterResourcesInitialized()</methodname>.</para>
-      <programlisting>public class TestSharedResourceObject implements 
-    SharedResourceObject, ExternalResourceAware {
-
-  @ConfigurationParameter(name=ExternalResourceFactory.PARAM_RESOURCE_NAME)
-  private String resourceName;
-
-  public final static String PARAM_CHAINED_RESOURCE = "chainedResource";
-  @ExternalResource(key = PARAM_CHAINED_RESOURCE)
-  private ChainableResource chainedResource;
-
-  public String getResourceName() {
-    return resourceName;
-  }
-
-  public void load(DataResource aData) 
-      throws ResourceInitializationException {
-
-    ConfigurationParameterInitializer.initialize(this, aData);
-    // rest of the init logic that does not require external resources
-  }
-
-  public void afterResourcesInitialized() {
-   // init logic that requires external resources
-  }
-}</programlisting>
-    </section>
-    <section>
-      <title>Note on injecting resources into resources</title>
-      <para>Nested resources are only initialized if they are used in a pipeline which contains at
-        least one component that calls
-          <methodname>ConfigurationParameterInitializer.initialize()</methodname>. Any component
-        extending uimaFIT's component base classes qualifies. If you use nested resources in a
-        pipeline without any uimaFIT-aware components, you can just add uimaFIT's
-          <classname>NoopAnnotator</classname> to the pipeline.</para>
-    </section>
-  </section>
-  <section>
-    <title>Resource locators</title>
-    <para>Normally, in UIMA an external resource needs to implement either
-        <interfacename>SharedResourceObject</interfacename> or
-        <interfacename>Resource</interfacename>. In order to inject arbitrary objects, uimaFIT has
-      the concept of <interfacename>ExternalResourceLocator</interfacename>. When a resource
-      implements this interface, not the resource itself is injected, but the method
-        <methodname>getResource()</methodname> is called on the resource and the result is injected.
-      The following example illustrates how to inject an object from JNDI into a UIMA
-      component:</para>
-    <programlisting>class MyAnalysisEngine2 extends JCasAnnotator_ImplBase {
-  static final String RES_DICTIONARY = "dictionary";
-  @ExternalResource(key = RES_DICTIONARY)
-  Dictionary dictionary;
-}
-
-AnalysisEngineDescription desc = createEngineDescription(
-  MyAnalysisEngine2.class);
-
-bindResource(desc, MyAnalysisEngine2.RES_DICTIONARY, 
-  JndiResourceLocator.class,
-  JndiResourceLocator.PARAM_NAME, "dictionaries/german");</programlisting>
-  </section>
-</chapter>
diff --git a/uimafit-docbook/src/docbook/tools.uimafit.gettingstarted.xml b/uimafit-docbook/src/docbook/tools.uimafit.gettingstarted.xml
deleted file mode 100644
index 3ab1dc5..0000000
--- a/uimafit-docbook/src/docbook/tools.uimafit.gettingstarted.xml
+++ /dev/null
@@ -1,141 +0,0 @@
-<!--
-	Licensed to the Apache Software Foundation (ASF) under one
-	or more contributor license agreements. See the NOTICE file
-	distributed with this work for additional information
-	regarding copyright ownership. The ASF licenses this file
-	to you under the Apache License, Version 2.0 (the
-	"License"); you may not use this file except in compliance
-	with the License. You may obtain a copy of the License at
-
-	http://www.apache.org/licenses/LICENSE-2.0
-
-	Unless required by applicable law or agreed to in writing,
-	software distributed under the License is distributed on an
-	"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-	KIND, either express or implied. See the License for the
-	specific language governing permissions and limitations
-	under the License.
--->
-<chapter id="ugr.tools.uimafit.gettingstarted">
-  <title>Getting Started</title>
-
-  <para>This quick start tutorial demonstrates how to use uimaFIT to define and set a configuration
-    parameter in an analysis engine, run it, and generate a descriptor file for it. The complete
-    code for this example can be found in the <emphasis>uimaFIT-examples</emphasis> module.</para>
-  <section>
-    <title>Adding uimaFIT to your project</title>
-    <para>The following instructions describe how to add uimaFIT to your project's classpath.</para>
-    <section>
-      <title>Maven users</title>
-      <para>If you use Maven, then uimaFIT can be added to your project by simply adding uimaFIT as
-        a project dependency by adding the following snippet of XML to your pom.xml file:</para>
-      <programlisting>&lt;dependency>
-  &lt;groupId>org.apache.uima&lt;/groupId>
-  &lt;artifactId>uimafit-core&lt;/artifactId>
-  &lt;version><?eval ${project.version}?>&lt;/version>
-&lt;/dependency></programlisting>
-      <para>uimaFIT distributions are hosted by Maven Central and so no repository needs to be added
-        to your pom.xml file. </para>
-    </section>
-    <section>
-      <title>Non-Maven users</title>
-      <para>If you do not build with Maven, then download uimaFIT from the <ulink
-          url="http://uima.apache.org/downloads.cgi">Apache UIMA downloads page</ulink>. The file
-        name should be uimafit-<?eval ${project.version}?>-bin.zip. Download and unpack this file.
-        The contents of the resulting upacked directory will contain a directory called
-          <filename>lib</filename>. Add all of the files in this directory to your classpath.</para>
-    </section>
-  </section>
-
-  <section>
-    <title>A simple analysis engine implementation</title>
-    <para> Here is the complete analysis engine implementation for this example.</para>
-
-    <programlisting format="linespecific">public class GetStartedQuickAE 
-    extends org.apache.uima.fit.component.JCasAnnotator_ImplBase {
-  
-  public static final String PARAM_STRING = "stringParam";
-  @ConfigurationParameter(name = PARAM_STRING)
-  private String stringParam;
-  
-  @Override
-  public void process(JCas jCas) throws AnalysisEngineProcessException {
-    System.out.println("Hello world!  Say 'hi' to " + stringParam);
-  }
-}</programlisting>
-    <para>The first thing to note is that the member variable <varname>stringParam</varname> is
-      annotated with <classname>@ConfigurationParameter</classname> which tells uimaFIT that this is
-      an analysis engine configuration parameter. It is best practice to create a public constant
-      for the parameter name, here <code>PARAM_STRING</code> The second thing to note is that we
-      extend uimaFIT's version of the <classname>JCasAnnotator_ImplBase</classname>. The initialize
-      method of this super class calls:</para>
-    <programlisting format="linespecific">ConfigurationParameterInitializer.initializeConfigurationParameters(
-  Object, UimaContext) </programlisting>
-    <para>which populates the configuration parameters with the appropriate contents of the
-        <interfacename>UimaContext</interfacename>. If you do not want to extend uimaFIT's
-        <classname>JCasAnnotator_ImplBase</classname>, then you can call this method directly in the
-        <methodname>initialize</methodname> method of your analysis engine or any class that
-      implements <interfacename>Initializable</interfacename>. You can call this method for an
-      instance of any class that has configuration parameters.</para>
-  </section>
-
-  <section>
-    <title>Running the analysis engine</title>
-    <para>The following lines of code demonstrate how to instantiate and run the analysis engine
-      from a main method:</para>
-    <programlisting>JCas jCas = JCasFactory.createJCas();
-  
-AnalysisEngine analysisEngine = AnalysisEngineFactory.createEngine(
-  GetStartedQuickAE.class,
-  GetStartedQuickAE.PARAM_STRING, "uimaFIT");
-  
-analysisEngine.process(jCas);  </programlisting>
-
-    <para>In a more involved example, we would probably instantiate a collection reader and run this
-      analysis engine over a collection of documents. Here, it suffices to simply create a
-        <interfacename>JCas</interfacename>. Line 3 instantiates the analysis engine using
-        <classname>AnalysisEngineFactory</classname> and sets the string parameter named
-        <parameter>stringParam</parameter> to the value <literal>uimaFIT</literal>. Running this
-      simple program sends the following output to the console: </para>
-
-    <programlisting>Hello world!  Say 'hi' to uimaFIT  </programlisting>
-
-    <para>Normally you would be using a type system with your analysis components. When using
-      uimaFIT, it is easiest to keep your type system descriptors in your source folders and make
-      them known to uimaFIT. To do so, create a file
-        <filename>META-INF/org.apache.uima.fit/types.txt</filename> in a source folder and add references to
-      all your type descriptors to the file, one per line. You can also use wildcards. For example: </para>
-
-    <programlisting>classpath*:org/apache/uima/fit/examples/type/Token.xml
-classpath*:org/apache/uima/fit/examples/type/Sentence.xml
-classpath*:org/apache/uima/fit/examples/tutorial/type/*.xml </programlisting>
-  </section>
-
-  <section>
-    <title>Generate a descriptor file</title>
-
-    <para>The following lines of code demonstrate how a descriptor file can be generated using the
-      class definition:</para>
-
-    <programlisting>AnalysisEngine analysisEngine = AnalysisEngineFactory.createEngine(
-  GetStartedQuickAE.class,
-  GetStartedQuickAE.PARAM_STRING, "uimaFIT");
-
-analysisEngineDescription.toXML(
-  new FileOutputStream("GetStartedQuickAE.xml"));</programlisting>
-
-    <para>If you open the resulting descriptor file you will see that the configuration parameter
-        <parameter>stringParam</parameter> is defined with the value set to
-        <literal>uimaFIT</literal>. We could now instantiate an analysis engine using this
-      descriptor file with a line of code like this:</para>
-
-    <programlisting>AnalysisEngineFactory.createEngine("GetStartedQuickAE");</programlisting>
-
-    <para>But, of course, we really wouldn't want to do that now that we can instantiate analysis
-      engines using the class definition as was done above!</para>
-
-    <para>This chapter, of course, did not demonstrate every feature of uimaFIT which provides
-      support for annotating external resources, creating aggregate engines, running pipelines,
-      testing components, among others.</para>
-  </section>
-</chapter>
diff --git a/uimafit-docbook/src/docbook/tools.uimafit.introduction.xml b/uimafit-docbook/src/docbook/tools.uimafit.introduction.xml
deleted file mode 100644
index d5f9dc4..0000000
--- a/uimafit-docbook/src/docbook/tools.uimafit.introduction.xml
+++ /dev/null
@@ -1,162 +0,0 @@
-<!--
-	Licensed to the Apache Software Foundation (ASF) under one
-	or more contributor license agreements. See the NOTICE file
-	distributed with this work for additional information
-	regarding copyright ownership. The ASF licenses this file
-	to you under the Apache License, Version 2.0 (the
-	"License"); you may not use this file except in compliance
-	with the License. You may obtain a copy of the License at
-
-	http://www.apache.org/licenses/LICENSE-2.0
-
-	Unless required by applicable law or agreed to in writing,
-	software distributed under the License is distributed on an
-	"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-	KIND, either express or implied. See the License for the
-	specific language governing permissions and limitations
-	under the License.
--->
-<chapter id="ugr.tools.uimafit.introduction">
-  <title>Introduction</title>
-  <para>While uimaFIT provides many features for a UIMA developer, there are two overarching themes
-    that most features fall under. These two sides of uimaFIT are,while complementary, largely
-    independent of each other. One of the beauties of uimaFIT is that a developer that uses one side
-    of uimaFIT extensively is not required to use the other side at all. </para>
-  <section>
-    <title>Simplify Component Implementation</title>
-    <para>The first broad theme of uimaFIT provides features that <emphasis>simplify component
-        implementation</emphasis>. Our favorite example of this is the
-        <classname>@ConfigurationParameter</classname> annotation which allows you to annotate a
-      member variable as a configuration parameter. This annotation in combination with the method
-        <methodname>ConfigurationParameterInitializer.initialize()</methodname> completely automates
-      the process of initializing member variables with values from the
-        <interfacename>UimaContext</interfacename> passed into your analysis engine's initialize
-      method. Similarly, the annotation <classname>@ExternalResource</classname> annotation in
-      combination with the method <methodname>ExternalResourceInitializer.initialize()</methodname>
-      completely automates the binding of an external resource as defined in the
-        <interfacename>UimaContext</interfacename> to a member variable. Dispensing with manually
-      writing the code that performs these two tasks reduces effort, eliminates verbose and
-      potentially buggy boiler-plate code, and makes implementing a UIMA component more enjoyable.
-      Consider, for example, a member variable that is of type <classname>Locale</classname>. With
-      uimaFIT you can simply annotate the member variable with
-        <classname>@ConfigurationParameter</classname> and have your initialize method automatically
-      initialize the variable correctly with a string value in the
-        <interfacename>UimaContext</interfacename> such as <literal>en_US</literal>. </para>
-  </section>
-  <section>
-    <title>Simplify Component Instantiation</title>
-    <para>The second broad theme of uimaFIT provides features that <emphasis>simplify component
-        instantiation</emphasis>. Working with UIMA, have you ever said to yourself <quote>but I
-        just want to tag some text!?</quote> What does it take to <quote>just tag some text?</quote>
-      Here's a list of things you must do with the traditional approach:</para>
-    <itemizedlist>
-      <listitem>
-        <para>wrap your tagger as a UIMA analysis engine</para>
-      </listitem>
-      <listitem>
-        <para>write a descriptor file for your analysis engine</para>
-      </listitem>
-      <listitem>
-        <para>write a CAS consumer that produces the desired output</para>
-      </listitem>
-      <listitem>
-        <para>write another descriptor file for the CAS consumer</para>
-      </listitem>
-      <listitem>
-        <para>write a descriptor file for a collection reader</para>
-      </listitem>
-      <listitem>
-        <para>write a descriptor file that describes a pipeline</para>
-      </listitem>
-      <listitem>
-        <para>invoke the Collection Processing Manager with your pipeline descriptor file</para>
-      </listitem>
-    </itemizedlist>
-    <section>
-      <title>From a class</title>
-      <para>Each of these steps has its own pitfalls and can be rather time consuming. This is a
-        rather unsatisfying answer to our simple desire to just tag some text. With uimaFIT you can
-        literally eliminate all of these steps. </para>
-      <para>Here's a simple snippet of Java code that illustrates <quote>tagging some text</quote>
-        with uimaFIT:</para>
-      <programlisting>import static org.apache.uima.fit.factory.JCasFactory.createJCas;
-import static org.apache.uima.fit.pipeline.SimplePipeline.runPipeline;
-import static 
- org.apache.uima.fit.factory.AnalysisEngineFactory.createEngineDescription;
-      
-JCas jCas = createJCas();
-
-jCas.setDocumentText("some text");
-
-runPipeline(jCas, 
-    createEngineDescription(MyTokenizer.class), 
-    createEngineDescription(MyTagger.class));
-
-for(Token token : iterate(jCas, Token.class)){
-    System.out.println(token.getTag());
-}</programlisting>
-      <para>This code uses several static method imports for brevity. And while the
-        terseness of this code won't make a Python programmer blush - it is certainly much easier
-        than the seven steps outlined above! </para>
-    </section>
-    <section>
-      <title>From an XML descriptor</title>
-      <para>uimaFIT provides mechanisms to instantiate and run UIMA components programmatically with
-        or without descriptor files. For example, if you have a descriptor file for your analysis
-        engine defined by <classname>MyTagger</classname> (as shown above), then you can instead
-        instantiate the analysis engine with:</para>
-      <programlisting>AnalysisEngineDescription tagger = createEngineDescription(
-    "mypackage.MyTagger");</programlisting>
-      <para>This will find the descriptor file <filename>mypackage/MyTagger.xml</filename> by name.
-        Similarly, you can find a descriptor file by location with
-          <methodname>createEngineDescriptionFromPath()</methodname>. However, if you want to dispense
-        with XML descriptor files altogether (and you probably do), you can use the method
-          <methodname>createEngineDescription()</methodname> as shown above. One of the driving motivations
-        for creating the second side of uimaFIT is our frustration with descriptor files and our
-        desire to eliminate them. Descriptor files are difficult to maintain because they are
-        generally tightly coupled with java code, they decay without warning, they are wearisome to
-        test, and they proliferate, among other reasons.</para>
-    </section>
-  </section>
-  <section>
-    <title>Is this cheating?</title>
-    <para>One question that is often raised by new uimaFIT users is whether or not it breaks the
-        <emphasis>UIMA way</emphasis>. That is, does adopting uimaFIT lead me down a path of
-      creating UIMA components and systems that are incompatible with the traditional UIMA approach?
-      The answer to this question is <emphasis>no</emphasis>. For starters, uimaFIT does not skirt
-      the UIMA mechanism of describing components - it only skips the XML part of it. For example,
-      when the method <methodname>createEngineDescription()</methodname> is called (as shown above) an
-        <interfacename>AnalysisEngineDescription</interfacename> is created for the analysis engine.
-      This is the same object type that is instantiated when a descriptor file is used. So, instead
-      of parsing XML to instantiate an analysis engine description from XML, uimaFIT uses a factory
-      method to instantiate it from method parameters. One of the happy benefits of this approach is
-      that for a given <interfacename>AnalysisEnginedDescription</interfacename> you can generate
-      an XML descriptor file using <methodname>AnalysisEngineDescription.toXML()</methodname>. So,
-      uimaFIT actually provides a very simple and direct path for <emphasis>generating</emphasis>
-      XML descriptor files rather than manually creating and maintaining them! </para>
-    <para>It is also useful to clarify that if you only want to use one side or the other of
-      uimaFIT, then you are free to do so. This is possible precisely because uimaFIT does not
-      workaround UIMA's mechanisms for describing components but rather uses them directly. For
-      example, if the only thing you want to use in uimaFIT is the
-        <classname>@ConfigurationParameter</classname>, then you can do so without worrying about
-      what effect this will have on your descriptor files. This is because your analysis engine will
-      be initialized with exactly the same <interfacename>UimaContext</interfacename> regardless of
-      whether you instantiate your analysis engine in the <emphasis>UIMA way</emphasis> or use one
-      of uimaFIT's factory methods. Similarly, a UIMA component does not need to be annotated with
-        <classname>@ConfiguratioParameter</classname> for you to make use of the
-        <methodname>createEngineDescription()</methodname> method. This is because when you pass
-      configuration parameter values in to the <methodname>createEngineDescription()</methodname> method,
-      they are added to an <interfacename>AnalysisEngineDescription</interfacename> which is used by
-      UIMA to populate a <interfacename>UimaContext</interfacename> - just as it would if you used a
-      descriptor file. </para>
-  </section>
-  <section>
-    <title>Conclusion</title>
-    <para>Because uimaFIT can be used to simplify component implementation and instantiation it is
-      easy to assume that you can't do one without the other. This page has demonstrated that while
-      these two sides of uimaFIT complement each other, they are not coupled together and each can
-      be effectively used without the other. Similarly, by understanding how uimaFIT uses the UIMA
-      component description mechanisms directly, one can be assured that uimaFIT enables UIMA
-      development that is compatible and consistent with the UIMA standard and APIs. </para>
-  </section>
-</chapter>
diff --git a/uimafit-docbook/src/docbook/tools.uimafit.maven.xml b/uimafit-docbook/src/docbook/tools.uimafit.maven.xml
deleted file mode 100644
index a41d141..0000000
--- a/uimafit-docbook/src/docbook/tools.uimafit.maven.xml
+++ /dev/null
@@ -1,190 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN"
-"http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd"[
-<!ENTITY imgroot "images/tools/tools.jcasgen/" >
-<!ENTITY % uimaents SYSTEM "../../target/docbook-shared/entities.ent" >  
-%uimaents;
-]>
-<!--
-Licensed to the Apache Software Foundation (ASF) under one
-or more contributor license agreements.  See the NOTICE file
-distributed with this work for additional information
-regarding copyright ownership.  The ASF licenses this file
-to you under the Apache License, Version 2.0 (the
-"License"); you may not use this file except in compliance
-with the License.  You may obtain a copy of the License at
-
-   http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing,
-software distributed under the License is distributed on an
-"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-KIND, either express or implied.  See the License for the
-specific language governing permissions and limitations
-under the License.
--->
-<chapter id="tools.uimafit.maven">
-  <title>uimaFIT Maven Plugin</title>
-  
-  <para>uimaFIT dynamically generates UIMA component descriptions from annotations in the Java
-    source code. The uimaFIT Maven plugin provides the ability to automatically create such
-    annotations in already compiled classes and to automatically generate XML descriptors from the
-    annotated classes.</para>
-  <section>
-    <title>enhance goal</title>
-    <para>The goal enhance allows automatically augmenting compiled classes with uimaFIT
-      annotations. Information like vendor, copyright, or version can be obtained from the Maven
-      POM. Additionally, descriptions for parameters and components can be generated from Javadoc
-      comments. Existing annotations are not overwritten unless forced. </para>
-    <programlisting>&lt;plugin>
-  &lt;groupId>org.apache.uima&lt;/groupId>
-  &lt;artifactId>uimafit-maven-plugin&lt;/artifactId>
-  &lt;version><?eval ${project.version}?>&lt;/version> &lt;!-- change to latest version -->
-  &lt;configuration>
-    &lt;!-- OPTIONAL -->
-    &lt;!-- Override component description in generated descriptors. -->
-    &lt;overrideComponentDescription>false&lt;/overrideComponentDescription>
-
-    &lt;!-- OPTIONAL -->
-    &lt;!-- Override version in generated descriptors. -->
-    &lt;overrideComponentVersion>false&lt;/overrideComponentVersion>
-
-    &lt;!-- OPTIONAL -->
-    &lt;!-- Override vendor in generated descriptors. -->
-    &lt;overrideComponentVendor>false&lt;/overrideComponentVendor>
-
-    &lt;!-- OPTIONAL -->
-    &lt;!-- Override copyright in generated descriptors. -->
-    &lt;overrideComponentCopyright>false&lt;/overrideComponentCopyright>
-
-    &lt;!-- OPTIONAL -->
-    &lt;!-- Version to use in generated descriptors. -->
-    &lt;componentVersion>${project.version}&lt;/componentVersion>
-
-    &lt;!-- OPTIONAL -->
-    &lt;!-- Vendor to use in generated descriptors. -->
-    &lt;componentVendor>Apache Foundation&lt;/componentVendor>
-
-    &lt;!-- OPTIONAL -->
-    &lt;!-- Copyright to use in generated descriptors. -->
-    &lt;componentCopyright>Apache Foundation 2013&lt;/componentCopyright>
-
-    &lt;!-- OPTIONAL -->
-    &lt;!-- Source file encoding. -->
-    &lt;encoding>${project.build.sourceEncoding}&lt;/encoding>
-
-    &lt;!-- OPTIONAL -->
-    &lt;!-- Generate a report of missing meta data in 
-         $project.build.directory/uimafit-missing-meta-data-report.txt -->
-    &lt;generateMissingMetaDataReport>true&lt;/generateMissingMetaDataReport>
-
-    &lt;!-- OPTIONAL -->
-    &lt;!-- Fail on missing meta data. This setting has no effect unless
-         generateMissingMetaDataReport is enabled. -->
-    &lt;failOnMissingMetaData>false&lt;/failOnMissingMetaData>
-
-    &lt;!-- OPTIONAL -->
-    &lt;!-- Constant name prefixes used for parameters and external resources,
-         e.g. "PARAM_". -->
-    &lt;parameterNameConstantPrefixes>
-      &lt;prefix>PARAM_&lt;prefix/>
-    &lt;/parameterNameConstantPrefixes>
-    
-    &lt;!-- OPTIONAL -->
-    &lt;!-- Fail on missing meta data. This setting has no effect unless
-         generateMissingMetaDataReport is enabled. -->
-    &lt;externalResourceNameConstantPrefixes>
-      &lt;prefix>KEY_&lt;prefix/>
-      &lt;prefix>RES_&lt;prefix/>
-    &lt;/externalResourceNameConstantPrefixes>
-    
-    &lt;!-- OPTIONAL -->
-    &lt;!-- Mode of adding type systems found on the classpath via the
-         uimaFIT detection mechanism at compile time to the generated
-         descriptor. By default, no type systems are added. -->
-    &lt;addTypeSystemDescriptions>NONE&lt;/addTypeSystemDescriptions>
-    
-  &lt;/configuration>
-  &lt;executions>
-    &lt;execution>
-      &lt;id>default&lt;/id>
-      &lt;phase>process-classes&lt;/phase>
-      &lt;goals>
-        &lt;goal>enhance&lt;/goal>
-      &lt;/goals>
-    &lt;/execution>
-  &lt;/executions>
-&lt;/plugin></programlisting>
-    <para>When generating descriptions for configuration parameters or external resources, the
-      plugin supports a common practice of placing the Javadoc on a constant field instead of the
-      parameter or external resource field. Per default, parameter name constants must be prefixed
-      with <code>PARAM_</code> and external resource key constants must be prefixed with <code>RES_
-      </code>or <code>KEY_</code>.</para>
-    <programlisting>/**
- * Enable or disable my feature.
- */
-public static final String PARAM_ENABLE_FEATURE = "enableFeature";
-@ConfigurationParameter(name=PARAM_ENABLE_FEATURE)
-private boolean enableFeature;
-
-/**
- * My external resource.
- */
-public static final String RES_MY_RESOURCE = "resource";
-@ExternalResource(key=RES_MY_RESOURCE)
-private MyResource resource;</programlisting>
-    <para>By enabling <code>generateMissingMetaDataReport</code>, the build can be made to fail if
-      meta data such as parameter descriptions are missing. A report about the missing data is
-      generated in <filename>uimafit-missing-meta-data-report.txt</filename> in the project build
-      directory.</para>
-  </section>
-  <section>
-    <title>generate goal</title>
-    <para>The generate goal generates XML component descriptors for UIMA components. </para>
-    <programlisting>&lt;plugin>
-  &lt;groupId>org.apache.uima&lt;/groupId>
-  &lt;artifactId>uimafit-maven-plugin&lt;/artifactId>
-  &lt;version><?eval ${project.version}?>&lt;/version> &lt;!-- change to latest version -->
-  &lt;configuration>
-    &lt;!-- OPTIONAL -->
-    &lt;!-- Path where the generated resources are written. -->
-    &lt;outputDirectory>
-      ${project.build.directory}/generated-sources/uimafit
-    &lt;/outputDirectory>
-
-    &lt;!-- OPTIONAL -->
-    &lt;!-- Skip generation of META-INF/org.apache.uima.fit/components.txt -->
-    &lt;skipComponentsManifest>false&lt;/skipComponentsManifest>
-
-    &lt;!-- OPTIONAL -->
-    &lt;!-- Source file encoding. -->
-    &lt;encoding>${project.build.sourceEncoding}&lt;/encoding>
-  &lt;/configuration>
-  &lt;executions>
-    &lt;execution>
-      &lt;id>default&lt;/id>
-      &lt;phase>process-classes&lt;/phase>
-      &lt;goals>
-        &lt;goal>generate&lt;/goal>
-      &lt;/goals>
-    &lt;/execution>
-  &lt;/executions>
-&lt;/plugin></programlisting>
-    <para>In addition to the XML descriptors, a manifest file is written to
-        <filename>META-INF/org.apache.uima.fit/components.txt</filename>. This file can be used to
-      conveniently locate the XML descriptors, which are written in the packages next to the classes
-      they
-      describe.<programlisting>classpath*:org/apache/uima/fit/examples/ExampleComponent.xml</programlisting></para>
-    <para>It is recommended to use both, the enhance and the generate goal. Both goals should be
-      specified in the same execution, first enhance, then generate:</para>
-    <programlisting>&lt;execution>
-  &lt;id>default&lt;/id>
-  &lt;phase>process-classes&lt;/phase>
-  &lt;goals>
-    &lt;goal>enhance&lt;/goal>
-    &lt;goal>generate&lt;/goal>
-  &lt;/goals>
-&lt;/execution></programlisting>
-  </section>
-  
-</chapter>
\ No newline at end of file
diff --git a/uimafit-docbook/src/docbook/tools.uimafit.migration.xml b/uimafit-docbook/src/docbook/tools.uimafit.migration.xml
deleted file mode 100644
index b804137..0000000
--- a/uimafit-docbook/src/docbook/tools.uimafit.migration.xml
+++ /dev/null
@@ -1,226 +0,0 @@
-<!--
-	Licensed to the Apache Software Foundation (ASF) under one
-	or more contributor license agreements. See the NOTICE file
-	distributed with this work for additional information
-	regarding copyright ownership. The ASF licenses this file
-	to you under the Apache License, Version 2.0 (the
-	"License"); you may not use this file except in compliance
-	with the License. You may obtain a copy of the License at
-
-	http://www.apache.org/licenses/LICENSE-2.0
-
-	Unless required by applicable law or agreed to in writing,
-	software distributed under the License is distributed on an
-	"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-	KIND, either express or implied. See the License for the
-	specific language governing permissions and limitations
-	under the License.
--->
-<chapter id="ugr.tools.uimafit.migration">
-  <title>Migration Guide</title>
-  <para>This section provides helpful information on incompatible changes between versions.</para>
-  <section>
-    <title>Version 2.3.0 to 2.4.0</title>
-    <formalpara>
-      <title>Version requirements</title>
-      <para>Depends on UIMA 2.10.2, Spring Framework 3.2.16 and Java 7.</para>
-    </formalpara>
-    <formalpara>
-      <para>Mind the updated version requirements. There should be no other potentially problematic
-      changes in this upgrade.</para>
-    </formalpara>
-  </section>
-  <section>
-    <title>Version 2.2.0 to 2.3.0</title>
-    <formalpara>
-      <title>CasIOUtil deprecated</title>
-      <para>The functionality of the uimaFIT CasIOUtil class has been superseded by the core UIMA
-      class CasIOUtils added in UIMA 2.9.0. The method signatures in the new class are not the
-      same, but provide more functionality. CasIOUtil has been deprecated and documentation has
-      been added which of the CasIOUtils methods should be used instead.</para>
-    </formalpara>
-    <formalpara>
-      <title>Version requirements</title>
-      <para>Depends on UIMA 2.9.1, Spring Framework 3.2.16 and Java 7.</para>
-    </formalpara>
-    <formalpara>
-      <para>Mind the updated version requirements. There should be no other potentially problematic
-      changes in this upgrade.</para>
-    </formalpara>
-  </section>
-  <section>
-    <title>Version 2.1.0 to 2.2.0</title>
-    <formalpara>
-      <title>Version requirements</title>
-      <para>Depends on UIMA 2.8.1, Spring Framework 3.2.16 and Java 7.</para>
-    </formalpara>
-    <formalpara>
-      <para>Mind the updated version requirements. There should be no other potentially problematic
-      changes in this upgrade.</para>
-    </formalpara>
-  </section>
-  <section>
-    <title>Version 2.0.0 to 2.1.0</title>
-    <formalpara>
-      <title>Version requirements</title>
-      <para>Depends on UIMA 2.6.0 and Java 6.</para>
-    </formalpara>
-    <formalpara>
-      <title>AnnotationFactory.createAnnotation()</title>
-      <para>No longer throws <literal>UIMAExcption</literal>. If this exception was cought, some
-        IDEs may complain here after upgrading to uimaFIT 2.1.0. </para>
-    </formalpara>
-  </section>
-  <section>
-    <title>Version 1.4.0 to 2.0.0</title>
-    <formalpara>
-      <title>Version requirements</title>
-      <para>Depends on UIMA 2.4.2.</para>
-    </formalpara>
-    <formalpara>
-      <title>Backwards compatibility</title>
-      <para>Compatibility with legacy annotation is provided by the Legacy support module.</para>
-    </formalpara>
-    <formalpara>
-      <title>Change of Maven groupId and artifactId</title>
-      <para>The Maven group ID has changed from <literal>org.uimafit</literal> to
-          <literal>org.apache.uima</literal>.</para>
-    </formalpara>
-    <para>The artifact ID of the main uimaFIT artifact has been changed from
-        <literal>uimafit</literal> to <literal>uimafit-core</literal>.</para>
-    <formalpara>
-      <title>Change of package names</title>
-      <para>The base package has been renamed from <literal>org.uimafit</literal> to
-          <literal>org.apache.uima.fit</literal>. A global search/replace on Java files with for
-        lines starting with <literal>import org.uimafit</literal> and replacing that with
-          <literal>import org.apache.uima.fit</literal> should work.</para>
-    </formalpara>
-    <formalpara>
-      <title>@ConfigurationParameter</title>
-      <para>The default value for the mandatory attribute now is <literal>true</literal>. The
-        default name of configuration parameters is now the name of the annotated field only. The
-        classname is no longer prefixed. The method
-          <code>ConfigurationParameterFactory.createConfigurationParameterName()</code> that was
-        used to generate the prefixed name has been removed.</para>
-    </formalpara>
-    <formalpara>
-      <title>Type detection: META-INF/org.uimafit folder</title>
-      <para>The <literal>META-INF/org.uimafit</literal> was renamed to
-          <literal>META-INF/org.apache.uima.fit</literal>.</para>
-    </formalpara>
-    <formalpara>
-      <title>JCasUtil</title>
-      <para>The deprecated <code>JCasUtil.iterate()</code> methods have been removed.
-          <code>JCasUtil.select()</code> should be used instead.</para>
-    </formalpara>
-    <formalpara>
-      <title>AnalysisEngineFactory</title>
-      <para>All <literal>createAggregateXXX</literal> and <literal>createPrimitiveXXX</literal>
-        methods have been renamed to <literal>createEngineXXX</literal>. The old names are
-        deprecated and will be removed in future versions.</para>
-    </formalpara>
-    <para>All <literal>createAnalysisEngineXXX</literal> methods have been renamed to
-        <literal>createEngineXXX</literal>. The old names are deprecated and will be removed in
-      future versions.</para>
-    <formalpara>
-      <title>CollectionReaderFactory</title>
-      <para>All <literal>createDescriptionXXX</literal> methods have been renamed to
-          <literal>createReaderDescriptionXXX</literal>. The old names are deprecated and will be
-        removed in future versions.</para>
-    </formalpara>
-    <para>All <literal>createCollectionReaderXXX</literal> methods have been renamed to
-        <literal>createReaderXXX</literal>. The old names are deprecated and will be removed in
-      future versions.</para>
-    <formalpara>
-      <title>JCasIterable</title>
-      <para><code>JCasIterable</code> now only accepts reader and engine descriptions (no instances)
-        and no longer implements the <code>Iterator</code> interface. Instead, new
-          <code>JCasIterator</code> has been added, which replaces <code>JCasIterable</code> in that
-        respect.</para>
-    </formalpara>
-    <formalpara>
-      <title>CasDumpWriter</title>
-      <para><literal>org.uimafit.component.xwriter.CASDumpWriter</literal> has been renamed to
-          <literal>org.apache.uima.fit.component.CasDumpWriter</literal>.</para>
-    </formalpara>
-    <formalpara>
-      <title>CpePipeline</title>
-      <para><literal>CpePipeline</literal> has been moved to a separate module with the artifact ID
-          <literal>uimafit-cpe</literal> to reduce the dependencies incurred by the main uimaFIT
-        artifact.</para>
-    </formalpara>
-    <formalpara>
-      <title>XWriter removed</title>
-      <para>The <literal>XWriter</literal> and associated file namers have been removed as they were
-        much more complex then acutally needed. As an alternative, <literal>CasIOUtil</literal> has
-        been introduced providing several convenience methods to read/write JCas/CAS data. </para>
-    </formalpara>
-    <formalpara>
-      <title>JCasFactory</title>
-      <para>Methods only loading JCas data have been removed from <literal>JCasFactory</literal>.
-        The new methods in <literal>CasIOUtil</literal> can be used instead.</para>
-    </formalpara>
-  </section>
-  <section>
-    <title>Legacy support module</title>
-    <para>The compatibility layer should allow you to migrate to uimaFIT <?eval ${project.version}?> without breaking
-      anything. You should then be able to gradually change the codebase to be compatible with
-      uimaFIT <?eval ${project.version}?>. As far as my tests go, uimaFIT 1.x and <?eval ${project.version}?> can coexist peacefully on the
-      classpath (and indeed both need to be on the classpath in order to use the legacy support
-      module).</para>
-    <para>To enable the legacy support, make sure that you have a dependency on uimaFIT 1.x and then
-      just add a dependency on the legacy module:</para>
-    <programlisting>&lt;dependency>
-  &lt;groupId>org.uimafit&lt;/groupId>
-  &lt;artifactId>uimafit&lt;/artifactId>
-  &lt;version>1.4.0&lt;/version>
-&lt;/dependency>
-&lt;dependency>
-  &lt;groupId>org.apache.uima&lt;/groupId>
-  &lt;artifactId>uimafit-legacy-support&lt;/artifactId>
-  &lt;version><?eval ${project.version}?>&lt;/version>
-&lt;/dependency></programlisting>
-    <para>uimaFIT <?eval ${project.version}?> automatically detects the presence of the legacy module and uses it - no
-      additional configuration is necessary.</para>
-    <para>The following bash script may help to partially automatize the source code migration process.
-      Please observe that it does not cover all of the necessary changes!</para>
-    <note>
-      <para>The script recursively changes all files under the current working directory! Make
-      sure you are in the right directory before running it! <emphasis>Use the script at your own 
-      risk!</emphasis></para>
-    </note>
-    <programlisting>#!/bin/sh
-
-############################################
-# MAKE SURE TO BACKUP YOUR FILES FIRST!
-# SCRIPT RECURSIVELY CHANGES ALL JAVA FILES!
-# USE AT YOUR OWN RISK!
-############################################
-
-# Change of package names
-find . -name '*.java' -print | 
-xargs perl -p -i -e 's/org.uimafit/org.apache.uima.fit/g'
-
-find . -name '*.java' -print | 
-xargs perl -p -i -e 's/org.uimafit.component.xwriter.CASDumpWriter/\
-org.apache.uima.fit.component.CasDumpWriter/g'
-
-# AnalysisEngineFactory
-find . -name '*.java' -print | 
-xargs perl -p -i -e 's/createAggregate/createEngine/g'
-
-find . -name '*.java' -print | 
-xargs perl -p -i -e 's/createPrimitive/createEngine/g'
-
-find . -name '*.java' -print | 
-xargs perl -p -i -e 's/createAnalysisEngine/createEngine/g'
-
-# Readers
-find . -name '*.java' -print | 
-xargs perl -p -i -e 's/createDescription/createReaderDescription/g'
-
-find . -name '*.java' -print | 
-xargs perl -p -i -e 's/createCollectionReader/createReader/g'
-</programlisting>    
-  </section>
-</chapter>
diff --git a/uimafit-docbook/src/docbook/tools.uimafit.packaging.xml b/uimafit-docbook/src/docbook/tools.uimafit.packaging.xml
deleted file mode 100644
index b0a0b53..0000000
--- a/uimafit-docbook/src/docbook/tools.uimafit.packaging.xml
+++ /dev/null
@@ -1,105 +0,0 @@
-<!--
-	Licensed to the Apache Software Foundation (ASF) under one
-	or more contributor license agreements. See the NOTICE file
-	distributed with this work for additional information
-	regarding copyright ownership. The ASF licenses this file
-	to you under the Apache License, Version 2.0 (the
-	"License"); you may not use this file except in compliance
-	with the License. You may obtain a copy of the License at
-
-	http://www.apache.org/licenses/LICENSE-2.0
-
-	Unless required by applicable law or agreed to in writing,
-	software distributed under the License is distributed on an
-	"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-	KIND, either express or implied. See the License for the
-	specific language governing permissions and limitations
-	under the License.
--->
-<chapter id="ugr.tools.uimafit.packaging">
-  <title>Building an executable JAR</title>
-  <para>Building an executable JAR including uimaFIT components typically requires extra care. Per
-    convention, uimaFIT expects certain information in specific locations on the classpath, e.g. the
-      <filename>types.txt</filename> file that controls the <link
-      linkend="ugr.tools.uimafit.packaging">automatic type system detection</link> mechanism must
-    reside at <filename>META-INF/org.apache.uima.fit/types.txt</filename>. It often occurs that a
-    project has several dependencies, each supplying its own configuration files at these standard
-    locations. However, this causes a problem with naive approaches to creating an executable
-      <emphasis>fat-jar</emphasis> merging all dependencies into a single JAR file. Without extra
-    care, the files supplied by the different dependencies overwrite each other during the packaging
-    process and only one file <emphasis>wins</emphasis> in the end. As a consequence, the types
-    configured in the other files cannot be detected at runtime. Such a native approach is taken,
-    for example, by the Maven Assembly Plugin.</para>
-  <para>The Maven Shade Plugin provides a convenient alternative for the creation of executable
-    fat-jars, as it provides a mechanism to concatenate the configuration files from different
-    dependencies while creating the fat-jar. To use the Maven Shade Plugin with uimaFIT, use the
-    following configuration section in your POM file and make sure to change the
-      <parameter>mainClass</parameter> as required for your project:</para>
-  <programlisting>&lt;build>
-  &lt;plugins>
-    &lt;plugin>
-      &lt;groupId>org.apache.maven.plugins&lt;/groupId>
-      &lt;artifactId>maven-shade-plugin&lt;/artifactId>
-      &lt;version>2.2&lt;/version>
-      &lt;executions>
-        &lt;execution>
-          &lt;phase>package&lt;/phase>
-          &lt;goals>&lt;goal>shade&lt;/goal>&lt;/goals>
-          &lt;configuration>
-            &lt;transformers>
-              &lt;!-- Set the main class of the executable JAR -->
-              &lt;transformer
-                implementation="org.apache.maven.plugins.shade.\
-                                resource.ManifestResourceTransformer">
-                &lt;mainClass>org.apache.uima.fit.example.Main&lt;/mainClass>
-              &lt;/transformer>
-              &lt;!-- Merge the uimaFIT configuration files -->
-              &lt;transformer
-                implementation="org.apache.maven.plugins.shade.\
-                                resource.AppendingTransformer">
-                &lt;resource>\
-                  META-INF/org.apache.uima.fit/fsindexes.txt\
-                &lt;/resource>
-              &lt;/transformer>
-              &lt;transformer
-                implementation="org.apache.maven.plugins.shade.\
-                                resource.AppendingTransformer">
-                &lt;resource>\
-                  META-INF/org.apache.uima.fit/types.txt\
-                &lt;/resource>
-              &lt;/transformer>
-              &lt;transformer
-                implementation="org.apache.maven.plugins.shade.\
-                                resource.AppendingTransformer">
-                &lt;resource>\
-                  META-INF/org.apache.uima.fit/typepriorities.txt\
-                &lt;/resource>
-              &lt;/transformer>
-            &lt;/transformers>
-            &lt;!-- 
-              Prevent huge shaded artifacts from being deployed
-              to a Maven repository (remove if not desired) 
-            -->
-            &lt;outputFile>\
-              ${project.build.directory}/\
-              ${artifactId}-${version}-standalone.jar\
-            &lt;/outputFile>
-          &lt;/configuration>
-        &lt;/execution>
-      &lt;/executions>
-    &lt;/plugin>
-  &lt;/plugins>
-&lt;/build></programlisting>
-  <note>
-    <para>Due to formatting constraints in the PDF version of this manual, the example above uses
-        <code>\</code> to indicate a line continuation. Remove these and join the lines when you
-      copy/paste this example.</para>
-  </note>
-  <note>
-    <para>You might want to consider also merging additional files, such as LICENSE, NOTICE, or
-      DEPENDENCY files,  configuration files for the Java Service Locator API, or  files used by
-      other frameworks that uses similar conventions for configuration file locations. Check the
-      documentation of the Maven Shade Plugin, as different kinds of configuration files require
-      different specialized transformers.</para>
-  </note>
-</chapter>
diff --git a/uimafit-docbook/src/docbook/tools.uimafit.pipelines.xml b/uimafit-docbook/src/docbook/tools.uimafit.pipelines.xml
deleted file mode 100644
index 6a89eb4..0000000
--- a/uimafit-docbook/src/docbook/tools.uimafit.pipelines.xml
+++ /dev/null
@@ -1,73 +0,0 @@
-<!--
-	Licensed to the Apache Software Foundation (ASF) under one
-	or more contributor license agreements. See the NOTICE file
-	distributed with this work for additional information
-	regarding copyright ownership. The ASF licenses this file
-	to you under the Apache License, Version 2.0 (the
-	"License"); you may not use this file except in compliance
-	with the License. You may obtain a copy of the License at
-
-	http://www.apache.org/licenses/LICENSE-2.0
-
-	Unless required by applicable law or agreed to in writing,
-	software distributed under the License is distributed on an
-	"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-	KIND, either express or implied. See the License for the
-	specific language governing permissions and limitations
-	under the License.
--->
-<chapter id="ugr.tools.uimafit.pipelines">
-  <title>Pipelines</title>
-  <para>UIMA is a component-based architecture that allows composing various processing components
-    into a complex processing pipeline. A pipeline typically involves a <emphasis>collection
-      reader</emphasis> which ingests documents and <emphasis>analysis engines</emphasis> that do
-    the actual processing.</para>
-  <para>Normally, you would run a pipeline using a UIMA Collection Processing Engine or using UIMA
-    AS. uimaFIT offers a third alternative that is much simpler to use and well suited for embedding
-    UIMA pipelines into applications or for writing tests.</para>
-  <para>As uimaFIT does not supply any readers or processing components, we just assume that we have
-    written three components:</para>
-  <itemizedlist>
-    <listitem>
-      <para><classname>TextReader</classname> - reads text files from a directory</para>
-    </listitem>
-    <listitem>
-      <para><classname>Tokenizer</classname> - annotates tokens</para>
-    </listitem>
-    <listitem>
-      <para><classname>TokenFrequencyWriter</classname> - writes a list of tokens and their
-        frequency to a file</para>
-    </listitem>
-  </itemizedlist>
-  <para>We create descriptors for all components and run them as a pipeline:</para>
-  <programlisting>CollectionReaderDescription reader = 
-  CollectionReaderFactory.createReaderDescription(
-    TextReader.class, 
-    TextReader.PARAM_INPUT, "/home/uimafit/documents");
-
-AnalysisEngineDescription tokenizer = 
-  AnalysisEngineFactory.createEngineDescription(
-    Tokenizer.class);
-
-AnalysisEngineDescription tokenFrequencyWriter = 
-  AnalysisEngineFactory.createEngineDescription(
-    TokenFrequencyWriter.class, 
-    TokenFrequencyWriter.PARAM_OUTPUT, "counts.txt");
-
-SimplePipeline.runPipeline(reader, tokenizer, writer);</programlisting>
-  <para>Instead of running the full pipeline end-to-end, we can also process one document at a time
-    and inspect the analysis results:</para>
-  <programlisting>CollectionReaderDescription reader = 
-  CollectionReaderFactory.createReaderDescription(
-    TextReader.class, 
-    TextReader.PARAM_INPUT, "/home/uimafit/documents");
-
-AnalysisEngineDescription tokenizer = 
-  AnalysisEngineFactory.createEngineDescription(
-    Tokenizer.class);
-
-for (JCas jcas : SimplePipeline.iteratePipeline(reader, tokenizer)) {
-  System.out.printf("Found %d tokens%n", 
-    JCasUtil.select(jcas, Token.class).size());
-}</programlisting>
-</chapter>
diff --git a/uimafit-docbook/src/docbook/tools.uimafit.testing.xml b/uimafit-docbook/src/docbook/tools.uimafit.testing.xml
deleted file mode 100644
index 6b7e704..0000000
--- a/uimafit-docbook/src/docbook/tools.uimafit.testing.xml
+++ /dev/null
@@ -1,105 +0,0 @@
-<!--
-	Licensed to the Apache Software Foundation (ASF) under one
-	or more contributor license agreements. See the NOTICE file
-	distributed with this work for additional information
-	regarding copyright ownership. The ASF licenses this file
-	to you under the Apache License, Version 2.0 (the
-	"License"); you may not use this file except in compliance
-	with the License. You may obtain a copy of the License at
-
-	http://www.apache.org/licenses/LICENSE-2.0
-
-	Unless required by applicable law or agreed to in writing,
-	software distributed under the License is distributed on an
-	"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-	KIND, either express or implied. See the License for the
-	specific language governing permissions and limitations
-	under the License.
--->
-<chapter id="ugr.tools.uimafit.introduction">
-  <title>Testing UIMA components</title>
-  <para>Writing tests without uimaFIT can be a laborious process that results in fragile tests that
-    are very verbose and break easily when code is refactored. This page demonstrates how you can
-    write tests that are both concise and robust. Here's an outline of how you might create a test
-    for a UIMA component <emphasis>without</emphasis> uimaFIT:</para>
-  <orderedlist>
-    <listitem>
-      <para>write a descriptor file that configures your component appropriately for the test. This
-        requires a minimum of 30-50 lines of XML.</para>
-    </listitem>
-    <listitem>
-      <para>begin a test with 5-10 lines of code that instantiate the e.g. analysis engine.</para>
-    </listitem>
-    <listitem>
-      <para>run the analysis engine against some text and test the contents of the CAS.</para>
-    </listitem>
-    <listitem>
-      <para>repeat steps 1-3 for your next test usually by copying the descriptor file, renaming it,
-        and changing e.g. configuration parameters.</para>
-    </listitem>
-  </orderedlist>
-  <para>If you have gone through the pain of creating tests like these and then decided you should
-    refactor your code, then you know how tedious it is to maintain them. </para>
-  <para>Instead of pasting variants of the setup code (see step 2) into other tests we began to
-    create a library of utility methods that we could call which helped shorten our code. We
-    extended these methods so that we could instantiate our components directly without a descriptor
-    file. These utility methods became the initial core of uimaFIT. </para>
-  <section>
-    <title>Examples</title>
-    <para>There are several examples that can be found in the <emphasis>uimafit-examples</emphasis>
-      module.</para>
-    <itemizedlist>
-      <listitem>
-        <para>There are a number of examples of unit tests in both the test suite for the uimafit
-          project and the uimafit-examples project. In particular, there are some well-documented
-          unit tests in the latter which can be found in
-            <classname>RoomNumberAnnotator1Test</classname></para>
-      </listitem>
-      <listitem>
-        <para>You can improve your testing strategy by introducing a <classname>TestBase</classname>
-          class such as the one found in <classname>ExamplesTestBase</classname>. This class is
-          intended as a super class for your other test classes and sets up a
-            <interfacename>JCas</interfacename> that is always ready to use along with a
-            <interfacename>TypeSystemDescription</interfacename> and a
-            <interfacename>TypePriorities</interfacename>. An example test that subclasses from
-            <classname>ExamplesTestBase</classname> is
-            <classname>RoomNumberAnnotator2Test</classname>.</para>
-      </listitem>
-      <listitem>
-        <para>Most analysis engines that you want to test will generally be downstream of many other
-          components that add annotations to the CAS. These annotations will likely need to be in
-          the CAS so that a downstream analysis engine will do something sensible. This poses a
-          problem for tests because it may be undesirable to set up and run an entire pipeline every
-          time you want to test a downstream analysis engine. Furthermore, such tests can become
-          fragile in the face of behavior changes to upstream components. For this reason, it can be
-          advantageous to serialize a CAS as an XMI file and use this as a starting point rather
-          than running an entire pipeline. An example of this approach can be found in
-            <classname>XmiTest</classname>. </para>
-      </listitem>
-    </itemizedlist>
-  </section>
-  <section>
-    <title>Tips &amp; Tricks</title>
-    <para>The package <package>org.apache.uima.fit.testing</package> provides some utility classes
-      that can be handy when writing tests for UIMA components. You may find the following
-      suggestions useful:</para>
-    <itemizedlist>
-      <listitem>
-        <para>add a <classname>TokenBuilder</classname> to your <classname>TestBase</classname>
-          class. An example of this can be found in <classname>ComponentTestBase</classname>. This
-          makes it easy to add tokens and sentences to the CAS you are testing which is a common
-          task for many tests.</para>
-      </listitem>
-      <listitem>
-        <para>use a <classname>JCasBuilder</classname> to add text and annotations incrementally to
-          a JCas instead of first setting the text and then adding all annotations. </para>
-      </listitem>
-      <listitem>
-        <para>use a <classname>CasDumpWriter</classname> to write the CAS contents is a human
-          readable format to a file or to the console. Compare this with a previously written and
-          manually verifed file to see if changes in the component result in changes of the
-          components output.</para>
-      </listitem>
-    </itemizedlist>
-  </section>
-</chapter>
diff --git a/uimafit-docbook/src/docbook/tools.uimafit.typesystem.xml b/uimafit-docbook/src/docbook/tools.uimafit.typesystem.xml
deleted file mode 100644
index 4c3443d..0000000
--- a/uimafit-docbook/src/docbook/tools.uimafit.typesystem.xml
+++ /dev/null
@@ -1,163 +0,0 @@
-<!--
-	Licensed to the Apache Software Foundation (ASF) under one
-	or more contributor license agreements. See the NOTICE file
-	distributed with this work for additional information
-	regarding copyright ownership. The ASF licenses this file
-	to you under the Apache License, Version 2.0 (the
-	"License"); you may not use this file except in compliance
-	with the License. You may obtain a copy of the License at
-
-	http://www.apache.org/licenses/LICENSE-2.0
-
-	Unless required by applicable law or agreed to in writing,
-	software distributed under the License is distributed on an
-	"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-	KIND, either express or implied. See the License for the
-	specific language governing permissions and limitations
-	under the License.
--->
-<chapter id="ugr.tools.uimafit.typesystem">
-  <title>Type System Detection</title>
-  <para>UIMA requires that types that are used in the CAS are defined in XML files - so-called
-      <emphasis>type system descriptions</emphasis> (TSD). Whenever a UIMA component is created, it
-    must be associated with such a type system. While it is possible to manually load the type
-    system descriptors and pass them to each UIMA component and to each created CAS, it is quite
-    inconvenient to do so. For this reason, uimaFIT supports the automatic detection of such files
-    in the classpath. Thus is becomes possible for a UIMA component provider to have component's
-    type automatically detected and thus the components becomes immediately usable by adding it to
-    the classpath.</para>
-  <section>
-    <title>Making types auto-detectable</title>
-    <para>The provider of a type system should create a file
-        <filename>META-INF/org.apache.uima.fit/types.txt</filename> in the classpath. This file
-      should define the locations of the type system descriptions. Assume that a type
-        <classname>org.apache.uima.fit.type.Token</classname> is specified in the TSD
-        <filename>org/apache/uima/fit/type/Token.xml</filename>, then the file should have the
-      following contents:</para>
-    <programlisting>classpath*:org/apache/uima/fit/type/Token.xml</programlisting>
-    <note>
-      <para>Mind that the file <filename>types.txt</filename> is must be located in
-          <filename>META-INF/org.apache.uima.fit</filename> where
-          <filename>org.apache.uima.fit</filename> is the name of a sub-directory inside
-          <filename>META-INF</filename>. <emphasis>We are not using the Java package notation
-          here!</emphasis></para>
-    </note>
-    <para>To specify multiple TSDs, add additonal lines to the file. If you have a large number of
-      TSDs, you may prefer to add a pattern. Assume that we have a large number of TSDs under
-        <filename>org/apache/uima/fit/type</filename>, we can use the following pattern which
-      recursively scans the package <package>org.apache.uima.fit.type</package> and all sub-packages
-      for XML files and tries to load them as TSDs.</para>
-    <programlisting>classpath*:org/apache/uima/fit/type/**/*.xml</programlisting>
-    <para>Try to design your packages structure in a way that TSDs and JCas wrapper classes
-      generated from them are separate from the rest of your code.</para>
-    <para>If it is not possible or inconvenient to add the `types.txt` file, patterns can also be
-      specified using the system property
-        <parameter>org.apache.uima.fit.type.import_pattern</parameter>. Multiple patterns may be
-      specified separated by semicolon:</para>
-    <programlisting>-Dorg.apache.uima.fit.type.import_pattern=\
-  classpath*:org/apache/uima/fit/type/**/*.xml</programlisting>
-    <note>
-      <para>The <literal>\</literal> in the example is used as a line-continuation indicator. It
-        and all spaces following it should be ommitted.</para>
-    </note>
-  </section>
-  <section>
-    <title>Making index definitions and type priorities auto-detectable</title>
-    <para>Auto-detection also works for index definitions and type priority definitions. For
-    index definitions, the respective file where to register the index definition XML files is
-    <filename>META-INF/org.apache.uima.fit/fsindexes.txt</filename> and for type priorities, it
-    is <filename>META-INF/org.apache.uima.fit/typepriorities.txt</filename>.</para>
-  </section>
-  <section>
-    <title>Using type auto-detection </title>
-    <para>The auto-detected type system can be obtained from the
-        <classname>TypeSystemDescriptionFactory</classname>:</para>
-    <programlisting>TypeSystemDescription tsd = 
-  TypeSystemDescriptionFactory.createTypeSystemDescription()</programlisting>
-    <para>Popular factory methods also support auto-detection:</para>
-    <programlisting>AnalysisEngine ae = createEngine(MyEngine.class);</programlisting>
-  </section>
-  <section>
-    <title>Multiple META-INF/org.apache.uima.fit/types.txt files</title>
-    <para>uimaFIT supports multiple <filename>types.txt</filename> files in the classpath (e.g. in differnt JARs). The
-        <filename>types.txt</filename> files are located via Spring using the classpath search
-      pattern: </para>
-    <programlisting>TYPE_MANIFEST_PATTERN = "classpath*:META-INF/org.apache.uima.fit/types.txt" </programlisting>
-    <para>This resolves to a list URLs pointing to ALL <filename>types.txt</filename> files. The
-      resolved URLs are unique and will point either to a specific point in the file system or into
-      a specific JAR. These URLs can be handled by the standard Java URL loading mechanism.
-      Example:</para>
-    <programlisting>jar:/path/to/syntax-types.jar!/META-INF/org.apache.uima.fit/types.txt 
-jar:/path/to/token-types.jar!/META-INF/org.apache.uima.fit/types.txt</programlisting>
-    <para>uimaFIT then reads all patters from all of these URLs and uses these to search the
-      classpath again. The patterns now resolve to a list of URLs pointing to the individual type
-      system XML descriptors. All of these URLs are collected in a set to avoid duplicate loading
-      (for performance optimization - not strictly necessary because the UIMA type system merger can
-      handle compatible duplicates). Then the descriptors are loaded into memory and merged using
-      the standard UIMA type system merger
-        (<methodname>CasCreationUtils.mergeTypeSystems()</methodname>). Example:</para>
-    <programlisting>jar:/path/to/syntax-types.jar!/desc/types/Syntax.xml 
-jar:/path/to/token-types.jar!/org/foobar/typesystems/Tokens.xml </programlisting>
-    <para>Voilá, the result is a type system covering all types could be found in the
-      classpath.</para>
-    <para>It is recommended <orderedlist>
-        <listitem>
-          <para>to put type system descriptors into packages resembling a namespace you "own" and to
-            use a package-scoped wildcard
-            search<programlisting>classpath*:org/apache/uima/fit/type/**/*.xml`</programlisting></para>
-        </listitem>
-        <listitem>
-          <para>or when putting descriptors into a "well-known" package like
-              <package>desc.type</package>, that <filename>types.txt</filename> file should
-            explicitly list all type system descriptors instead of using a wildcard
-            search<programlisting>classpath*:desc/type/Token.xml 
-classpath*:desc/type/Syntax.xml </programlisting></para>
-        </listitem>
-      </orderedlist>Method 1 should be preferred. Both methods can be mixed. </para>
-  </section>
-  <section>
-    <title>Performance note and caching</title>
-    <para>Currently uimaFIT evaluates the patterns for TSDs once and caches the locations, but not
-      the actual merged type system description. A rescan can be forced using
-        <methodname>TypeSystemDescriptionFactory.forceTypeDescriptorsScan()</methodname>. This may
-      change in future.</para>
-  </section>
-  <section>
-    <title>Potential problems</title>
-    <para>The mechanism works fine. However, there are specific issues with Java in general that one
-      should be aware of.</para>
-    <section>
-      <title>m2eclipse fails to copy descriptors to target/classes</title>
-      <para>There seems to be a bug in some older versions of m2eclipse that causes resources not
-        always to be copied to <filename>target/classes</filename>. If UIMA complains about type
-        definitions missing at runtime, try to <emphasis>clean/rebuild</emphasis> your project and
-        carefully check the m2eclipse console in the console view for error messages that might
-        cause m2eclipse to abort.</para>
-    </section>
-    <section>
-      <title>Class version conflicts</title>
-      <para>A problem can occur if you end up having multiple incompatible versions of the same type
-        system in the classpath. This is a general problem and not related to the auto-detection
-        feature. It is the same as when you have incompatible version of a particular class (e.g.
-          <interfacename>JCas</interfacename> wrapper or some third-party-library) in the classpath.
-        The behavior of the Java Classloader is undefined in that case. The detection will do its
-        best to try and load everything it can find, but the UIMA type system merger may barf or you
-        may end up with undefined behavior at runtime because one of the class versions is used at
-        random. </para>
-    </section>
-    <section>
-      <title>Classes and resources in the default package</title>
-      <para>It is bad practice to place classes into the default (unnamed) package. In fact it is
-        not possible to import classes from the default package in another class. Similarly it is a
-        bad idea to put resources at the root of the classpath. The Spring documentation on
-        resources <ulink
-          url="http://static.springsource.org/spring/docs/3.0.x/reference/resources.html#resources-app-ctx-wildcards-in-resource-paths"
-          >explains this in detail</ulink>.</para>
-      <para>For this reason the <filename>types.txt</filename> resides in
-          <filename>/META-INF/org.apache.uima.fit</filename> and it is suggest that type system
-        descriptors reside either in a proper package like
-          <filename>/org/foobar/typesystems/XXX.xml</filename> or in
-          <filename>/desc/types/XXX.xml</filename>. </para>
-    </section>
-  </section>
-</chapter>
diff --git a/uimafit-junit/pom.xml b/uimafit-junit/pom.xml
new file mode 100644
index 0000000..6ff4d41
--- /dev/null
+++ b/uimafit-junit/pom.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements. See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership. The ASF licenses this file
+  to you under the Apache License, Version 2.0 (the
+  "License"); you may not use this file except in compliance
+  with the License. You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing,
+  software distributed under the License is distributed on an
+  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  KIND, either express or implied. See the License for the
+  specific language governing permissions and limitations
+  under the License.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <groupId>org.apache.uima</groupId>
+    <artifactId>uimafit-parent</artifactId>
+    <version>2.5.1-SNAPSHOT</version>
+    <relativePath>../uimafit-parent</relativePath>
+  </parent>
+  <artifactId>uimafit-junit</artifactId>
+  <name>Apache UIMA uimaFIT - JUnit support</name>
+  <dependencies>
+    <dependency>
+      <groupId>org.apache.uima</groupId>
+      <artifactId>uimafit-core</artifactId>
+      <version>2.5.1-SNAPSHOT</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.uima</groupId>
+      <artifactId>uimaj-core</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+    </dependency>
+  </dependencies>
+</project>
\ No newline at end of file
diff --git a/uimafit-junit/src/main/java/org/apache/uima/fit/testing/junit/ManagedCas.java b/uimafit-junit/src/main/java/org/apache/uima/fit/testing/junit/ManagedCas.java
new file mode 100644
index 0000000..e19453b
--- /dev/null
+++ b/uimafit-junit/src/main/java/org/apache/uima/fit/testing/junit/ManagedCas.java
@@ -0,0 +1,99 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS 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.fit.testing.junit;
+
+import static java.util.Collections.newSetFromMap;
+import static java.util.Collections.synchronizedSet;
+import static org.apache.uima.fit.factory.CasFactory.createCas;
+
+import java.util.Set;
+import java.util.WeakHashMap;
+
+import org.apache.uima.UIMAException;
+import org.apache.uima.cas.CAS;
+import org.apache.uima.resource.metadata.TypeSystemDescription;
+import org.junit.rules.TestWatcher;
+import org.junit.runner.Description;
+
+/**
+ * Provides a {@link CAS} object which is automatically reset before the test. The idea of this
+ * class is to re-use CAS objects across different test method to avoid the overhead of having to
+ * set up a new CAS every time. Each thread requesting a CAS gets a different instance (the CASes
+ * are internally managed as {@link ThreadLocal}. When a test completes, all of the CASses that
+ * handed out to any thread are reset (except any CASes which may meanwhile have been garbage
+ * collected).
+ */
+public final class ManagedCas
+    extends TestWatcher
+{
+    private final ThreadLocal<CAS> casHolder;
+    
+    private final static Set<CAS> managedCases = synchronizedSet(newSetFromMap(new WeakHashMap<>()));
+
+    /**
+     * Provides a CAS with an auto-detected type system.
+     */
+    public ManagedCas()
+    {
+        casHolder = ThreadLocal.withInitial(() -> {
+            try {
+                CAS cas = createCas();
+                managedCases.add(cas);
+                return cas;
+            }
+            catch (UIMAException e) {
+                throw new RuntimeException(e);
+            }
+        });
+    }
+
+    /**
+     * Provides a CAS with the specified type system.
+     * 
+     * @param aTypeSystemDescription
+     *            the type system used to initialize the CAS.
+     */
+    public ManagedCas(TypeSystemDescription aTypeSystemDescription)
+    {
+        casHolder = ThreadLocal.withInitial(() -> {
+            try {
+                CAS cas = createCas(aTypeSystemDescription);
+                managedCases.add(cas);
+                return cas;
+            }
+            catch (UIMAException e) {
+                throw new RuntimeException(e);
+            }
+        });
+    }
+
+    /**
+     * @return the CAS object managed by this rule.
+     */
+    public CAS get()
+    {
+        return casHolder.get();
+    }
+
+    @Override
+    protected void starting(Description description)
+    {
+        managedCases.forEach(cas -> cas.reset());
+    }
+}
\ No newline at end of file
diff --git a/uimafit-junit/src/main/java/org/apache/uima/fit/testing/junit/ManagedJCas.java b/uimafit-junit/src/main/java/org/apache/uima/fit/testing/junit/ManagedJCas.java
new file mode 100644
index 0000000..5276cea
--- /dev/null
+++ b/uimafit-junit/src/main/java/org/apache/uima/fit/testing/junit/ManagedJCas.java
@@ -0,0 +1,99 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS 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.fit.testing.junit;
+
+import static java.util.Collections.newSetFromMap;
+import static java.util.Collections.synchronizedSet;
+import static org.apache.uima.fit.factory.JCasFactory.createJCas;
+
+import java.util.Set;
+import java.util.WeakHashMap;
+
+import org.apache.uima.UIMAException;
+import org.apache.uima.jcas.JCas;
+import org.apache.uima.resource.metadata.TypeSystemDescription;
+import org.junit.rules.TestWatcher;
+import org.junit.runner.Description;
+
+/**
+ * Provides a {@link JCas} object which is automatically reset before the test. The idea of this
+ * class is to re-use JCas objects across different test method to avoid the overhead of having to
+ * set up a new JCas every time. Each thread requesting a JCas gets a different instance (the JCases
+ * are internally managed as {@link ThreadLocal}. When a test completes, all of the JCasses that
+ * handed out to any thread are reset (except any JCases which may meanwhile have been garbage
+ * collected).
+ */
+public final class ManagedJCas
+    extends TestWatcher
+{
+    private final ThreadLocal<JCas> casHolder;
+    
+    private final static Set<JCas> managedCases = synchronizedSet(newSetFromMap(new WeakHashMap<>()));
+
+    /**
+     * Provides a JCas with an auto-detected type system.
+     */
+    public ManagedJCas()
+    {
+        casHolder = ThreadLocal.withInitial(() -> {
+            try {
+                JCas cas = createJCas();
+                managedCases.add(cas);
+                return cas;
+            }
+            catch (UIMAException e) {
+                throw new RuntimeException(e);
+            }
+        });
+    }
+
+    /**
+     * Provides a JCas with the specified type system.
+     * 
+     * @param aTypeSystemDescription
+     *            the type system used to initialize the CAS.
+     */
+    public ManagedJCas(TypeSystemDescription aTypeSystemDescription)
+    {
+        casHolder = ThreadLocal.withInitial(() -> {
+            try {
+                JCas cas = createJCas(aTypeSystemDescription);
+                managedCases.add(cas);
+                return cas;
+            }
+            catch (UIMAException e) {
+                throw new RuntimeException(e);
+            }
+        });
+    }
+
+    /**
+     * @return the JCas object managed by this rule.
+     */
+    public JCas get()
+    {
+        return casHolder.get();
+    }
+
+    @Override
+    protected void starting(Description description)
+    {
+        managedCases.forEach(cas -> cas.reset());
+    }
+}
\ No newline at end of file
diff --git a/uimafit-maven-plugin/src/main/java/org/apache/uima/fit/maven/GenerateDescriptorsMojo.java b/uimafit-maven-plugin/src/main/java/org/apache/uima/fit/maven/GenerateDescriptorsMojo.java
index c616d84..2e85b4b 100644
--- a/uimafit-maven-plugin/src/main/java/org/apache/uima/fit/maven/GenerateDescriptorsMojo.java
+++ b/uimafit-maven-plugin/src/main/java/org/apache/uima/fit/maven/GenerateDescriptorsMojo.java
@@ -80,6 +80,12 @@
   @Parameter(defaultValue = "${project.build.sourceEncoding}", required = true)
   private String encoding;
 
+  /**
+   * Fail on error.
+   */
+  @Parameter(defaultValue = "true", required = true)
+  private boolean failOnError;
+
   enum TypeSystemSerialization {
     NONE, EMBEDDED
   }
@@ -162,13 +168,13 @@
           componentsManifest.append("classpath*:").append(clazzPath + ".xml").append('\n');
         }
       } catch (SAXException e) {
-        getLog().warn("Cannot serialize descriptor for [" + clazzName + "]", e);
+        handleError("Cannot serialize descriptor for [" + clazzName + "]", e);
       } catch (IOException e) {
-        getLog().warn("Cannot write descriptor for [" + clazzName + "]", e);
+        handleError("Cannot write descriptor for [" + clazzName + "]", e);
       } catch (ClassNotFoundException e) {
-        getLog().warn("Cannot analyze class [" + clazzName + "]", e);
+        handleError("Cannot analyze class [" + clazzName + "]", e);
       } catch (ResourceInitializationException e) {
-        getLog().warn("Cannot generate descriptor for [" + clazzName + "]", e);
+        handleError("Cannot generate descriptor for [" + clazzName + "]", e);
       } finally {
         Thread.currentThread().setContextClassLoader(classLoader);
       }
@@ -185,12 +191,20 @@
       try {
         FileUtils.fileWrite(path.getPath(), encoding, componentsManifest.toString());
       } catch (IOException e) {
-        throw new MojoExecutionException("Cannot write components manifest to [" + path + "]"
+        handleError("Cannot write components manifest to [" + path + "]"
                 + ExceptionUtils.getRootCauseMessage(e), e);
       }
     }
   }
 
+  private void handleError(String message, Exception e) throws MojoExecutionException {
+    if (failOnError) {
+      throw new MojoExecutionException(message, e);
+    }
+
+    getLog().error(message, e);
+  }
+
   private void embedTypeSystems(ProcessingResourceMetaData metadata)
           throws ResourceInitializationException {
     TypeSystemDescriptionFactory.forceTypeDescriptorsScan();
diff --git a/uimafit-parent/pom.xml b/uimafit-parent/pom.xml
index 7b3c12f..3883cd4 100644
--- a/uimafit-parent/pom.xml
+++ b/uimafit-parent/pom.xml
@@ -1,3 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements. See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership. The ASF licenses this file
+  to you under the Apache License, Version 2.0 (the
+  "License"); you may not use this file except in compliance
+  with the License. You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing,
+  software distributed under the License is distributed on an
+  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  KIND, either express or implied. See the License for the
+  specific language governing permissions and limitations
+  under the License.
+-->
 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
   <modelVersion>4.0.0</modelVersion>
   <parent>
@@ -41,6 +60,9 @@
     </repository>
   </repositories>
   <pluginRepositories>
+    <!--
+      - For UIMA/uimaFIT SNAPSHOTs
+    -->
     <pluginRepository>
       <id>apache.snapshots.plugins</id>
       <name>Apache Snapshot Repository - Maven plugins</name>
@@ -74,7 +96,7 @@
       <dependency>
         <groupId>org.assertj</groupId>
         <artifactId>assertj-core</artifactId>
-        <version>3.10.0</version>
+        <version>3.15.0</version>
       </dependency>
       <dependency>
         <groupId>org.xmlunit</groupId>
@@ -178,6 +200,9 @@
         </executions>
         <configuration>
           <failOnWarning>true</failOnWarning>
+          <ignoredDependencies>
+            <ignoredDependency>junit:junit</ignoredDependency>
+          </ignoredDependencies>
         </configuration>
       </plugin>
       <plugin>
@@ -215,6 +240,14 @@
           </dependency>
         </dependencies>
       </plugin>
+      <plugin>
+        <groupId>org.apache.rat</groupId>
+        <artifactId>apache-rat-plugin</artifactId>
+        <!-- 
+          Normally this only gets executed during releases, but we want licenses to be checked on
+          every build to make sure the licenses are included in the PRs.
+         -->
+      </plugin>
     </plugins>
     <pluginManagement>
       <plugins>
@@ -226,19 +259,25 @@
         <plugin>
           <groupId>org.apache.rat</groupId>
           <artifactId>apache-rat-plugin</artifactId>
+          <version>0.13</version>
           <executions>
             <execution>
               <id>default-cli</id>
               <configuration>
+                <consoleOutput>true</consoleOutput>
                 <excludes combine.children="append">
                   <!-- Plain documentation -->
                   <exclude>README*</exclude>
+                  <!-- GitHub templates -->
+                  <exclude>.github/**</exclude>
                   <!-- Release files -->
                   <exclude>RELEASE_NOTES*</exclude>
                   <exclude>issuesFixed/**</exclude>
                   <exclude>release.properties</exclude>
                   <!-- Build controls -->
                   <exclude>.activate-enforce-compatibility</exclude>
+                  <!-- Logging configuration files -->
+                  <exclude>**/simplelogger.properties</exclude>
                 </excludes>
               </configuration>
             </execution>
@@ -369,6 +408,7 @@
       </plugins>
     </pluginManagement>
   </build>
+  
   <profiles>
     <profile>
       <id>enforce-compatibility</id>