Jira UIMA-525: move 2.1 SVN tags under common directory.

https://issues.apache.org/jira/browse/UIMA-525


git-svn-id: https://svn.apache.org/repos/asf/incubator/uima/uimaj/tags/uimaj-2.1.0@564105 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/META-INF/MANIFEST.MF b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..4e37e42
--- /dev/null
+++ b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/META-INF/MANIFEST.MF
@@ -0,0 +1,35 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: Apache UIMA Component Descriptor Editor
+Bundle-SymbolicName: org.apache.uima.desceditor; singleton:=true
+Bundle-Version: 2.1.0.incubating-hotfix-1
+Bundle-ClassPath: uima-ep-configurator.jar
+Bundle-Activator: org.eclipse.core.internal.compatibility.PluginActivator
+Bundle-Vendor: The Apache Software Foundation
+Bundle-Localization: plugin
+Export-Package: org.apache.uima.taeconfigurator,
+ org.apache.uima.taeconfigurator.editors,
+ org.apache.uima.taeconfigurator.editors.ui,
+ org.apache.uima.taeconfigurator.editors.ui.dialogs,
+ org.apache.uima.taeconfigurator.editors.xml,
+ org.apache.uima.taeconfigurator.files,
+ org.apache.uima.taeconfigurator.model,
+ org.apache.uima.taeconfigurator.wizards
+Require-Bundle: org.eclipse.core.runtime.compatibility,
+ org.eclipse.ui.ide,
+ org.eclipse.jface.text,
+ org.eclipse.ui.workbench.texteditor,
+ org.eclipse.ui.editors,
+ org.eclipse.core.resources,
+ org.eclipse.ui,
+ org.eclipse.core.runtime,
+ org.apache.uima.runtime,
+ org.eclipse.ui.forms,
+ org.eclipse.jdt.core,
+ org.eclipse.jdt.ui,
+ org.eclipse.pde.ui,
+ org.apache.uima.jcas.jcasgenp,
+ org.eclipse.jdt.launching,
+ org.eclipse.search
+Eclipse-AutoStart: true
+Plugin-Class: org.apache.uima.taeconfigurator.TAEConfiguratorPlugin
diff --git a/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/icons/annotator.gif b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/icons/annotator.gif
new file mode 100644
index 0000000..b60cc30
--- /dev/null
+++ b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/icons/annotator.gif
Binary files differ
diff --git a/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/icons/arrows.gif b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/icons/arrows.gif
new file mode 100644
index 0000000..feeafbe
--- /dev/null
+++ b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/icons/arrows.gif
Binary files differ
diff --git a/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/icons/big_ae.gif b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/icons/big_ae.gif
new file mode 100644
index 0000000..a0086b7
--- /dev/null
+++ b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/icons/big_ae.gif
Binary files differ
diff --git a/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/icons/big_t_s.gif b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/icons/big_t_s.gif
new file mode 100644
index 0000000..ed0da45
--- /dev/null
+++ b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/icons/big_t_s.gif
Binary files differ
diff --git a/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/icons/blank.GIF b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/icons/blank.GIF
new file mode 100644
index 0000000..6ad2049
--- /dev/null
+++ b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/icons/blank.GIF
Binary files differ
diff --git a/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/icons/common.gif b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/icons/common.gif
new file mode 100644
index 0000000..15cfc6d
--- /dev/null
+++ b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/icons/common.gif
Binary files differ
diff --git a/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/icons/editor.gif b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/icons/editor.gif
new file mode 100644
index 0000000..7e5866a
--- /dev/null
+++ b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/icons/editor.gif
Binary files differ
diff --git a/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/icons/form_banner.gif b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/icons/form_banner.gif
new file mode 100644
index 0000000..aebc0b2
--- /dev/null
+++ b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/icons/form_banner.gif
Binary files differ
diff --git a/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/icons/gelb.gif b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/icons/gelb.gif
new file mode 100644
index 0000000..95c03ba
--- /dev/null
+++ b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/icons/gelb.gif
Binary files differ
diff --git a/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/icons/group.GIF b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/icons/group.GIF
new file mode 100644
index 0000000..755a25e
--- /dev/null
+++ b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/icons/group.GIF
Binary files differ
diff --git a/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/icons/one_arrow.gif b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/icons/one_arrow.gif
new file mode 100644
index 0000000..5227a2c
--- /dev/null
+++ b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/icons/one_arrow.gif
Binary files differ
diff --git a/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/icons/parameter.GIF b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/icons/parameter.GIF
new file mode 100644
index 0000000..e4379bf
--- /dev/null
+++ b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/icons/parameter.GIF
Binary files differ
diff --git a/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/icons/t_s.gif b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/icons/t_s.gif
new file mode 100644
index 0000000..ece0847
--- /dev/null
+++ b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/icons/t_s.gif
Binary files differ
diff --git a/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/icons/th_horizontal.gif b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/icons/th_horizontal.gif
new file mode 100644
index 0000000..ef3066c
--- /dev/null
+++ b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/icons/th_horizontal.gif
Binary files differ
diff --git a/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/icons/th_vertical.gif b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/icons/th_vertical.gif
new file mode 100644
index 0000000..50a54e0
--- /dev/null
+++ b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/icons/th_vertical.gif
Binary files differ
diff --git a/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/plugin.xml b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/plugin.xml
new file mode 100644
index 0000000..2b7476d
--- /dev/null
+++ b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/plugin.xml
@@ -0,0 +1,143 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.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.
+	 ***************************************************************
+	-->
+
+<plugin>
+     <extension
+         point="org.eclipse.ui.editors">
+      <editor
+            name="Component Descriptor Editor"
+            default="false"
+            icon="icons/editor.gif"
+            extensions="xml"
+            contributorClass="org.apache.uima.taeconfigurator.editors.MultiPageEditorContributor"
+            class="org.apache.uima.taeconfigurator.editors.MultiPageEditor"
+            id="taeconfigurator.editors.MultiPageEditor">
+      </editor>
+   </extension>
+   <extension
+         point="org.eclipse.ui.newWizards">
+      <category
+            name="UIMA"
+            id="org.apache.uima.cpe.UIMA">
+      </category>
+      <category
+            parentCategory="org.apache.uima.cpe.UIMA"
+            name="Collection Processing Components"
+            id="org.apache.uima.cpe.cpmComponents"/>
+      <category
+            parentCategory="org.apache.uima.cpe.UIMA"
+            name="Importable Parts"
+            id="org.apache.uima.cpe.importParts"/>
+      <wizard
+            name="Analysis Engine Descriptor File"
+            icon="icons/editor.gif"
+            category="org.apache.uima.cpe.UIMA"
+            class="org.apache.uima.taeconfigurator.wizards.TAEConfiguratorNewWizard"
+            id="taeconfigurator.wizards.TAEConfiguratorNewWizard">
+      </wizard>
+      <wizard
+            name="Type System Descriptor File"
+            icon="icons/t_s.gif"
+            category="org.apache.uima.cpe.UIMA"
+            class="org.apache.uima.taeconfigurator.wizards.TypeSystemNewWizard"
+            id="taeconfigurator.wizards.TypeSystemNewWizard">
+      </wizard>
+      <wizard
+            name="Type Priorities Descriptor File"
+            icon="icons/t_s.gif"
+            category="org.apache.uima.cpe.UIMA/org.apache.uima.cpe.importParts"
+            class="org.apache.uima.taeconfigurator.wizards.TypePrioritiesNewWizard"
+            id="taeconfigurator.wizards.TypePrioritiesNewWizard">
+      </wizard>
+      <wizard
+            name="Index Collection Descriptor File"
+            icon="icons/t_s.gif"
+            category="org.apache.uima.cpe.UIMA/org.apache.uima.cpe.importParts"
+            class="org.apache.uima.taeconfigurator.wizards.FsIndexCollectionNewWizard"
+            id="taeconfigurator.wizards.FsIndexCollectionNewWizard">
+      </wizard>
+      <wizard
+            name="External Resource and Bindings (Resource Manager Configuration) Descriptor File"
+            icon="icons/editor.gif"
+            category="org.apache.uima.cpe.UIMA/org.apache.uima.cpe.importParts"
+            class="org.apache.uima.taeconfigurator.wizards.ResourceManagerConfigurationNewWizard"
+            id="taeconfigurator.wizards.ResourceManagerConfigurationNewWizard">
+      </wizard>
+      <wizard
+            name="Cas Consumer Descriptor File"
+            icon="icons/editor.gif"
+            category="org.apache.uima.cpe.UIMA/org.apache.uima.cpe.cpmComponents"
+            class="org.apache.uima.taeconfigurator.wizards.CasConsumerNewWizard"
+            id="taeconfigurator.wizards.CasConsumerNewWizard">
+      </wizard>
+      <wizard
+            name="Cas Initializer Descriptor File"
+            icon="icons/editor.gif"
+            category="org.apache.uima.cpe.UIMA/org.apache.uima.cpe.cpmComponents"
+            class="org.apache.uima.taeconfigurator.wizards.CasInitializerNewWizard"
+            id="taeconfigurator.wizards.CasInitializerNewWizard">
+      </wizard>
+      <wizard
+            name="Collection Reader Descriptor File"
+            icon="icons/editor.gif"
+            category="org.apache.uima.cpe.UIMA/org.apache.uima.cpe.cpmComponents"
+            class="org.apache.uima.taeconfigurator.wizards.CollectionReaderNewWizard"
+            id="taeconfigurator.wizards.CollectionReaderNewWizard">
+      </wizard>
+      <wizard
+            category="org.apache.uima.cpe.UIMA/org.apache.uima.cpe.importParts"
+            class="org.apache.uima.taeconfigurator.wizards.FlowControllerNewWizard"
+            icon="icons/editor.gif"
+            id="taeconfigurator.wizards.FlowControllerNewWizard"
+            name="Flow Controller Descriptor File"/>
+ 
+   </extension>
+   <extension
+         id="UIMA_DataPath"
+         name="DataPath"
+         point="org.eclipse.core.resources.markers">
+         <persistent value="true"/> 
+         <attribute name="path"/>
+   </extension>
+   <extension
+         id="UIMA_Preferences"
+         name="UIMA Preferences"
+         point="org.eclipse.ui.preferencePages">
+      <page
+            class="org.apache.uima.taeconfigurator.PreferencePage"
+            name="UIMA Preferences"
+            id="org.apache.uima.taeconfigurator.PreferencePage"/>
+   </extension>
+   <extension
+         id="org.apache.uima.taeconfigurator.projectProperties"
+         name="UIMA Component Descriptor Editor Properties"
+         point="org.eclipse.ui.propertyPages">
+      <page
+            adaptable="true"
+            objectClass="org.eclipse.core.resources.IProject"
+            class="org.apache.uima.taeconfigurator.CDEpropertyPage"
+            name="UIMA CDE Property Page"
+            id="org.apache.uima.taeconfigurator.CDEpropertyPage"/>
+   </extension>
+   
+</plugin>
diff --git a/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/pom.xml b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/pom.xml
new file mode 100644
index 0000000..17e00b5
--- /dev/null
+++ b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/pom.xml
@@ -0,0 +1,117 @@
+<!--

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

+   or more contributor license agreements.  See the NOTICE file

+   distributed with this work for additional information

+   regarding copyright ownership.  The ASF licenses this file

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

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

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

+

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

+

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

+   software distributed under the License is distributed on an

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

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

+   specific language governing permissions and limitations

+   under the License.    

+-->

+

+<project xmlns="http://maven.apache.org/POM/4.0.0"
+	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+	<modelVersion>4.0.0</modelVersion>
+	<groupId>org.apache.uima</groupId>
+	<artifactId>uimaj-ep-configurator</artifactId>
+	<packaging>jar</packaging>
+	<version>2.1.0-incubating-hotfix-1</version>
+	<name>Apache UIMA Configurator Eclipse Plugin</name>
+	<url>http://incubator.apache.org/uima</url>
+	<parent>
+		<groupId>org.apache.uima</groupId>
+		<artifactId>uimaj</artifactId>
+		<version>2.1.0-incubating</version>
+	</parent>
+	<dependencies>
+		<dependency>
+			<groupId>org.apache.uima</groupId>
+			<artifactId>uimaj-core</artifactId>
+			<version>2.1.0-incubating</version>
+			<scope>compile</scope>
+		</dependency>		
+		<dependency>
+			<groupId>org.apache.uima</groupId>
+			<artifactId>uimaj-tools</artifactId>
+			<version>2.1.0-incubating</version>
+			<scope>compile</scope>
+		</dependency>	
+		<dependency>
+			<groupId>org.apache.uima</groupId>
+			<artifactId>uimaj-ep-jcasgen</artifactId>
+			<version>2.1.0-incubating</version>
+			<scope>compile</scope>
+		</dependency>			
+		
+		<dependency>
+			<groupId>org.eclipse.core</groupId>
+			<artifactId>org.eclipse.core.runtime</artifactId>
+			<version>3.2.0</version>
+			<scope>provided</scope>
+		</dependency>
+		<dependency>
+			<groupId>org.eclipse.jdt</groupId>
+			<artifactId>org.eclipse.jdt.core</artifactId>
+			<version>3.2.0</version>
+			<scope>provided</scope>
+		</dependency>	
+		<dependency>
+			<groupId>org.eclipse.jdt</groupId>
+			<artifactId>org.eclipse.jdt.ui</artifactId>
+			<version>3.2.0</version>
+			<scope>provided</scope>
+		</dependency>					
+		<dependency>
+			<groupId>org.eclipse.pde</groupId>
+			<artifactId>org.eclipse.pde.ui</artifactId>
+			<version>3.2.0</version>
+			<scope>provided</scope>
+		</dependency>					
+		<dependency>
+			<groupId>org.eclipse.jface</groupId>
+			<artifactId>org.eclipse.jface.text</artifactId>
+			<version>3.2.0</version>
+			<scope>provided</scope>
+		</dependency>
+		<dependency>
+			<groupId>org.eclipse.swt</groupId>
+			<artifactId>org.eclipse.swt.win32.win32.x86</artifactId>
+			<version>3.2.0</version>
+			<scope>provided</scope>
+		</dependency>
+	</dependencies>
+	<build>
+		<finalName>uima-ep-configurator</finalName>	
+		<plugins>
+			<plugin>
+				<artifactId>maven-assembly-plugin</artifactId>
+				<executions>
+					<execution>
+						<id>bin</id>
+						<phase>package</phase>
+						<goals>
+							<goal>attached</goal>
+						</goals>
+						<configuration>
+							<descriptors>
+								<descriptor>
+									src/main/assembly/assemble-plugin.xml</descriptor>
+							</descriptors>
+							<finalName>org.apache.uima.desceditor.2.1.0.incubating-hotfix-1</finalName>
+							<appendAssemblyId>false</appendAssemblyId>
+						</configuration>
+					</execution>
+				</executions>
+			</plugin>
+		</plugins>
+	</build>
+</project>
\ No newline at end of file
diff --git a/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/assembly/assemble-plugin.xml b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/assembly/assemble-plugin.xml
new file mode 100644
index 0000000..e47b4c5
--- /dev/null
+++ b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/assembly/assemble-plugin.xml
@@ -0,0 +1,51 @@
+<assembly>
+

+<!--

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

+ or more contributor license agreements.  See the NOTICE file

+ distributed with this work for additional information

+ regarding copyright ownership.  The ASF licenses this file

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

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

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

+ 

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

+ 

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

+ software distributed under the License is distributed on an

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

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

+ specific language governing permissions and limitations

+ under the License.

+-->

+

+	<id>plugin</id>
+	<formats>
+		<format>zip</format>
+	</formats>
+	<includeBaseDirectory>true</includeBaseDirectory>
+	<fileSets>
+		<fileSet>
+			<directory>./</directory>
+			<includes>
+				<include>plugin.xml</include>
+				<include>META-INF/</include>
+				<include>icons/</include>
+				<include>about.html/</include>
+			</includes>
+			<outputDirectory>/</outputDirectory>
+		</fileSet>
+			<!-- for hotfix-1 -->
+		<fileSet>
+			<directory>src/main/readme</directory>
+			<outputDirectory>/</outputDirectory>
+		</fileSet>
+		<fileSet>
+			<directory>target</directory>
+			<includes>
+				<include>uima-ep-configurator.jar</include>
+			</includes>
+			<outputDirectory>/</outputDirectory>
+		</fileSet>
+	</fileSets>
+</assembly>
\ No newline at end of file
diff --git a/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/CDEpropertyPage.java b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/CDEpropertyPage.java
new file mode 100644
index 0000000..34a9950
--- /dev/null
+++ b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/CDEpropertyPage.java
@@ -0,0 +1,154 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS 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.taeconfigurator;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.QualifiedName;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.ui.dialogs.PropertyPage;
+
+public class CDEpropertyPage extends PropertyPage {
+
+  private static final String DATAPATH_LABEL = "&Data Path:";
+
+  private static final String DATAPATH_PROPERTY_KEY = "CDEdataPath";
+
+  private static final String DEFAULT_DATAPATH = "";
+
+  private static final String BY_DEFAULT_PROPERTY_KEY = "CDEByDefault";
+
+  // private static final int TEXT_FIELD_WIDTH = 50;
+
+  private Text dataPathUI;
+
+  public CDEpropertyPage() {
+    super();
+  }
+
+  /**
+   * @see PreferencePage#createContents(Composite)
+   */
+  protected Control createContents(Composite parent) {
+    Composite composite = create2ColComposite(parent);
+
+    Label instructions = new Label(composite, SWT.WRAP);
+    instructions
+            .setText("Enter the data path to use for finding resources by name;\n"
+                    + "This is a series of absolute paths, separated by\n"
+                    + "whatever character this platform uses for path separation (similar to class paths).\n\n");
+    GridData gd = new GridData(GridData.FILL_HORIZONTAL);
+    gd.horizontalSpan = 2;
+    gd.grabExcessHorizontalSpace = true;
+    instructions.setLayoutData(gd);
+
+    new Label(composite, SWT.NONE).setText(DATAPATH_LABEL);
+
+    dataPathUI = new Text(composite, SWT.MULTI | SWT.BORDER | SWT.V_SCROLL);
+    gd = new GridData(GridData.FILL_BOTH);
+    dataPathUI.setLayoutData(gd);
+
+    try {
+      String dataPath = ((IResource) getElement()).getPersistentProperty(new QualifiedName("",
+              DATAPATH_PROPERTY_KEY));
+      dataPathUI.setText((dataPath != null) ? dataPath : DEFAULT_DATAPATH);
+    } catch (CoreException e) {
+      dataPathUI.setText(DEFAULT_DATAPATH);
+    }
+    return composite;
+  }
+
+  private Composite create2ColComposite(Composite parent) {
+    Composite composite = new Composite(parent, SWT.NULL);
+    GridLayout layout = new GridLayout();
+    layout.numColumns = 2;
+    composite.setLayout(layout);
+
+    GridData data = new GridData();
+    data.verticalAlignment = GridData.FILL;
+    data.horizontalAlignment = GridData.FILL;
+    composite.setLayoutData(data);
+
+    return composite;
+  }
+
+  protected void performDefaults() {
+    dataPathUI.setText(DEFAULT_DATAPATH);
+  }
+
+  public boolean performOk() {
+    // store the value in the owner text field
+    try {
+      ((IResource) getElement()).setPersistentProperty(
+              new QualifiedName("", DATAPATH_PROPERTY_KEY), dataPathUI.getText());
+    } catch (CoreException e) {
+      return false;
+    }
+    return true;
+  }
+
+  public static String getDataPath(IProject project) {
+    String dataPath;
+    try {
+      dataPath = project.getPersistentProperty(new QualifiedName("", DATAPATH_PROPERTY_KEY));
+    } catch (CoreException e) {
+      dataPath = "";
+    }
+    if (null == dataPath)
+      dataPath = "";
+    return dataPath;
+  }
+
+  public static void setDataPath(IProject project, String dataPath) {
+    try {
+      project.setPersistentProperty(new QualifiedName("", DATAPATH_PROPERTY_KEY), dataPath);
+    } catch (CoreException e) {
+      throw new InternalErrorCDE("unhandled exception", e);
+    }
+  }
+
+  public static String getImportByDefault(IProject project) {
+    String byDefault;
+    try {
+      byDefault = project.getPersistentProperty(new QualifiedName("", BY_DEFAULT_PROPERTY_KEY));
+    } catch (CoreException e) {
+      byDefault = "";
+    }
+    if (null == byDefault)
+      byDefault = "";
+    return byDefault;
+  }
+
+  public static void setImportByDefault(IProject project, String byDefault) {
+    try {
+      project.setPersistentProperty(new QualifiedName("", BY_DEFAULT_PROPERTY_KEY), byDefault);
+    } catch (CoreException e) {
+      throw new InternalErrorCDE("unhandled exception", e);
+    }
+  }
+
+}
diff --git a/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/InternalErrorCDE.java b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/InternalErrorCDE.java
new file mode 100644
index 0000000..4ab8277
--- /dev/null
+++ b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/InternalErrorCDE.java
@@ -0,0 +1,56 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.uima.taeconfigurator;
+
+/**
+ */
+public class InternalErrorCDE extends RuntimeException {
+
+  /**
+   * 
+   */
+  public InternalErrorCDE() {
+    super();
+  }
+
+  /**
+   * @param message
+   */
+  public InternalErrorCDE(String message) {
+    super(message);
+  }
+
+  /**
+   * @param message
+   * @param cause
+   */
+  public InternalErrorCDE(String message, Throwable cause) {
+    super(message, cause);
+  }
+
+  /**
+   * @param cause
+   */
+  public InternalErrorCDE(Throwable cause) {
+    super(cause);
+  }
+
+  static final long serialVersionUID = 1041388340406853782L;
+}
diff --git a/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/Messages.java b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/Messages.java
new file mode 100644
index 0000000..cf00ec7
--- /dev/null
+++ b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/Messages.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.taeconfigurator;
+
+import java.text.MessageFormat;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+/**
+ */
+public class Messages {
+  private static final String BUNDLE_NAME = "org.apache.uima.taeconfigurator.messages";//$NON-NLS-1$
+
+  private static final ResourceBundle RESOURCE_BUNDLE = ResourceBundle.getBundle(BUNDLE_NAME);
+
+  private Messages() {
+  }
+
+  public static String getString(String key) {
+    try {
+      return RESOURCE_BUNDLE.getString(key);
+    } catch (MissingResourceException e) {
+      return '!' + key + '!';
+    }
+  }
+
+  public static String getFormattedString(String key, String[] args) {
+    return MessageFormat.format(RESOURCE_BUNDLE.getString(key), args);
+  }
+
+}
diff --git a/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/PreferencePage.java b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/PreferencePage.java
new file mode 100644
index 0000000..e90733c
--- /dev/null
+++ b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/PreferencePage.java
@@ -0,0 +1,77 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS 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.taeconfigurator;
+
+import org.eclipse.jface.preference.*;
+import org.eclipse.ui.IWorkbenchPreferencePage;
+import org.eclipse.ui.IWorkbench;
+import org.apache.uima.taeconfigurator.TAEConfiguratorPlugin;
+import org.eclipse.jface.preference.IPreferenceStore;
+
+public class PreferencePage extends FieldEditorPreferencePage implements IWorkbenchPreferencePage {
+  public static final String P_JCAS = "org.apache.uima.cde.autojcasgen";
+
+  public static final String P_SHOW_FULLY_QUALIFIED_NAMES = "org.apache.uima.cde.qualifiedtypes";
+
+  public static final String P_XML_TAB_SPACES = "org.apache.uima.cde.xmlIndentAmount";
+
+  public static final String P_VNS_HOST = "org.apache.uima.cde.vnsHost";
+
+  public static final String P_VNS_PORT = "org.apache.uima.cde.vnsPort";
+
+  public PreferencePage() {
+    super(GRID);
+    setPreferenceStore(TAEConfiguratorPlugin.getDefault().getPreferenceStore());
+    setDescription("UIMA Component Descriptor Editor Preferences");
+    initializeDefaults();
+  }
+
+  /**
+   * Sets the default values of the preferences.
+   */
+  private void initializeDefaults() {
+    IPreferenceStore store = getPreferenceStore();
+    store.setDefault(P_JCAS, true);
+    store.setDefault(P_SHOW_FULLY_QUALIFIED_NAMES, true);
+    store.setDefault(P_XML_TAB_SPACES, 2);
+    store.setDefault(P_VNS_HOST, "localhost");
+    store.setDefault(P_VNS_PORT, "9000");
+    // store.setDefault(P_DATA_PATH, "");
+  }
+
+  public void createFieldEditors() {
+    addField(new BooleanFieldEditor(P_JCAS, "&Automatically run JCasGen when Types change",
+            getFieldEditorParent()));
+
+    addField(new BooleanFieldEditor(P_SHOW_FULLY_QUALIFIED_NAMES, "&Show fully qualified names",
+            getFieldEditorParent()));
+
+    addField(new IntegerFieldEditor(P_XML_TAB_SPACES, "&XML indentation", getFieldEditorParent()));
+
+    addField(new StringFieldEditor(P_VNS_HOST, "&Vinci Name Service Host IP address",
+            getFieldEditorParent()));
+
+    addField(new StringFieldEditor(P_VNS_PORT, "Vinci NameService &Port number",
+            getFieldEditorParent()));
+  }
+
+  public void init(IWorkbench workbench) {
+  }
+}
diff --git a/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/StandardStrings.java b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/StandardStrings.java
new file mode 100644
index 0000000..7dd15d0
--- /dev/null
+++ b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/StandardStrings.java
@@ -0,0 +1,50 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.uima.taeconfigurator;
+
+/**
+ */
+public interface StandardStrings {
+  public static final String S_ADD = "Add...";
+
+  public static final String S_EDIT = "Edit...";
+
+  public static final String S_EDIT_TIP = "Click here to edit the selected item. You can also double-click the item to edit it.";
+
+  public static final String S_REMOVE = "Remove";
+
+  public static final String S_REMOVE_TIP = "Click here to remove the selected item.  You can also use the delete key.";
+
+  public static final String S_UP = "Up";
+
+  public static final String S_UP_TIP = "Click here to move the selected item up by one.";
+
+  public static final String S_DOWN = "Down";
+
+  public static final String S_DOWN_TIP = "Click here to move the selected item down by one.";
+
+  public static final String S_DESCRIPTION = "Description:";
+
+  public static final String S_ = "";
+
+  public static final String S_EXPORT = "Export...";
+
+  public static final String S_EXPORT_TIP = "Export to an importable part, and substitute an Import for that part here";
+}
diff --git a/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/TAEConfiguratorPlugin.java b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/TAEConfiguratorPlugin.java
new file mode 100644
index 0000000..7545e61
--- /dev/null
+++ b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/TAEConfiguratorPlugin.java
@@ -0,0 +1,229 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.uima.taeconfigurator;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+import org.eclipse.core.resources.IWorkspace;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.IPluginDescriptor;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.PluginVersionIdentifier;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jface.resource.ImageRegistry;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.ui.forms.FormColors;
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+
+/**
+ * The main plugin class to be used in the desktop.
+ */
+
+/*
+ * Plugin not yet converted to OSGi Bundle (3.0 design) - therefore will require the compatibility
+ * interface.
+ * 
+ * The descriptor editor is a Multi-page editor, and implements the Model View Controller pattern
+ * (MVC). Model: Maintain data, basic logic plus one or more data sources View: Display all or a
+ * portion of the data. Implements the GUI that displays information about the model to the user
+ * Controller: Handle events that affect the model or view. The flow-control mechanism means by
+ * which the user interacts with the application
+ * 
+ * View: in packages ...editors, editors.ui, and editors.ui.dialogs Observer links: View updates
+ * from model when update() is called on the page that is showing. This happens when which page is
+ * showing changes, or when the model changes.
+ * 
+ * 
+ * Life Cycle: On first activation - does almost nothing. Anything that could be done here is done
+ * lazily, on first use/need. On shutdown: shutdown call not done (it's deprecated.) Instead, we use
+ * the stop method. It releases SWT resources.
+ */
+
+public class TAEConfiguratorPlugin extends AbstractUIPlugin {
+
+  public static final boolean is30version;
+
+  public static final int eclipseVersionMajor;
+
+  public static final int eclipseVersionMinor;
+  static {
+    Bundle bundle = Platform.getBundle("org.eclipse.platform");
+    String versionString = (String) bundle.getHeaders().get(
+            org.osgi.framework.Constants.BUNDLE_VERSION);
+    PluginVersionIdentifier version = new PluginVersionIdentifier(versionString);
+    eclipseVersionMajor = version.getMajorComponent();
+    eclipseVersionMinor = version.getMinorComponent();
+    is30version = eclipseVersionMajor == 3 && eclipseVersionMinor == 0;
+  }
+
+  // The shared instance.
+  private static TAEConfiguratorPlugin plugin;
+
+  // Resource bundle.
+  private ResourceBundle resourceBundle;
+
+  private static FormColors formColors;
+
+  private static ImageRegistry imageRegistry = new ImageRegistry();
+
+  public final static String IMAGE_ANNOTATOR = "annotator.gif";
+
+  public final static String IMAGE_BIG_AE = "big_ae.gif";
+
+  public final static String IMAGE_BIG_T_S = "big_t_s.gif";
+
+  public final static String IMAGE_BLANK = "blank.gif";
+
+  public final static String IMAGE_COMMON = "common.gif";
+
+  public final static String IMAGE_EDITOR = "editor.gif";
+
+  public final static String IMAGE_FORM_BANNER = "form_banner.gif";
+
+  public final static String IMAGE_GELB = "gelb.gif";
+
+  public final static String IMAGE_GROUP = "group.gif";
+
+  public final static String IMAGE_PARAMETER = "parameter.gif";
+
+  public final static String IMAGE_T_S = "t_s.gif";
+
+  public final static String IMAGE_TH_HORIZONTAL = "th_horizontal.gif";
+
+  public final static String IMAGE_TH_VERTICAL = "th_vertical.gif";
+
+  public final static String IMAGE_MREFOK = "arrows.gif";
+
+  public final static String IMAGE_NOMREF = "one_arrow.gif";
+
+  private static URL installURL = null;
+
+  /**
+   * The constructor.
+   */
+  public TAEConfiguratorPlugin(IPluginDescriptor descriptor) {
+    super(descriptor);
+    plugin = this;
+    try {
+      resourceBundle = ResourceBundle.getBundle("org.apache.uima.taeconfigurator.taeconfigurator");
+    } catch (MissingResourceException x) {
+      resourceBundle = null;
+    }
+    imageRegistry.put(IMAGE_ANNOTATOR, getImageDescriptor("annotator.gif"));
+    imageRegistry.put(IMAGE_BIG_AE, getImageDescriptor("big_ae.gif"));
+    imageRegistry.put(IMAGE_BIG_T_S, getImageDescriptor("big_t_s.gif"));
+    imageRegistry.put(IMAGE_BLANK, getImageDescriptor("blank.gif"));
+    imageRegistry.put(IMAGE_COMMON, getImageDescriptor("common.gif"));
+    imageRegistry.put(IMAGE_EDITOR, getImageDescriptor("editor.gif"));
+    imageRegistry.put(IMAGE_FORM_BANNER, getImageDescriptor("form_banner.gif"));
+    imageRegistry.put(IMAGE_GELB, getImageDescriptor("gelb.gif"));
+    imageRegistry.put(IMAGE_GROUP, getImageDescriptor("group.gif"));
+    imageRegistry.put(IMAGE_PARAMETER, getImageDescriptor("parameter.gif"));
+    imageRegistry.put(IMAGE_T_S, getImageDescriptor("t_s.gif"));
+    imageRegistry.put(IMAGE_TH_HORIZONTAL, getImageDescriptor("th_horizontal.gif"));
+    imageRegistry.put(IMAGE_TH_VERTICAL, getImageDescriptor("th_vertical.gif"));
+    imageRegistry.put(IMAGE_MREFOK, getImageDescriptor("arrows.gif"));
+    imageRegistry.put(IMAGE_NOMREF, getImageDescriptor("one_arrow.gif"));
+  }
+
+  /**
+   * Returns the shared instance.
+   */
+  public static TAEConfiguratorPlugin getDefault() {
+    return plugin;
+  }
+
+  /**
+   * Returns the workspace instance.
+   */
+  public static IWorkspace getWorkspace() {
+    return ResourcesPlugin.getWorkspace();
+  }
+
+  /**
+   * Returns the string from the plugin's resource bundle, or 'key' if not found.
+   */
+  public static String getResourceString(String key) {
+    ResourceBundle bundle = TAEConfiguratorPlugin.getDefault().getResourceBundle();
+    try {
+      return bundle.getString(key);
+    } catch (MissingResourceException e) {
+      return key;
+    }
+  }
+
+  /**
+   * called when the Eclipse environment is shut down
+   */
+  public void stop(BundleContext context) throws Exception {
+    try {
+      if (null != formColors)
+        formColors.dispose();
+
+    } finally {
+      formColors = null;
+      super.stop(context);
+    }
+  }
+
+  /**
+   * On first call, gets a formColors instance; on subsequent calls, returns that instance.
+   * 
+   * @param display
+   * @return
+   */
+  public FormColors getFormColors(Display display) {
+    if (null == formColors) {
+      formColors = new FormColors(display);
+      formColors.markShared(); // keep it from being disposed early
+    }
+    return formColors;
+  }
+
+  /**
+   * Returns the plugin's resource bundle,
+   */
+  public ResourceBundle getResourceBundle() {
+    return resourceBundle;
+  }
+
+  public static Image getImage(String imageFile) {
+    return imageRegistry.get(imageFile);
+  }
+
+  public static ImageDescriptor getImageDescriptor(String imageFile) {
+    String iconPath = "icons/";
+    try {
+      if (null == installURL)
+        installURL = getDefault().getDescriptor().getInstallURL();
+      URL url = new URL(installURL, iconPath + imageFile);
+      return ImageDescriptor.createFromURL(url);
+    } catch (MalformedURLException exc) {
+      return ImageDescriptor.getMissingImageDescriptor();
+    }
+  }
+
+}
diff --git a/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/Form2Panel.java b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/Form2Panel.java
new file mode 100644
index 0000000..f86fe10
--- /dev/null
+++ b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/Form2Panel.java
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.uima.taeconfigurator.editors;
+
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * 3 element return value for 2 panel forms
+ */
+public class Form2Panel {
+
+  public Composite form;
+
+  public Composite left;
+
+  public Composite right;
+
+  public Form2Panel(Composite form, Composite left, Composite right) {
+    this.form = form;
+    this.left = left;
+    this.right = right;
+  }
+
+}
diff --git a/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/MultiPageEditor.java b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/MultiPageEditor.java
new file mode 100644
index 0000000..1a3fcac
--- /dev/null
+++ b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/MultiPageEditor.java
@@ -0,0 +1,2611 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS 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.taeconfigurator.editors;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.PrintStream;
+import java.io.StringWriter;
+import java.io.UnsupportedEncodingException;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.text.MessageFormat;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeMap;
+import java.util.Vector;
+
+import org.apache.uima.UIMAFramework;
+import org.apache.uima.analysis_engine.AnalysisEngineDescription;
+import org.apache.uima.analysis_engine.TypeOrFeature;
+import org.apache.uima.analysis_engine.impl.AnalysisEngineDescription_impl;
+import org.apache.uima.analysis_engine.metadata.AnalysisEngineMetaData;
+import org.apache.uima.analysis_engine.metadata.FlowControllerDeclaration;
+import org.apache.uima.cas.CAS;
+import org.apache.uima.cas.impl.CASImpl;
+import org.apache.uima.collection.CasConsumerDescription;
+import org.apache.uima.collection.CasInitializerDescription;
+import org.apache.uima.collection.CollectionReaderDescription;
+import org.apache.uima.flow.FlowControllerDescription;
+import org.apache.uima.jcas.jcasgenp.MergerImpl;
+import org.apache.uima.resource.ResourceCreationSpecifier;
+import org.apache.uima.resource.ResourceInitializationException;
+import org.apache.uima.resource.ResourceManager;
+import org.apache.uima.resource.ResourceServiceSpecifier;
+import org.apache.uima.resource.ResourceSpecifier;
+import org.apache.uima.resource.metadata.Capability;
+import org.apache.uima.resource.metadata.FsIndexCollection;
+import org.apache.uima.resource.metadata.Import;
+import org.apache.uima.resource.metadata.MetaDataObject;
+import org.apache.uima.resource.metadata.ProcessingResourceMetaData;
+import org.apache.uima.resource.metadata.ResourceManagerConfiguration;
+import org.apache.uima.resource.metadata.ResourceMetaData;
+import org.apache.uima.resource.metadata.TypeDescription;
+import org.apache.uima.resource.metadata.TypePriorities;
+import org.apache.uima.resource.metadata.TypePriorityList;
+import org.apache.uima.resource.metadata.TypeSystemDescription;
+import org.apache.uima.taeconfigurator.CDEpropertyPage;
+import org.apache.uima.taeconfigurator.InternalErrorCDE;
+import org.apache.uima.taeconfigurator.Messages;
+import org.apache.uima.taeconfigurator.TAEConfiguratorPlugin;
+import org.apache.uima.taeconfigurator.editors.ui.AbstractSection;
+import org.apache.uima.taeconfigurator.editors.ui.AggregatePage;
+import org.apache.uima.taeconfigurator.editors.ui.CapabilityPage;
+import org.apache.uima.taeconfigurator.editors.ui.HeaderPage;
+import org.apache.uima.taeconfigurator.editors.ui.IndexesPage;
+import org.apache.uima.taeconfigurator.editors.ui.OverviewPage;
+import org.apache.uima.taeconfigurator.editors.ui.ParameterPage;
+import org.apache.uima.taeconfigurator.editors.ui.ResourcesPage;
+import org.apache.uima.taeconfigurator.editors.ui.SettingsPage;
+import org.apache.uima.taeconfigurator.editors.ui.TypePage;
+import org.apache.uima.taeconfigurator.editors.ui.Utility;
+import org.apache.uima.taeconfigurator.editors.xml.XMLEditor;
+import org.apache.uima.taeconfigurator.files.ContextForPartDialog;
+import org.apache.uima.taeconfigurator.model.AllTypes;
+import org.apache.uima.taeconfigurator.model.DefinedTypesWithSupers;
+import org.apache.uima.taeconfigurator.model.DescriptorTCAS;
+import org.apache.uima.tools.jcasgen.IError;
+import org.apache.uima.tools.jcasgen.Jg;
+import org.apache.uima.util.CasCreationUtils;
+import org.apache.uima.util.InvalidXMLException;
+import org.apache.uima.util.Level;
+import org.apache.uima.util.Logger;
+import org.apache.uima.util.XMLInputSource;
+import org.apache.uima.util.XMLSerializer;
+import org.apache.uima.util.XMLizable;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IWorkspace;
+import org.eclipse.core.resources.IWorkspaceRunnable;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.QualifiedName;
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.core.IPackageFragmentRoot;
+import org.eclipse.jdt.core.IType;
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.core.search.IJavaSearchScope;
+import org.eclipse.jdt.core.search.SearchEngine;
+import org.eclipse.jdt.launching.JavaRuntime;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.window.Window;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IEditorSite;
+import org.eclipse.ui.IFileEditorInput;
+import org.eclipse.ui.ISaveablePart;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.PartInitException;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.forms.editor.FormEditor;
+import org.eclipse.ui.forms.widgets.FormToolkit;
+import org.eclipse.ui.part.FileEditorInput;
+import org.eclipse.ui.texteditor.ITextEditor;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.SAXException;
+
+/**
+ * Main class implementing the multi page editor. In Eclipse 3, we extend FormEditor, which extends
+ * in turn MultiPageEditorPart.
+ * 
+ * Life cycle: Create: An instance of this class is created each time the editor is started on a new
+ * resource. Base multipage editor createPartControl calls createPages; FormEditor's impl of
+ * createPages calls createToolkit, then calls addPages. FormEditor has field holding the toolkit
+ * This class overrides createToolkit to re-use the colors in the plugin. * Dispose: dispose is
+ * called. FormEditor impl of dispose disposes of the toolkit.
+ * 
+ * Superclass (FormEditor) holds vector of pages toolkit (disposed of in FormEditor dispose method)
+ * SuperSuperclass (MultiPageEditorPart) holds array of editors (we only have 1 "editor" - the xml
+ * source editor - the rest are views into that model / data).
+ * 
+ * Stale = model (on disk, saved) is ahead of widgets Dirty = widgets are ahead of model <<< NOT
+ * USED HERE
+ * 
+ * Each page of the multipage editor has its own class. ownclass -> HeaderPage -> FormPage (impl
+ * IFormPage) has instance of PageForm -> ManagedForm ManagedForm (impl IManagedForm): has instance
+ * of ScrolledForm has subparts (IFormPart - which live on the scrolled form) A part can be a
+ * section. A part can implement IPartSelectionListener to get selectionChanged(IFormPart,
+ * ISelection) calls. initialize() call propagated to all parts. dispose() call propagated to all
+ * parts. refresh() propagated to all parts (if part.isStale()) (Not Used) commit() propagated to
+ * all parts (if part.isDirty()) setInput() propagated to all parts setFocus() propagated to 1st
+ * part (not used) isDirty() propagated to all parts, is true if any are true isStale() propagated
+ * to all parts, is true if any are true reflow() delegated to the contained ScrolledForm (not used)
+ * fireSelectionChanged(IFormPart, ISelection) - can be used to notify other parts that implement
+ * IPartSelectionListener about selection changes
+ * 
+ * Each page has one or more sections. sectionSpecific -> (AbstractTableSection) -> AbstractSection ->
+ * SectionPart -> AbstractFormPart (impl IFormPart, see above)
+ * 
+ * AbstractFormPart holds back ref to managed form, a dirty and stale bit. Stale = model is ahead of
+ * widgets (Not used) Dirty = widgets are ahead of model Stale brought into sync by 'refresh'
+ * method. Part notifies containing ManagedForm when Stale/Dirty changes in the part; Part
+ * responsible for removing listeners from event providers. IFormPart can receive form input
+ * SectionPart adds listeners for expansionStateChang(ed)(ing) expansionStateChanged calls reflow on
+ * wrapped form Note: the forms framework Dirty mechanism and the "commit" methods are not used. In
+ * its place, the handlers directly update the model, rather than marking Dirty and letting someone
+ * call commit.
+ */
+public class MultiPageEditor extends FormEditor {
+
+  // ******************************
+  // * Tuning Parameters
+  public final int INITIAL_SIZE_TYPE_COLLECTIONS = 20;
+
+  public final int INITIAL_SIZE_FEATURE_COLLECTIONS = 40;
+
+  // ******************************
+
+  // ***********************************************************
+  // M O D E L
+  // the following are only populated based on what type
+  // of descriptor is being edited
+  private AnalysisEngineDescription aeDescription = null;
+
+  private TypeSystemDescription typeSystemDescription = null;
+
+  private TypeSystemDescription mergedTypeSystemDescription = null;
+  
+  private Map mergedTypesAddingFeatures = new TreeMap();
+
+  private TypeSystemDescription importedTypeSystemDescription = null;
+
+  /**
+   * Key = unique ID of included AE in aggregate Value = AnalysisEngineSpecification or URISpecifier
+   * if remote This value is obtained from aeDescription.getDelegateAnalysisEngineSpecifiers() for
+   * aggregates, and is cached so we don't need to repeatedly resolve it, with checks for invalid
+   * xml exceptions.
+   */
+  private Map resolvedDelegates = new HashMap();
+
+  // fully resolved (imports) and merged index collection
+  // resolve with mergeDelegateAnalysisEngineFsIndexCollections
+  // (This works also for primitives)
+  private FsIndexCollection mergedFsIndexCollection;
+
+  private FsIndexCollection importedFsIndexCollection;
+
+  // fully resolved (imports) and merged type priorities
+  // resolve with mergeDelegateAnalysisEngineTypePriorities
+  // (This works also for primitives)
+  // This collects all the type priority lists into one list, after
+  // resolving imports.
+  private TypePriorities mergedTypePriorities;
+
+  private TypePriorities importedTypePriorities;
+
+  // fully resolved (imports) ResourceManagerConfiguration
+  // This collects all the External Resources and bindings into 2 list,
+  // resolving imports. The resulting list may have
+  // overridden bindings
+  // unused external resources (not bound)
+  private ResourceManagerConfiguration resolvedExternalResourcesAndBindings;
+
+  // private ResourceManagerConfiguration importedExternalResourcesAndBindings;
+
+  private FlowControllerDeclaration resolvedFlowControllerDeclaration;
+
+  private CollectionReaderDescription collectionReaderDescription;
+
+  private CasInitializerDescription casInitializerDescription;
+
+  private CasConsumerDescription casConsumerDescription;
+
+  private FlowControllerDescription flowControllerDescription;
+
+  // values computed when first needed
+  // all use common markStale()
+  public DescriptorTCAS descriptorCAS;
+
+  public AllTypes allTypes;
+
+  public DefinedTypesWithSupers definedTypesWithSupers;
+
+  // ****************************************
+  // * Model parts not part of the descriptor
+  // ****************************************
+  private IFile file; // file being edited
+
+  private IFile fileNeedingContext;
+
+  // ***********************************************************
+  // End of M O D E L
+  // ***********************************************************
+
+  /*
+   * Each page is an instance of a particular class. These instances are created each time a new
+   * instance of the editor opens.
+   */
+
+  private int sourceIndex = -1;
+
+  private int overviewIndex = -1;
+
+  private int aggregateIndex = -1;
+
+  private int parameterIndex = -1;
+
+  private int settingsIndex = -1;
+
+  private int typeIndex = -1;
+
+  private int capabilityIndex = -1;
+
+  private int indexesIndex = -1;
+
+  private int resourcesIndex = -1;
+
+  private OverviewPage overviewPage = null;
+
+  private AggregatePage aggregatePage = null;
+
+  private ParameterPage parameterPage = null;
+
+  private SettingsPage settingsPage = null;
+
+  private TypePage typePage = null;
+
+  private CapabilityPage capabilityPage = null;
+
+  private IndexesPage indexesPage = null;
+
+  private ResourcesPage resourcesPage = null;
+
+  private XMLEditor sourceTextEditor;
+
+  private boolean m_bIsInited = false;
+
+  private boolean isBadXML = true;
+
+  public boolean sourceChanged = true;
+
+  private boolean fileDirty; // can only be set dirty once inited
+
+  private HashSet dirtyTypeNameHash; // for generating .java
+
+  // type files upon saving (this has a problem if user edited xml
+  // directly...)
+
+  private int m_nSaveAsStatus = SAVE_AS_NOT_IN_PROGRESS;
+
+  public static final int SAVE_AS_NOT_IN_PROGRESS = -1;
+
+  public static final int SAVE_AS_STARTED = -2;
+
+  public static final int SAVE_AS_CANCELLED = -3;
+
+  public static final int SAVE_AS_CONFIRMED = -4;
+
+  private boolean openingContext = false;
+
+  private boolean isContextLoaded = false;
+
+  public boolean getIsContextLoaded() {
+    return isContextLoaded;
+  }
+
+  /**
+   * Descriptor Types
+   */
+
+  private int descriptorType = 0;
+
+  public int getDescriptorType() {
+    return descriptorType;
+  }
+
+  public static final int DESCRIPTOR_AE = 1;
+
+  public static final int DESCRIPTOR_TYPESYSTEM = 1 << 1;
+
+  public static final int DESCRIPTOR_INDEX = 1 << 2;
+
+  public static final int DESCRIPTOR_TYPEPRIORITY = 1 << 3;
+
+  public static final int DESCRIPTOR_EXTRESANDBINDINGS = 1 << 4;
+
+  public static final int DESCRIPTOR_COLLECTIONREADER = 1 << 5;
+
+  public static final int DESCRIPTOR_CASINITIALIZER = 1 << 6;
+
+  public static final int DESCRIPTOR_CASCONSUMER = 1 << 7;
+
+  public static final int DESCRIPTOR_FLOWCONTROLLER = 1 << 8;
+
+  public String descriptorTypeString(int pDescriptorType) {
+    String r;
+    switch (pDescriptorType) {
+      case DESCRIPTOR_AE:
+        r = Messages.getString("MultiPageEditor.0");break; //$NON-NLS-1$
+      case DESCRIPTOR_TYPESYSTEM:
+        r = Messages.getString("MultiPageEditor.1");break; //$NON-NLS-1$
+      case DESCRIPTOR_INDEX:
+        r = Messages.getString("MultiPageEditor.2");break; //$NON-NLS-1$
+      case DESCRIPTOR_TYPEPRIORITY:
+        r = Messages.getString("MultiPageEditor.3");break; //$NON-NLS-1$
+      case DESCRIPTOR_EXTRESANDBINDINGS:
+        r = Messages.getString("MultiPageEditor.4");break; //$NON-NLS-1$
+      case DESCRIPTOR_COLLECTIONREADER:
+        r = Messages.getString("MultiPageEditor.5");break; //$NON-NLS-1$
+      case DESCRIPTOR_CASINITIALIZER:
+        r = Messages.getString("MultiPageEditor.6");break; //$NON-NLS-1$
+      case DESCRIPTOR_CASCONSUMER:
+        r = Messages.getString("MultiPageEditor.7");break; //$NON-NLS-1$
+      case DESCRIPTOR_FLOWCONTROLLER:
+        r = "Flow Controller";
+        break;
+      default:
+        throw new InternalErrorCDE(Messages.getString("MultiPageEditor.8")); //$NON-NLS-1$
+    }
+    return r + Messages.getString("MultiPageEditor.9"); //$NON-NLS-1$
+  }
+
+  public String descriptorTypeString() {
+    return descriptorTypeString(descriptorType);
+  }
+
+  public boolean isAeDescriptor() {
+    return 0 != (descriptorType & DESCRIPTOR_AE);
+  }
+
+  public boolean isTypeSystemDescriptor() {
+    return 0 != (descriptorType & DESCRIPTOR_TYPESYSTEM);
+  }
+
+  public boolean isFsIndexCollection() {
+    return 0 != (descriptorType & DESCRIPTOR_INDEX);
+  }
+
+  public boolean isTypePriorityDescriptor() {
+    return 0 != (descriptorType & DESCRIPTOR_TYPEPRIORITY);
+  }
+
+  public boolean isExtResAndBindingsDescriptor() {
+    return 0 != (descriptorType & DESCRIPTOR_EXTRESANDBINDINGS);
+  }
+
+  public boolean isCollectionReaderDescriptor() {
+    return 0 != (descriptorType & DESCRIPTOR_COLLECTIONREADER);
+  }
+
+  public boolean isCasInitializerDescriptor() {
+    return 0 != (descriptorType & DESCRIPTOR_CASINITIALIZER);
+  }
+
+  public boolean isCasConsumerDescriptor() {
+    return 0 != (descriptorType & DESCRIPTOR_CASCONSUMER);
+  }
+
+  public boolean isFlowControllerDescriptor() {
+    return 0 != (descriptorType & DESCRIPTOR_FLOWCONTROLLER);
+  }
+
+  public boolean isLocalProcessingDescriptor() {
+    return 0 != (descriptorType & (DESCRIPTOR_AE | DESCRIPTOR_COLLECTIONREADER
+            | DESCRIPTOR_CASINITIALIZER | DESCRIPTOR_CASCONSUMER | DESCRIPTOR_FLOWCONTROLLER));
+  }
+
+  public boolean isPrimitive() {
+    return isLocalProcessingDescriptor() && aeDescription.isPrimitive();
+  }
+
+  public boolean isAggregate() {
+    return isAeDescriptor() && (!aeDescription.isPrimitive());
+  }
+
+  private TypePriorities m_typePrioritiesBackup;
+
+  private Color fadeColor;
+
+  private boolean isRevertingIndex;
+
+  private boolean isPageChangeRecursion = false;
+
+  public static final TypeDescription[] typeDescriptionArray0 = new TypeDescription[0];
+
+  public MultiPageEditor() {
+    super();
+
+    // Model initialization
+    fileDirty = false;
+    dirtyTypeNameHash = new HashSet();
+    descriptorCAS = new DescriptorTCAS(this);
+    allTypes = new AllTypes(this);
+    definedTypesWithSupers = new DefinedTypesWithSupers(this);
+
+    // reasonable initial values
+    aeDescription = UIMAFramework.getResourceSpecifierFactory().createAnalysisEngineDescription();
+    typeSystemDescription = null;
+    importedTypeSystemDescription = null;
+    mergedTypeSystemDescription = null;
+    mergedFsIndexCollection = aeDescription.getAnalysisEngineMetaData().getFsIndexCollection();
+    resolvedExternalResourcesAndBindings = aeDescription.getResourceManagerConfiguration();
+    resolvedFlowControllerDeclaration = aeDescription.getFlowControllerDeclaration();
+    mergedTypePriorities = aeDescription.getAnalysisEngineMetaData().getTypePriorities();
+  }
+
+  /**
+   * override the createToolkit method in FormEditor - to use a shared colors resource.
+   * 
+   * This method is called by the FormEditor's createPages() method which will in turn call the
+   * addPages method below. The toolkit ref is stored in the FormEditor object, and can be retrieved
+   * by getToolkit().
+   * 
+   */
+
+  protected FormToolkit createToolkit(Display display) {
+    return new FormToolkit(TAEConfiguratorPlugin.getDefault().getFormColors(display));
+  }
+
+  /*
+   * Two forms of addPage - one for non-source-editors, and one for source-editor
+   */
+  private int addPageAndSetTabTitle(HeaderPage page, String keyTabTitle) throws PartInitException {
+    int pageIndex = addPage(page);
+    // set the text on the tab used to select the page in the multipage editor
+    setPageText(pageIndex, keyTabTitle);
+    return pageIndex;
+  }
+
+  private int addPageAndSetTabTitle(IEditorPart page, IEditorInput input, String keyTabTitle)
+          throws PartInitException {
+    int pageIndex = addPage(page, input);
+    // set the text on the tab used to select the page in the multipage editor
+    setPageText(pageIndex, keyTabTitle);
+    return pageIndex;
+  }
+
+  /*
+   * In general, 3 kinds of pages can be added. 1) an editor (IEditorPart, IEditorInput) 2) (lazy)
+   * an IFormPage (extends IEditorPart) - has a managedForm, can wrap an editor 3) (lazy) a SWT
+   * Control (Not Used)
+   * 
+   * (non-Javadoc)
+   * 
+   * @see org.eclipse.ui.forms.editor.FormEditor#addPages()
+   */
+  protected void addPages() {
+    boolean allPages = isLocalProcessingDescriptor();
+    try {
+      overviewIndex = addPageAndSetTabTitle(overviewPage = new OverviewPage(this), Messages
+              .getString("MultiPageEditor.overviewTab")); //$NON-NLS-1$
+
+      if (allPages) {
+        if (isAeDescriptor())
+          aggregateIndex = addPageAndSetTabTitle(aggregatePage = new AggregatePage(this), Messages
+                  .getString("MultiPageEditor.aggregateTab")); //$NON-NLS-1$
+        parameterIndex = addPageAndSetTabTitle(parameterPage = new ParameterPage(this), Messages
+                .getString("MultiPageEditor.parameterTab")); //$NON-NLS-1$
+        settingsIndex = addPageAndSetTabTitle(settingsPage = new SettingsPage(this), Messages
+                .getString("MultiPageEditor.settingsTab")); //$NON-NLS-1$
+      }
+
+      if (allPages || isTypeSystemDescriptor()) {
+        typeIndex = addPageAndSetTabTitle(typePage = new TypePage(this), Messages
+                .getString("MultiPageEditor.typeTab")); //$NON-NLS-1$
+      }
+
+      if (allPages) {
+        capabilityIndex = addPageAndSetTabTitle(capabilityPage = new CapabilityPage(this), Messages
+                .getString("MultiPageEditor.capabilityTab")); //$NON-NLS-1$
+      }
+
+      if (allPages || isTypePriorityDescriptor() || isFsIndexCollection()) {
+        indexesIndex = addPageAndSetTabTitle(indexesPage = new IndexesPage(this), Messages
+                .getString("MultiPageEditor.indexesTab")); //$NON-NLS-1$
+      }
+
+      if (allPages || isExtResAndBindingsDescriptor()) {
+        resourcesIndex = addPageAndSetTabTitle(resourcesPage = new ResourcesPage(this), Messages
+                .getString("MultiPageEditor.resourcesTab")); //$NON-NLS-1$
+      }
+
+      sourceIndex = addPageAndSetTabTitle(sourceTextEditor = new XMLEditor(this), getEditorInput(),
+              Messages.getString("MultiPageEditor.sourceTab")); //$NON-NLS-1$
+
+    } catch (PartInitException e) {
+      e.printStackTrace(); // TODO fix this
+    }
+    if (isBadXML) {
+      pageChange(sourceIndex);
+    }
+  }
+
+  /**
+   * @param monitor
+   */
+  public void jcasGen(IProgressMonitor monitor) {
+    if (MultiPageEditorContributor.getAutoJCasGen()) {
+      doJCasGenChkSrc(monitor);
+    }
+  }
+
+  public void doJCasGenChkSrc(IProgressMonitor monitor) {
+    if (isSourceFolderValid())
+      doJCasGen(monitor);
+  }
+
+  public boolean isSourceFolderValid() {
+    IResource folder = getPrimarySourceFolder();
+    if (folder == null) {
+      String msg = Messages.getString("MultiPageEditor.noSrcNoJCas"); //$NON-NLS-1$
+      Utility.popMessage(Messages.getString("MultiPageEditor.noSrcDir"), msg, MessageDialog.ERROR); //$NON-NLS-1$
+      return false;
+    }
+    return true;
+  }
+
+  private boolean syncSourceBeforeSavingToFile() {
+    boolean modelOK = true;
+    if (getCurrentPage() != sourceIndex) {
+      validateIndexes();
+      updateSourceFromModel();
+    } else { // have to check if there are dirty types
+      modelOK = validateSource();
+    }
+    if (modelOK && isLocalProcessingDescriptor()) {
+      return isValidAE(aeDescription);
+    }
+    return modelOK;
+  }
+
+  public boolean isValidAE(AnalysisEngineDescription aAe) {
+    AbstractSection.setVnsHostAndPort(aAe);
+    // copy Ae into real descriptors if needed
+    getTrueDescriptor();
+    // use clones because validation modifies (imports get imported)
+    if (isCollectionReaderDescriptor()) {
+      CollectionReaderDescription collRdr = (CollectionReaderDescription) collectionReaderDescription
+              .clone();
+      try {
+        collRdr.doFullValidation(createResourceManager());
+      } catch (Throwable e) { // all these are Throwable to catch errors like
+        // UnsupportedClassVersionError, which happens if the annotator
+        // class is compiled for Java 5.0, but the CDE is running Java 1.4.2
+        Utility
+                .popMessage(
+                        Messages.getString("MultiPageEditor.failedCollRdrValidation"), //$NON-NLS-1$
+                        Messages.getString("MultiPageEditor.failedCollRdrValidationMsg") + "\n" + getMessagesToRootCause(e), //$NON-NLS-1$ //$NON-NLS-2$
+                        MessageDialog.ERROR);
+        return false;
+      }
+    } else if (isCasInitializerDescriptor()) {
+      CasInitializerDescription casInit = (CasInitializerDescription) casInitializerDescription
+              .clone();
+      try {
+        casInit.doFullValidation(createResourceManager());
+      } catch (Throwable e) {
+        Utility
+                .popMessage(
+                        Messages.getString("MultiPageEditor.failedCasInitValidation"), //$NON-NLS-1$
+                        Messages.getString("MultiPageEditor.failedCasInitValidationMsg") + "\n" + getMessagesToRootCause(e), //$NON-NLS-1$ //$NON-NLS-2$
+                        MessageDialog.ERROR);
+        return false;
+      }
+    } else if (isCasConsumerDescriptor()) {
+      CasConsumerDescription casCons = (CasConsumerDescription) casConsumerDescription.clone();
+      try {
+        casCons.doFullValidation(createResourceManager());
+      } catch (Throwable e) {
+        Utility
+                .popMessage(
+                        Messages.getString("MultiPageEditor.failedCasConsValidation"), //$NON-NLS-1$
+                        Messages.getString("MultiPageEditor.failedCasConsValidationMsg") + "\n" + getMessagesToRootCause(e), //$NON-NLS-1$ //$NON-NLS-2$
+                        MessageDialog.ERROR);
+        return false;
+      }
+
+    } else if (isFlowControllerDescriptor()) {
+      FlowControllerDescription fc = (FlowControllerDescription) flowControllerDescription.clone();
+      try {
+        fc.doFullValidation(createResourceManager());
+      } catch (Throwable e) {
+        Utility.popMessage("Error in Flow Controller Descriptor",
+                "The Descriptor is invalid for the following reason:" + "\n"
+                        + getMessagesToRootCause(e), MessageDialog.ERROR);
+        return false;
+      }
+    } else {
+      AnalysisEngineDescription ae = (AnalysisEngineDescription) aAe.clone();
+
+      // speedup = replace typeSystem with resolved imports version
+      if (ae.isPrimitive()) {
+        TypeSystemDescription tsd = getMergedTypeSystemDescription();
+        if (null != tsd) {
+          tsd = (TypeSystemDescription) tsd.clone();
+        }
+        ae.getAnalysisEngineMetaData().setTypeSystem(tsd);
+      }
+      ae.getAnalysisEngineMetaData().setFsIndexCollection(getMergedFsIndexCollection());
+      ae.getAnalysisEngineMetaData().setTypePriorities(getMergedTypePriorities());
+      try {
+        ae.doFullValidation(createResourceManager());
+      } catch (Throwable e) {
+        Utility
+                .popMessage(
+                        Messages.getString("MultiPageEditor.failedAeValidation"), //$NON-NLS-1$
+                        Messages.getString("MultiPageEditor.failedAeValidationMsg") + "\n" + getMessagesToRootCause(e), //$NON-NLS-1$ //$NON-NLS-2$
+                        MessageDialog.ERROR);
+        return false;
+      }
+    }
+    return true;
+  }
+
+  /**
+   * Saves the multi-page editor's document.
+   */
+  public void doSave(IProgressMonitor monitor) {
+    boolean modelOK = syncSourceBeforeSavingToFile();
+    sourceTextEditor.doSave(monitor);
+    finishSave(monitor, modelOK);
+  }
+
+  private void finishSave(IProgressMonitor monitor, boolean modelOK) {
+    if (modelOK) {
+      if (dirtyTypeNameHash.size() > 0)
+        jcasGen(monitor);
+      dirtyTypeNameHash.clear();
+    }
+    fileDirty = false;
+    firePropertyChange(ISaveablePart.PROP_DIRTY);
+
+  }
+
+  /**
+   * Saves the multi-page editor's document as another file. Updates this multi-page editor's input
+   * to correspond to the nested editor's.
+   * 
+   * This is not implemented correctly: filename isn't switched to new filename, etc.
+   */
+  public void doSaveAs() {
+    boolean modelOK = syncSourceBeforeSavingToFile();
+    setSaveAsStatus(SAVE_AS_STARTED);
+    sourceTextEditor.doSaveAs();
+
+    if (m_nSaveAsStatus == SAVE_AS_CANCELLED) {
+      m_nSaveAsStatus = SAVE_AS_NOT_IN_PROGRESS;
+      return;
+    }
+    // should only do if editorInput is new
+    FileEditorInput newEditorInput = (FileEditorInput) sourceTextEditor.getEditorInput();
+
+    // if(old)
+    setInput(newEditorInput);
+    firePropertyChange(PROP_INPUT);
+    // setTitle(newEditorInput.getFile().getName());
+    setPartName(newEditorInput.getFile().getName());
+    // this next does NOT seem to change the overall page title
+
+    firePropertyChange(PROP_TITLE);
+    finishSave(null, modelOK);
+  }
+
+  public boolean isDirty() {
+    return fileDirty;
+  }
+
+  public boolean isSaveOnCloseNeeded() {
+    return fileDirty;
+  }
+
+  public void setFileDirty() {
+    if (m_bIsInited) {
+      fileDirty = true;
+      // next is key
+      this.firePropertyChange(ISaveablePart.PROP_DIRTY);
+    }
+  }
+
+  /*
+   * (non-Javadoc)
+   * 
+   * @see org.eclipse.ui.IEditorPart#init(org.eclipse.ui.IEditorSite, org.eclipse.ui.IEditorInput)
+   */
+  public void init(IEditorSite site, IEditorInput editorInput) throws PartInitException {
+    XMLInputSource input;
+
+    if (!(editorInput instanceof IFileEditorInput))
+      throw new PartInitException(Messages.getString("MultiPageEditor.invalidInputClass")); //$NON-NLS-1$
+    fileNeedingContext = file = ((IFileEditorInput) editorInput).getFile();
+    String filePathName = file.getLocation().toOSString();
+
+    try {
+      input = new XMLInputSource(filePathName);
+    } catch (IOException e) {
+      String m = Messages.getFormattedString("MultiPageEditor.IOError", //$NON-NLS-1$
+              new String[] { AbstractSection.maybeShortenFileName(filePathName) })
+              + Messages.getString("MultiPageEditor.10") + getMessagesToRootCause(e); //$NON-NLS-1$
+      // skip showing a message because the partInitException
+      // shows it
+      throw new PartInitException(m);
+    }
+
+    // leaves isBadXML set, if it can't parse but isn't throwing
+    isContextLoaded = false;
+    try {
+      parseSource(input, filePathName);
+    } catch (MultilevelCancel e) {
+      throw new PartInitException("Operation Cancelled");
+    }
+
+    isContextLoaded = true;
+
+    super.init(site, editorInput);
+    setPartName(editorInput.getName());
+    setContentDescription(editorInput.getName());
+    // setContentDescription(1 line summary); TODO
+
+    m_bIsInited = true;
+  }
+
+  private void parseSource(XMLInputSource input, String filePathName) throws PartInitException {
+    try {
+      XMLizable inputDescription = AbstractSection.parseDescriptor(input);
+      if (inputDescription instanceof AnalysisEngineDescription) {
+        validateDescriptorType(DESCRIPTOR_AE);
+        setAeDescription((AnalysisEngineDescription) inputDescription);
+      } else if (inputDescription instanceof TypeSystemDescription) {
+        validateDescriptorType(DESCRIPTOR_TYPESYSTEM);
+        setTypeSystemDescription((TypeSystemDescription) inputDescription);
+      } else if (inputDescription instanceof TypePriorities) {
+        validateDescriptorType(DESCRIPTOR_TYPEPRIORITY);
+        setTypePriorities((TypePriorities) inputDescription);
+      } else if (inputDescription instanceof FsIndexCollection) {
+        validateDescriptorType(DESCRIPTOR_INDEX);
+        setFsIndexCollection((FsIndexCollection) inputDescription);
+      } else if (inputDescription instanceof ResourceManagerConfiguration) {
+        validateDescriptorType(DESCRIPTOR_EXTRESANDBINDINGS);
+        setExtResAndBindings((ResourceManagerConfiguration) inputDescription);
+      } else if (inputDescription instanceof CollectionReaderDescription) {
+        validateDescriptorType(DESCRIPTOR_COLLECTIONREADER);
+        setCollectionReaderDescription((CollectionReaderDescription) inputDescription);
+      } else if (inputDescription instanceof CasInitializerDescription) {
+        validateDescriptorType(DESCRIPTOR_CASINITIALIZER);
+        setCasInitializerDescription((CasInitializerDescription) inputDescription);
+      } else if (inputDescription instanceof CasConsumerDescription) {
+        validateDescriptorType(DESCRIPTOR_CASCONSUMER);
+        setCasConsumerDescription((CasConsumerDescription) inputDescription);
+      } else if (inputDescription instanceof FlowControllerDescription) {
+        validateDescriptorType(DESCRIPTOR_FLOWCONTROLLER);
+        setFlowControllerDescription((FlowControllerDescription) inputDescription);
+      } else {
+        throw new PartInitException(Messages.getFormattedString(
+                "MultiPageEditor.unrecognizedDescType", //$NON-NLS-1$
+                new String[] { AbstractSection.maybeShortenFileName(filePathName) })
+                + Messages.getString("MultiPageEditor.11")); //$NON-NLS-1$
+      }
+      isBadXML = false;
+    } catch (InvalidXMLException e) {
+      e.printStackTrace();
+      Utility
+              .popMessage(
+                      Messages.getString("MultiPageEditor.XMLerrorInDescriptorTitle"), //$NON-NLS-1$
+                      Messages.getString("MultiPageEditor.XMLerrorInDescriptor") + "\n" + getMessagesToRootCause(e), //$NON-NLS-1$ //$NON-NLS-2$
+                      MessageDialog.ERROR);
+
+    } catch (ResourceInitializationException e) {
+      // occurs if bad xml
+      // leave isBadXML flag set to true
+      Utility.popMessage(Messages.getString("MultiPageEditor.errorInDescTitle"), //$NON-NLS-1$
+              Messages.getString("MultiPageEditor.errorInDesc") + "\n" + getMessagesToRootCause(e), //$NON-NLS-1$ //$NON-NLS-2$
+              MessageDialog.ERROR);
+    }
+  }
+
+  private void validateDescriptorType(int newDescriptorType) throws ResourceInitializationException {
+    if (0 != descriptorType && !openingContext && ((descriptorType & newDescriptorType) == 0))
+      throw new ResourceInitializationException(Messages.getString("MultiPageEditor.12"), //$NON-NLS-1$
+              Messages.getString("MultiPageEditor.13"), //$NON-NLS-1$
+              new String[] { descriptorTypeString(), descriptorTypeString(newDescriptorType) });
+    if (!openingContext)
+      descriptorType = newDescriptorType;
+  }
+
+  /**
+   * Create a resource manager that has a class loader that will search the compiled output of the
+   * current project, in addition to the plug-in's classpath.
+   * 
+   * We create a new resource manager every time it's needed to pick up any changes the user may
+   * have made to any classes that could have been loaded.
+   * 
+   * @return
+   */
+  public ResourceManager createResourceManager() {
+    // long time = System.currentTimeMillis();
+    ResourceManager rm = createResourceManager(null);
+    // System.out.println("CreateResourceManager: " + (System.currentTimeMillis() - time));
+    return rm;
+  }
+
+  public ResourceManager createResourceManager(String classPath) {
+    // workspacePath = TAEConfiguratorPlugin.getWorkspace().getRoot().getLocation().toString();
+    ResourceManager resourceManager = UIMAFramework.newDefaultResourceManager();
+
+    try {
+      if (null == classPath)
+        classPath = getProjectClassPath();
+      resourceManager.setExtensionClassPath(this.getClass().getClassLoader(), classPath, true);
+      resourceManager.setDataPath(CDEpropertyPage.getDataPath(getProject()));
+    } catch (MalformedURLException e1) {
+      throw new InternalErrorCDE(Messages.getString("MultiPageEditor.14"), e1); //$NON-NLS-1$
+    } catch (CoreException e1) {
+      throw new InternalErrorCDE(Messages.getString("MultiPageEditor.15"), e1); //$NON-NLS-1$
+    }
+    return resourceManager;
+  }
+
+  /*
+   * (non-Javadoc) Method declared on IEditorPart.
+   */
+  public boolean isSaveAsAllowed() {
+    return true;
+  }
+
+  protected void pageChange(int newPageIndex) {
+    if (isPageChangeRecursion)
+      return;
+    isRevertingIndex = false;
+    int oldPageIndex = getCurrentPage();
+
+    if (oldPageIndex != -1) {
+      if (oldPageIndex == sourceIndex) {
+        if (!validateSource()) {
+          setActivePageWhileBlockingRecursion(sourceIndex);
+          return;
+        }
+      } else if (oldPageIndex == indexesIndex &&
+      // could be the same page if users chose to
+              // edit current descriptor when validateIndexes detected a
+              // bad type priorities set
+              newPageIndex != indexesIndex) // could be the same
+        if (!validateIndexes())
+          return;
+        else if (newPageIndex != indexesIndex) {
+          saveGoodVersionOfTypePriorities();
+        }
+    }
+
+    super.pageChange(newPageIndex);
+
+    Object newPage = pages.get(newPageIndex);
+    if (newPage instanceof HeaderPage) {
+      // ((HeaderPage)newPage).getManagedForm().refresh(); //super.pageChange does this
+      if (newPage instanceof IndexesPage && oldPageIndex != indexesIndex) {
+        saveGoodVersionOfTypePriorities();
+      }
+    } else if (newPageIndex == sourceIndex) {
+      if (!isBadXML)
+        updateSourceFromModel();
+      else
+        setActivePageWhileBlockingRecursion(sourceIndex);
+      // set sourceChanged if badXML to redo error notification if nothing changed
+      // in case XML was bad
+      sourceChanged = (isBadXML || isRevertingIndex) ? true : false;
+    }
+  }
+
+  private void setActivePageWhileBlockingRecursion(int sourceIndex) {
+    try {
+      isPageChangeRecursion = true;
+      // next call needed to be done but wasn't prior to
+      // Eclipse 3.2
+      // In Eclipse 3.2 they fixed this, but call this now
+      // calls pageChange, and makes a recursive loop
+      // We break that loop here.
+      setActivePage(sourceIndex); // isn't being done otherwise?
+    } finally {
+      isPageChangeRecursion = false;
+    }
+  }
+
+  private void saveGoodVersionOfTypePriorities() {
+    TypePriorities tp = getAeDescription().getAnalysisEngineMetaData().getTypePriorities();
+    m_typePrioritiesBackup = (null == tp) ? null : (TypePriorities) tp.clone();
+  }
+
+  private boolean revertToLastValid(String msg, String msgDetails) {
+    String[] buttonLabels = new String[2];
+    buttonLabels[0] = Messages.getString("MultiPageEditor.revertToLastValid"); //$NON-NLS-1$
+    buttonLabels[1] = Messages.getString("MultiPageEditor.EditExisting"); //$NON-NLS-1$
+    MessageDialog dialog = new MessageDialog(getEditorSite().getShell(), msg, null, msgDetails,
+            MessageDialog.WARNING, buttonLabels, 0);
+    dialog.open();
+    // next line depends on return code for button 1 (which is 1)
+    // and CANCEL code both being == 1
+    return dialog.getReturnCode() == 0;
+  }
+
+  /**
+   * Called when switching off of the indexes page Goal is to validate indexes by making a CAS - as
+   * a side effect it does index validation.
+   * 
+   * We do this without changing the typeSystemDescription
+   * 
+   * @return
+   */
+  private boolean validateIndexes() {
+    CAS localCAS = descriptorCAS.get();
+    TypePriorities savedMergedTypePriorities = getMergedTypePriorities();
+    FsIndexCollection savedFsIndexCollection = getMergedFsIndexCollection();
+    try {
+      setMergedFsIndexCollection();
+      setMergedTypePriorities();
+      descriptorCAS.validate();
+    } catch (Exception ex) {
+      descriptorCAS.set(localCAS);
+      if (!revertToLastValid(Messages.getString("MultiPageEditor.indexDefProblemTitle"), //$NON-NLS-1$
+              Messages.getString("MultiPageEditor.indexDefProblem") + //$NON-NLS-1$
+                      getMessagesToRootCause(ex))) {
+        // currentIndex = -1; //irrelevent, but not sourceIndex
+        super.setActivePage(indexesIndex);
+        // currentIndex = indexesIndex;
+        return false;
+      } else {
+        getAeDescription().getAnalysisEngineMetaData().setTypePriorities(m_typePrioritiesBackup);
+        setMergedTypePriorities(savedMergedTypePriorities);
+        setMergedFsIndexCollection(savedFsIndexCollection);
+        isRevertingIndex = true;
+        return true;
+      }
+    }
+    return true;
+  }
+
+  private String getCharSet(String text) {
+    final String key = Messages.getString("MultiPageEditor.16"); //$NON-NLS-1$
+    int i = text.indexOf(key);
+    if (i == -1)
+      return Messages.getString("MultiPageEditor.17"); //$NON-NLS-1$
+    i += key.length();
+    int end = text.indexOf(Messages.getString("MultiPageEditor.18"), i); //$NON-NLS-1$
+    return text.substring(i, end);
+  }
+
+  private boolean validateSource() {
+    if (!sourceChanged)
+      return true;
+    isBadXML = true; // preset
+    IDocument doc = sourceTextEditor.getDocumentProvider().getDocument(
+            sourceTextEditor.getEditorInput());
+    String text = doc.get();
+    InputStream is;
+    try {
+      is = new ByteArrayInputStream(text.getBytes(getCharSet(text)));
+    } catch (UnsupportedEncodingException e2) {
+      Utility.popMessage(Messages.getString("MultiPageEditor.19"), //$NON-NLS-1$
+              getMessagesToRootCause(e2), MessageDialog.ERROR);
+      super.setActivePage(sourceIndex);
+      return false;
+    }
+
+    String filePathName = getFile().getLocation().toString();
+    XMLInputSource input = new XMLInputSource(is, new File(filePathName));
+
+    AnalysisEngineDescription oldAe = aeDescription;
+    TypeSystemDescription oldTsdWithResolvedImports = mergedTypeSystemDescription;
+
+    try {
+      parseSource(input, filePathName); // sets isBadXML to false if OK
+    } catch (PartInitException e1) { // if user switched the kind of descriptor
+      Utility.popMessage(Messages.getString("MultiPageEditor.20"), //$NON-NLS-1$
+              getMessagesToRootCause(e1), MessageDialog.ERROR);
+      super.setActivePage(sourceIndex);
+      return false;
+    }
+
+    if (isBadXML)
+      return false;
+
+    if (isPrimitive())
+      checkForNewlyDirtyTypes(oldTsdWithResolvedImports);
+
+    checkForNewlyStaleSections(oldAe.getAnalysisEngineMetaData(), aeDescription
+            .getAnalysisEngineMetaData());
+    return true;
+  }
+
+  public void markAllPagesStale() {
+    checkForNewlyStaleSections(null, null);
+  }
+
+  private void checkForNewlyStaleSections(MetaDataObject previous, MetaDataObject current) {
+
+    // AnalysisEngineMetaData previous,
+    // AnalysisEngineMetaData current
+
+    // some day can implement code to see what's affected
+    // for now, mark everything as stale
+    // index tests during development - some pages not done
+    if (overviewIndex >= 0)
+      ((HeaderPage) pages.get(overviewIndex)).markStale();
+    if (aggregateIndex >= 0)
+      ((HeaderPage) pages.get(aggregateIndex)).markStale();
+    if (parameterIndex >= 0)
+      ((HeaderPage) pages.get(parameterIndex)).markStale();
+    if (settingsIndex >= 0)
+      ((HeaderPage) pages.get(settingsIndex)).markStale();
+    if (typeIndex >= 0)
+      ((HeaderPage) pages.get(typeIndex)).markStale();
+    if (capabilityIndex >= 0)
+      ((HeaderPage) pages.get(capabilityIndex)).markStale();
+    if (indexesIndex >= 0)
+      ((HeaderPage) pages.get(indexesIndex)).markStale();
+    if (resourcesIndex >= 0)
+      ((HeaderPage) pages.get(resourcesIndex)).markStale();
+  }
+
+  private void checkForNewlyDirtyTypes(TypeSystemDescription oldTsd) {
+
+    // an array of TypeDescription objects (not CAS), including imported ones
+    TypeDescription[] oldTypes = (null == oldTsd || null == oldTsd.getTypes()) ? new TypeDescription[0]
+            : oldTsd.getTypes();
+    HashMap oldTypeHash = new HashMap(oldTypes.length);
+
+    for (int i = 0, length = oldTypes.length; i < length; i++) {
+      TypeDescription oldType = oldTypes[i];
+      oldTypeHash.put(oldType.getName(), oldType);
+    }
+
+    TypeDescription[] newTypes = mergedTypeSystemDescription.getTypes();
+    for (int i = 0; i < newTypes.length; i++) {
+      TypeDescription newType = newTypes[i];
+      TypeDescription oldType = (TypeDescription) oldTypeHash.get(newType.getName());
+
+      if (newType.equals(oldType)) {
+        oldTypeHash.remove(oldType.getName());
+      } else {
+        addDirtyTypeName(newType.getName());
+        if (oldType != null) {
+          oldTypeHash.remove(oldType.getName());
+        }
+      }
+    }
+
+    Set deletedTypes = oldTypeHash.keySet();
+    Iterator deletedTypeIterator = deletedTypes.iterator();
+    while (deletedTypeIterator.hasNext()) {
+      removeDirtyTypeName((String) deletedTypeIterator.next());
+    }
+
+  }
+
+  /*
+   * This returns the true descriptor, accounting for the "trick" when we put CPM descriptors in the
+   * AE descriptor. As a side effect, it updates the CPM descriptors
+   */
+  private XMLizable getTrueDescriptor() {
+    XMLizable thing;
+    if (isAeDescriptor())
+      thing = aeDescription;
+    else if (isTypeSystemDescriptor())
+      thing = typeSystemDescription;
+    else if (isTypePriorityDescriptor())
+      thing = aeDescription.getAnalysisEngineMetaData().getTypePriorities();
+    else if (isExtResAndBindingsDescriptor())
+      thing = aeDescription.getResourceManagerConfiguration();
+    else if (isFsIndexCollection())
+      thing = aeDescription.getAnalysisEngineMetaData().getFsIndexCollection();
+    else if (isCollectionReaderDescriptor()) {
+      thing = collectionReaderDescription;
+      linkLocalProcessingDescriptorsFromAe(collectionReaderDescription);
+    } else if (isCasInitializerDescriptor()) {
+      thing = casInitializerDescription;
+      linkLocalProcessingDescriptorsFromAe(casInitializerDescription);
+    } else if (isCasConsumerDescriptor()) {
+      thing = casConsumerDescription;
+      linkLocalProcessingDescriptorsFromAe(casConsumerDescription);
+    } else if (isFlowControllerDescriptor()) {
+      thing = flowControllerDescription;
+      linkLocalProcessingDescriptorsFromAe(flowControllerDescription);
+    } else
+      throw new InternalErrorCDE(Messages.getString("MultiPageEditor.21")); //$NON-NLS-1$
+    return thing;
+  }
+
+  public String prettyPrintModel() {
+    StringWriter writer = new StringWriter();
+    String parsedText = null;
+    try {
+      XMLSerializer xmlSerializer = new XMLSerializer(true);
+      xmlSerializer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", new Integer(
+              MultiPageEditorContributor.getXMLindent()).toString());
+      xmlSerializer.setWriter(writer);
+      ContentHandler contentHandler = xmlSerializer.getContentHandler();
+      contentHandler.startDocument();
+      XMLizable trueDescriptor = getTrueDescriptor();
+      if (trueDescriptor instanceof AnalysisEngineDescription) {
+        AnalysisEngineDescription aed = (AnalysisEngineDescription) trueDescriptor;
+        aed.toXML(contentHandler, true, true);
+      } else
+        trueDescriptor.toXML(contentHandler, true);
+      contentHandler.endDocument();
+      writer.close();
+      parsedText = writer.toString();
+
+    } catch (SAXException e) {
+      throw new InternalErrorCDE(Messages.getString("MultiPageEditor.22"), e); //$NON-NLS-1$
+    } catch (IOException e) {
+      throw new InternalErrorCDE(Messages.getString("MultiPageEditor.23"), e); //$NON-NLS-1$
+    }
+    return parsedText;
+  }
+
+  public void updateSourceFromModel() {
+    sourceTextEditor.setIgnoreTextEvent(true);
+    IDocument doc = sourceTextEditor.getDocumentProvider().getDocument(
+            sourceTextEditor.getEditorInput());
+    doc.set(prettyPrintModel());
+    sourceTextEditor.setIgnoreTextEvent(false);
+  }
+
+  public AnalysisEngineDescription getAeDescription() {
+    return aeDescription;
+  }
+
+  /**
+   * @return
+   * @throws ResourceInitializationException
+   */
+  public void setAeDescription(AnalysisEngineDescription aAnalysisEngineDescription)
+          throws ResourceInitializationException {
+    if (null == aAnalysisEngineDescription)
+      throw new InternalErrorCDE(Messages.getString("MultiPageEditor.24")); //$NON-NLS-1$
+    aeDescription = aAnalysisEngineDescription;
+
+    try {
+      // we do this to keep resolvedDelegates update-able
+      // The value from getDeletageAESpecs is an unmodifiable hash map
+      resolvedDelegates.putAll(aeDescription
+              .getDelegateAnalysisEngineSpecifiers(createResourceManager()));
+    } catch (InvalidXMLException e) {
+      throw new ResourceInitializationException(e);
+    }
+    // These come before setTypeSystemDescription call because that call
+    // invokeds tcas validate, which uses the merged values for speedup
+    // Here we set them to values that won't cause errors. They're set to actual values below.
+    mergedFsIndexCollection = aeDescription.getAnalysisEngineMetaData().getFsIndexCollection();
+    mergedTypePriorities = aeDescription.getAnalysisEngineMetaData().getTypePriorities();
+    resolvedExternalResourcesAndBindings = aeDescription.getResourceManagerConfiguration();
+    resolvedFlowControllerDeclaration = aeDescription.getFlowControllerDeclaration();
+
+    setTypeSystemDescription(aeDescription.isPrimitive() ? aeDescription
+            .getAnalysisEngineMetaData().getTypeSystem() : null); // aggregates have null
+    // tsd. If passed in one
+    // isn't null, make it
+    // null.
+
+    // These come after setTypeSystemDescription call, even though
+    // that call invokeds tcas validate, which uses the merged values for speedup
+    // Therefore, merged values have to be set to proper ideas first.
+    setMergedFsIndexCollection();
+    setImportedFsIndexCollection();
+    setMergedTypePriorities();
+    setImportedTypePriorities();
+    try {
+      setResolvedExternalResourcesAndBindings();
+      // setImportedExternalResourcesAndBindings();
+    } catch (InvalidXMLException e1) {
+      throw new ResourceInitializationException(e1);
+    }
+    try {
+      setResolvedFlowControllerDeclaration();
+    } catch (InvalidXMLException e1) {
+      throw new ResourceInitializationException(e1);
+    }
+  }
+
+  // note that this also updates merged type system
+  // Also called for aggregate TAEs
+  public void setTypeSystemDescription(TypeSystemDescription typeSystemDescription)
+          throws ResourceInitializationException {
+    boolean doValidation = true;
+
+    this.typeSystemDescription = typeSystemDescription;
+
+    // This could be a tsd associated with a primitive TAE descriptor, or
+    // it could be a tsd from a tsd
+    if (typeSystemDescription == null) {
+      if (!isAggregate()) {
+        this.typeSystemDescription = UIMAFramework.getResourceSpecifierFactory()
+                .createTypeSystemDescription();
+        doValidation = false; // speed up by 1/3 second
+      }
+    }
+
+    setMergedTypeSystemDescription();
+    // setImportedTypeSystemDescription(); // done in above call
+
+    if (aeDescription == null)
+      aeDescription = UIMAFramework.getResourceSpecifierFactory().createAnalysisEngineDescription();
+    aeDescription.getAnalysisEngineMetaData().setTypeSystem(this.typeSystemDescription);
+
+    if (doValidation)
+      descriptorCAS.validate();
+  }
+
+  // **************************************************************
+  // * From taeDescriptor back into the Collection part descriptors
+  // **************************************************************
+  private void linkLocalProcessingDescriptorsFromAe(CollectionReaderDescription d) {
+    d.setImplementationName(aeDescription.getAnnotatorImplementationName());
+    d.setFrameworkImplementation(aeDescription.getFrameworkImplementation());
+    linkCommonCollectionDescriptorsFromAe(d);
+  }
+
+  private void linkLocalProcessingDescriptorsFromAe(CasInitializerDescription d) {
+    d.setImplementationName(aeDescription.getAnnotatorImplementationName());
+    d.setFrameworkImplementation(aeDescription.getFrameworkImplementation());
+    linkCommonCollectionDescriptorsFromAe(d);
+  }
+
+  private void linkLocalProcessingDescriptorsFromAe(CasConsumerDescription d) {
+    d.setImplementationName(aeDescription.getAnnotatorImplementationName());
+    d.setFrameworkImplementation(aeDescription.getFrameworkImplementation());
+    linkCommonCollectionDescriptorsFromAe(d);
+  }
+
+  private void linkLocalProcessingDescriptorsFromAe(FlowControllerDescription d) {
+    d.setImplementationName(aeDescription.getAnnotatorImplementationName());
+    d.setFrameworkImplementation(aeDescription.getFrameworkImplementation());
+    linkCommonCollectionDescriptorsFromAe(d);
+  }
+
+  private void linkCommonCollectionDescriptorsFromAe(ResourceCreationSpecifier r) {
+    r.setExternalResourceDependencies(aeDescription.getExternalResourceDependencies());
+    r.setMetaData(convertFromAeMetaData((AnalysisEngineMetaData) aeDescription.getMetaData()));
+    r.setResourceManagerConfiguration(aeDescription.getResourceManagerConfiguration());
+  }
+
+  // *********************************************************
+  // * From Collection Part Descriptors into the taeDescriptor
+  // *********************************************************
+
+  private void createAndLinkLocalProcessingDescriptorsToAe(CollectionReaderDescription d)
+          throws ResourceInitializationException {
+    aeDescription = UIMAFramework.getResourceSpecifierFactory().createAnalysisEngineDescription();
+    aeDescription.setAnnotatorImplementationName(d.getImplementationName());
+    aeDescription.setFrameworkImplementation(d.getFrameworkImplementation());
+    linkLocalProcessingDescriptorsToAe(d);
+  }
+
+  private void createAndLinkLocalProcessingDescriptorsToAe(CasInitializerDescription d)
+          throws ResourceInitializationException {
+    aeDescription = UIMAFramework.getResourceSpecifierFactory().createAnalysisEngineDescription();
+    aeDescription.setAnnotatorImplementationName(d.getImplementationName());
+    aeDescription.setFrameworkImplementation(d.getFrameworkImplementation());
+    linkLocalProcessingDescriptorsToAe(d);
+  }
+
+  private void createAndLinkLocalProcessingDescriptorsToAe(CasConsumerDescription d)
+          throws ResourceInitializationException {
+    aeDescription = UIMAFramework.getResourceSpecifierFactory().createAnalysisEngineDescription();
+    aeDescription.setAnnotatorImplementationName(d.getImplementationName());
+    aeDescription.setFrameworkImplementation(d.getFrameworkImplementation());
+    linkLocalProcessingDescriptorsToAe(d);
+  }
+
+  private void createAndLinkLocalProcessingDescriptorsToAe(FlowControllerDescription d)
+          throws ResourceInitializationException {
+    aeDescription = UIMAFramework.getResourceSpecifierFactory().createAnalysisEngineDescription();
+    aeDescription.setAnnotatorImplementationName(d.getImplementationName());
+    aeDescription.setFrameworkImplementation(d.getFrameworkImplementation());
+    linkLocalProcessingDescriptorsToAe(d);
+  }
+
+  private void linkLocalProcessingDescriptorsToAe(ResourceCreationSpecifier r)
+          throws ResourceInitializationException {
+    aeDescription.setExternalResourceDependencies(r.getExternalResourceDependencies());
+    aeDescription.setMetaData(convertToAeMetaData(r.getMetaData()));
+    aeDescription.setPrimitive(true);
+    aeDescription.setResourceManagerConfiguration(r.getResourceManagerConfiguration());
+    setAeDescription(aeDescription);
+  }
+
+  private AnalysisEngineMetaData convertToAeMetaData(ResourceMetaData r) {
+    ProcessingResourceMetaData p = (ProcessingResourceMetaData) r;
+    AnalysisEngineMetaData d = UIMAFramework.getResourceSpecifierFactory()
+            .createAnalysisEngineMetaData();
+    d.setCapabilities(p.getCapabilities());
+    d.setConfigurationParameterDeclarations(p.getConfigurationParameterDeclarations());
+    d.setConfigurationParameterSettings(p.getConfigurationParameterSettings());
+    d.setCopyright(p.getCopyright());
+    d.setDescription(p.getDescription());
+    d.setFsIndexCollection(p.getFsIndexCollection());
+    d.setName(p.getName());
+    d.setTypePriorities(p.getTypePriorities());
+    d.setTypeSystem(p.getTypeSystem());
+    d.setVendor(p.getVendor());
+    d.setVersion(p.getVersion());
+    d.setOperationalProperties(p.getOperationalProperties());
+    return d;
+  }
+
+  private ProcessingResourceMetaData convertFromAeMetaData(AnalysisEngineMetaData p) {
+    ProcessingResourceMetaData d = UIMAFramework.getResourceSpecifierFactory()
+            .createProcessingResourceMetaData();
+    d.setCapabilities(p.getCapabilities());
+    d.setConfigurationParameterDeclarations(p.getConfigurationParameterDeclarations());
+    d.setConfigurationParameterSettings(p.getConfigurationParameterSettings());
+    d.setCopyright(p.getCopyright());
+    d.setDescription(p.getDescription());
+    d.setFsIndexCollection(p.getFsIndexCollection());
+    d.setName(p.getName());
+    d.setTypePriorities(p.getTypePriorities());
+    d.setTypeSystem(p.getTypeSystem());
+    d.setVendor(p.getVendor());
+    d.setVersion(p.getVersion());
+    d.setOperationalProperties(p.getOperationalProperties());
+    return d;
+  }
+
+  private void setCollectionReaderDescription(CollectionReaderDescription d)
+          throws ResourceInitializationException {
+    collectionReaderDescription = d;
+    createAndLinkLocalProcessingDescriptorsToAe(d);
+  }
+
+  private void setCasInitializerDescription(CasInitializerDescription d)
+          throws ResourceInitializationException {
+    casInitializerDescription = d;
+    createAndLinkLocalProcessingDescriptorsToAe(d);
+  }
+
+  private void setCasConsumerDescription(CasConsumerDescription d)
+          throws ResourceInitializationException {
+    casConsumerDescription = d;
+    createAndLinkLocalProcessingDescriptorsToAe(d);
+  }
+
+  private void setFlowControllerDescription(FlowControllerDescription d)
+          throws ResourceInitializationException {
+    flowControllerDescription = d;
+    createAndLinkLocalProcessingDescriptorsToAe(d);
+  }
+
+  private void setTypePriorities(TypePriorities typePriorities)
+          throws ResourceInitializationException {
+    loadContext(typePriorities);
+    aeDescription.getAnalysisEngineMetaData().setTypePriorities(typePriorities);
+    setMergedTypePriorities();
+    setImportedTypePriorities();
+    descriptorCAS.validate();
+  }
+
+  private static class MultilevelCancel extends RuntimeException {
+    private static final long serialVersionUID = 1L;
+  }
+
+  private void loadContext(XMLizable thing) {
+    // try to load a context that has the types
+    if (isContextLoaded)
+      return;
+    String contextFile = null;
+    XMLInputSource input = null;
+    aeDescription = null;
+    openingContext = true;
+    try {
+      try {
+        contextFile = fileNeedingContext.getPersistentProperty(new QualifiedName(
+                AbstractSection.PLUGIN_ID, AbstractSection.IMPORTABLE_PART_CONTEXT));
+      } catch (CoreException e) {
+        throw new InternalErrorCDE("unexpected exception", e);
+      }
+      ContextForPartDialog dialog = new ContextForPartDialog(PlatformUI.getWorkbench().getDisplay()
+              .getShells()[0], // ok in Eclipse 3.0
+              getFile().getProject().getParent(), thing, getFile().getLocation(), this, contextFile);
+      dialog.setTitle("File specifying context for editing importable part");
+      if (dialog.open() == Window.CANCEL)
+        throw new MultilevelCancel();
+
+      contextFile = dialog.contextPath;
+
+      if (null == contextFile) {
+        Utility
+                .popMessage(
+                        "Context Info",
+                        "A context is required to edit this part.  However no context was supplied.  Editing will be cancelled",
+                        Utility.INFORMATION);
+        throw new MultilevelCancel();
+      } else {
+        try {
+          input = new XMLInputSource(contextFile);
+        } catch (IOException e) {
+          showContextLoadFailureMessage(e, contextFile);
+          throw new MultilevelCancel();
+        }
+        if (null != input)
+          try {
+            fileNeedingContext = (IFile) getIFileOrFile(contextFile);
+            parseSource(input, contextFile);
+          } catch (PartInitException e) {
+            showContextLoadFailureMessage(e, contextFile);
+            throw new MultilevelCancel();
+          }
+      }
+    } finally {
+      openingContext = false;
+    }
+    if (null == aeDescription) {
+      aeDescription = UIMAFramework.getResourceSpecifierFactory().createAnalysisEngineDescription();
+    } else {
+      try {
+        file.setPersistentProperty(new QualifiedName(AbstractSection.PLUGIN_ID,
+                AbstractSection.IMPORTABLE_PART_CONTEXT), contextFile);
+      } catch (CoreException e) {
+        Utility.popMessage("Unexpected Exception", "While loading Context"
+                + getMessagesToRootCause(e), Utility.ERROR);
+        throw new InternalErrorCDE("Unexpected Exception:" + getMessagesToRootCause(e), e);
+      }
+    }
+  }
+
+  private void setFsIndexCollection(FsIndexCollection indexCollection)
+          throws ResourceInitializationException {
+    loadContext(indexCollection);
+    aeDescription.getAnalysisEngineMetaData().setFsIndexCollection(indexCollection);
+    setMergedFsIndexCollection();
+    setImportedFsIndexCollection();
+    descriptorCAS.validate();
+  }
+
+  private void showContextLoadFailureMessage(Exception e, String contextFile) {
+    String m = Messages.getFormattedString("MultiPageEditor.IOError", //$NON-NLS-1$
+            new String[] { AbstractSection.maybeShortenFileName(contextFile) })
+            + Messages.getString("MultiPageEditor.10") + getMessagesToRootCause(e); //$NON-NLS-1$
+    Utility.popMessage("Cannot load context", m
+            + "\nCannot load the context file for this importable part due to an I/O exception"
+            + " - proceeding without context", Utility.WARNING);
+  }
+
+  /**
+   * Only called when editing a resources/bindings descriptor
+   * 
+   * @param rb
+   * @throws ResourceInitializationException
+   */
+  private void setExtResAndBindings(ResourceManagerConfiguration rb)
+          throws ResourceInitializationException {
+    loadContext(rb);
+    aeDescription.setResourceManagerConfiguration(rb);
+    try {
+      setResolvedExternalResourcesAndBindings();
+      // setImportedExternalResourcesAndBindings();
+    } catch (InvalidXMLException e) {
+      throw new ResourceInitializationException(e);
+    }
+    descriptorCAS.validate();
+  }
+
+  public String getAbsolutePathFromImport(Import importItem) {
+    // getAbsoluteURLfromImport may return a bundleresource style url
+    return new File(getAbsoluteURLfromImport(importItem).getPath()).getPath();
+  }
+
+  private URL getAbsoluteURLfromImport(Import importItem) {
+    try {
+      // if by location, it's relative to the descriptor.
+      return Platform.asLocalURL(importItem.findAbsoluteUrl(createResourceManager()));
+    } catch (InvalidXMLException ex) {
+      ex.printStackTrace();
+    } catch (IOException e) {
+    }
+    return null;
+  }
+
+  public AggregatePage getAggregatePage() {
+    return aggregatePage;
+  }
+
+  public OverviewPage getOverviewPage() {
+    return overviewPage;
+  }
+
+  public ParameterPage getParameterPage() {
+    return parameterPage;
+  }
+
+  public TypePage getTypePage() {
+    return typePage;
+  }
+
+  public CapabilityPage getCapabilityPage() {
+    return capabilityPage;
+  }
+
+  public IndexesPage getIndexesPage() {
+    return indexesPage;
+  }
+
+  public ResourcesPage getResourcesPage() {
+    return resourcesPage;
+  }
+
+  public XMLEditor getXMLEditorPage() {
+    return sourceTextEditor;
+  }
+
+  public SettingsPage getSettingsPage() {
+    return settingsPage;
+  }
+
+  /**
+   * @return current file being edited
+   */
+  public IFile getFile() {
+    return file;
+  }
+
+  public Map getResolvedDelegates() {
+    return resolvedDelegates;
+  }
+
+  /**
+   * gets the Hash Map of resolved AE delegates Clones the description first because the getting
+   * updates it in some cases
+   * 
+   * @param aed
+   * @return
+   */
+  public Map getDelegateAEdescriptions(AnalysisEngineDescription aed) {
+    Map result = new HashMap();
+    AnalysisEngineDescription aedClone = (AnalysisEngineDescription) ((AnalysisEngineDescription_impl) aed)
+            .clone();
+    try {
+      result = aedClone.getDelegateAnalysisEngineSpecifiers(createResourceManager());
+    } catch (InvalidXMLException e) {
+
+    }
+    return result;
+  }
+
+  public void markTCasDirty() {
+    descriptorCAS.markDirty();
+    allTypes.markDirty();
+    definedTypesWithSupers.markDirty();
+  }
+
+  public CAS getCurrentView() {
+    return descriptorCAS.get();
+  }
+
+  public IProject getProject() {
+    IFile iFile = getFile();
+    if (null == iFile) // can be null when just creating the instance of the MPE, before init()
+      // call
+      return null;
+    return getFile().getProject();
+  }
+
+  public String getDescriptorDirectory() {
+    String sDir = file.getParent().getLocation().toString();
+    if (sDir.charAt(sDir.length() - 1) != '/') {
+      sDir += '/';
+    }
+    return sDir;
+  }
+
+  public String getDescriptorRelativePath(String aFullOrRelativePath) {
+    String sEditorFileFullPath = getFile().getLocation().toString();
+    String sFullOrRelativePath = aFullOrRelativePath.replace('\\', '/');
+
+    // first, if not in workspace, or if a relative path, not a full path, return path
+    String sWorkspacePath = TAEConfiguratorPlugin.getWorkspace().getRoot().getLocation().toString();
+    if (sFullOrRelativePath.indexOf(sWorkspacePath) == -1) {
+      return sFullOrRelativePath;
+    }
+
+    String sFullPath = sFullOrRelativePath; // rename the var to its semantics
+
+    String commonPrefix = getCommonParentFolder(sEditorFileFullPath, sFullPath);
+    if (commonPrefix.length() < 2 || commonPrefix.indexOf(':') == commonPrefix.length() - 2) {
+      return sFullPath;
+    }
+
+    // now count extra slashes to determine how many ..'s are needed
+    int nCountBackDirs = 0;
+    String sRelativePath = ""; //$NON-NLS-1$
+    for (int i = commonPrefix.length(); i < sEditorFileFullPath.length(); i++) {
+      if (sEditorFileFullPath.charAt(i) == '/') {
+        sRelativePath += "../"; //$NON-NLS-1$
+        nCountBackDirs++;
+      }
+    }
+    sRelativePath += sFullPath.substring(commonPrefix.length());
+    return sRelativePath;
+  }
+
+  private static String getCommonParentFolder(String sFile1, String sFile2) {
+    if (sFile1 == null || sFile2 == null) {
+      return ""; //$NON-NLS-1$
+    }
+
+    int maxLength = (sFile1.length() <= sFile2.length() ? sFile1.length() : sFile2.length());
+    int commonPrefixLength = 0;
+    for (int i = 0; i < maxLength; i++) {
+      if (sFile1.charAt(i) != sFile2.charAt(i) || (i == maxLength - 1)) { // catch files which have
+        // same prefix
+        for (int j = i; j >= 0; j--) {
+          if (sFile1.charAt(j) == '/' || sFile1.charAt(j) == '\\') {
+            commonPrefixLength = j + 1;
+            break;
+          }
+        }
+        break;
+      }
+    }
+
+    return sFile1.substring(0, commonPrefixLength);
+  }
+
+  public boolean isFileInWorkspace(String aFileRelPath) {
+    Object fileOrIFile = getIFileOrFile(aFileRelPath);
+    return (fileOrIFile instanceof IFile && ((IFile) fileOrIFile).exists());
+  }
+
+  public String getFullPathFromDescriptorRelativePath(String aDescRelPath) {
+
+    if (aDescRelPath.indexOf(':') > 0) { // indicates already an absolute path on Windows, at least
+      return aDescRelPath;
+    }
+
+    String sEditorFileFullPath = getFile().getLocation().toString();
+    String sDescRelPath = aDescRelPath.replace('\\', '/');
+
+    int nCountDirsToBackup = 0;
+    int nNextFindLoc = -1;
+    int nLastFindLoc = -1;
+    while (true) {
+      nLastFindLoc = nNextFindLoc;
+      nNextFindLoc = sDescRelPath.indexOf("../", nNextFindLoc + 1); //$NON-NLS-1$
+      if (nNextFindLoc > -1) {
+        nCountDirsToBackup++;
+      } else {
+        break;
+      }
+    }
+    String sFinalFragment = ""; //$NON-NLS-1$
+    if (nCountDirsToBackup > 0) {
+      sFinalFragment = sDescRelPath.substring(nLastFindLoc + 3);
+    }
+
+    if (nCountDirsToBackup == 0) {
+      int nEditorFileLastSlash = sEditorFileFullPath.lastIndexOf('/');
+      String sEditorFileDirectory = sEditorFileFullPath.substring(0, nEditorFileLastSlash + 1);
+      return sEditorFileDirectory + sDescRelPath;
+    }
+
+    int nSubDirCount = 0;
+    for (int i = 0; i < sEditorFileFullPath.length(); i++) {
+      if (sEditorFileFullPath.charAt(i) == '/') {
+        nSubDirCount++;
+      }
+    }
+    int[] subDirMarkerLocs = new int[nSubDirCount];
+    int j = 0;
+    for (int i = 0; i < sEditorFileFullPath.length(); i++) {
+      if (sEditorFileFullPath.charAt(i) == '/') {
+        subDirMarkerLocs[j++] = i;
+      }
+    }
+
+    if (nCountDirsToBackup > nSubDirCount) {
+      return null;
+    }
+
+    return sEditorFileFullPath.substring(0,
+            subDirMarkerLocs[nSubDirCount - nCountDirsToBackup - 1] + 1)
+            + sFinalFragment;
+  }
+
+  public void open(IFile fileToOpen) {
+    final IFile ffile = fileToOpen;
+    Shell shell = new Shell();
+    shell.getDisplay().asyncExec(new Runnable() {
+      public void run() {
+        IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
+        try {
+          page.openEditor(new FileEditorInput(ffile), "taeconfigurator.editors.MultiPageEditor"); //$NON-NLS-1$
+        } catch (PartInitException e) {
+          throw new InternalErrorCDE("unexpected exception");
+        }
+      }
+    });
+  }
+
+  public void openTextEditor(IFile fileToOpen) {
+    final IFile ffile = fileToOpen;
+    Shell shell = new Shell();
+    shell.getDisplay().asyncExec(new Runnable() {
+      public void run() {
+        IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
+        try {
+          page.openEditor(new FileEditorInput(ffile), "org.eclipse.ui.DefaultTextEditor"); //$NON-NLS-1$
+        } catch (PartInitException e) {
+          throw new InternalErrorCDE("unexpected exception");
+        }
+      }
+    });
+  }
+
+  public Object getIFileOrFile(String relOrAbsPath) {
+    String sFileFullPath = getFullPathFromDescriptorRelativePath(relOrAbsPath);
+    String sWorkspacePath = TAEConfiguratorPlugin.getWorkspace().getRoot().getLocation().toString();
+
+    boolean bHasWorkspacePath = (sFileFullPath.indexOf(sWorkspacePath) > -1);
+    if (bHasWorkspacePath) {
+      Path path = new Path(sFileFullPath);
+      return TAEConfiguratorPlugin.getWorkspace().getRoot().getFileForLocation(path);
+    }
+    return new File(sFileFullPath);
+  }
+
+  public void open(String fullPath) {
+    Path path = new Path(fullPath);
+    IFile fileToOpen = TAEConfiguratorPlugin.getWorkspace().getRoot().getFileForLocation(path);
+    open(fileToOpen);
+  }
+
+  public void openTextEditor(String fullPath) {
+    Path path = new Path(fullPath);
+    IFile fileToOpen = TAEConfiguratorPlugin.getWorkspace().getRoot().getFileForLocation(path);
+    openTextEditor(fileToOpen);
+  }
+
+  public void addDirtyTypeName(String typeName) {
+    dirtyTypeNameHash.add(typeName);
+    markTypeModelDirty();
+  }
+
+  private void markTypeModelDirty() {
+    allTypes.markDirty();
+    descriptorCAS.markDirty();
+    definedTypesWithSupers.markDirty();
+  }
+
+  public void removeDirtyTypeName(String typeName) {
+    dirtyTypeNameHash.remove(typeName);
+    markTypeModelDirty();
+  }
+
+  public void doJCasGen(IProgressMonitor monitor) {
+    if (0 < mergedTypesAddingFeatures.size()) {
+      if (Window.CANCEL == 
+      Utility.popOkCancel("Type feature merging extended features",
+              "Before generating the JCas classes for the CAS types, please note that " +
+              "the following types were generated by merging different type descriptors, " +
+              "where the resulting number of features is larger than that of the components. " +
+              "Although the resulting generated JCas classes are correct, " +
+              "doing this kind of merging makes reuse of this component more difficult." +
+              makeMergeMessage(mergedTypesAddingFeatures) +
+              "\n   Press OK to generate the JCas classes anyway, or cancel to skip generating the JCas classes.", 
+              MessageDialog.WARNING)) 
+        return;
+    }
+    final JCasGenThrower jCasGenThrower = new JCasGenThrower();
+
+    try {
+
+      final IWorkspace workspace = ResourcesPlugin.getWorkspace();
+      final Jg jg = new Jg();
+      final TypeDescription[] types = mergedTypeSystemDescription.getTypes();
+      final String outputDirectory = getPrimarySourceFolder().getLocation().toOSString();
+      final String inputFile = file.getLocation().toOSString(); // path to descriptor file
+      IWorkspaceRunnable runnable = new IWorkspaceRunnable() {
+        public void run(IProgressMonitor progressMonitor) {
+          try {
+            jg.mainForCde(new MergerImpl(), new JCasGenProgressMonitor(progressMonitor),
+                    jCasGenThrower, inputFile, outputDirectory, types, (CASImpl) getCurrentView());
+          } catch (IOException e) {
+            Utility.popMessage(Messages.getString("MultiPageEditor.25"), //$NON-NLS-1$
+                    Messages.getString("MultiPageEditor.26") //$NON-NLS-1$
+                            + getMessagesToRootCause(e), MessageDialog.ERROR);
+          }
+        }
+      };
+      workspace.run(runnable, monitor);
+      getPrimarySourceFolder().refreshLocal(IResource.DEPTH_INFINITE, null);
+
+      String jcasMsg = jCasGenThrower.getMessage();
+      if (null != jcasMsg && jcasMsg.length() > 0) {
+        Utility.popMessage(Messages.getString("MultiPageEditor.JCasGenErrorTitle"), //$NON-NLS-1$
+                Messages.getFormattedString("MultiPageEditor.jcasGenErr", //$NON-NLS-1$
+                        new String[] { jcasMsg }), MessageDialog.ERROR);
+        System.out.println(jcasMsg);
+      }
+    } catch (Exception ex) {
+      Utility.popMessage(Messages.getString("MultiPageEditor.JCasGenErrorTitle"), //$NON-NLS-1$
+              Messages.getFormattedString("MultiPageEditor.jcasGenErr", //$NON-NLS-1$
+                      new String[] { jCasGenThrower.getMessage() }), MessageDialog.ERROR);
+      ex.printStackTrace();
+    }
+  }
+
+  // message: TypeName = ".....", URLs defining this type = "xxxx", "xxxx", ....
+  private String makeMergeMessage(Map m) {
+    StringBuffer sb = new StringBuffer();  
+    for (Iterator it = m.entrySet().iterator(); it.hasNext();) {
+      Map.Entry entry = (Map.Entry)it.next();
+      String typeName =(String)entry.getKey();
+      sb.append("\n  ");
+      sb.append("TypeName having merged features = ").append(typeName).append("\n    URLs defining this type =");
+      Set urls = (Set)entry.getValue();
+      boolean afterFirst = false;
+      for (Iterator itUrls = urls.iterator(); itUrls.hasNext();) {
+        if (afterFirst)
+          sb.append(",\n        ");
+        else
+          sb.append("\n        ");
+        afterFirst = true;
+        String url = (String) itUrls.next();
+        sb.append('"').append(url).append('"');
+      }
+    }
+    return sb.toString();
+  }
+
+  final public static String PATH_SEPARATOR = System.getProperty("path.separator"); //$NON-NLS-1$
+
+  private long cachedStamp = -1;
+
+  private String cachedClassPath = null;
+
+  public String getProjectClassPath() throws CoreException {
+    IProject project = getProject();
+
+    if (null == project || !project.isNatureEnabled("org.eclipse.jdt.core.javanature")) { //$NON-NLS-1$
+      return ""; //$NON-NLS-1$
+    }
+    IJavaProject javaProj = JavaCore.create(project);
+    IProject projectRoot = javaProj.getProject();
+
+    IResource classFileResource = projectRoot.findMember(".classpath"); //$NON-NLS-1$
+    long stamp = classFileResource.getModificationStamp();
+    if (stamp == cachedStamp)
+      return cachedClassPath;
+    cachedStamp = stamp;
+
+    StringBuffer result = new StringBuffer(1000);
+
+    String[] classPaths = JavaRuntime.computeDefaultRuntimeClassPath(javaProj);
+
+    for (int i = 0; i < classPaths.length; i++) {
+      String classPath = classPaths[i];
+
+      URLClassLoader checker = null;
+      try {
+        // ignore this entry if it is the Java JVM path
+        checker = new URLClassLoader(new URL[] { new File(classPath).toURL() });
+
+      } catch (MalformedURLException e) {
+        // TODO Auto-generated catch block
+        e.printStackTrace();
+      }
+      if (null == checker
+      // || null != checker.findResource("java/lang/Object.class") //$NON-NLS-1$
+              || null != checker.findResource("org/apache/uima/impl/UIMAFramework_impl.class")) //$NON-NLS-1$
+        continue;
+      if (result.length() > 0)
+        result = result.append(PATH_SEPARATOR);
+      result = result.append(classPath);
+    }
+    cachedStamp = stamp;
+    cachedClassPath = result.toString();
+    return cachedClassPath;
+  }
+
+  public IResource getPrimarySourceFolder() {
+    IProject project = getProject();
+    try {
+      if (!project.isNatureEnabled("org.eclipse.jdt.core.javanature")) { //$NON-NLS-1$
+        return null;
+      }
+      IJavaProject javaProj = JavaCore.create(project);
+      IPackageFragmentRoot[] frs = javaProj.getPackageFragmentRoots();
+      for (int i = 0; i < frs.length; i++) {
+        frs[i].open(null);
+        IResource resource = frs[i].getResource(); // first folder resource will always be first
+        // source folder
+        if (resource instanceof IFolder || resource instanceof IProject) {
+          return resource;
+        }
+      }
+    } catch (Exception ex) {
+      ex.printStackTrace();
+    }
+
+    return null;
+  }
+
+  public void setSaveAsStatus(int nStatus) {
+    m_nSaveAsStatus = nStatus;
+  }
+
+  public TypeSystemDescription getTypeSystemDescription() {
+    return aeDescription.getAnalysisEngineMetaData().getTypeSystem();
+  }
+
+  public TypePriorities getTypePriorities() {
+    return aeDescription.getAnalysisEngineMetaData().getTypePriorities();
+  }
+
+  public FsIndexCollection getFsIndexCollection() {
+    return aeDescription.getAnalysisEngineMetaData().getFsIndexCollection();
+  }
+
+  public ResourceManagerConfiguration getExtResAndBindings() {
+    return aeDescription.getResourceManagerConfiguration();
+  }
+
+  private static final boolean VALIDATE_INPUTS = true;
+
+  // returns true if no inputs were removed, false otherwise
+  public boolean validateInputs(Map typeNameHash) {
+    return validateIOs(VALIDATE_INPUTS, typeNameHash);
+  }
+
+  // returns true if no outputs were removed, false otherwise
+  public boolean validateOutputs(Map typeNameHash) {
+    return validateIOs(!VALIDATE_INPUTS, typeNameHash);
+  }
+
+  public boolean validateIOs(boolean isValidateInputs, Map typeNameHash) {
+    boolean bRes = true;
+
+    if (aeDescription != null) {
+      Capability[] capabilities = aeDescription.getAnalysisEngineMetaData().getCapabilities();
+      if (capabilities == null || capabilities.length == 0) {
+        return true;
+      }
+
+      TypeOrFeature[] oldIOs = (isValidateInputs) ? capabilities[0].getInputs() : capabilities[0]
+              .getOutputs();
+      Vector validIOs = new Vector();
+      for (int i = 0; i < oldIOs.length; i++) {
+        String typeName;
+        int nColonLoc = oldIOs[i].getName().indexOf(':');
+        if (nColonLoc == -1) {
+          typeName = oldIOs[i].getName();
+        } else {
+          typeName = oldIOs[i].getName().substring(0, nColonLoc);
+        }
+        if (typeNameHash.containsKey(typeName)) {
+          validIOs.addElement(oldIOs[i]);
+        } else {
+          bRes = false;
+        }
+      }
+
+      if (!bRes) {
+        TypeOrFeature[] newIOs = new TypeOrFeature[validIOs.size()];
+        for (int i = 0; i < newIOs.length; i++) {
+          newIOs[i] = (TypeOrFeature) validIOs.elementAt(i);
+        }
+
+        if (isValidateInputs)
+          capabilities[0].setInputs(newIOs);
+        else
+          capabilities[0].setOutputs(newIOs);
+      }
+    }
+
+    return bRes;
+  }
+
+  // returns true if no type priorities were modified, false otherwise
+  public boolean validateTypePriorities(Map typeNameHash) {
+    boolean bRes = true;
+
+    TypePriorities priorities = aeDescription.getAnalysisEngineMetaData().getTypePriorities();
+    if (priorities != null) {
+      TypePriorityList[] priorityLists = priorities.getPriorityLists();
+      if (priorityLists != null) {
+        for (int i = 0; i < priorityLists.length; i++) {
+          String[] typeNames = priorityLists[i].getTypes();
+          if (typeNames != null) {
+            int nCountNewTypeNames = 0;
+            for (int j = 0; j < typeNames.length; j++) {
+              if (typeNameHash.containsKey(typeNames[j])) {
+                nCountNewTypeNames++;
+              }
+            }
+            if (nCountNewTypeNames < typeNames.length) {
+              bRes = false;
+              String[] newTypeNames = new String[nCountNewTypeNames];
+              for (int j = 0, k = 0; j < typeNames.length; j++) {
+                if (typeNameHash.containsKey(typeNames[j])) {
+                  newTypeNames[k++] = typeNames[j];
+                }
+              }
+              priorityLists[i].setTypes(newTypeNames);
+            }
+          }
+        }
+      }
+    }
+
+    return bRes;
+  }
+
+  private static final int previewSize = 1024 * 16;
+  
+  /**
+   * Used by code to get lists of delegate components by input/output type specs.
+   */
+  public static ResourceSpecifier getDelegateResourceSpecifier(IFile iFile,
+          String[] componentHeaders) {
+    if (!iFile.getName().toLowerCase().endsWith(".xml")) { //$NON-NLS-1$
+      return null;
+    }
+    // make a quick assesment of whether file is a TAE
+    // looking in the first part of the file, but 1024 isn't big enough
+    // because initial comment blocks like the apache license are that big
+    // Do 16 K
+    char[] acBuffer = new char[previewSize];
+    FileReader fileReader = null;
+    int nCharsRead = 0;
+    try {
+      // FileReader is FileInputStream using "default" char-encoding
+      fileReader = new FileReader(iFile.getLocation().toString());
+      while (true) {
+        int tempCharsRead = fileReader.read(acBuffer, nCharsRead, previewSize - nCharsRead);
+        if (-1 == tempCharsRead)
+          break;
+        nCharsRead = nCharsRead + tempCharsRead;
+        if (nCharsRead >= previewSize)
+          break;
+      }
+    } catch (FileNotFoundException e) {
+      return null;
+    } catch (IOException e) {
+      return null;
+    } finally {
+      if (null != fileReader)
+        try {
+          fileReader.close();
+        } catch (IOException e1) {
+        }
+    }
+    if (-1 == nCharsRead)
+      return null;
+    String sBuffer = (new String(acBuffer, 0, nCharsRead)).toLowerCase();
+    for (int i = 0; i < componentHeaders.length; i++) {
+      if (-1 != sBuffer.indexOf(componentHeaders[i]))
+        break;
+      if (i == (componentHeaders.length - 1))
+        return null;
+    }
+
+    try {
+      XMLInputSource input = new XMLInputSource(iFile.getLocation().toFile());
+      XMLizable inputDescription = AbstractSection.parseDescriptor(input);
+      if (inputDescription instanceof AnalysisEngineDescription
+              || inputDescription instanceof CasConsumerDescription
+              || inputDescription instanceof FlowControllerDescription)
+        return (ResourceCreationSpecifier) inputDescription;
+      else if (inputDescription instanceof ResourceServiceSpecifier)
+        return (ResourceSpecifier) inputDescription;
+      return null;
+    } catch (IOException e) {
+      return null;
+    } catch (InvalidXMLException e) {
+      return null;
+    }
+  }
+
+  // **************************************************
+  // * Getting exception messages down to root
+  // **************************************************
+  public String getMessagesToRootCause(Throwable e) {
+    boolean wantStackTrace = false;
+    StringBuffer b = new StringBuffer(200);
+    String messagePart = e.getMessage();
+    if (null == messagePart) {
+      b.append(e.getClass().getName());
+      wantStackTrace = true;
+    } else
+      b.append(messagePart);
+    Throwable cur = e;
+    Throwable next;
+
+    while (null != (next = cur.getCause())) {
+      String message = next.getMessage();
+      wantStackTrace = false; // only do stack trace if last item has no message
+      if (null == message) {
+        b.append(next.getClass().getName());
+        wantStackTrace = true;
+      }
+      if (null != message && !message.equals(messagePart)) {
+        b.append(Messages.getString("MultiPageEditor.causedBy")).append(message); //$NON-NLS-1$
+        messagePart = message;
+      }
+      cur = next;
+    }
+    if (wantStackTrace) {
+      ByteArrayOutputStream ba = new ByteArrayOutputStream();
+      PrintStream ps = new PrintStream(ba);
+      cur.printStackTrace(ps);
+      ps.flush();
+      b.append(ba.toString());
+      ps.close();
+    }
+    return b.toString();
+  }
+
+  public static class JCasGenProgressMonitor implements
+          org.apache.uima.tools.jcasgen.IProgressMonitor {
+    IProgressMonitor m_progressMonitor;
+
+    public JCasGenProgressMonitor(IProgressMonitor progressMonitor) {
+      m_progressMonitor = progressMonitor;
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see org.apache.uima.jcas.jcasgen_gen.IProgressMonitor#done()
+     */
+    public void done() {
+      m_progressMonitor.done();
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see org.apache.uima.jcas.jcasgen_gen.IProgressMonitor#beginTask(java.lang.String, int)
+     */
+    public void beginTask(String name, int totalWorked) {
+      m_progressMonitor.beginTask(name, totalWorked);
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see org.apache.uima.jcas.jcasgen_gen.IProgressMonitor#subTask(java.lang.String)
+     */
+    public void subTask(String name) {
+      m_progressMonitor.subTask(name);
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see org.apache.uima.jcas.jcasgen_gen.IProgressMonitor#worked(int)
+     */
+    public void worked(int work) {
+      m_progressMonitor.worked(work);
+    }
+
+  }
+
+  public static class JCasGenThrower implements IError {
+
+    private Level logLevels[] = { Level.INFO, Level.WARNING, Level.SEVERE };
+
+    private String m_message = null;
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see org.apache.uima.jcas.jcasgen_gen.IError#newError(int, java.lang.String)
+     */
+    public void newError(int severity, String message, Exception ex) {
+      Logger log = UIMAFramework.getLogger();
+      log.log(logLevels[severity], "JCasGen: " + message); //$NON-NLS-1$
+      System.out.println(Messages.getString("MultiPageEditor.JCasGenErr") //$NON-NLS-1$
+              + message);
+      if (null != ex)
+        ex.printStackTrace();
+      if (IError.WARN < severity) {
+        m_message = message;
+        throw new Jg.ErrorExit();
+      }
+    }
+
+    public String getMessage() {
+      return m_message;
+    }
+  }
+
+  public Color getFadeColor() {
+    if (null == fadeColor)
+      // COLOR_WIDGET_DARK_SHADOW is the same as black on SUSE KDE
+      fadeColor = getSite().getShell().getDisplay().getSystemColor(SWT.COLOR_WIDGET_NORMAL_SHADOW);
+    return fadeColor;
+  }
+
+  // **********************
+  // * Merged type system
+  // **********************
+  public void setMergedTypeSystemDescription(TypeSystemDescription saved) {
+    mergedTypeSystemDescription = saved;
+  }
+
+  public void setImportedTypeSystemDescription(TypeSystemDescription saved) {
+    importedTypeSystemDescription = saved;
+  }
+
+  private void setImportedTypeSystemDescription() throws ResourceInitializationException {
+    Collection tsdc = new ArrayList(1);
+    TypeSystemDescription tsd = typeSystemDescription;
+    if (null != tsd) {
+      tsd = (TypeSystemDescription) tsd.clone();
+      tsd.setTypes(typeDescriptionArray0);
+    }
+    tsdc.clear();
+    tsdc.add(tsd);
+    importedTypeSystemDescription = CasCreationUtils
+            .mergeTypeSystems(tsdc, createResourceManager());
+  }
+
+  public void setMergedTypeSystemDescription() throws ResourceInitializationException {
+    mergedTypesAddingFeatures.clear();
+    if (isAggregate())
+      mergedTypeSystemDescription = CasCreationUtils.mergeDelegateAnalysisEngineTypeSystems(
+              (AnalysisEngineDescription) aeDescription.clone(), createResourceManager(),
+              mergedTypesAddingFeatures);
+    else {
+      if (null == typeSystemDescription) {
+        mergedTypeSystemDescription = null;
+      } else {
+        ResourceManager resourceManager = createResourceManager();
+        Collection tsdc = new ArrayList(1);
+        tsdc.add(typeSystemDescription.clone());
+        // System.out.println("mergingTypeSystem 2"); //$NON-NLS-1$
+        // long time = System.currentTimeMillis();
+        mergedTypeSystemDescription = CasCreationUtils.mergeTypeSystems(tsdc, resourceManager,
+                mergedTypesAddingFeatures);
+        // System.out.println("Finished mergingTypeSystem 2; time= " + //$NON-NLS-1$
+        // (System.currentTimeMillis() - time));
+        setImportedTypeSystemDescription();
+      }
+    }
+  }
+
+  public TypeSystemDescription getMergedTypeSystemDescription() {
+    return mergedTypeSystemDescription;
+  }
+
+  public TypeSystemDescription getImportedTypeSystemDesription() {
+    return importedTypeSystemDescription;
+  }
+
+  public void setMergedFsIndexCollection() throws ResourceInitializationException {
+    mergedFsIndexCollection = CasCreationUtils.mergeDelegateAnalysisEngineFsIndexCollections(
+            (AnalysisEngineDescription) aeDescription.clone(), createResourceManager());
+  }
+
+  public void setMergedFsIndexCollection(FsIndexCollection saved) {
+    mergedFsIndexCollection = saved;
+  }
+
+  public FsIndexCollection getMergedFsIndexCollection() {
+    return mergedFsIndexCollection;
+  }
+
+  // full merge - including locally defined and imported ones
+  public void setMergedTypePriorities() throws ResourceInitializationException {
+    mergedTypePriorities = CasCreationUtils.mergeDelegateAnalysisEngineTypePriorities(
+            (AnalysisEngineDescription) aeDescription.clone(), createResourceManager());
+  }
+
+  public void setMergedTypePriorities(TypePriorities saved) {
+    mergedTypePriorities = saved;
+  }
+
+  public TypePriorities getMergedTypePriorities() {
+    return mergedTypePriorities;
+  }
+
+  public void setResolvedFlowControllerDeclaration() throws InvalidXMLException {
+    FlowControllerDeclaration fcDecl = aeDescription.getFlowControllerDeclaration();
+    if (null != fcDecl) {
+      resolvedFlowControllerDeclaration = (FlowControllerDeclaration) fcDecl.clone();
+      resolvedFlowControllerDeclaration.resolveImports(createResourceManager());
+    } else
+      resolvedFlowControllerDeclaration = null;
+  }
+
+  public FlowControllerDeclaration getResolvedFlowControllerDeclaration() {
+    return resolvedFlowControllerDeclaration;
+  }
+
+  /**
+   * A Merge method doesn't "fit". merging isn't done over aggregates for these. Instead, the
+   * outer-most one "wins".
+   * 
+   * But: resolving does fit. So we name this differently
+   * 
+   * @throws InvalidXMLException
+   */
+  public void setResolvedExternalResourcesAndBindings() throws InvalidXMLException {
+    AnalysisEngineDescription clonedAe = (AnalysisEngineDescription) aeDescription.clone();
+    ResourceManagerConfiguration rmc = clonedAe.getResourceManagerConfiguration();
+    if (null != rmc)
+      rmc.resolveImports(createResourceManager());
+    resolvedExternalResourcesAndBindings = rmc;
+  }
+
+  public void setResolvedExternalResourcesAndBindings(ResourceManagerConfiguration saved) {
+    resolvedExternalResourcesAndBindings = saved;
+  }
+
+  public ResourceManagerConfiguration getResolvedExternalResourcesAndBindings() {
+    return resolvedExternalResourcesAndBindings;
+  }
+
+  private void setImportedFsIndexCollection() throws ResourceInitializationException {
+    AnalysisEngineDescription localAe = (AnalysisEngineDescription) aeDescription.clone();
+    localAe.getAnalysisEngineMetaData().setFsIndexCollection(null);
+    importedFsIndexCollection = CasCreationUtils.mergeDelegateAnalysisEngineFsIndexCollections(
+            localAe, createResourceManager());
+  }
+
+  public FsIndexCollection getImportedFsIndexCollection() {
+    return importedFsIndexCollection;
+  }
+
+  // this is all the type priorities, except those locally defined
+  // used to distinguish between locally defined and imported ones
+  // (only locally defined ones can be edited)
+  private void setImportedTypePriorities() throws ResourceInitializationException {
+    AnalysisEngineDescription localAe = (AnalysisEngineDescription) aeDescription.clone();
+    localAe.getAnalysisEngineMetaData().setTypePriorities(null);
+    importedTypePriorities = CasCreationUtils.mergeDelegateAnalysisEngineTypePriorities(localAe,
+            createResourceManager());
+  }
+
+  public TypePriorities getImportedTypePriorities() {
+    return importedTypePriorities;
+  }
+
+  // private void setImportedExternalResourcesAndBindings() throws ResourceInitializationException {
+  // ResourceManagerConfiguration_impl rmc = ((ResourceManagerConfiguration_impl)
+  // aeDescription.getResourceManagerConfiguration());
+  // if (null != rmc) {
+  // rmc = (ResourceManagerConfiguration_impl) rmc.clone();
+  // rmc.setExternalResourceBindings(null);
+  // rmc.setExternalResources(null);
+  // try {
+  // rmc.resolveImports(createResourceManager());
+  // } catch (InvalidXMLException e) {
+  // throw new ResourceInitializationException(e);
+  // }
+  // }
+  // importedExternalResourcesAndBindings = rmc;
+  // }
+
+  // public ResourceManagerConfiguration getImportedExternalResourcesAndBindings() {
+  // return importedExternalResourcesAndBindings;
+  // }
+
+  public ITextEditor getSourcePageEditor() {
+    if (getCurrentPage() == sourceIndex) {
+      return sourceTextEditor;
+    } else
+      return null;
+  }
+
+  private IJavaProject javaProject = null;
+
+  public IJavaProject getJavaProject() {
+    if (null == javaProject && null != file) {
+      javaProject = JavaCore.create(file.getProject());
+    }
+    return javaProject;
+  }
+
+  public IType getTypeFromProject(String typename) {
+    IJavaProject jp = getJavaProject();
+    if (null != jp)
+      try {
+        return jp.findType(typename);
+      } catch (JavaModelException e) {
+        Utility.popMessage("Unexpected Exception", MessageFormat.format(
+                "Unexpected exception while getting type information for type ''{0}''. {1}",
+                new Object[] { typename, getMessagesToRootCause(e) }), Utility.ERROR);
+        throw new InternalErrorCDE("unexpected exception", e);
+      }
+    return null;
+  }
+
+  private IType analysisComponentIType = null;
+
+  private IType baseAnnotatorIType = null;
+
+  private IType collectionReaderIType = null;
+
+  private IType casInitializerIType = null;
+
+  private IType casConsumerIType = null;
+
+  private IType flowControllerIType = null;
+
+  public IType getAnalysisComponentIType() {
+    if (null == analysisComponentIType)
+      analysisComponentIType = getTypeFromProject("org.apache.uima.analysis_component.AnalysisComponent");
+    return analysisComponentIType;
+  }
+
+  public IType getBaseAnnotatorIType() {
+    if (null == baseAnnotatorIType)
+      baseAnnotatorIType = getTypeFromProject("org.apache.uima.analysis_engine.annotator.BaseAnnotator");
+    return baseAnnotatorIType;
+  }
+
+  public IType getCollectionReaderIType() {
+    if (null == collectionReaderIType)
+      collectionReaderIType = getTypeFromProject("org.apache.uima.collection.CollectionReader");
+    return collectionReaderIType;
+  }
+
+  public IType getCasInitializerIType() {
+    if (null == casInitializerIType)
+      casInitializerIType = getTypeFromProject("org.apache.uima.collection.CasInitializer");
+    return casInitializerIType;
+  }
+
+  public IType getCasConsumerIType() {
+    if (null == casConsumerIType)
+      casConsumerIType = getTypeFromProject("org.apache.uima.collection.CasConsumer");
+    return casConsumerIType;
+  }
+
+  public IType getFlowControllerIType() {
+    if (null == flowControllerIType)
+      flowControllerIType = getTypeFromProject("org.apache.uima.flow.FlowController");
+    return flowControllerIType;
+  }
+
+  private static class CombinedHierarchyScope implements IJavaSearchScope {
+
+    private IJavaSearchScope[] subScopes = new IJavaSearchScope[5];
+
+    private int nbrScopes = 0;
+
+    public IJavaSearchScope[] getScopes() {
+      return subScopes;
+    }
+
+    public void addScope(IJavaSearchScope newScope) {
+      subScopes[nbrScopes++] = newScope;
+    }
+
+    public boolean encloses(String resourcePath) {
+      for (int i = 0; i < nbrScopes; i++) {
+        if (subScopes[i].encloses(resourcePath)) {
+          return true;
+        }
+      }
+      if (!resourcePath.startsWith("C:\\p\\j"))
+        System.out.println(MessageFormat.format(" FALSE encloses resourcepath: ''{0}''",
+                new Object[] { resourcePath }));
+      return false;
+    }
+
+    public boolean encloses(IJavaElement element) {
+
+      for (int i = 0; i < nbrScopes; i++) {
+        if (subScopes[i].encloses(element))
+          return true;
+      }
+      return false;
+    }
+
+    public IPath[] enclosingProjectsAndJars() {
+      ArrayList result = new ArrayList(10);
+      for (int i = 0; i < nbrScopes; i++) {
+        IPath[] pjs = subScopes[i].enclosingProjectsAndJars();
+        if (null != pjs)
+          for (int j = 0; j < pjs.length; j++) {
+            if (!result.contains(pjs[j]))
+              result.add(pjs[j]);
+          }
+      }
+      return (IPath[]) result.toArray(new IPath[result.size()]);
+    }
+
+    public boolean includesBinaries() {
+      // TODO Auto-generated method stub
+      return true;
+    }
+
+    public boolean includesClasspaths() {
+      // TODO Auto-generated method stub
+      return true;
+    }
+
+    public void setIncludesBinaries(boolean includesBinaries) {
+      // implements interface method
+    }
+
+    public void setIncludesClasspaths(boolean includesClasspaths) {
+      // implements interface method
+    }
+  }
+
+  public IJavaSearchScope getSearchScopeForDescriptorType() {
+    try {
+      switch (descriptorType) {
+        case DESCRIPTOR_AE:
+          CombinedHierarchyScope scope = new CombinedHierarchyScope();
+          scope.addScope(SearchEngine.createHierarchyScope(getAnalysisComponentIType()));
+          scope.addScope(SearchEngine.createHierarchyScope(getBaseAnnotatorIType()));
+          scope.addScope(SearchEngine.createHierarchyScope(getCollectionReaderIType()));
+          scope.addScope(SearchEngine.createHierarchyScope(getCasConsumerIType()));
+          return scope;
+        case DESCRIPTOR_CASCONSUMER:
+          return SearchEngine.createHierarchyScope(getCasConsumerIType());
+        case DESCRIPTOR_CASINITIALIZER:
+          return SearchEngine.createHierarchyScope(getCasInitializerIType());
+        case DESCRIPTOR_COLLECTIONREADER:
+          return SearchEngine.createHierarchyScope(getCollectionReaderIType());
+        case DESCRIPTOR_FLOWCONTROLLER:
+          return SearchEngine.createHierarchyScope(getFlowControllerIType());
+      }
+    } catch (JavaModelException e) {
+      throw new InternalErrorCDE("unexpected exception", e);
+    }
+    return null;
+  }
+}
diff --git a/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/MultiPageEditorContributor.java b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/MultiPageEditorContributor.java
new file mode 100644
index 0000000..44967d9
--- /dev/null
+++ b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/MultiPageEditorContributor.java
@@ -0,0 +1,283 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS 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.taeconfigurator.editors;
+
+import org.eclipse.core.runtime.Preferences;
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.action.MenuManager;
+import org.eclipse.ui.IActionBars;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IWorkbenchActionConstants;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.actions.ActionFactory;
+import org.eclipse.ui.ide.IDEActionFactory;
+import org.eclipse.ui.part.MultiPageEditorActionBarContributor;
+import org.eclipse.ui.part.MultiPageEditorPart;
+import org.eclipse.ui.texteditor.ITextEditor;
+import org.eclipse.ui.texteditor.ITextEditorActionConstants;
+
+import org.apache.uima.taeconfigurator.Messages;
+import org.apache.uima.taeconfigurator.PreferencePage;
+import org.apache.uima.taeconfigurator.TAEConfiguratorPlugin;
+import org.apache.uima.taeconfigurator.editors.xml.XMLEditor;
+
+// import org.eclipse.jdt.launching.IVMRunner;
+
+// import org.apache.uima.jcas.jcasgen.Prefs;
+
+/**
+ * Manages the installation/deinstallation of global actions for multi-page editors. Responsible for
+ * the redirection of global actions to the active editor. Multi-page contributor replaces the
+ * contributors for the individual editors in the multi-page editor.
+ */
+public class MultiPageEditorContributor extends MultiPageEditorActionBarContributor {
+  private IEditorPart activeEditorPart;
+
+  Action autoJCasAction;
+
+  Action qualifiedTypesAction;
+
+  Action runJCasGenAction;
+
+  /**
+   * Creates a multi-page contributor.
+   */
+  public MultiPageEditorContributor() {
+    super();
+    createActions();
+  }
+
+  /**
+   * Returns the action registed with the given text editor.
+   * 
+   * @return IAction or null if editor is null.
+   */
+  protected IAction getAction(MultiPageEditorPart editor, String actionID) {
+    ITextEditor txtEditor = ((MultiPageEditor) editor).getSourcePageEditor();
+    return (txtEditor == null ? null : txtEditor.getAction(actionID));
+  }
+
+  protected IAction getAction1(ITextEditor editor, String actionID) {
+    return (editor == null ? null : editor.getAction(actionID));
+  }
+
+  /*
+   * (non-JavaDoc) Method declared in AbstractMultiPageEditorActionBarContributor.
+   */
+
+  public void setActiveEditor(IEditorPart part) {
+    if (activeEditorPart == part)
+      return;
+
+    if (null == part)
+      return;
+    activeEditorPart = part;
+
+    IActionBars actionBars = getActionBars();
+    if (actionBars != null) {
+
+      MultiPageEditorPart editor = (MultiPageEditorPart) part;
+
+      actionBars.setGlobalActionHandler(ActionFactory.DELETE.getId(), getAction(editor,
+              ITextEditorActionConstants.DELETE));
+      actionBars.setGlobalActionHandler(ActionFactory.UNDO.getId(), getAction(editor,
+              ITextEditorActionConstants.UNDO));
+      actionBars.setGlobalActionHandler(ActionFactory.REDO.getId(), getAction(editor,
+              ITextEditorActionConstants.REDO));
+      actionBars.setGlobalActionHandler(ActionFactory.CUT.getId(), getAction(editor,
+              ITextEditorActionConstants.CUT));
+      actionBars.setGlobalActionHandler(ActionFactory.COPY.getId(), getAction(editor,
+              ITextEditorActionConstants.COPY));
+      actionBars.setGlobalActionHandler(ActionFactory.PASTE.getId(), getAction(editor,
+              ITextEditorActionConstants.PASTE));
+      actionBars.setGlobalActionHandler(ActionFactory.SELECT_ALL.getId(), getAction(editor,
+              ITextEditorActionConstants.SELECT_ALL));
+      actionBars.setGlobalActionHandler(ActionFactory.FIND.getId(), getAction(editor,
+              ITextEditorActionConstants.FIND));
+      actionBars.setGlobalActionHandler(IDEActionFactory.BOOKMARK.getId(), getAction(editor,
+              IDEActionFactory.BOOKMARK.getId()));
+      actionBars.updateActionBars();
+    }
+  }
+
+  /*
+   * (non-Javadoc)
+   * 
+   * @see org.eclipse.ui.part.MultiPageEditorActionBarContributor#setActivePage(org.eclipse.ui.IEditorPart)
+   */
+  public void setActivePage(IEditorPart part) {
+
+    IActionBars actionBars = getActionBars();
+    if (actionBars != null) {
+
+      ITextEditor textEditor = (part instanceof XMLEditor) ? (ITextEditor) part : null;
+
+      actionBars.setGlobalActionHandler(ActionFactory.DELETE.getId(), getAction1(textEditor,
+              ITextEditorActionConstants.DELETE));
+      actionBars.setGlobalActionHandler(ActionFactory.UNDO.getId(), getAction1(textEditor,
+              ITextEditorActionConstants.UNDO));
+      actionBars.setGlobalActionHandler(ActionFactory.REDO.getId(), getAction1(textEditor,
+              ITextEditorActionConstants.REDO));
+      actionBars.setGlobalActionHandler(ActionFactory.CUT.getId(), getAction1(textEditor,
+              ITextEditorActionConstants.CUT));
+      actionBars.setGlobalActionHandler(ActionFactory.COPY.getId(), getAction1(textEditor,
+              ITextEditorActionConstants.COPY));
+      actionBars.setGlobalActionHandler(ActionFactory.PASTE.getId(), getAction1(textEditor,
+              ITextEditorActionConstants.PASTE));
+      actionBars.setGlobalActionHandler(ActionFactory.SELECT_ALL.getId(), getAction1(textEditor,
+              ITextEditorActionConstants.SELECT_ALL));
+      actionBars.setGlobalActionHandler(ActionFactory.FIND.getId(), getAction1(textEditor,
+              ITextEditorActionConstants.FIND));
+      actionBars.setGlobalActionHandler(IDEActionFactory.BOOKMARK.getId(), getAction1(textEditor,
+              IDEActionFactory.BOOKMARK.getId()));
+      actionBars.updateActionBars();
+    }
+  }
+
+  private void createActions() {
+
+    autoJCasAction = new Action() {
+      public void run() {
+        TAEConfiguratorPlugin plugin = TAEConfiguratorPlugin.getDefault();
+        Preferences prefs = plugin.getPluginPreferences();
+        boolean bAutoJCasGen = !prefs.getBoolean(PreferencePage.P_JCAS); //$NON-NLS-1$
+        autoJCasAction.setChecked(bAutoJCasGen);
+        prefs.setValue(PreferencePage.P_JCAS, bAutoJCasGen); //$NON-NLS-1$
+      }
+    };
+
+    runJCasGenAction = new Action() {
+      public void run() {
+        ((MultiPageEditor) activeEditorPart).doJCasGenChkSrc(null); // don't know how to get
+        // progress monitor
+      }
+    };
+
+    qualifiedTypesAction = new Action() {
+      public void run() {
+        TAEConfiguratorPlugin plugin = TAEConfiguratorPlugin.getDefault();
+        Preferences prefs = plugin.getPluginPreferences();
+        boolean bFullyQualifiedTypeNames = !prefs
+                .getBoolean(PreferencePage.P_SHOW_FULLY_QUALIFIED_NAMES); //$NON-NLS-1$
+        qualifiedTypesAction.setChecked(bFullyQualifiedTypeNames);
+        prefs.setValue(PreferencePage.P_SHOW_FULLY_QUALIFIED_NAMES, bFullyQualifiedTypeNames); //$NON-NLS-1$
+
+        // mark all pages as stale for all editors, since this is a global setting
+        IWorkbenchPage[] pages = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getPages();
+        for (int i = 0; i < pages.length; i++) {
+          IWorkbenchPart[] editors = pages[i].getEditors();
+          for (int j = 0; j < editors.length; j++) {
+            if (editors[j] != null && editors[j] instanceof MultiPageEditor) {
+              ((MultiPageEditor) editors[j]).markAllPagesStale();
+            }
+          }
+        }
+
+      }
+    };
+
+    autoJCasAction.setText(Messages.getString("MultiPageEditorContributor.autoGenJCas")); //$NON-NLS-1$
+    autoJCasAction.setChecked(getAutoJCasGen()); //$NON-NLS-1$
+
+    qualifiedTypesAction.setText(Messages.getString("MultiPageEditorContributor.showFullNames")); //$NON-NLS-1$
+    qualifiedTypesAction.setChecked(getUseQualifiedTypes()); //$NON-NLS-1$
+
+    runJCasGenAction.setText("Run JCasGen");
+  }
+
+  public void contributeToMenu(IMenuManager manager) {
+
+    IMenuManager menu = new MenuManager("&UIMA"); //$NON-NLS-1$
+    manager.prependToGroup(IWorkbenchActionConstants.MB_ADDITIONS, menu);
+    menu.add(runJCasGenAction);
+    IMenuManager settingsMenu = new MenuManager("Settings"); //$NON-NLS-1$
+    menu.add(settingsMenu);
+    settingsMenu.add(autoJCasAction);
+    settingsMenu.add(qualifiedTypesAction);
+  }
+
+  public static boolean getAutoJCasGen() {
+    return getUimaPrefBoolean(PreferencePage.P_JCAS, true);
+  }
+
+  public static boolean getUseQualifiedTypes() {
+    return getUimaPrefBoolean(PreferencePage.P_SHOW_FULLY_QUALIFIED_NAMES, true);
+  }
+
+  public static int getXMLindent() {
+    return getUimaPrefInt(PreferencePage.P_XML_TAB_SPACES, 2);
+  }
+
+  public static String getCDEVnsHost() {
+    return getUimaPrefString(PreferencePage.P_VNS_HOST, "localhost");
+  }
+
+  public static String getCDEVnsPort() {
+    return getUimaPrefString(PreferencePage.P_VNS_PORT, "9000");
+  }
+
+  public static void setVnsHost(String v) {
+    System.setProperty("VNS_HOST", v);
+  }
+
+  public static void setVnsPort(String v) {
+    System.setProperty("VNS_PORT", v);
+  }
+
+  public static void setVnsHost() {
+    setVnsHost(getCDEVnsHost());
+  }
+
+  public static void setVnsPort() {
+    setVnsPort(getCDEVnsPort());
+  }
+
+  private static String getUimaPrefString(String key, String defaultValue) {
+    TAEConfiguratorPlugin plugin = TAEConfiguratorPlugin.getDefault();
+    Preferences prefs = plugin.getPluginPreferences();
+    boolean isDefault = prefs.isDefault(key);
+    if (isDefault)
+      prefs.setDefault(key, defaultValue);
+    return prefs.getString(key);
+  }
+
+  private static boolean getUimaPrefBoolean(String key, boolean defaultValue) {
+    TAEConfiguratorPlugin plugin = TAEConfiguratorPlugin.getDefault();
+    Preferences prefs = plugin.getPluginPreferences();
+    boolean isDefault = prefs.isDefault(key);
+    if (isDefault)
+      prefs.setDefault(key, defaultValue);
+    return prefs.getBoolean(key);
+  }
+
+  private static int getUimaPrefInt(String key, int defaultValue) {
+    TAEConfiguratorPlugin plugin = TAEConfiguratorPlugin.getDefault();
+    Preferences prefs = plugin.getPluginPreferences();
+    boolean isDefault = prefs.isDefault(key);
+    if (isDefault)
+      prefs.setDefault(key, defaultValue);
+    return prefs.getInt(key);
+  }
+
+}
diff --git a/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/AbstractImportablePartSection.java b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/AbstractImportablePartSection.java
new file mode 100644
index 0000000..5eaebbe
--- /dev/null
+++ b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/AbstractImportablePartSection.java
@@ -0,0 +1,186 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS 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.taeconfigurator.editors.ui;
+
+import org.apache.uima.resource.metadata.AllowedValue;
+import org.apache.uima.resource.metadata.FeatureDescription;
+import org.apache.uima.resource.metadata.TypeDescription;
+import org.apache.uima.resource.metadata.TypeSystemDescription;
+import org.apache.uima.taeconfigurator.editors.MultiPageEditor;
+import org.apache.uima.taeconfigurator.model.BuiltInTypes;
+import org.eclipse.swt.custom.TableTreeItem;
+import org.eclipse.swt.widgets.Composite;
+
+public abstract class AbstractImportablePartSection extends AbstractSection {
+
+  /**
+   * @param editor
+   * @param parent
+   * @param headerText
+   * @param description
+   */
+  public AbstractImportablePartSection(MultiPageEditor aEditor, Composite parent,
+          String headerText, String description) {
+    super(aEditor, parent, headerText, description);
+  }
+
+  // ********************************
+  // * GUI methods
+  // ********************************
+  protected boolean isLocalItem(TableTreeItem item) {
+    return !item.getForeground().equals(editor.getFadeColor());
+  }
+
+  // ********************************
+  // * Universal Getters
+  // ********************************
+  /**
+   * returns null if no feature by this name
+   * 
+   * @param name
+   * @param td
+   * @return
+   */
+  public FeatureDescription getFeatureFromTypeDescription(String name, TypeDescription td) {
+    FeatureDescription[] fds = td.getFeatures();
+    if (fds == null)
+      return null;
+    for (int i = 0; i < fds.length; i++) {
+      if (name.equals(fds[i].getName()))
+        return fds[i];
+    }
+    return null;
+  }
+
+  public AllowedValue getAllowedValue(String value, TypeDescription td) {
+    AllowedValue[] avs = td.getAllowedValues();
+    if (null == avs)
+      return null;
+    for (int i = 0; i < avs.length; i++) {
+      if (value.equals(avs[i].getString()))
+        return avs[i];
+    }
+    return null;
+  }
+
+  // ********************************
+  // * Local Getters
+  // ********************************
+
+  protected TypeDescription getLocalTypeDefinition(TypeDescription td) {
+    TypeSystemDescription tsdLocal = getTypeSystemDescription();
+    if (null == tsdLocal)
+      return null;
+    return tsdLocal.getType(td.getName());
+  }
+
+  protected FeatureDescription getLocalFeatureDefinition(TypeDescription td, FeatureDescription fd) {
+    return getLocalFeatureDefinition(td, fd.getName());
+  }
+
+  protected FeatureDescription getLocalFeatureDefinition(TypeDescription td, String featureName) {
+    TypeDescription localTd = getLocalTypeDefinition(td);
+    if (null == localTd)
+      return null;
+    return getFeatureFromTypeDescription(featureName, localTd);
+  }
+
+  protected AllowedValue getLocalAllowedValue(TypeDescription td, AllowedValue unchangedAv) {
+    TypeDescription localTd = getLocalTypeDefinition(td);
+    if (null == localTd)
+      return null;
+    return getAllowedValue(unchangedAv.getString(), localTd);
+  }
+
+  // ********************************
+  // * Built-in Getters
+  // * used to do GUI "merge" with built-in things
+  // ********************************
+  public TypeDescription getBuiltInTypeDescription(TypeDescription td) {
+    return (TypeDescription) BuiltInTypes.typeDescriptions.get(td.getName());
+  }
+
+  // ********************************
+  // * Local Testers
+  // ********************************
+  protected boolean isLocalType(TypeDescription td) {
+    return (null != getLocalTypeDefinition(td));
+  }
+
+  protected boolean isLocalType(String typeName) {
+    return null != editor.getTypeSystemDescription().getType(typeName);
+  }
+
+  protected boolean isLocalFeature(String featureName, TypeDescription td) {
+    return (null != getLocalFeatureDefinition(td, featureName));
+  }
+
+  protected boolean isLocalAllowedValue(String avString, TypeDescription td) {
+    TypeDescription localTd = getLocalTypeDefinition(td);
+    if (null == localTd)
+      return false;
+    return Utility.arrayContains(localTd.getAllowedValues(), avString);
+  }
+
+  // ********************************
+  // * Imported Testers
+  // ********************************
+
+  public boolean isImportedType(String typeName) {
+    return null != editor.getImportedTypeSystemDesription().getType(typeName);
+  }
+
+  protected boolean isImportedType(TypeDescription td) {
+    return null != editor.getImportedTypeSystemDesription().getType(td.getName());
+  }
+
+  protected boolean isImportedFeature(String name, TypeDescription td) {
+    TypeDescription importedTd = editor.getImportedTypeSystemDesription().getType(td.getName());
+    if (null == importedTd)
+      return false;
+    return null != getFeatureFromTypeDescription(name, importedTd);
+  }
+
+  protected boolean isImportedAllowedValue(TypeDescription td, AllowedValue av) {
+    TypeDescription importedTd = editor.getImportedTypeSystemDesription().getType(td.getName());
+    if (null == importedTd)
+      return false;
+    return null != getAllowedValue(av.getString(), importedTd);
+  }
+
+  // ********************************
+  // * Built-in Testers
+  // ********************************
+  protected boolean isBuiltInType(TypeDescription td) {
+    return null != getBuiltInTypeDescription(td);
+  }
+
+  protected boolean isBuiltInType(String typeName) {
+    return null != BuiltInTypes.typeDescriptions.get(typeName);
+  }
+
+  protected boolean isBuiltInFeature(String name, TypeDescription td) {
+    TypeDescription builtInTd = (TypeDescription) BuiltInTypes.typeDescriptions.get(td.getName());
+    if (null == builtInTd)
+      return false;
+    return null != getFeatureFromTypeDescription(name, builtInTd);
+  }
+
+}
diff --git a/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/AbstractSection.java b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/AbstractSection.java
new file mode 100644
index 0000000..2d8a9c6
--- /dev/null
+++ b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/AbstractSection.java
@@ -0,0 +1,1595 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS 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.taeconfigurator.editors.ui;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.text.MessageFormat;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+import java.util.StringTokenizer;
+import java.util.TreeSet;
+
+import org.apache.uima.UIMAFramework;
+import org.apache.uima.analysis_engine.AnalysisEngine;
+import org.apache.uima.analysis_engine.TypeOrFeature;
+import org.apache.uima.analysis_engine.metadata.AnalysisEngineMetaData;
+import org.apache.uima.analysis_engine.metadata.FlowControllerDeclaration;
+import org.apache.uima.analysis_engine.metadata.SofaMapping;
+import org.apache.uima.cas.CAS;
+import org.apache.uima.resource.ExternalResourceDependency;
+import org.apache.uima.resource.ExternalResourceDescription;
+import org.apache.uima.resource.ResourceCreationSpecifier;
+import org.apache.uima.resource.ResourceInitializationException;
+import org.apache.uima.resource.ResourceManager;
+import org.apache.uima.resource.ResourceSpecifier;
+import org.apache.uima.resource.URISpecifier;
+import org.apache.uima.resource.metadata.Capability;
+import org.apache.uima.resource.metadata.ConfigurationGroup;
+import org.apache.uima.resource.metadata.ConfigurationParameter;
+import org.apache.uima.resource.metadata.ConfigurationParameterDeclarations;
+import org.apache.uima.resource.metadata.ExternalResourceBinding;
+import org.apache.uima.resource.metadata.FeatureDescription;
+import org.apache.uima.resource.metadata.FsIndexCollection;
+import org.apache.uima.resource.metadata.FsIndexDescription;
+import org.apache.uima.resource.metadata.FsIndexKeyDescription;
+import org.apache.uima.resource.metadata.Import;
+import org.apache.uima.resource.metadata.NameValuePair;
+import org.apache.uima.resource.metadata.OperationalProperties;
+import org.apache.uima.resource.metadata.ProcessingResourceMetaData;
+import org.apache.uima.resource.metadata.ResourceManagerConfiguration;
+import org.apache.uima.resource.metadata.ResourceMetaData;
+import org.apache.uima.resource.metadata.TypeDescription;
+import org.apache.uima.resource.metadata.TypePriorities;
+import org.apache.uima.resource.metadata.TypePriorityList;
+import org.apache.uima.resource.metadata.TypeSystemDescription;
+import org.apache.uima.resource.metadata.impl.Import_impl;
+import org.apache.uima.taeconfigurator.InternalErrorCDE;
+import org.apache.uima.taeconfigurator.Messages;
+import org.apache.uima.taeconfigurator.StandardStrings;
+import org.apache.uima.taeconfigurator.editors.MultiPageEditor;
+import org.apache.uima.taeconfigurator.editors.MultiPageEditorContributor;
+import org.apache.uima.taeconfigurator.model.BuiltInTypes;
+import org.apache.uima.util.InvalidXMLException;
+import org.apache.uima.util.XMLInputSource;
+import org.apache.uima.util.XMLParser;
+import org.apache.uima.util.XMLizable;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.window.Window;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.CCombo;
+import org.eclipse.swt.custom.PopupList;
+import org.eclipse.swt.custom.TableTree;
+import org.eclipse.swt.custom.TableTreeItem;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Listener;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.TableColumn;
+import org.eclipse.swt.widgets.TableItem;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.swt.widgets.Tree;
+import org.eclipse.swt.widgets.TreeItem;
+import org.eclipse.swt.widgets.Widget;
+import org.eclipse.ui.forms.AbstractFormPart;
+import org.eclipse.ui.forms.IFormPart;
+import org.eclipse.ui.forms.IManagedForm;
+import org.eclipse.ui.forms.SectionPart;
+import org.eclipse.ui.forms.widgets.ExpandableComposite;
+import org.eclipse.ui.forms.widgets.FormToolkit;
+import org.eclipse.ui.forms.widgets.Section;
+
+public abstract class AbstractSection extends SectionPart /* extends FormSection */
+implements Listener, StandardStrings {
+
+  protected FormToolkit toolkit;
+
+  public MultiPageEditor editor;
+
+  public FormToolkit getToolkit() {
+    return toolkit;
+  }
+
+  public final static String IMPORTABLE_PART_CONTEXT = "ipc";
+
+  public final static String PLUGIN_ID = "org.apache.uima.desceditor";
+
+  public final static boolean SELECTED = true;
+
+  public final static boolean NOT_SELECTED = false;
+
+  public final static boolean ENABLED = true;
+
+  public final static boolean EQUAL_WIDTH = true;
+
+  public final static TreeItem[] treeItemArray0 = new TreeItem[0];
+
+  public final static ConfigurationGroup[] configurationGroup0 = new ConfigurationGroup[0];
+
+  public final static ConfigurationParameter[] configurationParameter0 = new ConfigurationParameter[0];
+
+  public final static Capability[] capabilityArray0 = new Capability[0];
+
+  public final static FeatureDescription[] featureDescriptionArray0 = new FeatureDescription[0];
+
+  public final static SofaMapping[] sofaMapping0 = new SofaMapping[0];
+
+  public final static FsIndexDescription[] fsIndexDescription0 = new FsIndexDescription[0];
+
+  public final static ExternalResourceBinding[] externalResourceBinding0 = new ExternalResourceBinding[0];
+
+  public final static ExternalResourceDescription[] externalResourceDescription0 = new ExternalResourceDescription[0];
+
+  public final static TypeDescription[] typeDescription0 = new TypeDescription[0];
+
+  public final static TypePriorityList[] typePriorityList0 = new TypePriorityList[0];
+
+  protected int initialFormWidth; // width of the form before putting controls in it
+
+  public AbstractSection(MultiPageEditor aEditor, Composite parent, String headerText,
+          String description) {
+    super(parent, aEditor.getToolkit(), ((null != description) ? Section.DESCRIPTION : 0)
+            | Section.TWISTIE | Section.EXPANDED);
+    toolkit = aEditor.getToolkit();
+    getSection().setText(headerText);
+    getSection().setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+    toolkit.createCompositeSeparator(getSection());
+    if (null != description)
+      getSection().setDescription(description);
+    editor = aEditor;
+  }
+
+  public void initialize(IManagedForm form) {
+    super.initialize(form);
+    getSection().setLayoutData(new GridData(GridData.FILL_BOTH));
+  }
+
+  // **************************************************
+  // * Subclasses need to implement these methods
+  // **************************************************
+
+  public abstract void enable();
+
+  // **************************************************
+  // * convenience methods
+  // **************************************************
+  protected void setFileDirty() {
+    editor.setFileDirty();
+  }
+
+  // **************************************************
+  // * Creating Composites
+  // **************************************************
+  public Composite newComposite(Composite parent) {
+    return newNcolumnComposite(parent, 1);
+  }
+
+  public Composite new2ColumnComposite(Composite parent) {
+    return newNcolumnComposite(parent, 2);
+  }
+
+  public Composite new3ColumnComposite(Composite parent) {
+    return newNcolumnComposite(parent, 3);
+  }
+
+  public Composite new4ColumnComposite(Composite parent) {
+    return newNcolumnComposite(parent, 4);
+  }
+
+  public Composite newNcolumnComposite(Composite parent, int cols) {
+    Composite composite = toolkit.createComposite(parent);
+    if (parent instanceof ExpandableComposite)
+      ((ExpandableComposite) parent).setClient(composite);
+    GridLayout layout = new GridLayout(cols, !EQUAL_WIDTH);
+    layout.marginHeight = 0;
+    layout.marginWidth = 0;
+    composite.setLayout(layout);
+    composite.setLayoutData(new GridData(GridData.FILL_BOTH));
+    return composite;
+  }
+
+  public void setMargins(Composite composite, int height, int width) {
+    GridLayout g = (GridLayout) composite.getLayout();
+    g.marginHeight = height;
+    g.marginWidth = width;
+  }
+
+  public void enableBorders(Composite composite) {
+    GridLayout g = (GridLayout) composite.getLayout();
+    if (g.marginHeight < 2)
+      g.marginHeight = 2;
+    if (g.marginWidth < 1)
+      g.marginWidth = 1;
+  }
+
+  // **************************************************
+  // * Special Composites to hold buttons
+  // **************************************************
+  final static public int VERTICAL_BUTTONS = 1;
+
+  final static public int HORIZONTAL_BUTTONS = 2;
+
+  public Composite newButtonContainer(Composite parent) {
+    return newButtonContainer(parent, VERTICAL_BUTTONS, 0);
+  }
+
+  public Composite newButtonContainer(Composite parent, int style, int widthMin) {
+    Composite buttonContainer = toolkit.createComposite(parent);
+    GridLayout gl = new GridLayout();
+    GridData gd = null;
+    switch (style) {
+      case VERTICAL_BUTTONS:
+        gd = new GridData(GridData.VERTICAL_ALIGN_BEGINNING);
+        gd.horizontalAlignment = SWT.FILL;
+        // gd.widthHint = widthMin; // 70, 100
+        break;
+      case HORIZONTAL_BUTTONS:
+        gl.marginWidth = 20;
+        gl.numColumns = 2;
+        gl.makeColumnsEqualWidth = true;
+        gd = new GridData(GridData.HORIZONTAL_ALIGN_CENTER);
+        gd.widthHint = widthMin; // 180
+    }
+
+    buttonContainer.setLayout(gl);
+    buttonContainer.setLayoutData(gd);
+    return buttonContainer;
+  }
+
+  // public Composite newLabeledButtonContainer(Composite parent, int cellsToSpan, int nbrCols) {
+  // Composite buttonContainer = toolkit.createComposite(parent);
+  // GridLayout gl = new GridLayout();
+  // GridData gd = null;
+  // gl.marginWidth = 0;
+  // gl.numColumns = nbrCols;
+  // gl.makeColumnsEqualWidth = false;
+  // gd = new GridData();
+  // gd.horizontalSpan = cellsToSpan;
+  // buttonContainer.setLayout(gl);
+  // buttonContainer.setLayoutData(gd);
+  // return buttonContainer;
+  // }
+
+  // **************************************************
+  // * Getting internationalized text
+  // **************************************************
+
+  // **************************************************
+  // * Widgets
+  // **************************************************
+
+  protected Text newLabeledTextField(Composite parent, String label, String tip) {
+    return newLabeledTextField(parent, label, tip, SWT.NONE);
+  }
+
+  protected Text newLabeledTextField(Composite parent, String labelKey, String textToolTip,
+          int style) {
+    enableBorders(parent);
+    Label label = toolkit.createLabel(parent, labelKey);
+    label.setToolTipText(textToolTip);
+    if ((style & SWT.V_SCROLL) == SWT.V_SCROLL) {
+      label.setLayoutData(new GridData(GridData.VERTICAL_ALIGN_BEGINNING));
+    }
+    return newTextWithTip(parent, "", style, textToolTip); //$NON-NLS-1$
+  }
+
+  protected Text newTextWithTip(Composite parent, String initialTxt, String tip) {
+    return newTextWithTip(parent, initialTxt, SWT.NONE, tip);
+  }
+
+  protected Text newTextWithTip(Composite parent, String text, int style, String tip) {
+    Text t = toolkit.createText(parent, text, style);
+    t.setToolTipText(tip);
+    if ((style & SWT.V_SCROLL) == SWT.V_SCROLL) {
+      t.setLayoutData(new GridData(GridData.FILL_BOTH));
+    } else {
+      t.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+    }
+    addListenerForPastableWidget(t);
+    return t;
+  }
+
+  public Label newLabelWithData(Composite parent, String text) {
+    return newLabelWithTip(parent, text, ""); //$NON-NLS-1$
+  }
+
+  public Label newLabelWithTip(Composite parent, String text, String tip) {
+    return newLabelWithTip(parent, text, tip, SWT.NULL);
+  }
+
+  public Label newUnUpdatableTextWithTip(Composite parent, String text, String tip) {
+    Label label = newLabelWithTip(parent, text, tip, SWT.BORDER);
+    label.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+    return label;
+  }
+
+  public Label newLabelWithTip(Composite parent, String text, String tip, int style) {
+    Label t = toolkit.createLabel(parent, text, style);
+    if ((tip != null) && (tip.length()) > 0)
+      t.setToolTipText(tip);
+    return t;
+  }
+
+  protected CCombo newLabeledCComboWithTip(Composite parent, String labelKey, String tip) {
+    newLabelWithTip(parent, labelKey, tip);
+    return newCComboWithTip(parent, tip);
+  }
+
+  protected CCombo newCComboWithTip(Composite parent, String tip) {
+    CCombo ccombo = new CCombo(parent, SWT.FLAT | SWT.READ_ONLY);
+    toolkit.adapt(ccombo, false, false);
+    ccombo.setToolTipText(tip);
+    ccombo.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING));
+    ccombo.addListener(SWT.Selection, this);
+    return ccombo;
+  }
+
+  protected Text newDescriptionTextBox(Composite parent, String tip) {
+    return newLabeledTextField(parent, S_DESCRIPTION, tip, SWT.MULTI | SWT.WRAP | SWT.V_SCROLL);
+  }
+
+  // **************************************************
+  // * Widgets Buttons
+  // **************************************************
+  public Button newRadioButton(Composite parent, String label, String toolTip, boolean selected) {
+    Button button = toolkit.createButton(parent, label, SWT.RADIO);
+    button.setToolTipText(toolTip);
+    button.setSelection(selected);
+    button.addListener(SWT.Selection, this);
+    return button;
+  }
+
+  /**
+   * add pushbutton to container, set enabled, add listener for it
+   * 
+   * @param parent
+   * @param root
+   * @return
+   */
+  public Button newPushButton(Composite parent, String label, String tip) {
+    return newPushButton(parent, label, tip, true); // set enabled by default
+  }
+
+  /**
+   * Add a push button to a container, add a listener for it too
+   * 
+   * @param parent
+   * @param root
+   * @param enabled
+   * @return
+   */
+  public Button newPushButton(Composite parent, String label, String tip, boolean enabled) {
+    return newPushButton(parent, label, tip, enabled, 0);
+  }
+
+  public Button newPushButton(Composite parent, String label, String tip, boolean enabled, int style) {
+    Button button = toolkit.createButton(parent, label, SWT.PUSH | style);
+    GridData gd = new GridData(GridData.VERTICAL_ALIGN_BEGINNING | GridData.FILL_HORIZONTAL);
+    button.setLayoutData(gd);
+    button.pack(false);
+    button.setToolTipText(tip);
+    button.setEnabled(enabled);
+    button.addListener(SWT.Selection, this);
+    Point buttonSize = button.getSize();
+    gd.heightHint = buttonSize.y - 2;
+    gd.widthHint = buttonSize.x - 2;
+    return button;
+  }
+
+  public Button newCheckBox(Composite parent, String label, String tip) {
+    Button button = toolkit.createButton(parent, label, SWT.CHECK);
+    button.setLayoutData(new GridData(GridData.VERTICAL_ALIGN_BEGINNING
+            | GridData.HORIZONTAL_ALIGN_FILL));
+    button.pack();
+    button.setToolTipText(tip);
+    button.addListener(SWT.Selection, this);
+    return button;
+  }
+
+  public static void spacer(Composite container) {
+    Label label = new Label(container, SWT.NONE);
+    label.setVisible(false);
+    // toolkit.createLabel(container, " ");
+  }
+
+  // **************************************************
+  // * Tables
+  // **************************************************
+  final public static int NO_MIN_HEIGHT = -1;
+
+  final public static int NOTHING_SELECTED = -1;
+
+  // these flags can be or-ed together
+  final public static int LINES_VISIBLE = 1;
+
+  final public static int HEADER_VISIBLE = 2;
+
+  final public static int WIDTH_NOT_SPECIFIED = 0;
+
+  protected Table newTable(Composite parent) {
+    return newTable(parent, SWT.FULL_SELECTION, NO_MIN_HEIGHT, 0);
+  }
+
+  protected Table newTable(Composite parent, int style, int minHeight) {
+    return newTable(parent, style, minHeight, 0);
+  }
+
+  protected Table newTable(Composite parent, int style, int minHeight, int flags) {
+    Table table = toolkit.createTable(parent, style);
+    GridData gd = new GridData(GridData.FILL_BOTH);
+    if (minHeight != NO_MIN_HEIGHT)
+      gd.heightHint = minHeight;
+    table.setLayoutData(gd);
+
+    table.setLinesVisible(0 != (flags & LINES_VISIBLE));
+    table.setHeaderVisible(0 != (flags & HEADER_VISIBLE));
+    table.addListener(SWT.Selection, this);
+    table.addListener(SWT.KeyUp, this); // delete key
+    return table;
+  }
+
+  protected Tree newTree(Composite parent) {
+    Tree tree = toolkit.createTree(parent, SWT.SINGLE);
+    tree.setLayoutData(new GridData(GridData.FILL_BOTH));
+    tree.addListener(SWT.Selection, this);
+    tree.addListener(SWT.KeyUp, this);
+    return tree;
+  }
+
+  protected TreeItem getPreviousSelection(TreeItem[] items, TreeItem nextItem) {
+    TreeItem prevItem = nextItem.getParentItem();
+    for (int i = 0; i < items.length; i++) {
+      if (nextItem == items[i])
+        return prevItem;
+      prevItem = items[i];
+    }
+    return prevItem;
+  }
+
+  protected int getItemIndex(TreeItem[] items, TreeItem item) {
+    for (int i = 0; i < items.length; i++) {
+      if (items[i] == item)
+        return i;
+    }
+    return -1;
+  }
+
+  /**
+   * @param parent
+   * @param style
+   *          SWT.SINGLE SWT.MULTI SWT.CHECK SWT.FULL_SELECTION
+   * @return
+   */
+  protected TableTree newTableTree(Composite parent, int style) {
+    TableTree tt = new TableTree(parent, style);
+    tt.setLayoutData(new GridData(GridData.FILL_BOTH));
+    toolkit.adapt(tt, true, true);
+    tt.addListener(SWT.Selection, this);
+    tt.getTable().addListener(SWT.KeyUp, this); // for delete key
+    tt.getTable().addListener(SWT.MouseDoubleClick, this); // for edit
+    tt.addListener(SWT.Expand, this);
+    tt.addListener(SWT.Collapse, this);
+    return tt;
+  }
+
+  public void packTable(Table table) {
+    TableColumn[] columns = table.getColumns();
+    for (int i = 0; i < columns.length; i++) {
+      columns[i].pack();
+    }
+  }
+
+  public static int getIndex(TableItem item) {
+    Table parent = item.getParent();
+    TableItem[] items = parent.getItems();
+    for (int i = items.length - 1; i >= 0; i--) {
+      if (items[i] == item)
+        return i;
+    }
+    throw new InternalErrorCDE("invalid state"); //$NON-NLS-1$
+  }
+
+  public static int getIndex(TableTreeItem item) {
+    TableTreeItem parent = item.getParentItem();
+    TableTreeItem[] items = (null == parent) ? item.getParent().getItems() : parent.getItems();
+    for (int i = items.length - 1; i >= 0; i--) {
+      if (items[i] == item)
+        return i;
+    }
+    throw new InternalErrorCDE("invalid state"); //$NON-NLS-1$
+  }
+
+  protected void removeChildren(TableTreeItem item) {
+    TableTreeItem[] items = item.getItems();
+    if (null != items)
+      for (int i = 0; i < items.length; i++) {
+        items[i].dispose();
+      }
+  }
+
+  protected void removeChildren(TreeItem item) {
+    TreeItem[] items = item.getItems();
+    if (null != items)
+      for (int i = 0; i < items.length; i++) {
+        items[i].dispose();
+      }
+  }
+
+  // **********************************
+  // * Table Column with header setting
+  // **********************************
+  protected TableColumn newTableColumn(Table table) {
+    return newTableColumn(table, ""); //$NON-NLS-1$
+  }
+
+  protected TableColumn newTableColumn(Table container, String header) {
+    return newTableColumn(container, 50, SWT.LEFT, header);
+  }
+
+  protected TableColumn newTableColumn(Table container, int width, int alignment, String header) {
+    TableColumn tc = new TableColumn(container, alignment);
+    if (header != null && (!header.equals(""))) { //$NON-NLS-1$
+      tc.setText(header);
+    }
+    tc.setWidth(width);
+    return tc;
+  }
+
+  protected TableColumn newTableColumn(Table container, int width) {
+    return newTableColumn(container, width, SWT.LEFT, Messages.getString("AbstractSection.0")); //$NON-NLS-1$
+  }
+
+  // **************************************************
+  // * Model Access
+  // **************************************************
+
+  public boolean isPrimitive() {
+    return editor.isPrimitive();
+  }
+
+  public boolean isAggregate() {
+    return editor.isAggregate();
+  }
+
+  public boolean isAeDescriptor() {
+    return editor.isAeDescriptor();
+  }
+
+  public boolean isTypeSystemDescriptor() {
+    return editor.isTypeSystemDescriptor();
+  }
+
+  public boolean isIndexDescriptor() {
+    return editor.isFsIndexCollection();
+  }
+
+  public boolean isTypePriorityDescriptor() {
+    return editor.isTypePriorityDescriptor();
+  }
+
+  public boolean isExtResAndBindingsDescriptor() {
+    return editor.isExtResAndBindingsDescriptor();
+  }
+
+  public boolean isCollectionReaderDescriptor() {
+    return editor.isCollectionReaderDescriptor();
+  }
+
+  public boolean isCasInitializerDescriptor() {
+    return editor.isCasInitializerDescriptor();
+  }
+
+  public boolean isCasConsumerDescriptor() {
+    return editor.isCasConsumerDescriptor();
+  }
+
+  public boolean isFlowControllerDescriptor() {
+    return editor.isFlowControllerDescriptor();
+  }
+
+  public boolean isLocalProcessingDescriptor() {
+    return editor.isLocalProcessingDescriptor();
+  }
+
+  public AnalysisEngineMetaData getAnalysisEngineMetaData() {
+    return editor.getAeDescription().getAnalysisEngineMetaData();
+  }
+
+  public FlowControllerDeclaration getFlowControllerDeclaration() {
+    return editor.getAeDescription().getFlowControllerDeclaration();
+  }
+
+  public void setFlowControllerDeclaration(FlowControllerDeclaration fcd) {
+    editor.getAeDescription().setFlowControllerDeclaration(fcd);
+  }
+
+  public OperationalProperties getOperationalProperties() {
+    return editor.getAeDescription().getAnalysisEngineMetaData().getOperationalProperties();
+  }
+
+  public SofaMapping[] getSofaMappings() {
+    SofaMapping[] sofaMappings = editor.getAeDescription().getSofaMappings();
+    return null == sofaMappings ? sofaMapping0 : sofaMappings;
+  }
+
+  public static SofaMapping[] getSofaMappings(MultiPageEditor pEditor) {
+    SofaMapping[] sofaMappings = pEditor.getAeDescription().getSofaMappings();
+    return null == sofaMappings ? sofaMapping0 : sofaMappings;
+  }
+
+  public Map getDelegateAnalysisEngineSpecifiersWithImports() {
+    return editor.getAeDescription().getDelegateAnalysisEngineSpecifiersWithImports();
+  }
+
+  public Capability[] getCapabilities() {
+    Capability[] c = getAnalysisEngineMetaData().getCapabilities();
+    if (null == c)
+      return capabilityArray0;
+    return c;
+  }
+
+  protected TypeSystemDescription getMergedTypeSystemDescription() {
+    return editor.getMergedTypeSystemDescription();
+  }
+
+  protected TypeSystemDescription getTypeSystemDescription() {
+    return editor.getTypeSystemDescription();
+  }
+
+  protected TypePriorities getTypePriorities() {
+    TypePriorities tps = getAnalysisEngineMetaData().getTypePriorities();
+    if (null == tps) {
+      getAnalysisEngineMetaData().setTypePriorities(
+              tps = UIMAFramework.getResourceSpecifierFactory().createTypePriorities());
+    }
+    return tps;
+  }
+
+  public final static String[] stringArray0 = new String[0];
+
+  public final static ConfigurationParameter[] configurationParameterArray0 = new ConfigurationParameter[0];
+
+  public final static ConfigurationGroup[] configurationGroupArray0 = new ConfigurationGroup[0];
+
+  public final static NameValuePair[] nameValuePairArray0 = new NameValuePair[0];
+
+  public String[] getAvailableTypeNames(Set excluded) {
+    Map allTypes = editor.allTypes.get();
+    Collection availableTypes = new ArrayList();
+    Iterator it = allTypes.keySet().iterator();
+    while (it.hasNext()) {
+      String item = (String) it.next();
+      if (!excluded.contains(item))
+        availableTypes.add(item);
+    }
+    return (String[]) availableTypes.toArray(stringArray0);
+  }
+
+  // ************
+  // * Parameters
+  // ************
+  public boolean isParmGroup() {
+    ConfigurationParameterDeclarations lcpd = getAnalysisEngineMetaData()
+            .getConfigurationParameterDeclarations();
+    return (lcpd.getCommonParameters() != null && lcpd.getCommonParameters().length > 0)
+            || (lcpd.getConfigurationGroups() != null && lcpd.getConfigurationGroups().length > 0);
+  }
+
+  public ConfigurationParameterDeclarations getConfigurationParameterDeclarations() {
+    return editor.getAeDescription().getAnalysisEngineMetaData()
+            .getConfigurationParameterDeclarations();
+  }
+
+  // **************************************************
+  // * Common GUI state access
+  // **************************************************
+
+  public ResourceManagerConfiguration getResourceManagerConfiguration() {
+    ResourceManagerConfiguration rmc = editor.getAeDescription().getResourceManagerConfiguration();
+    if (null == rmc) {
+      rmc = UIMAFramework.getResourceSpecifierFactory().createResourceManagerConfiguration();
+      editor.getAeDescription().setResourceManagerConfiguration(rmc);
+    }
+    return rmc;
+  }
+
+  public ExternalResourceDependency[] getExternalResourceDependencies() {
+    ExternalResourceDependency[] erd = editor.getAeDescription().getExternalResourceDependencies();
+    if (null == erd) {
+      return new ExternalResourceDependency[0];
+    }
+    return erd;
+  }
+
+  public ExternalResourceBinding[] getExternalResourceBindings() {
+    ExternalResourceBinding[] erb = getResourceManagerConfiguration().getExternalResourceBindings();
+    if (null == erb)
+      getResourceManagerConfiguration().setExternalResourceBindings(
+              erb = new ExternalResourceBinding[0]);
+    return erb;
+  }
+
+  public ExternalResourceDescription[] getExternalResources() {
+    ExternalResourceDescription[] erd = getResourceManagerConfiguration().getExternalResources();
+    if (null == erd)
+      getResourceManagerConfiguration().setExternalResources(
+              erd = new ExternalResourceDescription[0]);
+    return erd;
+  }
+
+  // **************************************************
+  // * Common Listener things
+  // **************************************************
+  protected void addListenerForPastableWidget(Widget w) {
+    w.addListener(SWT.KeyUp, this);
+    w.addListener(SWT.MouseUp, this); // for paste operation
+  }
+
+  // **************************************************
+  // * Common Actions in Handlers
+  // **************************************************
+
+  protected boolean valueChanged;
+
+  protected String setValueChanged(String newValue, String oldValue) {
+    if (null == newValue)
+      valueChanged = valueChanged || (null == oldValue);
+    else if (!newValue.equals(oldValue))
+      valueChanged = true;
+    return newValue;
+  }
+
+  protected int setValueChangedInt(int newValue, int oldValue) {
+    if (newValue != oldValue)
+      valueChanged = true;
+    return newValue;
+  }
+
+  protected boolean setValueChangedBoolean(boolean newValue, boolean oldValue) {
+    if (newValue != oldValue)
+      valueChanged = true;
+    return newValue;
+  }
+
+  protected Boolean setValueChangedCapitalBoolean(Boolean newValue, Boolean oldValue) {
+    if (null == newValue) {
+      valueChanged |= null != oldValue;
+    } else if (null == oldValue) {
+      valueChanged = true;
+    } else if (newValue.booleanValue() != oldValue.booleanValue())
+      valueChanged = true;
+    return newValue;
+  }
+
+  protected FsIndexKeyDescription[] setValueChangedKeys(FsIndexKeyDescription[] newKeys,
+          FsIndexKeyDescription[] oldKeys) {
+    if (valueChanged) {
+    } else if (oldKeys == null && newKeys == null) {
+    } else if (oldKeys != null && Arrays.equals(oldKeys, newKeys)) {
+    } else if (Arrays.equals(newKeys, oldKeys)) // newKeys must be non-null here
+    {
+    } else
+      valueChanged = true;
+
+    return newKeys;
+  }
+
+  protected boolean isValidAe() {
+    if (editor.isValidAE(editor.getAeDescription()))
+      return true;
+    return false;
+  }
+
+  protected void revertTypeSystem(TypeSystemDescription tsd) {
+    try {
+      editor.setTypeSystemDescription(tsd);
+    } catch (ResourceInitializationException e) {
+    }
+  }
+
+  protected void revertMsg(String msgTitle, String msgTxt, String exceptionMessage) {
+    Utility.popMessage(msgTitle, msgTxt + "\r\n" + exceptionMessage, //$NON-NLS-1$
+            MessageDialog.ERROR);
+    return;
+  }
+
+  /**
+   * 
+   * @param msg
+   * @param msgDetails
+   * @return true to revert, false to continue
+   */
+  public static boolean revertOrContinue(String msg, String msgDetails) {
+    if (Window.CANCEL == Utility.popMessage(msg, msgDetails
+            + "\nDo you want to continue, or Abort the last action?", MessageDialog.QUESTION,
+            new String[] { "Continue", "Abort" }))
+      return true; // for closing the window or hitting Undo
+    return false;
+  }
+
+  public void markStale(IFormPart section) {
+    if (section != null)
+      ((AbstractFormPart) section).markStale();
+  }
+
+  protected void markRestOfPageStale(IManagedForm mform, AbstractSection section) {
+    if (null == mform)
+      return;
+    IFormPart[] parts = mform.getParts();
+    for (int i = 0; i < parts.length; i++) {
+      markStaleIfDifferent(section, parts[i]);
+    }
+  }
+
+  protected void markStaleIfDifferent(IFormPart thisOne, IFormPart otherOne) {
+    if (thisOne != otherOne)
+      markStale(otherOne);
+  }
+
+  protected String multiLineFix(String s) {
+    if (null == s)
+      return null;
+    return s.replaceAll("\\r\\n", "\n"); //$NON-NLS-1$ //$NON-NLS-2$
+  }
+
+  /*************************************************************************************************
+   * Augment arrays (make new array, add one item to it at end
+   * *********************************************************
+   */
+
+  public String[] stringArrayAdd(String[] a, String s) {
+    if (a == null)
+      return new String[] { s };
+
+    String[] newA = new String[a.length + 1];
+    System.arraycopy(a, 0, newA, 0, a.length);
+    newA[newA.length - 1] = s;
+    return newA;
+  }
+
+  public String[] stringArrayRemove(String[] a, String s) {
+    String[] result = new String[a.length - 1];
+    for (int i = 0, j = 0; i < a.length; i++) {
+      if (!a[i].equals(s))
+        result[j++] = a[i];
+    }
+    return result;
+  }
+
+  public TypeOrFeature[] typeOrFeatureArrayAdd(TypeOrFeature[] a, TypeOrFeature item) {
+    if (null == a)
+      return new TypeOrFeature[] { item };
+
+    TypeOrFeature[] result = new TypeOrFeature[a.length + 1];
+    System.arraycopy(a, 0, result, 0, a.length);
+    result[result.length - 1] = item;
+    return result;
+  }
+
+  public TypeOrFeature[] typeOrFeatureArrayRemove(TypeOrFeature[] a, TypeOrFeature item) {
+    TypeOrFeature[] result = new TypeOrFeature[a.length - 1];
+    for (int i = 0, j = 0; i < a.length; i++) {
+      if (a[i] != item)
+        result[j++] = a[i];
+    }
+    return result;
+  }
+
+  public TypeOrFeature[] typeOrFeatureArrayRemove(TypeOrFeature[] a, String s) {
+    TypeOrFeature[] result = new TypeOrFeature[a.length - 1];
+    for (int i = 0, j = 0; i < a.length; i++) {
+      if (!a[i].getName().equals(s)) {
+        // debug
+        if (j == a.length - 1)
+          throw new InternalErrorCDE("feature or type not found: looking for " + s);
+        result[j++] = a[i];
+      }
+    }
+    return result;
+  }
+
+  public static TypeOrFeature getTypeOrFeature(TypeOrFeature[] a, String name) {
+    if (null == a)
+      return null;
+    for (int i = 0; i < a.length; i++) {
+      if (a[i].getName().equals(name))
+        return a[i];
+    }
+    return null;
+  }
+
+  // tool tips seem to require no blanks following /n on Windows.
+  protected static String parseToFitInToolTips(String text) {
+    if (null == text)
+      return "";
+    StringBuffer buffer = new StringBuffer();
+    final int MAGIC_LENGTH = 65;
+    StringTokenizer tokenizer = new StringTokenizer(text);
+    int lengthAccumulator = 0;
+    while (tokenizer.hasMoreTokens()) {
+      if (lengthAccumulator > 0) {
+        buffer.append(' ');
+      }
+      String nextToken = tokenizer.nextToken();
+      buffer.append(nextToken);
+      lengthAccumulator += (nextToken.length() + 1);
+      if (lengthAccumulator > MAGIC_LENGTH && tokenizer.hasMoreTokens()) {
+        // this is to avoid a final blank line
+        buffer.append("\n"); //$NON-NLS-1$
+        lengthAccumulator = 0;
+      }
+    }
+    return new String(buffer);
+  }
+
+  public String formatName(String name) {
+    if (null == name)
+      return ""; //$NON-NLS-1$
+    if (MultiPageEditorContributor.getUseQualifiedTypes())
+      return name;
+    return getShortName(name);
+  }
+
+  public static String getShortName(String name) {
+    if (null == name)
+      return ""; //$NON-NLS-1$
+    int i = name.lastIndexOf('.');
+    if (i < 0)
+      return name;
+    return name.substring(i + 1);
+  }
+
+  public static String getShortFeatureName(String name) {
+    return (name.substring(name.indexOf(':') + 1));
+  }
+
+  public static String getTypeFromFullFeatureName(String name) {
+    return (name.substring(0, name.indexOf(':')));
+  }
+
+  public static String getNameSpace(String name) {
+    int i = name.lastIndexOf('.');
+    if (i < 0)
+      return "";
+    return (name.substring(0, i));
+  }
+
+  /**
+   * gets a feature description for a type, including supertypes.
+   * 
+   * @param td
+   * @param featureName
+   * @return
+   */
+  public FeatureDescription getFeature(TypeDescription td, String featureName) {
+    FeatureDescription[] features = td.getFeatures();
+    String supertypeName;
+    if (null != features)
+      for (int i = 0; i < features.length; i++) {
+        if (featureName.equals(features[i].getName()))
+          return features[i];
+      }
+    if (null != (supertypeName = td.getSupertypeName()))
+      if (!CAS.TYPE_NAME_TOP.equals(supertypeName)) { //$NON-NLS-1$
+        TypeDescription supertype = getMergedTypeSystemDescription().getType(supertypeName);
+        if (null == supertype)
+          supertype = (TypeDescription) BuiltInTypes.typeDescriptions.get(supertypeName);
+        return getFeature(supertype, featureName);
+      }
+    return null;
+  }
+
+  // means is this range allowed in the UIMA Index Spec as a Key
+  public static boolean isIndexableRange(String rangeName) {
+    return CAS.TYPE_NAME_BYTE.equals(rangeName) || CAS.TYPE_NAME_SHORT.equals(rangeName)
+            || CAS.TYPE_NAME_INTEGER.equals(rangeName) || CAS.TYPE_NAME_LONG.equals(rangeName)
+            || CAS.TYPE_NAME_FLOAT.equals(rangeName) || CAS.TYPE_NAME_DOUBLE.equals(rangeName)
+            || CAS.TYPE_NAME_STRING.equals(rangeName);
+  }
+
+  public static void setToolTipText(Control w, String text) {
+    if (null != text)
+      w.setToolTipText(parseToFitInToolTips(text));
+  }
+
+  public static String maybeShortenFileName(String filePathName) {
+    if (filePathName.length() > 65) {
+      String pathName = filePathName.replace('\\', '/');
+      int nLoc = pathName.lastIndexOf('/');
+      return filePathName.substring(0, 61 - (pathName.length() - nLoc)) + ".../"
+              + filePathName.substring(nLoc + 1);
+    }
+    return filePathName;
+  }
+
+  public static void swapTableTreeItems(TableTreeItem itemBelow, int newSelection) {
+    TableTreeItem parent = itemBelow.getParentItem();
+    if (null == parent)
+      throw new InternalErrorCDE("invalid arg");
+    int i = getIndex(itemBelow);
+    TableTreeItem itemAbove = parent.getItems()[i - 1];
+    TableTreeItem newItemAbove = new TableTreeItem(parent, SWT.NONE, i - 1);
+    copyTableTreeItem(newItemAbove, itemBelow);
+    TableTreeItem newItemBelow = new TableTreeItem(parent, SWT.NONE, i);
+    copyTableTreeItem(newItemBelow, itemAbove);
+    itemAbove.dispose();
+    itemBelow.dispose();
+    parent.getParent().setSelection(new TableTreeItem[] { parent.getItems()[newSelection] });
+  }
+
+  public static void copyTableTreeItem(TableTreeItem target, TableTreeItem source) {
+    int columnCount = target.getParent().getTable().getColumnCount();
+    for (int i = 0; i < columnCount; i++) {
+      String text = source.getText(i);
+      if (null != text)
+        target.setText(i, text);
+    }
+    target.setData(source.getData());
+  }
+
+  public static void swapIndexKeys(TableTreeItem itemBelow, int newSelection) {
+    TableTreeItem parent = itemBelow.getParentItem();
+    FsIndexDescription fsid = getFsIndexDescriptionFromTableTreeItem(parent);
+    int i = getIndex(itemBelow);
+    FsIndexKeyDescription[] keys = fsid.getKeys();
+    FsIndexKeyDescription temp = keys[i];
+    keys[i] = keys[i - 1];
+    keys[i - 1] = temp;
+
+    // swap items in the GUI
+    swapTableTreeItems(itemBelow, newSelection);
+  }
+
+  public static void swapTableItems(TableItem itemBelow, int newSelection) {
+    Table parent = itemBelow.getParent();
+    int i = getIndex(itemBelow);
+    TableItem itemAbove = parent.getItems()[i - 1];
+    TableItem newItemAbove = new TableItem(parent, SWT.NONE, i - 1);
+    copyTableItem(newItemAbove, itemBelow);
+    TableItem newItemBelow = new TableItem(parent, SWT.NONE, i);
+    copyTableItem(newItemBelow, itemAbove);
+    itemAbove.dispose();
+    itemBelow.dispose();
+    parent.setSelection(newSelection);
+  }
+
+  public static void copyTableItem(TableItem target, TableItem source) {
+    int columnCount = target.getParent().getColumnCount();
+    for (int i = 0; i < columnCount; i++) {
+      String text = source.getText(i);
+      if (null != text)
+        target.setText(i, text);
+    }
+    target.setData(source.getData());
+  }
+
+  public static FsIndexDescription getFsIndexDescriptionFromTableTreeItem(TableTreeItem item) {
+    return (FsIndexDescription) item.getData();
+  }
+
+  public String[][] getCapabilitySofaNames() {
+    Set[] inOut = getCapabilitySofaNames(editor.getAeDescription(), null);
+
+    String[] inputSofas = (String[]) inOut[0].toArray(stringArray0);
+    String[] outputSofas = (String[]) inOut[1].toArray(stringArray0);
+    Arrays.sort(inputSofas);
+    Arrays.sort(outputSofas);
+
+    return new String[][] { inputSofas, outputSofas };
+  }
+
+  public static Capability[] getCapabilities(ResourceSpecifier rs) {
+    if (rs instanceof ResourceCreationSpecifier)
+      return ((ProcessingResourceMetaData) ((ResourceCreationSpecifier) rs).getMetaData())
+              .getCapabilities();
+    return null;
+  }
+
+  protected static Set[] getCapabilitySofaNames(ResourceCreationSpecifier rs, String componentKey) {
+    Capability[] cs = getCapabilities(rs);
+    Set inputSofasSet = new TreeSet();
+    Set outputSofasSet = new TreeSet();
+    for (int i = 0; i < cs.length; i++) {
+      Capability c = cs[i];
+      mergeSofaNames(inputSofasSet, c.getInputSofas(), componentKey);
+      mergeSofaNames(outputSofasSet, c.getOutputSofas(), componentKey);
+    }
+    return new Set[] { inputSofasSet, outputSofasSet };
+  }
+
+  private static void mergeSofaNames(Set set, String[] items, String componentKey) {
+    if (null != items) {
+      for (int i = 0; i < items.length; i++) {
+        if (null != componentKey)
+          set.add(componentKey + '/' + items[i]);
+        else
+          set.add(items[i]);
+      }
+    } else if (null != componentKey)
+      set.add(componentKey);
+  }
+
+  protected Capability addCapabilitySet() {
+    Capability newCset = UIMAFramework.getResourceSpecifierFactory().createCapability();
+    // update the model
+    AnalysisEngineMetaData md = getAnalysisEngineMetaData();
+    Capability[] c = getCapabilities();
+    if (c == null)
+      md.setCapabilities(new Capability[] { newCset });
+    else {
+      Capability[] newC = new Capability[c.length + 1];
+      System.arraycopy(c, 0, newC, 0, c.length);
+      newC[c.length] = newCset;
+      md.setCapabilities(newC);
+    }
+    return newCset;
+  }
+
+  /**
+   * Get the metadata for a local or remote descriptor. If the descriptor is remote, but cannot be
+   * currently connected to, return null. Note that this make take some time to determine.
+   * 
+   * @param r
+   *          is the AnalysisEngineDescription or the URISpecifier for remotes.
+   * @return AnalysisEngineMetaData or null
+   */
+  public ResourceMetaData getMetaDataFromDescription(ResourceSpecifier o) {
+    if (o instanceof ResourceCreationSpecifier) {
+      return ((ResourceCreationSpecifier) o).getMetaData();
+    }
+    if (o instanceof URISpecifier) {
+      URISpecifier uriSpec = ((URISpecifier) o);
+      AnalysisEngine ae = null;
+      try {
+        setVnsHostAndPort(o);
+        ae = UIMAFramework.produceAnalysisEngine(uriSpec);
+      } catch (ResourceInitializationException e) {
+        return null;
+      }
+      AnalysisEngineMetaData aemd = ae.getAnalysisEngineMetaData();
+      ae.destroy();
+      return aemd;
+    } else
+      throw new InternalErrorCDE("invalid call");
+  }
+
+  public static void setVnsHostAndPort(String vnsHost, String vnsPort) {
+    MultiPageEditorContributor.setVnsHost(vnsHost);
+    MultiPageEditorContributor.setVnsPort(vnsPort);
+  }
+
+  public static void setVnsHostAndPort(Object descriptor) {
+    String vnsHost = MultiPageEditorContributor.getCDEVnsHost();
+    String vnsPort = MultiPageEditorContributor.getCDEVnsPort();
+    // don't need this next part - the framework does it itself
+    // if (null != descriptor) {
+    // if (descriptor instanceof URISpecifier) {
+    // URISpecifier rd = (URISpecifier) descriptor;
+    // Parameter[] parms = rd.getParameters();
+    // if (null != parms) {
+    // for (int i = 0; i < parms.length; i++) {
+    // if ("VNS_HOST".equals(parms[i].getName()))
+    // vnsHost = parms[i].getValue();
+    // else if ("VNS_PORT".equals(parms[i].getName()))
+    // vnsPort = parms[i].getValue();
+    // }
+    // }
+    // }
+    // }
+    setVnsHostAndPort(vnsHost, vnsPort);
+  }
+
+  protected void requestPopUpOverImport(Import importItem, Control control, Event event) {
+    String path = editor.getAbsolutePathFromImport(importItem);
+    IPath iPath = new Path(path);
+    IFile[] files = editor.getProject().getWorkspace().getRoot().findFilesForLocation(iPath);
+    if (null == files || files.length != 1)
+      return;
+
+    String filePathName = files[0].getLocation().toOSString();
+    XMLizable inputDescription;
+    try {
+      inputDescription = parseDescriptor(new XMLInputSource(filePathName));
+    } catch (InvalidXMLException e) {
+      return;
+    } catch (IOException e) {
+      return;
+    }
+
+    PopupList popupList = new PopupList(control.getShell());
+    String[] items = { "Open in new window..." };
+    popupList.setItems(items);
+    int HACK_MARGIN = 30;
+    Point absPoint = getAbsoluteLocation(control, event.x, event.y + HACK_MARGIN);
+    Rectangle rect = new Rectangle(absPoint.x, absPoint.y, 150, 25);
+    control.setToolTipText("");
+    String res = popupList.open(rect);
+
+    // code to open selected file, by location or by name
+    if (null != res) {
+      if (inputDescription instanceof URISpecifier)
+        editor.openTextEditor(path);
+      else
+        editor.open(path);
+    }
+  }
+
+  private Point getAbsoluteLocation(Control control, int x, int y) {
+    Point point = new Point(x, y);
+    Composite composite = control.getParent();
+    while (composite != null) {
+      point.x += composite.getLocation().x;
+      point.y += composite.getLocation().y;
+      composite = composite.getParent();
+    }
+    return point;
+  }
+
+  public static String convertNull(String s) {
+    if (null == s)
+      return "";
+    return s;
+  }
+
+  public Import createImport(String fileName, boolean isByName) {
+    if (isByName) {
+      return createByNameImport(fileName);
+    } else
+      try {
+        return createLocationImport(fileName);
+      } catch (MalformedURLException e1) {
+        throw new InternalErrorCDE("unhandled exception", e1);
+      }
+  }
+
+  /**
+   * @param location
+   * @return
+   * @throws MalformedURLException
+   */
+  public Import createLocationImport(String location) throws MalformedURLException {
+
+    String sDescriptorRelativePath = editor.getDescriptorRelativePath(location);
+    // If relative path is not "relative", on Windows might get back
+    // an absolute path starting with C: or something like it.
+    // If a path starts with "C:", it must be preceeded by
+    // file:/ so the C: is not interpreted as a "scheme".
+    if (sDescriptorRelativePath.indexOf("file:/") == -1 //$NON-NLS-1$
+            && sDescriptorRelativePath.indexOf(":/") > -1) { //$NON-NLS-1$
+      sDescriptorRelativePath = "file:/" + sDescriptorRelativePath; //$NON-NLS-1$
+    }
+
+    Import imp = new Import_impl();
+    // fails on unix? URL url = new URL("file:/" + getDescriptorDirectory());
+    // Set relative Path Base
+    // a version that might work on all platforms
+    URL url = new File(editor.getDescriptorDirectory()).toURL();
+    ((Import_impl) imp).setSourceUrl(url);
+
+    imp.setLocation(sDescriptorRelativePath);
+    return imp;
+  }
+
+  public Import createByNameImport(String fileName) {
+    if (fileName.endsWith(".xml"))
+      fileName = fileName.substring(0, fileName.length() - 4);
+    fileName = fileName.replace('\\', '/');
+    fileName = fileName.replace('/', '.');
+    int i = fileName.indexOf(":");
+    if (i >= 0)
+      fileName = fileName.substring(i + 1);
+    if (fileName.charAt(0) == '.')
+      fileName = fileName.substring(1);
+    int partStart = 0;
+
+    Import imp = UIMAFramework.getResourceSpecifierFactory().createImport();
+    ResourceManager rm = editor.createResourceManager();
+
+    for (;;) {
+      imp.setName(fileName.substring(partStart));
+      try {
+        imp.findAbsoluteUrl(rm);
+      } catch (InvalidXMLException e) {
+        partStart = fileName.indexOf('.', partStart) + 1;
+        if (0 == partStart)
+          return imp; // not found -outer code will catch error later
+        continue;
+      }
+      return imp;
+    }
+  }
+
+  // subtype of FSLists should not match
+  public static boolean isFSArrayOrListType(String type) {
+    return (null != type)
+            && (type.equals(CAS.TYPE_NAME_FS_ARRAY) || type.equals(CAS.TYPE_NAME_FS_LIST));
+  }
+
+  public static boolean isArrayOrListType(String type) {
+    return (null != type)
+            && (type.equals(CAS.TYPE_NAME_FS_ARRAY) || type.equals(CAS.TYPE_NAME_FS_LIST)
+                    || type.equals(CAS.TYPE_NAME_STRING_LIST)
+                    || type.equals(CAS.TYPE_NAME_FLOAT_LIST)
+                    || type.equals(CAS.TYPE_NAME_INTEGER_LIST)
+                    || type.equals(CAS.TYPE_NAME_STRING_ARRAY)
+                    || type.equals(CAS.TYPE_NAME_FLOAT_ARRAY)
+
+                    || type.equals(CAS.TYPE_NAME_BOOLEAN_ARRAY)
+                    || type.equals(CAS.TYPE_NAME_BYTE_ARRAY)
+                    || type.equals(CAS.TYPE_NAME_SHORT_ARRAY)
+                    || type.equals(CAS.TYPE_NAME_INTEGER_ARRAY)
+                    || type.equals(CAS.TYPE_NAME_LONG_ARRAY) || type
+                    .equals(CAS.TYPE_NAME_DOUBLE_ARRAY));
+  }
+
+  private final static int RIDICULOUSLY_LARGE = 10000;
+
+  /**
+   * Produce Unique key for a newly added descriptor file
+   * 
+   * @param fileName
+   * @return
+   */
+  protected String produceUniqueComponentKey(String fileName) {
+    // get existing set of delegates from model, with imports
+    Set existingKeyNames = new HashSet(getDelegateAnalysisEngineSpecifiersWithImports().keySet());
+    FlowControllerDeclaration fcd = getFlowControllerDeclaration();
+    if (null != fcd && null != fcd.getKey() && !"".equals(fcd.getKey()))
+      existingKeyNames.add(fcd.getKey());
+    String keyName = fileName;
+    String keyNameLowerCase = keyName.toLowerCase();
+    keyName = keyName.substring(0, keyNameLowerCase.indexOf(".xml"));
+    if (!existingKeyNames.contains(keyName)) {
+      return keyName;
+    }
+
+    for (int i = 2; i < RIDICULOUSLY_LARGE; i++) {
+      String sKeyName = keyName + i;
+      if (!existingKeyNames.contains(sKeyName)) {
+        return sKeyName;
+      }
+    }
+    Utility.popMessage("Failed to create unique key", "The Flow Controller name, '" + fileName
+            + "', could not be "
+            + "converted to a unique key name -- tried with 10000 different suffixes",
+            MessageDialog.ERROR);
+    return null;
+  }
+
+  private static URL urlForResourceSpecifierSchema;
+  static {
+    try {
+      urlForResourceSpecifierSchema = new URL("file:resourceSpecifierSchema.xsd");
+    } catch (MalformedURLException e) {
+      urlForResourceSpecifierSchema = null;
+    }
+  }
+
+  public static XMLizable parseDescriptor(XMLInputSource input) throws InvalidXMLException {
+    // turn off environment variable expansion
+    XMLParser.ParsingOptions parsingOptions = new XMLParser.ParsingOptions(false);
+    XMLParser parser = UIMAFramework.getXMLParser();
+    // disabled - error messages from XML validation not very helpful
+    // parser.enableSchemaValidation(true);
+    return parser.parse(input, "http://uima.apache.org/resourceSpecifier",
+            urlForResourceSpecifierSchema, parsingOptions);
+  }
+
+  protected void showExceptionReadingImportedDescriptor(Exception e) {
+    StringBuffer msg = new StringBuffer(1000);
+    msg
+            .append("There was an exception raised while reading and parsing an imported descriptor. "
+                    + "If this is a ''not found'' message for a remote descriptor imported by name, insure that the class path or data path includes an entry where this file should be found.\n");
+    msg.append(editor.getMessagesToRootCause(e));
+    Utility.popMessage("Exception reading Imported File", msg.toString(), MessageDialog.ERROR);
+  }
+
+  /**
+   * Update the model while checking for validity If invalid - ask if want to continue or not
+   * 
+   * @return
+   */
+  protected boolean isValidAggregateChange() {
+
+    // doing this check here is expensive, but gives the best error location information
+    if (!editor.isValidAE(editor.getAeDescription()))
+      if (revertOrContinue("Continue or Abort",
+              "Because of errors in validating the resulting Analysis Engine:\n"))
+        return false; // want to revert
+
+    try {
+      editor.setMergedTypeSystemDescription();
+    } catch (ResourceInitializationException e) {
+      // no error here - continue if possible
+    }
+
+    try {
+      editor.setResolvedExternalResourcesAndBindings();
+    } catch (InvalidXMLException e3) {
+      // no error here - continue if possible
+    }
+    try {
+      editor.setResolvedFlowControllerDeclaration();
+    } catch (InvalidXMLException e3) {
+      // no error here - continue if possible
+    }
+    try {
+      editor.setMergedFsIndexCollection();
+    } catch (ResourceInitializationException e1) {
+      // no error here - continue if possible
+    }
+    try {
+      editor.setMergedTypePriorities();
+    } catch (ResourceInitializationException e2) {
+      // no error here - continue if possible
+    }
+    return true;
+  }
+
+  protected void finishAggregateChangeAction() {
+
+    editor.setFileDirty();
+    editor.getTypePage().markStale();
+    editor.getIndexesPage().markStale();
+    editor.getCapabilityPage().markStale();
+    SectionPart s = editor.getParameterPage().getParameterDelegatesSection();
+    if (null != s)
+      s.markStale();
+    editor.getResourcesPage().markStale();
+  }
+
+  protected XMLizable readImport(Import imp, String fileName, boolean isImportByName) {
+    URL byNameURL;
+    XMLInputSource input;
+    if (isImportByName) {
+      try {
+        byNameURL = imp.findAbsoluteUrl(editor.createResourceManager());
+      } catch (InvalidXMLException e) {
+        showExceptionReadingImportedDescriptor(e);
+        return null;
+      }
+
+      try {
+        input = new XMLInputSource(byNameURL.openStream(), new File(byNameURL.getFile())
+                .getParentFile());
+      } catch (IOException e) {
+        showExceptionReadingImportedDescriptor(e);
+        return null;
+      }
+    } else {
+      try {
+        input = new XMLInputSource(new File(fileName));
+      } catch (IOException e) {
+        throw new InternalErrorCDE("invalid state");
+      }
+    }
+    // read the content and merge into our model
+    XMLizable inputDescription;
+    try {
+      inputDescription = parseDescriptor(input);
+    } catch (InvalidXMLException e1) {
+      showExceptionReadingImportedDescriptor(e1);
+      return null;
+    }
+    return inputDescription;
+  }
+
+  protected static void enableCtrl(Control c, boolean enabled) {
+    if (null != c)
+      c.setEnabled(enabled);
+  }
+
+  protected static void setButtonSelection(Button c, boolean selected) {
+    if (null != c)
+      c.setSelection(selected);
+  }
+
+  /**
+   * Return a String made from the description of a given resource specifier. If the specifier is
+   * for a remote, try and connect to the remote and get its info.
+   * 
+   * @param fileRef
+   * @param rs
+   */
+  private ResourceSpecifier lastResourceForDescription = null;
+
+  private String lastDescriptionFromDescriptor = "";
+
+  private long lastTimeDescriptionRequested = 0;
+
+  private static final long TABLE_HOVER_REQUERY_TIME = 15000;
+
+  protected String getDescriptionForDescriptor(String fileRef, ResourceSpecifier rs) {
+    if (null == fileRef || "".equals(fileRef) || null == rs)
+      return "";
+    String sDesc;
+    long lCurrentTimeInMillis = System.currentTimeMillis();
+    if (rs == lastResourceForDescription
+            && ((lCurrentTimeInMillis - lastTimeDescriptionRequested) < TABLE_HOVER_REQUERY_TIME)) {
+      return lastDescriptionFromDescriptor;
+    } else {
+      sDesc = fileRef + ":\n";
+      ResourceMetaData resourceMetaData = getMetaDataFromDescription(rs);
+      if (null == resourceMetaData) {
+        sDesc += "(Remote service is not responding)";
+      } else {
+        String description = resourceMetaData.getDescription();
+        if (null != description && !description.equals("")) {
+          sDesc += parseToFitInToolTips(description);
+        } else
+          sDesc += "(No Description)";
+      }
+      lastResourceForDescription = rs;
+      lastTimeDescriptionRequested = System.currentTimeMillis();
+      lastDescriptionFromDescriptor = sDesc;
+    }
+    return sDesc;
+  }
+
+  protected PrintWriter setupToPrintFile(String filePath) {
+    if (new File(filePath).exists())
+      if (Window.CANCEL == Utility.popOkCancel("File exists, OK to replace?", MessageFormat.format(
+              "The file ''{0}'' exists. Press OK if it can be replaced; otherwise press Cancel.",
+              new Object[] { filePath }), MessageDialog.WARNING))
+        return null;
+    FileOutputStream fos = null;
+    try {
+      fos = new FileOutputStream(filePath);
+      return new PrintWriter(fos);
+    } catch (FileNotFoundException ex) {
+      ex.printStackTrace();
+      return null;
+    }
+  }
+
+  protected FsIndexCollection getFsIndexCollection() {
+    FsIndexCollection fsic = getAnalysisEngineMetaData().getFsIndexCollection();
+    if (null == fsic)
+      getAnalysisEngineMetaData().setFsIndexCollection(
+              fsic = UIMAFramework.getResourceSpecifierFactory().createFsIndexCollection());
+    return fsic;
+  }
+
+  public static String handleDefaultIndexKind(String indexKind) {
+    if (null == indexKind)
+      return "sorted";
+    return indexKind;
+  }
+}
diff --git a/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/AbstractSectionParm.java b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/AbstractSectionParm.java
new file mode 100644
index 0000000..81fb0f2
--- /dev/null
+++ b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/AbstractSectionParm.java
@@ -0,0 +1,797 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS 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.taeconfigurator.editors.ui;
+
+import java.util.AbstractList;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeMap;
+import java.util.TreeSet;
+
+import org.apache.uima.resource.metadata.ConfigurationGroup;
+import org.apache.uima.resource.metadata.ConfigurationParameter;
+import org.apache.uima.resource.metadata.ConfigurationParameterDeclarations;
+import org.apache.uima.resource.metadata.ConfigurationParameterSettings;
+import org.apache.uima.taeconfigurator.InternalErrorCDE;
+import org.apache.uima.taeconfigurator.Messages;
+import org.apache.uima.taeconfigurator.editors.MultiPageEditor;
+import org.apache.uima.taeconfigurator.model.ConfigGroup;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Tree;
+import org.eclipse.swt.widgets.TreeItem;
+
+/**
+ */
+public abstract class AbstractSectionParm extends AbstractSection {
+
+  public final static String NOT_IN_ANY_GROUP = Messages
+          .getString("AbstractSectionParm.notInAnyGroup"); //$NON-NLS-1$
+
+  public final static String COMMON_GROUP = Messages.getString("AbstractSectionParm.common"); //$NON-NLS-1$
+
+  // maintainers note: names below have extra trailing blanks to get them to approximately line up
+  // where possible
+  protected final static String DELEGATE_HEADER = Messages
+          .getString("AbstractSectionParm.delegateKeyName"); //$NON-NLS-1$
+
+  protected final static String FLOWCTLR_HEADER = "Flow Controller Key Name: ";
+
+  protected final static String GROUP_HEADER = Messages
+          .getString("AbstractSectionParm.headerGroupNames"); //$NON-NLS-1$
+
+  protected final static String COMMON_GROUP_HEADER = Messages
+          .getString("AbstractSectionParm.headerCommon"); //$NON-NLS-1$
+
+  protected final static String NOT_IN_ANY_GROUP_HEADER = Messages
+          .getString("AbstractSectionParm.headerNotInAnyGroup"); //$NON-NLS-1$
+
+  protected final String OVERRIDE_HEADER = Messages.getString("AbstractSectionParm.overrides"); // nonstatic
+
+  // for
+  // easy
+  // ref
+  // in
+  // subclass
+  // //$NON-NLS-1$
+
+  protected final static String MULTI_VALUE_INDICATOR = "Multi   "; //$NON-NLS-1$
+
+  protected final static String SINGLE_VALUE_INDICATOR = "Single "; //$NON-NLS-1$
+
+  protected final static String OPTIONAL_INDICATOR = "Opt  "; //$NON-NLS-1$
+
+  protected final static String REQUIRED_INDICATOR = "Req "; //$NON-NLS-1$
+
+  protected final String nameHeader = "  Name: "; //$NON-NLS-1$
+
+  protected final static Map typeNamesW = new HashMap(4);
+  static { // map extra spaces to get these to take the same
+    typeNamesW.put("Boolean", "Boolean"); //$NON-NLS-1$ //$NON-NLS-2$
+    typeNamesW.put("Float", "Float     "); //$NON-NLS-1$ //$NON-NLS-2$
+    typeNamesW.put(Messages.getString("AbstractSectionParm.16"), "Integer  "); //$NON-NLS-1$ //$NON-NLS-2$
+    typeNamesW.put("String", "String    "); //$NON-NLS-1$ //$NON-NLS-2$
+  }
+
+  protected Tree tree;
+
+  protected Tree parameterSectionTree = null;
+
+  protected boolean showOverrides;
+
+  protected boolean splitGroupNames;
+
+  protected ConfigurationParameter[] commonParms;
+
+  protected Map groupParms;
+
+  protected ConfigurationParameterDeclarations cpd;
+
+  // settings set by other page when it is created
+  protected ParameterSettingsSection settings = null;
+
+  protected Tree settingsTree = null;
+
+  public void setSettings(ParameterSettingsSection v) {
+    settings = v;
+    settingsTree = v.getTree();
+  }
+
+  /**
+   * @param editor
+   * @param parent
+   * @param hasDescription
+   */
+  public AbstractSectionParm(MultiPageEditor aEditor, Composite parent, String header,
+          String description) {
+    super(aEditor, parent, header, description);
+  }
+
+  /*
+   * (non-Javadoc)
+   * 
+   * @see org.apache.uima.taeconfigurator.editors.ui.AbstractSection#enable()
+   */
+  public void enable() {
+  }
+
+  /*
+   * (non-Javadoc)
+   * 
+   * @see org.eclipse.swt.widgets.Listener#handleEvent(org.eclipse.swt.widgets.Event)
+   */
+  public abstract void handleEvent(Event event);
+
+  /*************************************************************************************************
+   * methods shared with multiple param pages ****************************************
+   */
+
+  /**
+   * Two modes: settingsDisplayMode - if true, shows groups one name at a time, and puts all
+   * <common> parms in other groups
+   */
+  protected void clearAndRefillTree(boolean usingGroups) {
+    cpd = getConfigurationParameterDeclarations();
+
+    tree.removeAll();
+
+    // when filling ParameterSection, it might or might not have
+    // settings tree set, depending on which panel is shown first
+    // Filling parmaterSection on initial refresh should not update, in any case, the
+    // the settings page; it has its own refresh.
+    // To prevent this, we turn off the settingsTree reference while filling
+    // and restore it at the end
+
+    Tree savedSettingsTree = settingsTree;
+    settingsTree = null;
+    groupParms = new TreeMap();
+    try {
+
+      // tree has 2 dummy groups
+      // first is the <Not in any group>, 2nd is the <Common>
+      if (null == cpd.getConfigurationParameters())
+        cpd.setConfigurationParameters(configurationParameterArray0);
+
+      fillGroup(cpd.getConfigurationParameters(), NOT_IN_ANY_GROUP, null);
+
+      if (null == cpd.getCommonParameters())
+        cpd.setCommonParameters(configurationParameterArray0);
+
+      if (usingGroups) {
+        fillGroup(cpd.getCommonParameters(), COMMON_GROUP, null);
+      }
+
+      ConfigurationGroup[] groups = cpd.getConfigurationGroups();
+      for (int i = 0; i < groups.length; i++) {
+        ConfigurationParameter[] cps = groups[i].getConfigurationParameters();
+        if (null == cps)
+          groups[i].setConfigurationParameters(cps = configurationParameterArray0);
+        fillGroup(groups[i].getConfigurationParameters(), groups[i].getNames(), groups[i]);
+      }
+
+      if (splitGroupNames)
+        fillGroupsFromGroupParms();
+
+      expandAllItems(tree.getItems()); // expand for overrides or groups
+
+    } finally {
+      settingsTree = savedSettingsTree;
+      groupParms = null;
+    }
+  }
+
+  private void expandAllItems(TreeItem[] items) {
+    TreeItem[] containedItems;
+    for (int i = 0; i < items.length; i++) {
+      items[i].setExpanded(true);
+      containedItems = items[i].getItems();
+      if (null != containedItems)
+        expandAllItems(containedItems);
+    }
+  }
+
+  /**
+   * Called by refresh; add a normal named group and a set of parmaters
+   */
+  private void fillGroup(ConfigurationParameter[] parms, String[] names, ConfigurationGroup modelCG) {
+    fillGroup(parms, groupNameArrayToString(names), modelCG);
+  }
+
+  /**
+   * called by refresh() for <Common> and refresh() for named, via another path with names as array
+   * first converted to concatenated string.
+   * 
+   * @param parms
+   * @param names
+   */
+  private void fillGroup(ConfigurationParameter[] parms, String names, ConfigurationGroup modelCG) {
+    if (splitGroupNames) {
+      if (names.equals(COMMON_GROUP)) {
+        commonParms = parms;
+      } else {
+        String[] nameArray = groupNamesToArray(names);
+        if (nameArray.length == 1 && nameArray[0].equals(NOT_IN_ANY_GROUP)) {
+          TreeItem groupItem = addGroupToGUI(nameArray[0], modelCG);
+          fill(parms, groupItem);
+        } else
+          for (int i = 0; i < nameArray.length; i++) {
+            List g = (List) groupParms.get(nameArray[i]);
+            if (null == g) {
+              g = new ArrayList();
+              groupParms.put(nameArray[i], g);
+            }
+            g.add(new Object[] { modelCG, parms });
+          }
+      }
+    } else {
+      if (names.equals(COMMON_GROUP))
+        commonParms = parms;
+      TreeItem groupItem = addGroupToGUI(names, modelCG);
+      fill(parms, groupItem);
+    }
+  }
+
+  private void fillGroupsFromGroupParms() {
+    for (Iterator grpInfo = groupParms.entrySet().iterator(); grpInfo.hasNext();) {
+      Map.Entry entry = (Map.Entry) grpInfo.next();
+      String key = (String) entry.getKey();
+      List pairs = (List) entry.getValue();
+      TreeItem groupItem = addGroupToGUI(key, null); // modelCG not available, but not used
+      for (Iterator pi = pairs.iterator(); pi.hasNext();) {
+        Object[] v = (Object[]) pi.next();
+        ConfigurationParameter[] parms = (ConfigurationParameter[]) v[1];
+        fill(parms, groupItem);
+      }
+      fill(commonParms, groupItem);
+    }
+  }
+
+  /**
+   * called by refresh() when no groups, just plain parm sets, also for group case
+   * 
+   * @param parms
+   * @param group
+   *          <Not in any group> if not in a group, otherwise the group tree item
+   */
+  protected void fill(ConfigurationParameter[] parms, TreeItem group) {
+    if (parms == null)
+      return;
+    for (int i = 0; i < parms.length; i++) {
+      addNewConfigurationParameterToGUI(parms[i], group);
+    }
+  }
+
+  public static String groupNameArrayToString(String[] strings) {
+    StringBuffer b = new StringBuffer();
+    for (int i = 0; i < strings.length; i++) {
+      if (i > 0)
+        b.append("   "); //$NON-NLS-1$
+      b.append(strings[i]);
+    }
+    return b.toString();
+  }
+
+  protected String[] groupNamesToArray(String names) {
+    if (names.equals(NOT_IN_ANY_GROUP))
+      return new String[] { names };
+
+    AbstractList items = new ArrayList();
+    int start = 0;
+    int end;
+
+    while (start < names.length() && (names.charAt(start) == ' '))
+      start++;
+
+    for (; start < names.length();) {
+      end = names.indexOf(' ', start);
+      if (end == -1) {
+        items.add(names.substring(start));
+        break;
+      }
+      items.add(names.substring(start, end));
+      start = end;
+      while (start < names.length() && names.charAt(start) == ' ')
+        start++;
+    }
+    return (String[]) items.toArray(stringArray0);
+  }
+
+  /**
+   * Takes an existing model parm and fills a pre-allocated treeItem. 3 callers:
+   * addNewConfigurationParameter, alterExistingConfigurationParamater (editing), fill (bulk update
+   * from refresh)
+   * 
+   * @param item
+   * @param parm
+   */
+  protected void fillParmItem(TreeItem item, ConfigurationParameter parm) {
+    item.setText(parmGuiString(parm));
+
+    // // set data if tree == parmsection tree
+    // if (item.getParent() == parameterSectionTree)
+    // back link used to find corresponding model parm decl from tree item
+    item.setData(parm);
+  }
+
+  protected String parmGuiString(ConfigurationParameter parm) {
+    return ((parm.isMultiValued()) ? MULTI_VALUE_INDICATOR : SINGLE_VALUE_INDICATOR)
+            + ((parm.isMandatory()) ? REQUIRED_INDICATOR : OPTIONAL_INDICATOR)
+            + typeNamesW.get(parm.getType()) + " " + nameHeader + //$NON-NLS-1$
+            (parm.getName());
+  }
+
+  protected void setGroupText(TreeItem groupItem, String names) {
+    if (names.equals(COMMON_GROUP))
+      groupItem.setText(COMMON_GROUP_HEADER);
+    else if (names.equals(NOT_IN_ANY_GROUP))
+      groupItem.setText(NOT_IN_ANY_GROUP_HEADER);
+    else
+      // next line formats the names with the right number of spaces and makes it
+      // possible to do future equal compares
+      groupItem.setText(GROUP_HEADER + groupNameArrayToString(groupNamesToArray(names)));
+  }
+
+  protected TreeItem addGroupToGUI(String names, ConfigurationGroup cg) {
+    TreeItem groupItem = new TreeItem(tree, SWT.NONE);
+    setGroupText(groupItem, names);
+    ConfigGroup mcg;
+    if (names.equals(COMMON_GROUP))
+      mcg = new ConfigGroup(cpd, ConfigGroup.COMMON);
+    else if (names.equals(NOT_IN_ANY_GROUP))
+      mcg = new ConfigGroup(cpd, ConfigGroup.NOT_IN_ANY_GROUP);
+    else
+      mcg = new ConfigGroup(cpd, cg);
+    groupItem.setData(mcg);
+    String[] nameArray = groupNamesToArray(names);
+    if (null != settingsTree) {
+      for (int i = 0; i < nameArray.length; i++) {
+        TreeItem[] settingsItems = settingsTree.getItems();
+        if (!containsGroup(nameArray[i], settingsItems)) {
+          TreeItem settingsItem = new TreeItem(settingsTree, SWT.NONE);
+          setGroupText(settingsItem, nameArray[i]);
+          settingsItem.setData(null);
+          fill(commonParms, settingsItem);
+        }
+      }
+    }
+    return groupItem;
+  }
+
+  private boolean containsGroup(String groupName, final TreeItem[] settingsItems) {
+    for (int i = 0; i < settingsItems.length; i++) {
+      if (groupName.equals(getName(settingsItems[i])))
+        return true;
+    }
+    return false;
+  }
+
+  /**
+   * This is called sometimes with Settings group
+   * 
+   * @param newCP
+   * @param group -
+   *          is never null. May be <Not in any group>, indicate no groups; may be the "<Common>"
+   *          group; or may be a regular group with a set of group names
+   */
+  protected void addNewConfigurationParameterToGUI(ConfigurationParameter newCP, TreeItem group) {
+
+    if (null == group)
+      throw new InternalErrorCDE("invalid state"); //$NON-NLS-1$
+
+    // is part of group but could be NOT_IN_ANY_GROUP
+    if (null != settingsTree) {
+      boolean isCommonOrNotInAnyGrp = COMMON_GROUP.equals(getName(group))
+              || NOT_IN_ANY_GROUP.equals(getName(group));
+      TreeItem[] groups = getSettingsGroups(group);
+      for (int i = 0; i < groups.length; i++) {
+        // this next test tries to add parms so that common ones come at the end,
+        // and non-common ones come before the start of common ones.
+        TreeItem newParmGuiItem = (isCommonOrNotInAnyGrp) ? new TreeItem(groups[i], SWT.NONE)
+                : new TreeItem(groups[i], SWT.NONE, 0);
+        fillParmItem(newParmGuiItem, newCP);
+      }
+    }
+
+    // next only done for non-setting page
+    if (group.getParent() != settingsTree) {
+      TreeItem newItem;
+      fillParmItem(newItem = new TreeItem(group, SWT.NONE), newCP);
+
+      if (showOverrides) {
+        fillOverrides(newItem, newCP);
+      }
+    }
+  }
+
+  // this is overriden where needed
+  // here just make above fn compile OK
+  protected void fillOverrides(TreeItem parent, ConfigurationParameter modelCP) {
+  }
+
+  protected boolean isOverride(TreeItem item) {
+    return (item.getText().startsWith(OVERRIDE_HEADER));
+  }
+
+  protected boolean isParameter(TreeItem item) {
+    String s = item.getText();
+    return (!isGroup(item) && !s.startsWith(DELEGATE_HEADER) && !s.startsWith(FLOWCTLR_HEADER) && !item
+            .getText().startsWith(OVERRIDE_HEADER));
+  }
+
+  // Note: rest of code considers NOT_IN_ANY_GROUP to be a kind of group
+  protected boolean isGroup(TreeItem item) {
+    String s = item.getText();
+    return s.startsWith(GROUP_HEADER) || s.startsWith(COMMON_GROUP_HEADER)
+            || s.startsWith(NOT_IN_ANY_GROUP_HEADER);
+  }
+
+  protected boolean isNOT_IN_ANY_GROUP(TreeItem item) {
+    return item.getText().startsWith(NOT_IN_ANY_GROUP_HEADER);
+  }
+
+  protected boolean isCommonGroup(TreeItem item) {
+    return item.getText().startsWith(COMMON_GROUP_HEADER);
+  }
+
+  protected boolean isDelegate(TreeItem item) {
+    return item.getText().startsWith(DELEGATE_HEADER) || item.getText().startsWith(FLOWCTLR_HEADER);
+  }
+
+  protected boolean isGroupSelection() {
+    return isGroup(tree.getSelection()[0]);
+  }
+
+  protected boolean isCommonGroupSelection() {
+    return isCommonGroup(tree.getSelection()[0]);
+  }
+
+  protected boolean isOverrideSelection() {
+    return isOverride(tree.getSelection()[0]);
+  }
+
+  protected boolean isParmSelection() {
+    return isParameter(tree.getSelection()[0]);
+  }
+
+  protected String getName(TreeItem item) {
+    return getName(item.getText());
+  }
+
+  protected String getName(String s) {
+
+    if (s.startsWith(NOT_IN_ANY_GROUP_HEADER))
+      return NOT_IN_ANY_GROUP;
+    if (s.startsWith(COMMON_GROUP_HEADER))
+      return COMMON_GROUP;
+
+    if (s.startsWith(GROUP_HEADER))
+      return s.substring(GROUP_HEADER.length());
+    if (s.startsWith(OVERRIDE_HEADER))
+      return s.substring(OVERRIDE_HEADER.length());
+    // parameter
+    return s.substring(s.indexOf(nameHeader) + nameHeader.length());
+  }
+
+  protected int getItemIndex(TreeItem parent, TreeItem child) {
+    return getItemIndex(parent.getItems(), child);
+  }
+
+  protected int getItemIndex(Tree parent, TreeItem child) {
+    return getItemIndex(parent.getItems(), child);
+  }
+
+  /**
+   * Works between parameter tree and settings tree We don't use any relative index offsets.
+   * Instead, we search for the item with the same parameter name.
+   * 
+   * 
+   * @param containingGroup
+   *          in parm section; if null = means all groups (common parms)
+   * @return
+   */
+  protected TreeItem[] getSettingsParameter(TreeItem containingGroup, String sourceItemName) {
+    if (null == settingsTree)
+      return null;
+
+    if (null != containingGroup && isNOT_IN_ANY_GROUP(containingGroup))
+      return new TreeItem[] { findMatchingParm(settingsTree.getItems()[0], sourceItemName) };
+
+    TreeItem[] groups = getSettingsGroups((null == containingGroup) ? tree.getItems()[1] // use
+            // common
+            // group,
+            // will
+            // return
+            // all
+            // groups
+            // in
+            // settings
+            // pg
+            : containingGroup);
+    TreeItem[] results = new TreeItem[groups.length];
+
+    for (int i = 0; i < groups.length; i++) {
+      results[i] = findMatchingParm(groups[i], sourceItemName);
+    }
+    return results;
+  }
+
+  private TreeItem findMatchingParm(TreeItem group, String name) {
+    final TreeItem[] items = group.getItems();
+    for (int i = 0; i < items.length; i++) {
+      if (name.equals(getName(items[i])))
+        return items[i];
+    }
+    throw new InternalErrorCDE("invalid state");
+  }
+
+  /**
+   * get set of settings group from settingsTree that correspond to parmsection group
+   * 
+   * @param group
+   * @return
+   */
+  protected TreeItem[] getSettingsGroups(TreeItem group) {
+    if (null == settingsTree)
+      return null;
+
+    if (isNOT_IN_ANY_GROUP(group))
+      return new TreeItem[] { settingsTree.getItems()[0] };
+
+    AbstractList results = new ArrayList();
+
+    String[] groupNamesArray = groupNamesToArray(getName(group.getText()));
+    TreeItem[] items = settingsTree.getItems();
+
+    if (groupNamesArray.length == 1 && groupNamesArray[0].equals(COMMON_GROUP)) {
+      // add parm to all groups except <Not in any group>
+      TreeItem[] result = new TreeItem[items.length - 1];
+      System.arraycopy(items, 1, result, 0, result.length);
+      return result;
+    }
+
+    for (int itemIndex = 0; itemIndex < items.length; itemIndex++) {
+      String name = getName(items[itemIndex].getText());
+      for (int i = 0; i < groupNamesArray.length; i++) {
+        if (name.equals(groupNamesArray[i]))
+          results.add(items[itemIndex]);
+      }
+    }
+    return (TreeItem[]) results.toArray(treeItemArray0);
+  }
+
+  /**
+   * find settings tree item for group name
+   * 
+   * @param name
+   * @return
+   */
+  protected TreeItem getSettingsGroupTreeItemByName(String name) {
+    TreeItem[] items = settingsTree.getItems();
+    for (int i = 0; i < items.length; i++) {
+      if (name.equals(getName(items[i].getText())))
+        return items[i];
+    }
+    throw new InternalErrorCDE("invalid state"); //$NON-NLS-1$
+  }
+
+  protected ConfigurationParameter getCorrespondingModelParm(TreeItem item) {
+    if (!isParameter(item))
+      throw new InternalErrorCDE("invalid argument"); //$NON-NLS-1$
+    return (ConfigurationParameter) item.getData();
+  }
+
+  protected ConfigGroup getCorrespondingModelGroup(TreeItem item) {
+    if (!isGroup(item))
+      throw new InternalErrorCDE("invalid argument"); //$NON-NLS-1$
+    return (ConfigGroup) item.getData();
+  }
+
+  public ConfigurationParameterSettings getConfigurationParameterSettings() {
+    return editor.getAeDescription().getMetaData().getConfigurationParameterSettings();
+  }
+
+  /*************************************************************************************************
+   * * methods affecting the parameter settings. * These run whether or not the settings page has
+   * been instantiated. * If the settings page is instantiated, that GUI is also updated.
+   * *******************************************************************
+   */
+
+  public ConfigurationParameterSettings getModelSettings() {
+    return getAnalysisEngineMetaData().getConfigurationParameterSettings();
+  }
+
+  /**
+   * Remove a parameter from all groups it lives in the Settings. If settings page is shown, also
+   * update the GUI.
+   * 
+   * @param treeItem
+   *          in ParameterSection of parameter belonging to (multiple) groups
+   */
+  public void removeParmSettingFromMultipleGroups(TreeItem parmItem, boolean removeFromGUI) {
+    if (!isParameter(parmItem))
+      throw new InternalErrorCDE("invalid argument"); //$NON-NLS-1$
+
+    ConfigurationParameterSettings modelSettings = getModelSettings();
+    String parmName = getName(parmItem);
+    TreeItem parent = parmItem.getParentItem();
+    String groupName = getName(parent.getText());
+    if (!groupName.equals(NOT_IN_ANY_GROUP)) {
+      String[] groupNames = (getName(parent.getText()).equals(COMMON_GROUP)) ? getAllGroupNames()
+              : getCorrespondingModelGroup(parent).getNameArray();
+
+      for (int i = 0; i < groupNames.length; i++) {
+        modelSettings.setParameterValue(groupNames[i], parmName, null);
+      }
+    } else {
+      modelSettings.setParameterValue(parmName, null);
+    }
+
+    if (null != settings) {
+      if (removeFromGUI) {
+        TreeItem[] settingsTreeParms = getSettingsParameter(parent, parmName);
+        for (int i = 0; i < settingsTreeParms.length; i++) {
+          settingsTreeParms[i].dispose();
+        }
+      } else { // leave parm but remove value
+        editor.getSettingsPage().getValueSection().refresh();
+      }
+    }
+  }
+
+  public void updateParmInSettingsGUI(ConfigurationParameter existingCP, TreeItem existingTreeItem,
+          String prevName) {
+    if (null != settings) {
+      TreeItem[] settingsTreeParms = getSettingsParameter(existingTreeItem.getParentItem(),
+              prevName);
+      for (int i = 0; i < settingsTreeParms.length; i++) {
+        fillParmItem(settingsTreeParms[i], existingCP);
+      }
+    }
+  }
+
+  protected String[] getAllGroupNames() {
+    return getAllGroupNames(cpd);
+  }
+
+  /**
+   * 
+   * @param aCpd
+   * @return all named groups, excludes <Common> and <Not in any group>
+   */
+  protected String[] getAllGroupNames(ConfigurationParameterDeclarations aCpd) {
+    ConfigurationGroup[] cgs = aCpd.getConfigurationGroups();
+    Set results = new TreeSet();
+    for (int i = 0; i < cgs.length; i++) {
+      String[] names = cgs[i].getNames();
+      for (int j = 0; j < names.length; j++) {
+        results.add(names[j]);
+      }
+    }
+    return (String[]) results.toArray(stringArray0);
+  }
+
+  public void removeCommonParmSettingsFromMultipleGroups() {
+    ConfigurationParameterSettings modelSettings = getModelSettings();
+    String[] allGroupNames = getAllGroupNames();
+    // TreeItem [] items = new TreeItem[0]; // done to avoid may not have been initialized msg
+    // int offset = 0;
+    commonParms = cpd.getCommonParameters();
+
+    for (int i = 0; i < allGroupNames.length; i++) {
+      // if (null != settings) {
+      // items = getSettingsGroupTreeItemByName(allGroupNames[i]).getItems();
+      // offset = items.length - commonParms.length;
+      // }
+      for (int j = 0; j < commonParms.length; j++) {
+        modelSettings.setParameterValue(allGroupNames[i], commonParms[j].getName(), null);
+      }
+    }
+
+    if (null != settings) {
+      for (int j = 0; j < commonParms.length; j++) {
+        TreeItem[] settingsParms = getSettingsParameter(null, commonParms[j].getName());
+        for (int k = 0; k < settingsParms.length; k++) {
+          settingsParms[k].dispose();
+        }
+      }
+    }
+  }
+
+  /**
+   * Remove some of the parameter settings associated with this particular group, not all the
+   * parameters for that group name (some parameters may be associated with other instances of a
+   * particular group name.) If no other group-set contains a particular individual group name, in
+   * the Settings: remove the common parameters, and remove the individual group itself. Remove the
+   * particular group-set definition. Note that a group may be defined in more than one group-set.
+   * 
+   * Method: for the group-set, get the parms. Remove just those parms from all groups. Remove the
+   * group on the settings page (together with common parms for it) if no other group-set has this
+   * group name Remove the group-set.
+   * 
+   * @param groupNames
+   * @param cps
+   */
+  public void removeIncludedParmSettingsFromMultipleGroups(String[] groupNames,
+          ConfigurationParameter[] cps) {
+    for (int j = 0; j < groupNames.length; j++) {
+      removeIncludedParmSettingsFromSingleGroup(groupNames[j], cps);
+    }
+  }
+
+  /**
+   * 
+   * @param treeItem
+   *          in ParameterSection of items an array of tree items to remove Can be all items under a
+   *          particular group, or a set of items from different groups
+   */
+  public void removeIncludedParmSettingsFromSingleGroup(String groupName,
+          ConfigurationParameter[] cps) {
+    ConfigurationParameterSettings modelSettings = getModelSettings();
+    // modelSettings.setParameterValue()
+    if (groupName.equals(COMMON_GROUP))
+      throw new InternalErrorCDE("invalid state"); //$NON-NLS-1$
+
+    if (groupName.equals(NOT_IN_ANY_GROUP)) {
+      modelSettings.setParameterSettings(nameValuePairArray0);
+
+    } else {
+      for (int i = 0; i < cps.length; i++)
+        modelSettings.setParameterValue(groupName, cps[i].getName(), null);
+    }
+    if (null != settings) {
+      TreeItem settingGroup = getSettingsGroupTreeItemByName(groupName);
+      if (groupName.equals(COMMON_GROUP) || groupName.equals(NOT_IN_ANY_GROUP)) {
+        disposeAllChildItems(settingGroup);
+      } else {
+        if (getConfigurationParameterDeclarations().getConfigurationGroupDeclarations(groupName).length == 1) {
+          settingGroup.dispose();
+        } else {
+
+          for (int i = 0; i < cps.length; i++) {
+            findMatchingParm(settingGroup, cps[i].getName()).dispose();
+          }
+        }
+
+      }
+    }
+  }
+
+  public void disposeAllChildItems(TreeItem parent) {
+    TreeItem[] items = parent.getItems();
+    for (int j = 0; j < items.length; j++) {
+      items[j].dispose();
+    }
+  }
+
+  protected void showDescriptionAsToolTip(Event event) {
+    TreeItem item = tree.getItem(new Point(event.x, event.y));
+    if (null != item && isParameter(item)) {
+      setToolTipText(tree, getCorrespondingModelParm(item).getDescription());
+    } else
+      tree.setToolTipText(""); //$NON-NLS-1$
+  }
+
+}
diff --git a/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/AggregatePage.java b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/AggregatePage.java
new file mode 100644
index 0000000..83ca349
--- /dev/null
+++ b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/AggregatePage.java
@@ -0,0 +1,55 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.uima.taeconfigurator.editors.ui;
+
+import org.apache.uima.taeconfigurator.editors.Form2Panel;
+import org.apache.uima.taeconfigurator.editors.MultiPageEditor;
+import org.eclipse.ui.forms.IManagedForm;
+
+public class AggregatePage extends HeaderPageWithSash {
+
+  private FlowSection flowSection;
+
+  private AggregateSection aggregateSection;
+
+  public AggregatePage(MultiPageEditor aEditor) {
+    super(aEditor, "Aggregate Component Settings");
+  }
+
+  /** Called by the framework to fill in the contents */
+  protected void createFormContent(IManagedForm managedForm) {
+
+    final Form2Panel form = setup2ColumnLayout(managedForm, !EQUAL_WIDTH);
+    managedForm.getForm().setText("Aggregate Delegates and Flows");
+
+    managedForm.addPart(aggregateSection = new AggregateSection(editor, form.left));
+    managedForm.addPart(flowSection = new FlowSection(editor, form.right));
+    createToolBarActions(managedForm);
+  }
+
+  public FlowSection getFlowSection() {
+    return flowSection;
+  }
+
+  public AggregateSection getAggregateSection() {
+    return aggregateSection;
+  }
+
+}
diff --git a/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/AggregateSection.java b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/AggregateSection.java
new file mode 100644
index 0000000..04c602e
--- /dev/null
+++ b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/AggregateSection.java
@@ -0,0 +1,711 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS 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.taeconfigurator.editors.ui;
+
+import java.io.PrintWriter;
+import java.text.MessageFormat;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Vector;
+
+import org.apache.uima.analysis_engine.AnalysisEngineDescription;
+import org.apache.uima.collection.CasConsumerDescription;
+import org.apache.uima.resource.ResourceSpecifier;
+import org.apache.uima.resource.URISpecifier;
+import org.apache.uima.resource.metadata.ConfigurationParameter;
+import org.apache.uima.resource.metadata.Import;
+import org.apache.uima.resource.metadata.NameValuePair;
+import org.apache.uima.taeconfigurator.TAEConfiguratorPlugin;
+import org.apache.uima.taeconfigurator.editors.MultiPageEditor;
+import org.apache.uima.taeconfigurator.editors.ui.dialogs.AddRemoteServiceDialog;
+import org.apache.uima.taeconfigurator.editors.ui.dialogs.FindComponentDialog;
+import org.apache.uima.taeconfigurator.editors.ui.dialogs.PickTaeForTypesDialog;
+import org.apache.uima.taeconfigurator.files.MultiResourceSelectionDialogWithFlowOption;
+import org.apache.uima.taeconfigurator.model.FlowNodes;
+import org.apache.uima.util.XMLizable;
+import org.eclipse.jface.dialogs.InputDialog;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.window.Window;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.TableItem;
+import org.eclipse.ui.forms.IManagedForm;
+
+public class AggregateSection extends AbstractSection {
+
+  private Table filesTable;
+
+  private Button addButton;
+
+  private Button addRemoteButton;
+
+  private Button findAnalysisEngineButton;
+
+  private Button removeButton;
+
+  private Button addToFlowButton;
+
+  private Button removeFromFlowButton;
+
+  public Button getRemoveFromFlowButton() {
+    return removeFromFlowButton;
+  }
+
+  private boolean bDisableToolTipHelp = false;
+
+  /**
+   * Creates a section for aggregate specifiers to add their delegates
+   * 
+   * @param editor
+   *          backpointer to the main multipage editor
+   * @param parent
+   *          the Composite where this section lives
+   */
+  public AggregateSection(MultiPageEditor aEditor, Composite parent) {
+    super(aEditor, parent, "Component Engines",
+            "The following engines are included in this aggregate.");
+  }
+
+  /*
+   * Called by the page constructor after all sections are created, to initialize them.
+   * (non-Javadoc)
+   * 
+   * @see org.eclipse.ui.forms.IFormPart#initialize(org.eclipse.ui.forms.IManagedForm)
+   */
+  public void initialize(IManagedForm form) {
+    super.initialize(form);
+
+    Composite sectionClient = new2ColumnComposite(this.getSection());
+
+    // Table Container has table and buttons on bottom
+    Composite tableContainer = newComposite(sectionClient);
+    enableBorders(tableContainer);
+    toolkit.paintBordersFor(tableContainer);
+
+    filesTable = newTable(tableContainer, SWT.FULL_SELECTION, 150);
+
+    filesTable.setHeaderVisible(true);
+
+    newTableColumn(filesTable, 50, SWT.LEFT, "Delegate");
+    newTableColumn(filesTable, 75, SWT.LEFT, "Key Name");
+
+    // This little code fragment is an attempt to get the right sizing for the buttons
+    // Was wrong on Mac platforms
+    //   Word below is the longer of the two words in the button container
+    Button tempForSize = toolkit.createButton(tableContainer, "Remove", SWT.PUSH);
+    Point p = tempForSize.computeSize(SWT.DEFAULT, SWT.DEFAULT);
+    tempForSize.dispose();
+    
+    Composite bottomButtonContainer = newButtonContainer(tableContainer, HORIZONTAL_BUTTONS, 3* p.x);
+
+    addButton = newPushButton(bottomButtonContainer, S_ADD,
+            "Click here to add a locally defined AE or CAS Consumer delegate", ENABLED);
+    removeButton = newPushButton(bottomButtonContainer, "Remove",
+            "Click here to remove the selected item", ENABLED);
+
+    Composite sideButtonContainer = newButtonContainer(sectionClient, VERTICAL_BUTTONS, 80);
+
+    // this next just serves as a spacer
+    spacer(sideButtonContainer);
+    spacer(sideButtonContainer);
+
+    addToFlowButton = newPushButton(sideButtonContainer, ">>",
+            "Click here to add the selected item to the flow", !ENABLED);
+    removeFromFlowButton = newPushButton(sideButtonContainer, "<<",
+            "Click here to remove the selected item from the flow", !ENABLED);
+
+    spacer(sideButtonContainer);
+
+    addRemoteButton = newPushButton(sideButtonContainer, "AddRemote",
+            "Click here to add a Remote Analysis Engine", ENABLED);
+    findAnalysisEngineButton = newPushButton(sideButtonContainer, "Find AE",
+            "Click here to search for an Analysis Engine", ENABLED);
+
+    addButton.setSize(removeButton.getSize());
+
+    filesTable.addListener(SWT.MouseDown, this);
+    filesTable.addListener(SWT.MouseHover, this);
+  }
+
+  /*
+   * (non-Javadoc)
+   * 
+   * @see org.eclipse.ui.forms.IFormPart#refresh()
+   */
+  public void refresh() {
+    super.refresh();
+
+    // if annotator is primitive - page should be disabled
+    if (!isAggregate()) {
+      filesTable.removeAll();
+      getSection().setText("Not Used");
+      getSection().setDescription("This section is only applicable for Aggregate descriptors.");
+    } else {
+      getSection().setText("Component Engines");
+      getSection().setDescription("The following engines are included in this aggregate.");
+
+      // these can be changed by direct editing of source
+      Map delegates = getDelegateAnalysisEngineSpecifiersWithImports();
+
+      // first clear list
+      // (we do this carefully to preserve order)
+      String[] priorOrderedKeys = new String[filesTable.getItemCount()];
+      for (int i = 0; i < priorOrderedKeys.length; i++) {
+        priorOrderedKeys[i] = filesTable.getItem(i).getText(1);
+      }
+      filesTable.removeAll();
+      // get delegate keys
+      HashSet keys = new HashSet();
+      if (delegates != null) {
+        keys.addAll(delegates.keySet());
+      }
+
+      // first add keys that we know about in order as we knew it
+      for (int i = 0; i < priorOrderedKeys.length; i++) {
+        if (keys.contains(priorOrderedKeys[i])) {
+          Object o = delegates.get(priorOrderedKeys[i]);
+          if (o instanceof Import)
+            addFile(o, priorOrderedKeys[i]);
+          keys.remove(priorOrderedKeys[i]);
+        }
+      }
+
+      Iterator itKeys = keys.iterator();
+      // add what's left to list
+      while (itKeys.hasNext()) {
+        String key = (String) itKeys.next();
+        Object o = delegates.get(key);
+        if (o instanceof Import)
+          addFile(o, key);
+      }
+      packTable(filesTable);
+    }
+    enable();
+  }
+
+  /*
+   * (non-Javadoc)
+   * 
+   * @see org.eclipse.swt.widgets.Listener#handleEvent(org.eclipse.swt.widgets.Event)
+   */
+  public void handleEvent(Event event) {
+    if (event.widget == addButton)
+      handleAdd();
+    else if (event.widget == removeButton
+            || (event.type == SWT.KeyUp && event.character == SWT.DEL))
+      handleRemove();
+    else if (event.widget == addToFlowButton)
+      handleAddToFlow();
+    else if (event.widget == removeFromFlowButton)
+      handleRemoveFromFlow();
+    else if (event.widget == addRemoteButton)
+      handleAddRemote();
+    else if (event.widget == findAnalysisEngineButton)
+      handleFindAnalysisEngine();
+
+    // actions on table
+    else if (event.widget == filesTable) {
+      if (event.type == SWT.Selection) {
+        // if no delegate is selected disable edit and remove
+        boolean bEnableButtons = (filesTable.getSelectionCount() > 0);
+        removeButton.setEnabled(bEnableButtons);
+        addToFlowButton.setEnabled(bEnableButtons);
+      } else if (event.type == SWT.MouseDown && 
+                  (event.button == 3  || 
+                          // this is for Macintosh - they just have one button
+                   (event.button == 1 && (0 != (event.stateMask & SWT.CTRL))))) {
+        handleTableContextMenuRequest(event);
+      } else if (event.type == SWT.MouseHover && !bDisableToolTipHelp) {
+        handleTableHoverHelp(event);
+      } 
+      // Don't need this. Next mouse hover kills tool tip anyway
+      // else if (event.type == SWT.MouseMove) {
+      // filesTable.setToolTipText("");
+      // }
+    }
+  }
+
+  private void handleAdd() {
+
+    MultiResourceSelectionDialogWithFlowOption dialog = new MultiResourceSelectionDialogWithFlowOption(
+            getSection().getShell(), editor.getFile().getProject().getParent(),
+            "Component Engine Selection", editor.getFile().getLocation(), editor);
+    dialog.setTitle("Component Engine Selection");
+    dialog.setMessage("Select one or more component engines from the workspace:");
+    dialog.open();
+    Object[] files = dialog.getResult();
+
+    if (files != null && files.length > 0) {
+      for (int i = 0; i < files.length; i++) {
+        FileAndShortName fsn = new FileAndShortName(files[i]);
+        produceKeyAddDelegate(fsn.shortName, fsn.fileName, dialog.getAutoAddToFlow(),
+                dialog.isImportByName);
+      }
+    }
+  }
+
+  private void produceKeyAddDelegate(String shortName, String fullPathFileName, boolean addToFlow,
+          boolean isImportByName) {
+    boolean bSuccess = false;
+
+    // key is shortName plus a suffix if needed to make it unique.
+    // The set of existing keys is obtained from the model,
+    // not from the GUI table (as was the case in earlier design)
+
+    String keyName = produceUniqueComponentKey(shortName);
+    if (null != keyName) {
+      bSuccess = addDelegate(fullPathFileName, shortName, keyName, isImportByName);
+
+      if (bSuccess) {
+        editor.addDirtyTypeName("<Aggregate>"); // force running jcasgen
+        refresh(); // refresh every time to capture the order of items added
+        if (addToFlow) {
+          addNodeToFlow(keyName);
+        }
+      }
+    }
+  }
+
+  private void handleRemove() {
+    // get the keyName to remove
+    int nSelectionIndex = filesTable.getSelectionIndex();
+    String key = filesTable.getItem(nSelectionIndex).getText(1);
+
+    // if delegate is still on flow list warn that it may be removed
+    if (editor.getAggregatePage().getFlowSection().containsNode(key)) {
+      String sCascadeDeleteTitle = "Cascade delete warning";
+      String sCascadeDeleteMessage = "This will cause a cascading deletion of an associated input, output, index, or type priority.  Ok to continue?";
+      boolean bContinue = MessageDialog.openConfirm(getSection().getShell(), sCascadeDeleteTitle,
+              sCascadeDeleteMessage);
+      if (!bContinue) {
+        return;
+      }
+    }
+    ResourceSpecifier delegate = (ResourceSpecifier) editor.getResolvedDelegates().get(key);
+    // remove the selected delegate from delegate list
+
+    Map delegatesWithImport = editor.getAeDescription()
+            .getDelegateAnalysisEngineSpecifiersWithImports();
+    Object savedDelegate1 = delegatesWithImport.get(key);
+    delegatesWithImport.remove(key);
+
+    Object savedDelegate2 = getDelegateAnalysisEngineSpecifiersWithImports().get(key);
+    getDelegateAnalysisEngineSpecifiersWithImports().remove(key);
+
+    // update the model: flow lists: remove the item from the flow list
+    // This has to be done before validation - otherwise get validation error.
+    // Support undo
+
+    FlowNodes flow = new FlowNodes(getAnalysisEngineMetaData().getFlowConstraints());
+    String[] savedFlowNodes = flow.getFlow();
+    if (null == savedFlowNodes) 
+      savedFlowNodes = stringArray0;
+
+    // item may be in the flow 0, 1 or more times
+
+    List nodes = new ArrayList(savedFlowNodes.length);
+    for (int i = 0; i < savedFlowNodes.length; i++) {
+      String flowNode = savedFlowNodes[i];
+      if (!flowNode.equals(key)) {
+        nodes.add(flowNode);
+      }
+    }
+    flow.setFlow((String[]) nodes.toArray(stringArray0));
+
+    if (!isValidAggregateChange()) {
+      getDelegateAnalysisEngineSpecifiersWithImports().put(key, savedDelegate2);
+      delegatesWithImport.put(key, savedDelegate1);
+      flow.setFlow(savedFlowNodes);
+      return;
+    }
+
+    Map typeNameHash = editor.allTypes.get();
+
+    boolean bInputsChanged = !editor.validateInputs(typeNameHash);
+    boolean bOutputsChanged = !editor.validateOutputs(typeNameHash);
+
+    if (bInputsChanged || bOutputsChanged) {
+      String msg = "Some of the following are no longer valid and have been deleted (or appropriately altered): \n\n";
+      if (bInputsChanged) {
+        msg += "Inputs \n";
+      }
+      if (bOutputsChanged) {
+        msg += "Outputs \n";
+      }
+      Utility.popMessage("Capabilities Changed", msg, MessageDialog.INFORMATION);
+    }
+    SofaMapSection.removeSofaMappings(key, delegate, editor);
+    editor.getAggregatePage().getFlowSection().refresh();
+    if (filesTable.getItemCount() > nSelectionIndex) {
+      filesTable.setSelection(nSelectionIndex);
+      filesTable.setFocus();
+      enable();
+    }
+    refresh();
+    finishAggregateChangeAction();
+
+    // remove still must handle removal of parameters and param settings
+    // removed delegate (if params dont appear elsewhere)
+  }
+
+  private void handleAddToFlow() {
+    String node = filesTable.getSelection()[0].getText(1);
+    addNodeToFlow(node);
+    getTable().setSelection(-1);
+    enable();
+    Table flowList = editor.getAggregatePage().getFlowSection().getFlowList();
+    flowList.setSelection(flowList.getItemCount() - 1);
+    editor.getAggregatePage().getFlowSection().enable();
+    flowList.setFocus();
+  }
+
+  /**
+   * @param node
+   */
+  private void addNodeToFlow(String node) {
+    FlowSection fs = editor.getAggregatePage().getFlowSection();
+    fs.addNode(node);
+//    fs.refresh();  // the fs.addNode does a refresh
+  }
+
+  private void handleRemoveFromFlow() {
+    FlowSection fs = editor.getAggregatePage().getFlowSection();
+    String selectedKey = fs.getFlowList().getSelection()[0].getText();
+    fs.handleRemove();
+    for (int i = 0; i < getTable().getItemCount(); i++) {
+      String thisKey = getTable().getItem(i).getText(1);
+      if (selectedKey.equals(thisKey)) {
+        getTable().setSelection(i);
+        enable();
+        getTable().setFocus();
+        break;
+      }
+    }
+  }
+
+  private final static String REMOTE_TEMPLATE = "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n"
+          + "<uriSpecifier xmlns=\"http://uima.apache.org/resourceSpecifier\">\n"
+          + "  <resourceType>{0}</resourceType>\n" + // AnalysisEngine CasConsumer
+          "  <uri>{1}</uri> \n" + // sURI
+          "  <protocol>{2}</protocol>\n" + // SOAP or Vinci
+          "  <timeout>{3}</timeout>" + "  {4}" + // <parameters> for VNS </parameters>
+          "\n</uriSpecifier>";
+
+  private void handleAddRemote() {
+    String sDescriptorPath = editor.getFile().getParent().getLocation().toString() + '/';
+    AddRemoteServiceDialog dialog = new AddRemoteServiceDialog(this, sDescriptorPath);
+    dialog.open();
+    if (dialog.getReturnCode() == InputDialog.CANCEL)
+      return;
+
+    String sServiceType = dialog.getSelectedServiceTypeName();
+    if (sServiceType != null && !sServiceType.equals("SOAP") && !sServiceType.equals("Vinci")) {
+      return;
+    }
+    String sURI = dialog.getSelectedUri();
+    String sKey = dialog.getSelectedKey();
+
+    if (!isNewKey(sKey)) {
+      Utility.popMessage("Duplicate Key", "You have specified a duplicate key.  Please try again.",
+              MessageDialog.ERROR);
+      return;
+    }
+
+    PrintWriter printWriter = setupToPrintFile(dialog.genFilePath);
+    if (null != printWriter) {
+      String vnsHostPort = "";
+      if (dialog.vnsHost.length() > 0) {
+        vnsHostPort = MessageFormat.format("    <parameter name=\"VNS_HOST\" value=\"{0}\"/>\n",
+                new Object[] { dialog.vnsHost });
+      }
+      if (dialog.vnsPort.length() > 0) {
+        vnsHostPort += MessageFormat.format("    <parameter name=\"VNS_PORT\" value=\"{0}\"/>\n",
+                new Object[] { dialog.vnsPort });
+      }
+      if (vnsHostPort.length() > 0)
+        vnsHostPort = "\n  <parameters>" + vnsHostPort + "  </parameters>";
+      printWriter.println(MessageFormat.format(REMOTE_TEMPLATE, new Object[] { dialog.aeOrCc, sURI,
+          sServiceType, dialog.timeout, vnsHostPort }));
+      printWriter.close();
+
+      boolean bSuccess = addDelegate(dialog.genFilePath, sKey, sKey, dialog.isImportByName);
+      if (bSuccess) {
+        boolean bAutoAddToFlow = dialog.getAutoAddToFlow();
+        if (bAutoAddToFlow) {
+          addNodeToFlow(sKey);
+        }
+        refresh();
+      }
+    }
+  }
+
+  private static final String[] delegateComponentStringHeadersLC = new String[] {
+      "<analysisenginedescription", "<casconsumerdescription", "<taedescription" };
+
+  private void handleFindAnalysisEngine() {
+    FindComponentDialog dialog1 = new FindComponentDialog(
+            this,
+            "Find an Analysis Engine (AE), CAS Consumer, or Remote Service Descriptor",
+            "Specify a name pattern and/or additional constraints, and then push the Search button",
+            delegateComponentStringHeadersLC);
+    if (Window.CANCEL == dialog1.open())
+      return;
+
+    List matchingDelegateComponentDescriptors = dialog1.getMatchingDelegateComponentDescriptors();
+    List matchingDelegateComponentDescriptions = dialog1.getMatchingDelegateComponentDescriptions();
+
+    if (matchingDelegateComponentDescriptors.size() == 0) {
+      Utility.popMessage("No matching Delegate Components",
+              "There are no Delegate Components matching your search criteria.",
+              MessageDialog.ERROR);
+      return;
+    }
+
+    PickTaeForTypesDialog dialog2 = new PickTaeForTypesDialog(this, editor.getFile().getName(),
+            matchingDelegateComponentDescriptors, matchingDelegateComponentDescriptions);
+    if (Window.CANCEL == dialog2.open())
+      return;
+
+    String[] selectedDelegateComponentDescriptors = dialog2
+            .getSelectedDelegateComponentDescriptors();
+
+    if (selectedDelegateComponentDescriptors == null
+            || selectedDelegateComponentDescriptors.length == 0) {
+      return;
+    }
+
+    for (int i = 0; i < selectedDelegateComponentDescriptors.length; i++) {
+      String fileName = selectedDelegateComponentDescriptors[i].replace('\\', '/');
+      int nLastSlashLoc = fileName.lastIndexOf('/');
+      String shortName;
+      if (nLastSlashLoc == -1) {
+        shortName = fileName;
+      } else {
+        shortName = fileName.substring(nLastSlashLoc + 1);
+      }
+      produceKeyAddDelegate(shortName, editor.getFullPathFromDescriptorRelativePath(fileName),
+      // dialog2.getAutoAddToFlow(),
+              true, dialog2.isImportByName);
+    }
+    finishAggregateChangeAction();
+  }
+
+  private void handleTableContextMenuRequest(Event event) {
+    TableItem item = filesTable.getItem(new Point(event.x, event.y));
+    if (null == item) {
+      return;
+    }
+
+    String thisKey = item.getText(1);
+    Import imp = (Import) getDelegateAnalysisEngineSpecifiersWithImports().get(thisKey);
+
+    bDisableToolTipHelp = true;
+    requestPopUpOverImport(imp, filesTable, event);
+    bDisableToolTipHelp = false;
+  }
+
+  private void handleTableHoverHelp(Event event) {
+    TableItem item = filesTable.getItem(new Point(event.x, event.y));
+    String sDesc = "";
+    if (null != item) {
+      Map dels = editor.getResolvedDelegates();
+      if (null != dels) {
+        sDesc = getDescriptionForDescriptor(item.getText(0), (ResourceSpecifier) dels.get(item
+                .getText(1)));
+      }
+    }
+    filesTable.setToolTipText(sDesc);
+  }
+
+  private boolean addDelegate(String fileName, String shortName, String keyName,
+          boolean isImportByName) {
+    Import imp;
+    Map delegatesWithImport = getDelegateAnalysisEngineSpecifiersWithImports();
+
+    // if the delegate is not a remote, read / parse it and add ae to
+    // the delegate hash map
+    // -- also add the import
+    // If it is a remote - try and get it's metadata (we can if it is running)
+
+    // first: create import, needed in both cases
+    imp = createImport(fileName, isImportByName);
+
+    // read the content and merge into our model
+    XMLizable inputDescription = readImport(imp, fileName, isImportByName);
+    if (null == inputDescription)
+      return false;
+
+    if (!(inputDescription instanceof AnalysisEngineDescription)
+            && !(inputDescription instanceof CasConsumerDescription)
+            && !(inputDescription instanceof URISpecifier)) {
+      Utility
+              .popMessage(
+                      "Invalid kind of descriptor",
+                      MessageFormat
+                              .format(
+                                      "Operation cancelled: The descriptor ''{0}'' being added is not an Analysis Engine or a CAS Consumer or a Remote Service.",
+                                      new Object[] { maybeShortenFileName(fileName) }),
+                      MessageDialog.ERROR);
+      return false;
+    }
+
+    editor.getResolvedDelegates().put(keyName, inputDescription);
+    delegatesWithImport.put(keyName, imp);
+
+    // before adding the import, see if the merge type system is OK
+    if (!isValidAggregateChange()) {
+      // revert
+      editor.getResolvedDelegates().remove(keyName);
+      delegatesWithImport.remove(keyName);
+      return false;
+    }
+
+    finishAggregateChangeAction();
+    return true;
+  }
+
+  private boolean isNewKey(String keyName) {
+    for (int i = 0; i < filesTable.getItemCount(); i++) {
+      if (filesTable.getItem(i).getText(1).equals(keyName)) {
+        return false;
+      }
+    }
+    return true;
+  }
+
+  public void addParametersForDelegate(AnalysisEngineDescription tae) {
+    ConfigurationParameter[] candidateNewParams = tae.getAnalysisEngineMetaData()
+            .getConfigurationParameterDeclarations().getConfigurationParameters();
+
+    NameValuePair[] candidateSettings = tae.getAnalysisEngineMetaData()
+            .getConfigurationParameterSettings().getParameterSettings();
+
+    ConfigurationParameter[] oldParams = getAnalysisEngineMetaData()
+            .getConfigurationParameterDeclarations().getConfigurationParameters();
+
+    NameValuePair[] oldSettings = getAnalysisEngineMetaData().getConfigurationParameterSettings()
+            .getParameterSettings();
+
+    if (candidateNewParams == null || candidateNewParams.length == 0) {
+      return;
+    }
+
+    if (oldParams == null || oldParams.length == 0) {
+      getAnalysisEngineMetaData().getConfigurationParameterDeclarations()
+              .setConfigurationParameters(candidateNewParams);
+      getAnalysisEngineMetaData().getConfigurationParameterSettings().setParameterSettings(
+              candidateSettings);
+    } else {
+      // first do parameters
+      Vector newParams = new Vector();
+      for (int i = 0; i < candidateNewParams.length; i++) {
+        boolean bNew = true;
+        for (int j = 0; j < oldParams.length; j++) {
+          if (candidateNewParams[i].getName().equals(oldParams[j].getName())
+                  && candidateNewParams[i].getType().equals(oldParams[j].getType())) {
+            bNew = false;
+          }
+        }
+        if (bNew) {
+          newParams.add(candidateNewParams[i]);
+        }
+      }
+
+      ConfigurationParameter[] newPlusOldParams = new ConfigurationParameter[oldParams.length
+              + newParams.size()];
+      for (int i = 0; i < oldParams.length; i++) {
+        newPlusOldParams[i] = oldParams[i];
+      }
+      for (int i = 0; i < newParams.size(); i++) {
+        newPlusOldParams[oldParams.length + i] = (ConfigurationParameter) newParams.elementAt(i);
+      }
+      getAnalysisEngineMetaData().getConfigurationParameterDeclarations()
+              .setConfigurationParameters(newPlusOldParams);
+
+      // next do settings
+      Vector newSettings = new Vector();
+      if (candidateSettings != null) {
+        for (int i = 0; i < candidateSettings.length; i++) {
+          boolean bNew = true;
+          for (int j = 0; j < oldSettings.length; j++) {
+            if (candidateSettings[i].getName().equals(oldSettings[j].getName())) {
+              bNew = false;
+            }
+          }
+          if (bNew) {
+            newSettings.add(candidateSettings[i]);
+          }
+        }
+      }
+
+      NameValuePair[] newPlusOldSettings = new NameValuePair[oldSettings.length
+              + newSettings.size()];
+      for (int i = 0; i < oldSettings.length; i++) {
+        newPlusOldSettings[i] = oldSettings[i];
+      }
+      for (int i = 0; i < newSettings.size(); i++) {
+        newPlusOldSettings[oldSettings.length + i] = (NameValuePair) newSettings.elementAt(i);
+      }
+      getAnalysisEngineMetaData().getConfigurationParameterSettings().setParameterSettings(
+              newPlusOldSettings);
+    }
+  }
+
+  public void enable() {
+    boolean isPrimitive = isPrimitive();
+    boolean bEnable = (filesTable.getSelectionIndex() > -1);
+
+    addButton.setEnabled(!isPrimitive);
+    addRemoteButton.setEnabled(!isPrimitive);
+    findAnalysisEngineButton.setEnabled(!isPrimitive);
+    removeButton.setEnabled(bEnable);
+    addToFlowButton.setEnabled(bEnable);
+  }
+
+  /**
+   * adds a tableItem to the table
+   * 
+   * @param fileName
+   * @param keyName
+   */
+  private void addFile(Object o, String keyName) {
+    Import impItem = (Import) o;
+    String fileName = impItem.getLocation();
+    if (null == fileName || (0 == fileName.length()))
+      fileName = impItem.getName();
+    // create new TableItem
+    TableItem item = new TableItem(filesTable, SWT.NONE);
+    item.setImage(TAEConfiguratorPlugin.getImage(TAEConfiguratorPlugin.IMAGE_ANNOTATOR));
+    item.setText(0, fileName);
+    item.setText(1, keyName);
+  }
+
+  public Table getTable() {
+    return filesTable;
+  }
+
+}
diff --git a/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/CapabilityPage.java b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/CapabilityPage.java
new file mode 100644
index 0000000..02718ec
--- /dev/null
+++ b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/CapabilityPage.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.taeconfigurator.editors.ui;
+
+import org.apache.uima.taeconfigurator.editors.Form2Panel;
+import org.apache.uima.taeconfigurator.editors.MultiPageEditor;
+import org.eclipse.swt.SWT;
+import org.eclipse.ui.forms.IManagedForm;
+
+public class CapabilityPage extends HeaderPageWithSash {
+
+  private SofaMapSection sofaMapSection;
+
+  public CapabilityPage(MultiPageEditor aEditor) {
+    super(aEditor, "Capabilities");
+  }
+
+  /**
+   * Called by the framework to fill in the contents
+   */
+  protected void createFormContent(IManagedForm managedForm) {
+    final Form2Panel form2Panel = setup2ColumnLayout(managedForm, editor.isAggregate() ? 50 : 90,
+            editor.isAggregate() ? 50 : 10);
+    managedForm.getForm().setText("Capabilities: Inputs and Outputs");
+    managedForm.addPart(/* inputSection = */new CapabilitySection(editor, form2Panel.left));
+    managedForm.addPart(sofaMapSection = new SofaMapSection(editor, form2Panel.right));
+    createToolBarActions(managedForm);
+    sashForm.setOrientation(SWT.VERTICAL);
+    vaction.setChecked(true);
+    haction.setChecked(false);
+    managedForm.getForm().reflow(true);
+  }
+
+  public SofaMapSection getSofaMapSection() {
+    return sofaMapSection;
+  }
+}
diff --git a/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/CapabilitySection.java b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/CapabilitySection.java
new file mode 100644
index 0000000..0eadaec
--- /dev/null
+++ b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/CapabilitySection.java
@@ -0,0 +1,1088 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS 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.taeconfigurator.editors.ui;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.TreeMap;
+
+import org.apache.uima.analysis_engine.TypeOrFeature;
+import org.apache.uima.analysis_engine.impl.TypeOrFeature_impl;
+import org.apache.uima.analysis_engine.metadata.SofaMapping;
+import org.apache.uima.cas.Type;
+import org.apache.uima.resource.metadata.Capability;
+import org.apache.uima.taeconfigurator.InternalErrorCDE;
+import org.apache.uima.taeconfigurator.editors.MultiPageEditor;
+import org.apache.uima.taeconfigurator.editors.ui.dialogs.AddCapabilityFeatureDialog;
+import org.apache.uima.taeconfigurator.editors.ui.dialogs.AddCapabilityTypeDialog;
+import org.apache.uima.taeconfigurator.editors.ui.dialogs.AddSofaDialog;
+import org.apache.uima.taeconfigurator.editors.ui.dialogs.CommonInputDialog;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.window.Window;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.TableTree;
+import org.eclipse.swt.custom.TableTreeItem;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.TableColumn;
+import org.eclipse.ui.forms.IManagedForm;
+
+public class CapabilitySection extends AbstractSection {
+
+  private final static String CAPABILITY_SET = "Set";
+
+  private final static String INPUT = "Input";
+
+  private final static String OUTPUT = "Output";
+
+  public final static String ALL_FEATURES = "<all features>";
+
+  private final static String TYPE_TITLE = "Type:";
+
+  private final static String FEAT_TITLE = "F:"; // not shown, in data field
+
+  private final static String NAME_TITLE = "Name                ";
+
+  private final static String NAMESPACE_TITLE = "Name Space";
+
+  private final static String LANGS_TITLE = "Languages";
+
+  private final static String LANG_TITLE = "L:"; // not shown, in datafield
+
+  private final static String SOFAS_TITLE = "Sofas";
+
+  private final static String SOFA_TITLE = "S:"; // not shown, in data field
+
+  private final static int CS = 1;
+
+  private final static int TYPE = 1 << 1;
+
+  private final static int FEAT = 1 << 2;
+
+  private final static int LANG = 1 << 3;
+
+  private final static int LANG_ITEM = 1 << 4;
+
+  private final static int SOFA = 1 << 5;
+
+  private final static int SOFA_ITEM = 1 << 6;
+
+  public final static int TITLE_COL = 0;
+
+  public final static int NAME_COL = 1;
+
+  public final static int INPUT_COL = 2;
+
+  public final static int OUTPUT_COL = 3;
+
+  public final static int NAMESPACE_COL = 4;
+
+  TableTree tt; // for inner class access
+
+  private Button addCapabilityButton;
+
+  private Button addLangButton;
+
+  private Button addTypeButton;
+
+  private Button addSofaButton;
+
+  private Button addEditFeatureButton;
+
+  private Button editButton;
+
+  private Button removeButton;
+
+  private Map typeInfo;
+
+  private SofaMapSection sofaMapSection;
+
+  public CapabilitySection(MultiPageEditor aEditor, Composite parent) {
+    super(
+            aEditor,
+            parent,
+            "Component Capabilities",
+            "This section describes the languages handled, and the inputs needed and outputs provided in terms of the Types and Features.");
+  }
+
+  public void initialize(IManagedForm form) {
+    super.initialize(form);
+
+    Composite sectionClient = new2ColumnComposite(getSection());
+    enableBorders(sectionClient);
+    toolkit.paintBordersFor(sectionClient);
+
+    tt = newTableTree(sectionClient, SWT.V_SCROLL | SWT.SINGLE | SWT.FULL_SELECTION);
+    Table table = tt.getTable();
+
+    // work around for bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=65865
+    new TableColumn(table, SWT.NONE).setText("                 ");
+
+    newTableColumn(table, SWT.NONE).setText(NAME_TITLE); // type or feat name
+    newTableColumn(table, SWT.NONE).setText(INPUT);
+    newTableColumn(table, SWT.NONE).setText(OUTPUT);
+    newTableColumn(table, SWT.NONE).setText(NAMESPACE_TITLE); // rest of typename
+    table.setHeaderVisible(true);
+    table.setLinesVisible(true);
+    tt.addListener(SWT.MouseHover, this); // to show description
+
+    final Composite buttonContainer = newButtonContainer(sectionClient);
+    addCapabilityButton = newPushButton(
+            buttonContainer,
+            "Add Capability Set",
+            "Analysis Engines can have one or more sets of capabilities; each one describes a set of outputs that are produced, given a particular set of inputs. Click here to add a capability set.");
+    addLangButton = newPushButton(buttonContainer, "Add Language",
+            "Click here to add a Language Capability to the selected set.");
+    addTypeButton = newPushButton(buttonContainer, "Add Type",
+            "Click here to add a Type to the selected capability set.");
+    addSofaButton = newPushButton(buttonContainer, "Add Sofa",
+            "Click here to add a Subject of Analysis (Sofa) to the selected capability set.");
+    addEditFeatureButton = newPushButton(buttonContainer, "Add/Edit Features",
+            "Click here to specify the features of a selected type as input or output");
+    editButton = newPushButton(buttonContainer, S_EDIT,
+            "Edit the selected item. You can also double-click the item to edit it.");
+    removeButton = newPushButton(buttonContainer, "Remove",
+            "Remove the selected item.  You can also press the Delete key to remove an item.");
+  }
+
+  /*
+   * (non-Javadoc)
+   * 
+   * @see org.eclipse.ui.forms.IFormPart#refresh()
+   */
+  public void refresh() {
+    super.refresh();
+    sofaMapSection = editor.getCapabilityPage().getSofaMapSection();
+    tt.getParent().setRedraw(false);
+    tt.removeAll();
+
+    Capability[] cs = getCapabilities();
+    if (null != cs) {
+      for (int i = 0; i < cs.length; i++) {
+        TableTreeItem item = new TableTreeItem(tt, SWT.NONE);
+        item.setText(TITLE_COL, CAPABILITY_SET);
+        item.setData(cs[i]);
+        tt.setSelection(new TableTreeItem[] { item }); // set default selection
+        fillCapability(item, cs[i]);
+        // if (0 == i) {
+        item.setExpanded(true);
+        TableTreeItem[] types = item.getItems();
+        if (types != null)
+          for (int j = 0; j < types.length; j++) {
+            types[j].setExpanded(true);
+          }
+        // }
+      }
+    }
+    packTable(tt.getTable());
+    enable();
+    tt.getParent().setRedraw(true);
+  }
+
+  /**
+   * value of hash table keyed on type name
+   */
+  private static class TypeCapability {
+    boolean isInputType; // true if mentioned in <type>
+
+    boolean isOutputType; // true if mentioned in <type>
+
+    Map features = new TreeMap();
+  }
+
+  private static class FeatureCapability {
+    boolean isInputFeature = false;
+
+    boolean isOutputType = false;
+
+    boolean isOutputUpdate = false;
+  }
+
+  private TableTreeItem createLanguageHeaderGui(TableTreeItem parent) {
+    TableTreeItem langHdr = new TableTreeItem(parent, SWT.NONE);
+    langHdr.setText(TITLE_COL, LANGS_TITLE);
+    langHdr.setData(LANGS_TITLE);
+    return langHdr;
+  }
+
+  private TableTreeItem createSofaHeaderGui(TableTreeItem parent) {
+    TableTreeItem sofaHdr = new TableTreeItem(parent, SWT.NONE);
+    sofaHdr.setText(TITLE_COL, SOFAS_TITLE);
+    sofaHdr.setData(SOFAS_TITLE);
+    return sofaHdr;
+  }
+
+  private void fillCapability(TableTreeItem parent, Capability c) {
+    // first output language capabilities
+    TableTreeItem langHdr = createLanguageHeaderGui(parent);
+    String[] languages = c.getLanguagesSupported();
+    if (null != languages) {
+      for (int i = 0; i < languages.length; i++) {
+        TableTreeItem lItem = new TableTreeItem(langHdr, SWT.NONE);
+        lItem.setData(LANG_TITLE);
+        lItem.setText(NAME_COL, languages[i]);
+      }
+    }
+
+    // second, output Sofas
+    TableTreeItem sofaHdr = createSofaHeaderGui(parent);
+    String[] inputSofaNames = c.getInputSofas();
+    String[] outputSofaNames = c.getOutputSofas();
+    Arrays.sort(inputSofaNames);
+    Arrays.sort(outputSofaNames);
+    for (int i = 0; i < inputSofaNames.length; i++) {
+      TableTreeItem item = new TableTreeItem(sofaHdr, SWT.NONE);
+      setGuiSofaName(item, inputSofaNames[i], true);
+    }
+    for (int i = 0; i < outputSofaNames.length; i++) {
+      TableTreeItem item = new TableTreeItem(sofaHdr, SWT.NONE);
+      setGuiSofaName(item, outputSofaNames[i], false);
+    }
+
+    // scan capability, collecting for each type:
+    // inputs, outputs, updatesToInputs(features)
+    // (updatesToInputs are output features without corresponding output type)
+    // <noFeatures>, or <allFeatures> or feature set
+    // For each item, generate minimal number of Type items:
+
+    TypeCapability tc = null;
+    FeatureCapability fc;
+    TypeOrFeature[] inputs = c.getInputs();
+    TypeOrFeature[] outputs = c.getOutputs();
+    typeInfo = new TreeMap();
+
+    if (null != inputs) {
+      for (int i = 0; i < inputs.length; i++) {
+        String name = inputs[i].getName();
+        if (inputs[i].isType()) {
+          tc = getTypeCapability(name);
+          tc.isInputType = true;
+          if (inputs[i].isAllAnnotatorFeatures()) {
+            fc = getFeatureCapability(tc, ALL_FEATURES);
+            fc.isInputFeature = true;
+          }
+        } else {
+          tc = getTypeCapability(getTypeNameFromFullFeatureName(name)); // create a typecapability
+          // if one doesn't exist
+          fc = getFeatureCapability(tc, getShortFeatureName(name));
+          fc.isInputFeature = true;
+        }
+      }
+    }
+
+    if (null != outputs) {
+      for (int i = 0; i < outputs.length; i++) {
+        String name = outputs[i].getName();
+        if (outputs[i].isType()) {
+          tc = getTypeCapability(name);
+          tc.isOutputType = true;
+          if (outputs[i].isAllAnnotatorFeatures()) {
+            fc = getFeatureCapability(tc, ALL_FEATURES);
+            fc.isOutputType = true;
+          }
+        } else {
+          tc = getTypeCapability(getTypeNameFromFullFeatureName(name));
+          fc = getFeatureCapability(tc, getShortFeatureName(name));
+          fc.isOutputUpdate = true;
+        }
+      }
+    }
+
+    for (Iterator it = typeInfo.entrySet().iterator(); it.hasNext();) {
+      Map.Entry entry = (Map.Entry) it.next();
+      String typeName = (String) entry.getKey();
+      tc = (TypeCapability) entry.getValue();
+
+      TableTreeItem item = new TableTreeItem(parent, SWT.NONE);
+      setGuiTypeName(item, typeName);
+      if (tc.isInputType)
+        item.setText(INPUT_COL, INPUT);
+      if (tc.isOutputType)
+        item.setText(OUTPUT_COL, OUTPUT);
+
+      for (Iterator fit = tc.features.entrySet().iterator(); fit.hasNext();) {
+        Map.Entry fEntry = (Map.Entry) fit.next();
+        String featName = (String) fEntry.getKey();
+        fc = (FeatureCapability) fEntry.getValue();
+
+        TableTreeItem fItem = new TableTreeItem(item, SWT.NONE);
+        fItem.setData(FEAT_TITLE);
+        fItem.setText(NAME_COL, featName);
+        if (fc.isInputFeature)
+          fItem.setText(INPUT_COL, INPUT);
+        if (fc.isOutputUpdate || fc.isOutputType) {
+          fItem.setText(OUTPUT_COL, OUTPUT);
+        }
+      }
+    }
+  }
+
+  private void setGuiTypeName(TableTreeItem item, String typeName) {
+    item.setText(TITLE_COL, TYPE_TITLE);
+    item.setText(NAME_COL, getShortName(typeName));
+    item.setText(NAMESPACE_COL, getNameSpace(typeName));
+  }
+
+  private void setGuiSofaName(TableTreeItem item, String sofaName, boolean isInput) {
+    item.setData(SOFA_TITLE);
+    item.setText(NAME_COL, sofaName);
+    if (isInput) {
+      item.setText(INPUT_COL, INPUT);
+      item.setText(OUTPUT_COL, "");
+    } else {
+      item.setText(OUTPUT_COL, OUTPUT);
+      item.setText(INPUT_COL, "");
+    }
+  }
+
+  private TypeCapability getTypeCapability(String typeName) {
+    TypeCapability typeCapability = (TypeCapability) typeInfo.get(typeName);
+    if (null == typeCapability) {
+      typeInfo.put(typeName, typeCapability = new TypeCapability());
+    }
+    return typeCapability;
+  }
+
+  private FeatureCapability getFeatureCapability(TypeCapability tc, String featureShortName) {
+    FeatureCapability fc = (FeatureCapability) tc.features.get(featureShortName);
+    if (null == fc) {
+      tc.features.put(featureShortName, fc = new FeatureCapability());
+    }
+    return fc;
+  }
+
+  public String getTypeNameFromFullFeatureName(String name) {
+    return (name.substring(0, name.indexOf(":")));
+  }
+
+  /*
+   * (non-Javadoc)
+   * 
+   * @see org.apache.uima.taeconfigurator.editors.ui.AbstractTableSection#handleEvent(org.eclipse.swt.widgets.Event)
+   */
+  public void handleEvent(Event event) {
+    if (event.type == SWT.Expand || event.type == SWT.Collapse) {
+      pack04();
+      return;
+    }
+    if (event.widget == addCapabilityButton) {
+      handleAddCapability();
+      enable();
+      return;
+    }
+
+    TableTreeItem selItem = tt.getSelection()[0];
+    int itemKind = getItemKind(selItem);
+
+    if (event.widget == addLangButton) {
+      handleAddLang(selItem, itemKind);
+    } else if (event.widget == addTypeButton) {
+      handleAddType(selItem, itemKind);
+    } else if (event.widget == addSofaButton) {
+      handleAddSofa(selItem, itemKind);
+    } else if (event.widget == addEditFeatureButton) {
+      handleAddEditFeature(selItem, itemKind);
+    } else if (event.widget == editButton || event.type == SWT.MouseDoubleClick) {
+      handleEdit(selItem, itemKind);
+    } else if (event.widget == removeButton
+            || (event.widget == tt.getTable() && event.type == SWT.KeyUp && event.character == SWT.DEL)) {
+      handleRemove(selItem, itemKind);
+    }
+
+    enable();
+  }
+
+  private void handleAddCapability() {
+    Capability newCset = addCapabilitySet();
+
+    // update the GUI
+    TableTreeItem item = new TableTreeItem(tt, SWT.NONE);
+    item.setText(CAPABILITY_SET);
+    item.setData(newCset);
+    createLanguageHeaderGui(item);
+    createSofaHeaderGui(item);
+
+    item.setExpanded(true);
+    tt.setSelection(new TableTreeItem[] { item });
+    if (tt.getItemCount() == 1)
+      tt.getTable().getColumn(TITLE_COL).pack();
+    finishAction();
+  }
+
+  private void getOrCreateAllFeatItem(TableTreeItem editItem, int column, String inOrOut) {
+    TableTreeItem allFeatItem = getAllFeatItem(editItem);
+    if (null == allFeatItem) {
+      allFeatItem = new TableTreeItem(editItem, SWT.NONE, 0);
+      allFeatItem.setData(FEAT_TITLE);
+      allFeatItem.setText(NAME_COL, ALL_FEATURES);
+    }
+    allFeatItem.setText(column, inOrOut);
+  }
+
+  private TableTreeItem getAllFeatItem(TableTreeItem editItem) {
+    TableTreeItem[] subItems = editItem.getItems();
+    if (null == subItems || subItems.length == 0)
+      return null;
+    TableTreeItem item = subItems[0];
+    if (ALL_FEATURES.equals(item.getText(NAME_COL)))
+      return item;
+    return null;
+  }
+
+  private void removeAllFeatItemGui(TableTreeItem editItem, int column) {
+    TableTreeItem allFeatItem = getAllFeatItem(editItem);
+    if (null == allFeatItem)
+      // throw new InternalErrorCDE("invalid state");
+      return; // happens when no allfeat is set
+    allFeatItem.setText(column, "");
+    String otherCol = allFeatItem.getText((column == INPUT_COL) ? OUTPUT_COL : INPUT_COL);
+    if (null == otherCol || "".equals(otherCol))
+      allFeatItem.dispose();
+  }
+
+  private void handleEdit(TableTreeItem editItem, int itemKind) {
+    Capability c = getCapability(editItem);
+    switch (itemKind) {
+      case SOFA_ITEM: {
+        boolean existingIsInput = INPUT.equals(editItem.getText(INPUT_COL));
+        String existingSofaName = editItem.getText(NAME_COL);
+        AddSofaDialog dialog = new AddSofaDialog(this, c, existingSofaName, existingIsInput);
+        if (dialog.open() == Window.CANCEL)
+          return;
+
+        if (dialog.isInput == existingIsInput && dialog.sofaName.equals(existingSofaName))
+          return;
+
+        // MODEL UPDATING
+        // if rename,
+        // update entry or remove / add entry
+        // DO FOR ALL INSTANCES IN ALL CAPABILITY SETS.
+        // change name in all mappings
+        // if switch from input to output, delete from one array, add to other,
+        // mappings: no change (maybe the user switches the other items too).
+        if (Window.CANCEL == Utility
+                .popOkCancel(
+                        "Confirm Change to all Capability Sets",
+                        "This edit operation will change the Sofa in all Capability Sets in which it is defined.  Please confirm.",
+                        MessageDialog.WARNING))
+          return;
+        final Capability[] cSets = getCapabilities();
+        for (int i = 0; i < cSets.length; i++) {
+          boolean wasRemoved;
+          String[] prevSofas;
+          if (existingIsInput) {
+            cSets[i].setInputSofas((String[]) Utility.removeElementsFromArray(prevSofas = cSets[i]
+                    .getInputSofas(), existingSofaName, String.class));
+            wasRemoved = prevSofas != cSets[i].getInputSofas();
+          } else {
+            cSets[i].setOutputSofas((String[]) Utility.removeElementsFromArray(prevSofas = cSets[i]
+                    .getOutputSofas(), existingSofaName, String.class));
+            wasRemoved = prevSofas != cSets[i].getOutputSofas();
+          }
+          if (wasRemoved) {
+            if (dialog.isInput) {
+              cSets[i].setInputSofas(stringArrayAdd(cSets[i].getInputSofas(), dialog.sofaName));
+            } else {
+              cSets[i].setOutputSofas(stringArrayAdd(cSets[i].getOutputSofas(), dialog.sofaName));
+            }
+          }
+        }
+        if (!dialog.sofaName.equals(existingSofaName)) {
+          // rename in mappings
+          SofaMapping[] mappings = getSofaMappings();
+          for (int i = 0; i < mappings.length; i++) {
+            if (existingSofaName.equals(mappings[i].getAggregateSofaName())) {
+              mappings[i].setAggregateSofaName(dialog.sofaName);
+            }
+          }
+        }
+
+        // GUI updating:
+        // setGuiSofaName(editItem, dialog.sofaName, dialog.isInput);
+        refresh(); // because multiple capability sets may have changed
+        sofaMapSection.markStale();
+        finishAction();
+        pack04();
+        break;
+      }
+      case TYPE: {
+        AddCapabilityTypeDialog dialog = new AddCapabilityTypeDialog(this, c, editItem);
+        if (dialog.open() == Window.CANCEL)
+          return;
+
+        TypeOrFeature typeInput = getTypeOrFeature(c.getInputs(), getFullyQualifiedName(editItem));
+
+        if (dialog.inputs[0]) {
+          if (null == typeInput) {
+            c.addInputType(dialog.types[0], true);
+            // add all-features
+            getOrCreateAllFeatItem(editItem, INPUT_COL, INPUT);
+          }
+        } else if (null != typeInput) { // check for any input features done in dialog
+          c.setInputs(typeOrFeatureArrayRemove(c.getInputs(), typeInput));
+          removeAllFeatItemGui(editItem, INPUT_COL);
+        }
+
+        TypeOrFeature typeOutput = getTypeOrFeature(c.getOutputs(), getFullyQualifiedName(editItem));
+
+        if (dialog.outputs[0]) {
+          if (null == typeOutput) {
+            c.addOutputType(dialog.types[0], true);
+            getOrCreateAllFeatItem(editItem, OUTPUT_COL, OUTPUT);
+          }
+        } else if (null != typeOutput) {
+          c.setOutputs(typeOrFeatureArrayRemove(c.getOutputs(), typeOutput));
+          removeAllFeatItemGui(editItem, OUTPUT_COL);
+        }
+
+        if (dialog.inputs[0] || dialog.outputs[0]) {
+          editItem.setText(INPUT_COL, dialog.inputs[0] ? INPUT : "");
+          editItem.setText(OUTPUT_COL, dialog.outputs[0] ? OUTPUT : "");
+        } else {
+          editItem.dispose();
+          pack04();
+        }
+        finishAction();
+        break;
+      }
+      case LANG_ITEM: {
+        CommonInputDialog dialog = new CommonInputDialog(
+                this,
+                "Edit Language",
+                "Enter a two letter ISO-639 language code, followed optionally by a two-letter ISO-3166 country code (Examples: fr or fr-CA)",
+                CommonInputDialog.LANGUAGE, editItem.getText(NAME_COL));
+        if (dialogForLanguage(c, dialog) == Window.CANCEL)
+          return;
+        c.getLanguagesSupported()[getIndex(editItem)] = dialog.getValue();
+        // update GUI
+        editItem.setText(NAME_COL, dialog.getValue());
+        finishAction();
+        break;
+      }
+
+      case FEAT: {
+        TableTreeItem typeItem = editItem.getParentItem();
+        String typeName = getFullyQualifiedName(typeItem);
+
+        // using the CAS to get all the inherited features
+        Type type = editor.getCurrentView().getTypeSystem().getType(typeName);
+
+        AddCapabilityFeatureDialog dialog = new AddCapabilityFeatureDialog(this, type, c);
+        if (dialog.open() == Window.CANCEL)
+          return;
+
+        addOrEditFeature(dialog, typeName, typeItem, c);
+        break;
+      }
+      default:
+        break; // happens when mouse double click on non-editable item - ignore
+    }
+  }
+
+  private boolean anyCapabilitySetDeclaresSofa(String name, boolean isInput) {
+    final Capability[] cSets = getAnalysisEngineMetaData().getCapabilities();
+    for (int i = 0; i < cSets.length; i++) {
+      final String[] sofaNames = isInput ? cSets[i].getInputSofas() : cSets[i].getOutputSofas();
+      for (int j = 0; j < sofaNames.length; j++) {
+        if (name.equals(sofaNames[j]))
+          return true;
+      }
+    }
+    return false;
+  }
+
+  private void handleRemove(TableTreeItem removeItem, int itemKind) {
+    Table table = tt.getTable();
+    int previousSelection = table.getSelectionIndex() - 1;
+    Capability c = getCapability(removeItem);
+    switch (itemKind) {
+      case CS: {
+        if (Window.CANCEL == Utility.popOkCancel("Confirm Remove",
+                "This action will remove an entire capability set.  Please confirm.",
+                MessageDialog.WARNING)) {
+          table.setSelection(table.getSelectionIndex() + 1);
+          return;
+        }
+        removeCapabilitySet(c);
+        removeItem.dispose();
+        break;
+      }
+      case LANG_ITEM: {
+        c.setLanguagesSupported(stringArrayRemove(c.getLanguagesSupported(), removeItem
+                .getText(NAME_COL)));
+        removeItem.dispose();
+        break;
+      }
+      case SOFA_ITEM: {
+        if (Window.CANCEL == Utility
+                .popOkCancel(
+                        "Confirm Removal of Sofa",
+                        "This action will remove this Sofa as a capability, and delete its mappings if no other capability set declares this Sofa."
+                                + "  Please confirm.", MessageDialog.WARNING)) {
+          table.setSelection(table.getSelectionIndex() + 1);
+          return;
+        }
+        String sofaName = removeItem.getText(NAME_COL);
+        boolean isInput = INPUT.equals(removeItem.getText(INPUT_COL));
+        if (isInput)
+          c.setInputSofas((String[]) Utility.removeElementFromArray(c.getInputSofas(), sofaName,
+                  String.class));
+        else
+          c.setOutputSofas((String[]) Utility.removeElementFromArray(c.getOutputSofas(), sofaName,
+                  String.class));
+        removeItem.dispose();
+
+        if (!anyCapabilitySetDeclaresSofa(sofaName, isInput)) {
+          Comparator comparator = new Comparator() {
+            public int compare(Object o1, Object o2) {
+              String name = (String) o1;
+              SofaMapping sofaMapping = (SofaMapping) o2;
+              if (name.equals(sofaMapping.getAggregateSofaName()))
+                return 0;
+              return 1;
+            }
+          };
+          editor.getAeDescription().setSofaMappings(
+                  (SofaMapping[]) Utility.removeElementsFromArray(getSofaMappings(), sofaName,
+                          SofaMapping.class, comparator));
+
+          sofaMapSection.markStale();
+        }
+        break;
+      }
+      case TYPE: {
+        if (Window.CANCEL == Utility.popOkCancel("Confirm Removal of Type",
+                "This action will remove this type as a capability.  Please confirm.",
+                MessageDialog.WARNING)) {
+          table.setSelection(table.getSelectionIndex() + 1);
+          return;
+        }
+        TableTreeItem[] features = removeItem.getItems();
+        if (null != features)
+          for (int i = 0; i < features.length; i++) {
+            removeFeature(c, features[i]);
+          }
+        String typeNameToRemove = getFullyQualifiedName(removeItem);
+        if (isInput(removeItem))
+          c.setInputs(typeOrFeatureArrayRemove(c.getInputs(), typeNameToRemove));
+        if (isOutput(removeItem) /* || isUpdate(removeItem) */)
+          c.setOutputs(typeOrFeatureArrayRemove(c.getOutputs(), typeNameToRemove));
+
+        removeItem.dispose();
+        break;
+      }
+      case FEAT: {
+        removeFeature(c, removeItem);
+        break;
+      }
+      default:
+        throw new InternalErrorCDE("invalid state");
+    }
+
+    table.setSelection(previousSelection);
+    finishAction();
+  }
+
+  private void removeCapabilitySet(Capability c) {
+    Capability[] cs = getAnalysisEngineMetaData().getCapabilities();
+    Capability[] newCs = new Capability[cs.length - 1];
+    for (int i = 0, j = 0; i < newCs.length; i++) {
+      if (cs[i] != c)
+        newCs[j++] = cs[i];
+    }
+    getAnalysisEngineMetaData().setCapabilities(newCs);
+  }
+
+  private boolean isInput(TableTreeItem item) {
+    return INPUT.equals(item.getText(INPUT_COL)); // works if getText() returns null
+  }
+
+  private boolean isOutput(TableTreeItem item) {
+    return OUTPUT.equals(item.getText(OUTPUT_COL));
+  }
+
+  public static boolean isInput(String fullFeatureName, Capability c) {
+    return null != getTypeOrFeature(c.getInputs(), fullFeatureName);
+  }
+
+  public static boolean isOutput(String fullFeatureName, Capability c) {
+    return null != getTypeOrFeature(c.getOutputs(), fullFeatureName);
+  }
+
+  private void removeFeature(Capability c, TableTreeItem removeItem) {
+    String shortFeatureName = removeItem.getText(NAME_COL);
+    if (shortFeatureName.equals(ALL_FEATURES)) {
+      if (isInput(removeItem)) {
+        TypeOrFeature tfItem = getTypeOrFeature(c.getInputs(), getFullyQualifiedName(removeItem
+                .getParentItem()));
+        tfItem.setAllAnnotatorFeatures(false);
+      }
+      if (isOutput(removeItem) /* || isUpdate(removeItem) */) {
+        TypeOrFeature tfItem = getTypeOrFeature(c.getOutputs(), getFullyQualifiedName(removeItem
+                .getParentItem()));
+        tfItem.setAllAnnotatorFeatures(false);
+      }
+    } else {
+      String featureNameToRemove = getFullyQualifiedName(removeItem.getParentItem()) + ":"
+              + removeItem.getText(NAME_COL);
+      if (isInput(removeItem))
+        c.setInputs(typeOrFeatureArrayRemove(c.getInputs(), featureNameToRemove));
+      if (isOutput(removeItem) /* || isUpdate(removeItem) */)
+        c.setOutputs(typeOrFeatureArrayRemove(c.getOutputs(), featureNameToRemove));
+    }
+    removeItem.dispose();
+  }
+
+  public Capability getCapabilityFromTableTreeItem(TableTreeItem item) {
+    return (Capability) item.getData();
+  }
+
+  private void handleAddLang(TableTreeItem selItem, int itemKind) {
+    if (itemKind == CS)
+      selItem = selItem.getItems()[0]; // lang is 1st item in capability set
+    else if (itemKind == LANG_ITEM)
+      selItem = selItem.getParentItem();
+    else if (itemKind == TYPE || itemKind == SOFA)
+      selItem = selItem.getParentItem().getItems()[0];
+    else if (itemKind == FEAT || itemKind == SOFA_ITEM)
+      selItem = selItem.getParentItem().getParentItem().getItems()[0];
+    Capability c = getCapabilityFromTableTreeItem(selItem.getParentItem());
+    CommonInputDialog dialog = new CommonInputDialog(
+            this,
+            "Add Language",
+            "Enter a two letter ISO-639 language code, followed optionally by a two-letter ISO-3166 country code (Examples: fr or fr-CA)",
+            CommonInputDialog.LANGUAGE);
+    if (dialogForLanguage(c, dialog) == Window.CANCEL)
+      return;
+
+    c.setLanguagesSupported(stringArrayAdd(c.getLanguagesSupported(), dialog.getValue()));
+
+    // update GUI
+    TableTreeItem lItem = new TableTreeItem(selItem, SWT.NONE);
+    lItem.setData(LANG_TITLE);
+    lItem.setText(NAME_COL, dialog.getValue());
+    selItem.setExpanded(true);
+    pack04();
+    finishAction();
+  }
+
+  private void handleAddType(TableTreeItem selItem, int itemKind) {
+    if (itemKind == LANG || itemKind == TYPE || itemKind == SOFA)
+      selItem = selItem.getParentItem();
+    else if (itemKind == LANG_ITEM || itemKind == FEAT || itemKind == SOFA_ITEM)
+      selItem = selItem.getParentItem().getParentItem();
+    Capability c = getCapabilityFromTableTreeItem(selItem);
+    AddCapabilityTypeDialog dialog = new AddCapabilityTypeDialog(this, c);
+    if (dialog.open() == Window.CANCEL)
+      return;
+
+    for (int i = 0; i < dialog.types.length; i++) {
+
+      if (dialog.inputs[i])
+        c.addInputType(dialog.types[i], dialog.inputs[i]);
+
+      if (dialog.outputs[i])
+        c.addOutputType(dialog.types[i], dialog.outputs[i]);
+
+      TableTreeItem item = new TableTreeItem(selItem, SWT.NONE);
+      setGuiTypeName(item, dialog.types[i]);
+      item.setText(INPUT_COL, dialog.inputs[i] ? INPUT : "");
+      item.setText(OUTPUT_COL, dialog.outputs[i] ? OUTPUT : "");
+
+      TableTreeItem fItem = new TableTreeItem(item, SWT.NONE);
+      fItem.setData(FEAT_TITLE);
+      fItem.setText(NAME_COL, ALL_FEATURES);
+      fItem.setText(INPUT_COL, dialog.inputs[i] ? INPUT : "");
+      fItem.setText(OUTPUT_COL, dialog.outputs[i] ? OUTPUT : "");
+
+      item.setExpanded(true);
+    }
+    pack04();
+    selItem.setExpanded(true);
+    finishAction();
+  }
+
+  private void handleAddSofa(TableTreeItem selItem, int itemKind) {
+    if (itemKind == CS)
+      selItem = selItem.getItems()[1];
+    else if (itemKind == LANG || itemKind == TYPE)
+      selItem = selItem.getParentItem().getItems()[1];
+    else if (itemKind == LANG_ITEM || itemKind == FEAT || itemKind == SOFA_ITEM)
+      selItem = selItem.getParentItem().getParentItem().getItems()[1];
+
+    Capability c = getCapabilityFromTableTreeItem(selItem.getParentItem());
+    AddSofaDialog dialog = new AddSofaDialog(this, c);
+    if (dialog.open() == Window.CANCEL)
+      return;
+
+    // dialog.isInput, dialog.sofaName
+    if (dialog.isInput)
+      c.setInputSofas(stringArrayAdd(c.getInputSofas(), dialog.sofaName));
+    else
+      c.setOutputSofas(stringArrayAdd(c.getOutputSofas(), dialog.sofaName));
+
+    TableTreeItem item = new TableTreeItem(selItem, SWT.NONE);
+    setGuiSofaName(item, dialog.sofaName, dialog.isInput);
+    selItem.setExpanded(true);
+    pack04();
+
+    sofaMapSection.markStale();
+    finishAction();
+  }
+
+  private void handleAddEditFeature(TableTreeItem selItem, int itemKind) {
+    if (itemKind == FEAT)
+      selItem = selItem.getParentItem();
+
+    Capability c = getCapabilityFromTableTreeItem(selItem.getParentItem());
+    String typeName = getFullyQualifiedName(selItem);
+
+    // using the CAS to get all the inherited features
+    Type type = editor.getCurrentView().getTypeSystem().getType(typeName);
+
+    AddCapabilityFeatureDialog dialog = new AddCapabilityFeatureDialog(this, type, c);
+    if (dialog.open() == Window.CANCEL)
+      return;
+
+    addOrEditFeature(dialog, typeName, selItem, c);
+  }
+
+  private void addOrEditFeature(AddCapabilityFeatureDialog dialog, String typeName, // fully
+          // qualified
+          TableTreeItem parentItem, Capability c) {
+    // set the <all features> flag on the type in the model, for input and output
+    c.setInputs(setAllFeatures(c.getInputs(), typeName, dialog.allFeaturesInput));
+    // The logic for output features is complicated. Output features are always listed in the
+    // outputs section of the capability.
+    // Their type must be in either the output section or the input section.
+    // When a feature is added here as an output, and the input section has a type,
+    // we don't require that there be a type capability with output marked.
+    // If the user wants to have an output type,
+    // they can add one explicitly.
+    // There must be either an input or an output Type in order for a feature to be added.
+    //
+    // For the "all features" case, we can't set an output state for all features on an input type.
+    if (dialog.allFeaturesOutput && (null == getTypeOrFeature(c.getOutputs(), typeName))) {
+      Utility
+              .popMessage(
+                      "Unable to set AllFeatures",
+                      "Skipping setting of <All Features> for output, because you must have the type specified itself"
+                              + " as an output in order to set the <All Features>.  You can individually set all the features, instead.",
+                      MessageDialog.WARNING);
+      dialog.allFeaturesOutput = false;
+    } else
+      c.setOutputs(setAllFeatures(c.getOutputs(), typeName, dialog.allFeaturesOutput));
+
+    TableTreeItem[] prevFeatGUI = parentItem.getItems();
+    for (int i = 0; i < prevFeatGUI.length; i++) {
+      prevFeatGUI[i].dispose();
+    }
+
+    // update GUI for <all features> - add element if needed
+    if (dialog.allFeaturesInput || dialog.allFeaturesOutput) {
+      TableTreeItem item = new TableTreeItem(parentItem, SWT.NONE);
+      item.setData(FEAT_TITLE);
+      item.setText(NAME_COL, ALL_FEATURES);
+      item.setText(INPUT_COL, dialog.allFeaturesInput ? INPUT : "");
+      item.setText(OUTPUT_COL, dialog.allFeaturesOutput ? OUTPUT : "");
+    }
+
+    List inputsL = new ArrayList();
+    List outputsL = new ArrayList();
+
+    for (int i = 0; i < dialog.features.length; i++) {
+      String fullName = typeName + ":" + dialog.features[i];
+      if (dialog.inputs[i])
+        inputsL.add(newFeature(fullName));
+      if (dialog.outputs[i])
+        outputsL.add(newFeature(fullName));
+      // update the GUI
+      TableTreeItem item = new TableTreeItem(parentItem, SWT.NONE);
+      item.setData(FEAT_TITLE);
+      item.setText(NAME_COL, dialog.features[i]);
+      item.setText(INPUT_COL, dialog.inputs[i] ? INPUT : "");
+      item.setText(OUTPUT_COL, dialog.outputs[i] ? OUTPUT : "");
+    }
+    parentItem.setExpanded(true);
+    tt.getTable().getColumn(NAME_COL).pack();
+    tt.setSelection(new TableTreeItem[] { parentItem });
+
+    c.setInputs(replaceFeaturesKeepingTypes(c.getInputs(), typeName, inputsL));
+    c.setOutputs(replaceFeaturesKeepingTypes(c.getOutputs(), typeName, outputsL));
+
+    finishAction();
+  }
+
+  private TypeOrFeature newFeature(String name) {
+    TypeOrFeature result = new TypeOrFeature_impl();
+    result.setType(false);
+    result.setName(name);
+    return result;
+  }
+
+  public String getFullyQualifiedName(TableTreeItem item) {
+    String namespace = item.getText(NAMESPACE_COL);
+    String name = item.getText(NAME_COL);
+    return "".equals(namespace) ? name : namespace + "." + name;
+  }
+
+  // used by dialog table -has different columns
+  public String getFullyQualifiedName(String namespace, String name) {
+    return (null == namespace || "".equals(namespace)) ? name : namespace + "." + name;
+  }
+
+  /**
+   * Given a current list of inputs/ outputs, made up of "Types" and "features", make a new list
+   * keeping all the types, and keeping all the features that belong to other types, and adding the
+   * features that are passed in for one particular type in the "features" parameter
+   * 
+   * @param items
+   * @param type
+   *          A string representing the fully qualified type name
+   * @param features -
+   *          associated with the type
+   * @return
+   */
+  private TypeOrFeature[] replaceFeaturesKeepingTypes(TypeOrFeature[] items, String typeName,
+          List features) {
+    List newItems = new ArrayList();
+    typeName = typeName + ':';
+    if (null != items)
+      for (int i = 0; i < items.length; i++) {
+        if (items[i].isType() || !items[i].getName().startsWith(typeName))
+          newItems.add(items[i]);
+      }
+
+    for (Iterator it = features.iterator(); it.hasNext();) {
+      newItems.add(it.next());
+    }
+    return (TypeOrFeature[]) newItems.toArray(new TypeOrFeature[newItems.size()]);
+  }
+
+  /**
+   * 
+   * @param items
+   *          Existing array of TypeOrFeature items (input or output)
+   * @param typeName
+   * @param isAllFeatures
+   *          AllFeatures value
+   * @return
+   */
+  private TypeOrFeature[] setAllFeatures(TypeOrFeature[] items, String typeName,
+          boolean isAllFeatures) {
+
+    TypeOrFeature type = getTypeOrFeature(items, typeName);
+
+    if (null != type) {
+      type.setAllAnnotatorFeatures(isAllFeatures);
+      return items;
+    }
+
+    // If get here, case = Type declared as Output(input) or not at all while all Features
+    // declared as Input (output)
+    // Need to add the Type and set the all annotator features value
+    if (isAllFeatures)
+      throw new InternalErrorCDE("invalid state");
+    return items;
+  }
+
+  private void finishAction() {
+    setFileDirty();
+  }
+
+  private void pack04() {
+    tt.getTable().getColumn(TITLE_COL).pack();
+    tt.getTable().getColumn(NAME_COL).pack();
+    tt.getTable().getColumn(NAMESPACE_COL).pack();
+  }
+
+  private int getItemKind(TableTreeItem item) {
+    String itemID = item.getText(TITLE_COL);
+
+    if (CAPABILITY_SET.equals(itemID))
+      return CS;
+    if (TYPE_TITLE.equals(itemID))
+      return TYPE;
+    itemID = (String) item.getData();
+    if (LANGS_TITLE.equals(itemID))
+      return LANG;
+    if (FEAT_TITLE.equals(itemID))
+      return FEAT;
+    if (LANG_TITLE.equals(itemID))
+      return LANG_ITEM;
+    if (SOFAS_TITLE.equals(itemID))
+      return SOFA;
+    if (SOFA_TITLE.equals(itemID))
+      return SOFA_ITEM;
+    throw new InternalErrorCDE("invalid state");
+  }
+
+  public void enable() {
+    addCapabilityButton.setEnabled(true);
+
+    boolean selectOK = tt.getSelectionCount() == 1;
+    TableTreeItem item = selectOK ? tt.getSelection()[0] : null;
+    int kind = selectOK ? getItemKind(item) : 0;
+
+    addLangButton.setEnabled(selectOK);
+    addTypeButton.setEnabled(selectOK);
+    addSofaButton.setEnabled(selectOK);
+    addEditFeatureButton.setEnabled((kind & (FEAT + TYPE)) > 0);
+    editButton.setEnabled((kind & (SOFA_ITEM + LANG_ITEM + FEAT + TYPE)) > 0);
+    removeButton.setEnabled((kind & (CS + SOFA_ITEM + LANG_ITEM + FEAT + TYPE)) > 0);
+  }
+
+  private int dialogForLanguage(Capability c, CommonInputDialog dialog) {
+    for (;;) {
+      if (dialog.open() == Window.CANCEL)
+        return Window.CANCEL;
+
+      String[] languages = c.getLanguagesSupported();
+      boolean alreadySpecified = false;
+      for (int i = 0; i < languages.length; i++) {
+        if (languages[i].equals(dialog.getValue())) {
+          Utility
+                  .popMessage(
+                          "Language spec already defined",
+                          "The language specification you entered is already specified.\nPlease enter a different specification, or Cancel this operation."
+                                  + "\n\nLanguage: " + dialog.getValue(), MessageDialog.ERROR);
+          alreadySpecified = true;
+          break;
+        }
+      }
+      if (!alreadySpecified)
+        break;
+    }
+    return Window.OK;
+  }
+
+  private Capability getCapability(TableTreeItem item) {
+    while (null != item.getParentItem())
+      item = item.getParentItem();
+    return getCapabilityFromTableTreeItem(item);
+  }
+
+}
diff --git a/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/ExtnlResBindSection.java b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/ExtnlResBindSection.java
new file mode 100644
index 0000000..01f2e6f
--- /dev/null
+++ b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/ExtnlResBindSection.java
@@ -0,0 +1,391 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS 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.taeconfigurator.editors.ui;
+
+import org.apache.uima.resource.ExternalResourceDescription;
+import org.apache.uima.resource.FileLanguageResourceSpecifier;
+import org.apache.uima.resource.FileResourceSpecifier;
+import org.apache.uima.resource.ResourceSpecifier;
+import org.apache.uima.resource.impl.ExternalResourceDescription_impl;
+import org.apache.uima.resource.impl.FileLanguageResourceSpecifier_impl;
+import org.apache.uima.resource.impl.FileResourceSpecifier_impl;
+import org.apache.uima.resource.metadata.ExternalResourceBinding;
+import org.apache.uima.resource.metadata.impl.ExternalResourceBinding_impl;
+import org.apache.uima.taeconfigurator.editors.MultiPageEditor;
+import org.apache.uima.taeconfigurator.editors.ui.dialogs.AddExternalResourceDialog;
+import org.apache.uima.taeconfigurator.wizards.ResourceManagerConfigurationNewWizard;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.window.Window;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.TableItem;
+import org.eclipse.swt.widgets.Tree;
+import org.eclipse.swt.widgets.TreeItem;
+import org.eclipse.ui.forms.IManagedForm;
+
+/**
+ */
+public class ExtnlResBindSection extends AbstractSection {
+  private final static String boundHeader = "Bound to: ";
+
+  private Composite sectionClient;
+
+  private Tree tree;
+
+  private Button addButton;
+
+  private Button editButton;
+
+  private Button removeButton;
+
+  private Button bindButton;
+
+  private Button exportButton;
+
+  private ResourceDependencySection resourceDependencySection;
+
+  private ImportResBindSection resBindImportSection;
+
+  public ExtnlResBindSection(MultiPageEditor aEditor, Composite parent) {
+    super(
+            aEditor,
+            parent,
+            "Resources Needs, Definitions and Bindings",
+            "Specify External Resources; Bind them to dependencies on the right panel by selecting the corresponding dependency and clicking Bind.");
+  }
+
+  public void initialize(IManagedForm form) {
+    super.initialize(form);
+    // set up Composite to hold widgets in the section
+    sectionClient = new2ColumnComposite(getSection());
+
+    tree = newTree(sectionClient);
+    // Buttons
+    Composite buttonContainer = newButtonContainer(sectionClient);
+
+    addButton = newPushButton(buttonContainer, S_ADD,
+            "Click to add a new External Resource definition");
+    editButton = newPushButton(buttonContainer, S_EDIT,
+            "Click to edit an External Resource definition");
+    removeButton = newPushButton(buttonContainer, "Remove",
+            "Click to remove selected binding or External Resource");
+    bindButton = newPushButton(buttonContainer, "Bind",
+            "Click to bind selected dependency with selected Resource");
+    exportButton = newPushButton(buttonContainer, S_EXPORT, S_EXPORT_TIP);
+
+    buttonContainer.pack();
+    getSection().getParent().getParent().pack();
+    getSection().getParent().getParent().layout();
+    initialFormWidth = getSection().getSize().x;
+    ((GridData) tree.getLayoutData()).widthHint = initialFormWidth - buttonContainer.getSize().x;
+
+    enableBorders(sectionClient);
+    toolkit.paintBordersFor(sectionClient);
+
+    tree.addListener(SWT.MouseDoubleClick, this);
+  }
+
+  public void refresh() {
+    if (null == resBindImportSection)
+      resBindImportSection = editor.getResourcesPage().getResBindImportSection();
+    super.refresh();
+    resourceDependencySection = editor.getResourcesPage().getResourceDependencySection();
+    ExternalResourceDescription[] xrds = getExternalResources();
+    ExternalResourceBinding[] bindings = getExternalResourceBindings();
+    tree.removeAll();
+    if (null != xrds) {
+      for (int i = 0; i < xrds.length; i++) {
+        addExternalResourceDescriptionToGUI(xrds[i], bindings);
+      }
+    }
+    enable();
+  }
+
+  private void addExternalResourceDescriptionToGUI(ExternalResourceDescription xrd,
+          ExternalResourceBinding[] bindings) {
+    TreeItem item = new TreeItem(tree, SWT.NONE);
+    fillXrdItem(item, xrd);
+    fillBindings(item, xrd, bindings);
+    item.setExpanded(true);
+  }
+
+  private void fillXrdItem(TreeItem item, ExternalResourceDescription xrd) {
+    StringBuffer text = new StringBuffer();
+    text.append(xrd.getName());
+    ResourceSpecifier rs = xrd.getResourceSpecifier();
+    if (rs instanceof FileLanguageResourceSpecifier) {
+      FileLanguageResourceSpecifier flrs = (FileLanguageResourceSpecifier) rs;
+      text.append("  URL_Prefix: ").append(flrs.getFileUrlPrefix()).append("  URL_Suffix: ")
+              .append(flrs.getFileUrlSuffix());
+    } else if (rs instanceof FileResourceSpecifier) {
+      FileResourceSpecifier frs = (FileResourceSpecifier) rs;
+      text.append("  URL: ").append(frs.getFileUrl());
+    } else {
+      text.append("  Custom Resource Specifier");
+    }
+    String implName = xrd.getImplementationName();
+    if (null != implName && !implName.equals("")) {
+      text.append("  Implementation: ").append(implName);
+    }
+    item.setText(text.toString());
+    item.setData(xrd);
+  }
+
+  private void fillBindings(TreeItem parent, ExternalResourceDescription xrd,
+          ExternalResourceBinding[] bindings) {
+    if (null != bindings) {
+      for (int i = 0; i < bindings.length; i++) {
+        if (bindings[i].getResourceName().equals(xrd.getName())) {
+          addBindingToGUI(parent, bindings[i].getKey(), bindings[i]);
+        }
+      }
+    }
+  }
+
+  private void addBindingToGUI(TreeItem parent, String key, ExternalResourceBinding xrb) {
+    TreeItem item = new TreeItem(parent, SWT.NONE);
+    item.setText(boundHeader + key);
+    item.setData(xrb);
+  }
+
+  /*
+   * (non-Javadoc)
+   * 
+   * @see org.eclipse.swt.widgets.Listener#handleEvent(org.eclipse.swt.widgets.Event)
+   */
+  public void handleEvent(Event event) {
+    if (event.widget == addButton)
+      handleAdd();
+    else if (event.widget == editButton || event.type == SWT.MouseDoubleClick)
+      handleEdit();
+    else if (event.widget == removeButton
+            || (event.widget == tree && event.type == SWT.KeyUp && event.character == SWT.DEL))
+      handleRemove();
+    else if (event.widget == bindButton)
+      handleBind();
+    else if (event.widget == exportButton) {
+      try {
+        resBindImportSection.exportImportablePart("<resourceManagerConfiguration>",
+                ResourceManagerConfigurationNewWizard.RESOURCEMANGERCONFIGURATION_TEMPLATE);
+      } finally {
+        refresh(); // update in case of throw, even
+      }
+    }
+
+    enable();
+  }
+
+  public ExternalResourceDescription getXRDescriptionFromTreeItem(TreeItem item) {
+    return (ExternalResourceDescription) item.getData();
+  }
+
+  /**
+   * Bindings can't be edited. They can be removed or new ones bound. External resources can be
+   * edited. Edit button is disabled unles an editable thing is selected. But user could double
+   * click an illegal entry
+   * 
+   */
+  private void handleEdit() {
+    TreeItem item = tree.getSelection()[0];
+    if (isBoundSpec(item))
+      return;
+    ExternalResourceDescription xrd = getXRDescriptionFromTreeItem(item);
+    ResourceSpecifier rs = xrd.getResourceSpecifier();
+    if (!((rs instanceof FileResourceSpecifier) || (rs instanceof FileLanguageResourceSpecifier))) {
+      Utility.popMessage("Can''t edit custom resource", "This resource is a '"
+              + rs.getClass().getName()
+              + "', and any edits have to be done directly in the XML in the Source view.",
+              MessageDialog.INFORMATION);
+      return;
+    }
+
+    AddExternalResourceDialog dialog = new AddExternalResourceDialog(this, xrd);
+
+    if (dialog.open() == Window.CANCEL)
+      return;
+    alterExistingXRD(dialog, xrd, item);
+  }
+
+  /**
+   * Add new external resource, with no bindings
+   * 
+   */
+  private void handleAdd() {
+    AddExternalResourceDialog dialog = new AddExternalResourceDialog(this);
+
+    if (dialog.open() == Window.CANCEL)
+      return;
+    ExternalResourceDescription xrd = new ExternalResourceDescription_impl();
+    TreeItem item = new TreeItem(tree, SWT.NONE);
+    alterExistingXRD(dialog, xrd, item);
+    getResourceManagerConfiguration().addExternalResource(xrd);
+  }
+
+  private void alterExistingXRD(AddExternalResourceDialog dialog, ExternalResourceDescription xrd,
+          TreeItem item) {
+    valueChanged = false;
+    xrd.setName(setValueChanged(dialog.xrName, xrd.getName()));
+    xrd.setDescription(setValueChanged(dialog.xrDescription, xrd.getDescription()));
+    xrd
+            .setImplementationName(setValueChanged(dialog.xrImplementation, xrd
+                    .getImplementationName()));
+
+    ResourceSpecifier rs = xrd.getResourceSpecifier();
+    if (null == dialog.xrUrlSuffix || "".equals(dialog.xrUrlSuffix)) {
+      FileResourceSpecifier frs;
+      if (null != rs && rs instanceof FileResourceSpecifier) {
+        frs = (FileResourceSpecifier) rs;
+      } else {
+        frs = new FileResourceSpecifier_impl();
+      }
+      frs.setFileUrl(setValueChanged(dialog.xrUrl, frs.getFileUrl()));
+      xrd.setResourceSpecifier(frs);
+    } else {
+      FileLanguageResourceSpecifier flrs;
+      if (null != rs && rs instanceof FileLanguageResourceSpecifier) {
+        flrs = (FileLanguageResourceSpecifier) rs;
+      } else {
+        flrs = new FileLanguageResourceSpecifier_impl();
+      }
+      flrs.setFileUrlPrefix(setValueChanged(dialog.xrUrl, flrs.getFileUrlPrefix()));
+      flrs.setFileUrlSuffix(setValueChanged(dialog.xrUrlSuffix, flrs.getFileUrlSuffix()));
+      xrd.setResourceSpecifier(flrs);
+    }
+    fillXrdItem(item, xrd);
+    if (valueChanged)
+      setFileDirty();
+  }
+
+  /**
+   * Bind button - enabled only when one dependency is selected, and one External Resource, not
+   * already bound to this key, is selected
+   */
+  private void handleBind() {
+    TreeItem xrItem = tree.getSelection()[0];
+    if (null != xrItem.getParentItem())
+      xrItem = xrItem.getParentItem();
+    ExternalResourceDescription xrd = getXRDescriptionFromTreeItem(xrItem);
+
+    TableItem keyItem = resourceDependencySection.getTable().getSelection()[0];
+
+    ExternalResourceBinding xrb = new ExternalResourceBinding_impl();
+    String key = keyItem.getText(ResourceDependencySection.KEY_COL);
+    xrb.setKey(key);
+    xrb.setResourceName(xrd.getName());
+    getResourceManagerConfiguration().addExternalResourceBinding(xrb);
+    addBindingToGUI(xrItem, key, xrb);
+    xrItem.setExpanded(true);
+    keyItem.setText(0, "Bound");
+    keyItem.getParent().getColumn(0).pack();
+    setFileDirty();
+  }
+
+  /**
+   * remove either a binding or an external resource. Removing the resource removes all bindings
+   * associated with it
+   * 
+   */
+  private void handleRemove() {
+    int selectionCount = tree.getSelectionCount();
+    if (1 != selectionCount)
+      return;
+    TreeItem item = tree.getSelection()[0];
+    if (null == item.getParentItem()) { // case of removing a resource
+      if (Window.CANCEL == Utility
+              .popOkCancel("Removing Resource",
+                      "Removing an External Resource and all its bindings. Resource name:"
+                              + item.getText(), MessageDialog.WARNING))
+        return;
+      removeAllBindings(item);
+      removeResource(item);
+    } else { // case of removing a binding
+      removeBinding(item);
+    }
+  }
+
+  public ExternalResourceBinding getXRBindingFromTreeItem(TreeItem item) {
+    return (ExternalResourceBinding) item.getData();
+  }
+
+  private void removeBinding(TreeItem item) {
+    ExternalResourceBinding xrb = getXRBindingFromTreeItem(item);
+    getResourceManagerConfiguration().removeExternalResourceBinding(xrb);
+    removeBoundFlagInDependencySection(xrb);
+    item.dispose();
+    setFileDirty();
+  }
+
+  private void removeBoundFlagInDependencySection(ExternalResourceBinding xrb) {
+    String key = xrb.getKey();
+    TableItem[] items = resourceDependencySection.getTable().getItems();
+    for (int i = 0; i < items.length; i++) {
+      if (key.equals(items[i].getText(ResourceDependencySection.KEY_COL)))
+        items[i].setText(0, ""); // reset bound
+    }
+  }
+
+  private void removeAllBindings(TreeItem item) {
+    TreeItem[] items = item.getItems();
+    for (int i = items.length - 1; i >= 0; i--) {
+      removeBinding(items[i]);
+    }
+  }
+
+  private void removeResource(TreeItem item) {
+    ExternalResourceDescription xrd = getXRDescriptionFromTreeItem(item);
+    getResourceManagerConfiguration().removeExternalResource(xrd);
+    item.dispose();
+    setFileDirty();
+  }
+
+  public void enable() {
+    // bind enabled when one item in tree and one in table is selected
+    bindButton.setEnabled(tree.getSelectionCount() == 1
+            && resourceDependencySection.getTable().getSelectionCount() == 1
+            && "".equals(resourceDependencySection.getTable().getSelection()[0].getText(0))); // not
+                                                                                              // bound
+
+    removeButton.setEnabled(tree.getSelectionCount() > 0);
+    editButton.setEnabled(tree.getSelectionCount() == 1 && !isBoundSpec(tree.getSelection()[0]));
+    exportButton.setEnabled(tree.getItemCount() > 0);
+  }
+
+  private boolean isBoundSpec(TreeItem item) {
+    return item.getText().startsWith(boundHeader);
+  }
+
+  public boolean resourceNameAlreadyDefined(String name) {
+    ExternalResourceDescription[] xrds = getExternalResources();
+    if (xrds != null) {
+      for (int i = 0; i < xrds.length; i++) {
+        if (xrds[i].getName().equals(name)) {
+          Utility.popMessage("Name Already Defined",
+                  "The External Resource Name specified is already defined", MessageDialog.ERROR);
+          return true;
+        }
+      }
+    }
+    return false;
+  }
+
+}
diff --git a/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/FileAndShortName.java b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/FileAndShortName.java
new file mode 100644
index 0000000..4f22426
--- /dev/null
+++ b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/FileAndShortName.java
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.uima.taeconfigurator.editors.ui;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.runtime.IPath;
+
+public class FileAndShortName {
+  public String fileName;
+
+  public String shortName;
+
+  public FileAndShortName(Object o) {
+
+    if (o instanceof IFile) {
+      IFile file = (IFile) o;
+      fileName = file.getLocation().toString();
+      shortName = file.getName();
+    } else {
+      IPath path = (IPath) o;
+      fileName = path.toString();
+      shortName = path.toFile().getName();
+    }
+  }
+}
diff --git a/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/FlowSection.java b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/FlowSection.java
new file mode 100644
index 0000000..494a0bc
--- /dev/null
+++ b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/FlowSection.java
@@ -0,0 +1,671 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS 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.taeconfigurator.editors.ui;
+
+import java.text.MessageFormat;
+import java.util.List;
+
+import org.apache.uima.UIMAFramework;
+import org.apache.uima.analysis_engine.metadata.CapabilityLanguageFlow;
+import org.apache.uima.analysis_engine.metadata.FixedFlow;
+import org.apache.uima.analysis_engine.metadata.FlowConstraints;
+import org.apache.uima.analysis_engine.metadata.FlowControllerDeclaration;
+import org.apache.uima.analysis_engine.metadata.impl.CapabilityLanguageFlow_impl;
+import org.apache.uima.analysis_engine.metadata.impl.FixedFlow_impl;
+import org.apache.uima.analysis_engine.metadata.impl.FlowControllerDeclaration_impl;
+import org.apache.uima.flow.FlowControllerDescription;
+import org.apache.uima.resource.metadata.Import;
+import org.apache.uima.taeconfigurator.Messages;
+import org.apache.uima.taeconfigurator.TAEConfiguratorPlugin;
+import org.apache.uima.taeconfigurator.editors.MultiPageEditor;
+import org.apache.uima.taeconfigurator.editors.ui.dialogs.FindComponentDialog;
+import org.apache.uima.taeconfigurator.editors.ui.dialogs.PickTaeForTypesDialog;
+import org.apache.uima.taeconfigurator.files.MultiResourceSelectionDialog;
+import org.apache.uima.taeconfigurator.model.FlowNodes;
+import org.apache.uima.util.XMLizable;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.window.Window;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.CCombo;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.TableItem;
+import org.eclipse.ui.forms.IManagedForm;
+
+public class FlowSection extends AbstractSection {
+
+  public static final String FIXED_FLOW = "Fixed Flow"; //$NON-NLS-1$
+
+  public static final String CAPABILITY_LANGUAGE_FLOW = "Capability Language Flow"; //$NON-NLS-1$
+
+  public static final String USER_DEFINED_FLOW = "User-defined Flow";
+
+  private CCombo flowControllerChoice;
+
+  Table flowList; // need access from inner class
+
+  private Button upButton;
+
+  private Button downButton;
+
+  private Label flowControllerGUI;
+
+  private Button specifyFlowControllerImportButton;
+
+  private Button findFlowControllerDescriptorButton;
+
+  private Label flowControllerLabel;
+
+  private Label flowControllerKeyLabel;
+
+  private Label flowControllerKeyGUI;
+
+  // private Label flowControllerSpecifierLabel;
+  private Label flowChoiceLabel;
+
+  private boolean bDisableToolTipHelp;
+
+  /**
+   * creates a section only for aggregate specifiers to define the flow of their delegates
+   * 
+   * @param editor
+   *          the referenced multipage editor
+   */
+  public FlowSection(MultiPageEditor aEditor, Composite parent) {
+    super(aEditor, parent, Messages.getString("FlowSection.ComponentEngineFlowTitle"), //$NON-NLS-1$
+            Messages.getString("FlowSection.ComponentEngineFlowDescription")); //$NON-NLS-1$
+  }
+
+  /*
+   * Called by the page constructor after all sections are created, to initialize them.
+   * (non-Javadoc)
+   * 
+   * @see org.eclipse.ui.forms.IFormPart#initialize(org.eclipse.ui.forms.IManagedForm)
+   */
+  public void initialize(IManagedForm form) {
+    super.initialize(form);
+
+    Composite sectionClient = new2ColumnComposite(this.getSection());
+    // sectionClient (2 col)
+    // label / ccombo
+    // comp2
+    // comp2a fcButtonContainer
+    // label / text
+
+    ((GridData) sectionClient.getLayoutData()).grabExcessHorizontalSpace = false;
+
+    flowChoiceLabel = newLabelWithTip(sectionClient, Messages.getString("FlowSection.FlowKind"), //$NON-NLS-1$
+            Messages.getString("FlowSection.FlowKindTip")); //$NON-NLS-1$ 
+    flowControllerChoice = newCComboWithTip(sectionClient, Messages
+            .getString("FlowSection.FlowKindTip")); //$NON-NLS-1$ 
+
+    flowControllerChoice.add(FIXED_FLOW);
+    flowControllerChoice.add(CAPABILITY_LANGUAGE_FLOW);
+    flowControllerChoice.add(USER_DEFINED_FLOW);
+
+    Composite comp2 = new2ColumnComposite(sectionClient);
+    ((GridData) comp2.getLayoutData()).horizontalSpan = 2;
+    ((GridData) comp2.getLayoutData()).grabExcessVerticalSpace = false;
+
+    Composite comp2a = new2ColumnComposite(comp2);
+    Composite fcButtonContainer = newButtonContainer(comp2, VERTICAL_BUTTONS, 0);
+
+    flowControllerLabel = newLabelWithTip(comp2a, "Flow Controller:",
+            "The XML descriptor for the Custom Flow Controller");
+    flowControllerGUI = newUnUpdatableTextWithTip(comp2a, "",
+            "The XML descriptor for the Custom Flow Controller");
+
+    flowControllerGUI.addListener(SWT.MouseDown, this);
+    flowControllerGUI.addListener(SWT.MouseHover, this);
+
+    flowControllerKeyLabel = newLabelWithTip(comp2a, "Key Name:",
+            "A unique key name for this Flow Controller");
+    flowControllerKeyGUI = newUnUpdatableTextWithTip(comp2a, "",
+            "A unique key name for this Flow Controller");
+
+    // flowControllerSpecifierLabel = newLabelWithTip(sectionClient, "Specify:",
+    // "Click the Browse or Search button to specify a Flow Controller");
+    // Composite fcButtonContainer = newButtonContainer(sectionClient, HORIZONTAL_BUTTONS, 150);
+    specifyFlowControllerImportButton = newPushButton(fcButtonContainer, "Browse...",
+            "Click here to specify a locally defined Flow Controller", ENABLED);
+    findFlowControllerDescriptorButton = newPushButton(fcButtonContainer, "Search",
+            "Click here to search for a Flow Controller", ENABLED);
+
+    // flow list
+
+    Composite flowComposite = new2ColumnComposite(sectionClient);
+    ((GridData) flowComposite.getLayoutData()).horizontalSpan = 2;
+    enableBorders(flowComposite);
+    toolkit.paintBordersFor(flowComposite);
+
+    flowList = newTable(flowComposite, SWT.FULL_SELECTION, 0);
+
+    // Buttons
+    final Composite buttonContainer = newButtonContainer(flowComposite, VERTICAL_BUTTONS, 70);
+
+    upButton = newPushButton(buttonContainer, S_UP,
+            Messages.getString("FlowSection.upTip"), !ENABLED); //$NON-NLS-1$
+    downButton = newPushButton(buttonContainer, S_DOWN,
+            Messages.getString("FlowSection.downTip"), !ENABLED); //$NON-NLS-1$
+    enableBorders(sectionClient);
+    toolkit.paintBordersFor(sectionClient);
+  }
+
+  /*
+   * (non-Javadoc)
+   * 
+   * @see org.eclipse.ui.forms.IFormPart#refresh()
+   */
+  public void refresh() {
+    super.refresh();
+
+    flowList.removeAll();
+    if (!isAggregate()) {
+      getSection().setText(Messages.getString("FlowSection.notUsed")); //$NON-NLS-1$
+      getSection().setDescription(Messages.getString("FlowSection.onlyForAggregates")); //$NON-NLS-1$
+    } else {
+      getSection().setText(Messages.getString("FlowSection.ComponentEngineFlowTitle")); //$NON-NLS-1$
+      getSection().setDescription(Messages.getString("FlowSection.ComponentEngineFlowDescription")); //$NON-NLS-1$
+
+      FlowControllerDeclaration fcd = getFlowControllerDeclaration();
+      flowList.setEnabled(true);
+      FlowConstraints flowConstraints = getModelFlow();
+      FlowNodes nodesModel = new FlowNodes(flowConstraints);
+      String[] nodes = nodesModel.getFlow();
+      if (null == nodes)
+        nodesModel.setFlow(nodes = stringArray0);
+      // add them to the list
+      for (int i = 0; i < nodes.length; i++) {
+        TableItem item = new TableItem(flowList, SWT.NONE);
+        item.setImage(TAEConfiguratorPlugin.getImage(TAEConfiguratorPlugin.IMAGE_ANNOTATOR) //$NON-NLS-1$
+                );
+        item.setText(0, nodes[i]);
+      }
+      packTable(flowList);
+
+      if (null == fcd) {
+        // Not a custom, user-defined flow
+        FixedFlow ff;
+        if (null == flowConstraints) {
+          // force fixed flow if nothing is specified
+          getAnalysisEngineMetaData().setFlowConstraints(
+                  flowConstraints = ff = new FixedFlow_impl());
+          ff.setFixedFlow(stringArray0);
+        }
+        String modelFlowType = flowConstraints.getFlowConstraintsType();
+
+        flowControllerChoice.setText(modelFlowType
+                .equals(CapabilityLanguageFlow.FLOW_CONSTRAINTS_TYPE) ? CAPABILITY_LANGUAGE_FLOW
+                : FIXED_FLOW);
+
+        enableFlowControllerGUI(false);
+      } else {
+        // User-specified Flow Controller defined
+        refreshFcd(fcd);
+      }
+    }
+    enable();
+  }
+
+  private void refreshFcd(FlowControllerDeclaration fcd) {
+    enableFlowControllerGUI(true);
+    String keyName;
+    if (null == fcd.getKey() || "".equals(fcd.getKey())) {
+      keyName = "Warning: no key name is specified";
+      flowControllerKeyGUI.setToolTipText(
+              "Use Source tab below to specify a key name " +
+              "in the <flowController> element, or the imported <flowController>");
+    } else
+      keyName = fcd.getKey();
+    flowControllerKeyGUI.setText(keyName);
+    Import fcdImport = fcd.getImport();
+    String fileName = null;
+    if (null != fcdImport) {
+      fileName = fcdImport.getLocation();
+      if (null == fileName || (0 == fileName.length()))
+        fileName = fcdImport.getName();
+    }
+    flowControllerGUI.setText(null == fileName ? 
+            "Warning: no <import> in <flowController>" : fileName);
+    flowControllerChoice.setText(USER_DEFINED_FLOW);
+    // must follow label updates
+    // because this method also does the redraw
+    // otherwise, label updates are not redrawn...
+    flowControllerGUI.getParent().redraw();
+  }
+
+  private void enableFlowControllerGUI(boolean enableState) {
+    flowControllerLabel.setEnabled(enableState);
+    flowControllerGUI.setEnabled(enableState);
+    specifyFlowControllerImportButton.setEnabled(enableState);
+    findFlowControllerDescriptorButton.setEnabled(enableState);
+    flowControllerKeyLabel.setEnabled(enableState);
+    // flowControllerSpecifierLabel.setEnabled(enableState);
+    flowControllerKeyGUI.setEnabled(enableState);
+    // if (!enableState) {
+    // flowControllerKeyGUI.setText("");
+    // flowControllerGUI.setText("");
+    // }
+  }
+
+  /**
+   * @return
+   */
+  private FlowConstraints getModelFlow() {
+    return getAnalysisEngineMetaData().getFlowConstraints();
+  }
+
+  /*
+   * (non-Javadoc)
+   * 
+   * @see org.eclipse.swt.widgets.Listener#handleEvent(org.eclipse.swt.widgets.Event)
+   */
+  public void handleEvent(Event event) {
+    if (event.widget == flowControllerChoice) {
+      String flowTypeGUI = flowControllerChoice.getText();
+      if (null == flowTypeGUI || flowTypeGUI.equals(S_))
+        return;
+
+      String prevFlowTypeGUI;
+      FlowControllerDeclaration fcd = getFlowControllerDeclaration();
+      FlowConstraints modelFlow = getModelFlow();
+      if (null != fcd)
+        prevFlowTypeGUI = USER_DEFINED_FLOW;
+      else {
+        if (null == modelFlow)
+          prevFlowTypeGUI = "";
+        else {
+          String prevFlowType = modelFlow.getFlowConstraintsType();
+          if (CapabilityLanguageFlow.FLOW_CONSTRAINTS_TYPE.equals(prevFlowType))
+            prevFlowTypeGUI = CAPABILITY_LANGUAGE_FLOW;
+          else
+            prevFlowTypeGUI = FIXED_FLOW;
+        }
+      }
+
+      if (prevFlowTypeGUI.equals(flowTypeGUI))
+        return;
+
+      CapabilityLanguageFlow clf = null;
+      FixedFlow ff = null;
+
+      String[] nodes = new FlowNodes(modelFlow).getFlow();
+
+      if (flowTypeGUI.equals(CAPABILITY_LANGUAGE_FLOW)) {
+        setFlowControllerDeclaration(null);
+        getAnalysisEngineMetaData().setFlowConstraints(clf = new CapabilityLanguageFlow_impl());
+        clf.setCapabilityLanguageFlow(nodes);
+      } else if (flowTypeGUI.equals(FIXED_FLOW)) {
+        setFlowControllerDeclaration(null);
+        getAnalysisEngineMetaData().setFlowConstraints(ff = new FixedFlow_impl());
+        ff.setFixedFlow(nodes);
+      } else if (flowTypeGUI.equals(USER_DEFINED_FLOW)) {
+        // use case: user set user-defined-flow from some other state.
+        // user will have to fill in the import (CDE only supports that format)
+        // flow nodes kept, put under "Fixed Flow" arbitrarily
+        FlowControllerDeclaration newFcd = new FlowControllerDeclaration_impl();
+        setFlowControllerDeclaration(newFcd);
+        refreshFcd(newFcd);
+        getAnalysisEngineMetaData().setFlowConstraints(ff = new FixedFlow_impl());
+        ff.setFixedFlow(nodes);
+      }
+      enable();
+      setFileDirty();
+    }
+
+    else if (event.widget == upButton) {
+      String[] nodes = new FlowNodes(getModelFlow()).getFlow();
+      // update both model and gui: swap nodes
+      int selection = flowList.getSelectionIndex();
+      if (selection == 0)
+        return; // can't move up 0
+      String temp = nodes[selection - 1];
+      nodes[selection - 1] = nodes[selection];
+      nodes[selection] = temp;
+      finishFlowAction();
+      flowList.setSelection(selection - 1);
+      enable(); // after setting selection
+    } else if (event.widget == downButton) {
+      String[] nodes = new FlowNodes(getModelFlow()).getFlow();
+      // update both model and gui: swap nodes
+      int selection = flowList.getSelectionIndex();
+      if (selection == flowList.getItemCount() - 1)
+        return; // can't move down at end of list
+      String temp = nodes[selection + 1];
+      nodes[selection + 1] = nodes[selection];
+      nodes[selection] = temp;
+      finishFlowAction();
+      flowList.setSelection(selection + 1);
+      enable(); // after setting selection
+    } else if (event.widget == specifyFlowControllerImportButton) {
+      handleSpecifyFlowController();
+    } else if (event.widget == findFlowControllerDescriptorButton) {
+      handleFindFlowController();
+    } else if (event.widget == flowControllerGUI && event.type == SWT.MouseDown
+            && event.button == 3) {
+      handleContextMenuRequest(event);
+    } else if (event.widget == flowControllerGUI && event.type == SWT.MouseHover
+            && !bDisableToolTipHelp) {
+      handleHoverHelp(event);
+    }
+
+    // handle selection
+    else if (event.widget == flowList) {
+      if (event.type == SWT.Selection) {
+        enable();
+      }
+
+      if (event.character == SWT.DEL) {
+        if (flowList.getSelectionIndex() > -1) {
+          handleRemove();
+        }
+      }
+    }
+  }
+
+  private void handleHoverHelp(Event event) {
+    String sDesc = "";
+    FlowControllerDeclaration fcd = editor.getResolvedFlowControllerDeclaration();
+    String text = flowControllerGUI.getText();
+    if (null != fcd && !"".equals(text) && null != fcd.getSpecifier()) {
+      sDesc = getDescriptionForDescriptor(flowControllerGUI.getText(), fcd.getSpecifier());
+    }
+    flowControllerGUI.setToolTipText(sDesc);
+  }
+
+  private void handleContextMenuRequest(Event event) {
+    Import imp = getFlowControllerDeclaration().getImport();
+
+    bDisableToolTipHelp = true;
+    requestPopUpOverImport(imp, flowControllerGUI, event);
+    bDisableToolTipHelp = false;
+  }
+
+  private void finishFlowAction() {
+    setFileDirty();
+    refresh(); // calls enable
+  }
+
+  public void handleRemove() {
+    // get node to remove
+    int removedItemIndex = flowList.getSelectionIndex();
+    String[] nodes = new FlowNodes(getModelFlow()).getFlow();
+    int origItemCount = nodes.length;
+    // remove node from array by copying additional items above down 1
+    for (int i = removedItemIndex + 1; i < origItemCount; i++) {
+      nodes[i - 1] = nodes[i];
+    }
+    // copy array in a smaller one
+    String newNodes[] = new String[origItemCount - 1];
+    if (newNodes.length > 0) {
+      System.arraycopy(nodes, 0, newNodes, 0, newNodes.length);
+    }
+
+    new FlowNodes(getModelFlow()).setFlow(newNodes);
+
+    finishFlowAction(); // does also enable() and refresh()
+    flowList.setSelection(removedItemIndex - 1);
+    enable(); // after setting selection
+  }
+
+  /**
+   * Adds a node to the flowList
+   * 
+   * @param node
+   *          the key of the delegate
+   */
+  public void addNode(String node) {
+    FlowConstraints flowConstraints = getModelFlow();
+    if (null == flowConstraints) {
+      // no constraints declared
+      // set up Fix Flow style of contraints
+      //   This can happen if the style is user-defined flow
+      flowConstraints = UIMAFramework.getResourceSpecifierFactory().createFixedFlow();
+      getAnalysisEngineMetaData().setFlowConstraints(flowConstraints);
+    }
+    FlowNodes flowNodes = new FlowNodes(flowConstraints);
+    String[] nodes = flowNodes.getFlow();
+
+    if (nodes == null) {
+      nodes = new String[] { node };
+      flowNodes.setFlow(nodes);
+    } else {
+      // create a new String array and copy old Strings
+      String newNodes[] = new String[nodes.length + 1];
+      System.arraycopy(nodes, 0, newNodes, 0, nodes.length);
+      newNodes[newNodes.length - 1] = node;
+      flowNodes.setFlow(newNodes);
+    }
+    finishFlowAction(); // setFileDirty, enable() and setFocus()
+  }
+
+  /**
+   * Enables and disables section, enables and disables buttons after content.
+   * 
+   */
+  public void enable() {
+
+    // if annotator is primitive disable whole section
+    if (!isAggregate()) {
+      upButton.setEnabled(false);
+      downButton.setEnabled(false);
+      flowChoiceLabel.setEnabled(false);
+      flowControllerChoice.setEnabled(false);
+      enableFlowControllerGUI(false);
+    } else {
+      FlowControllerDeclaration fcd = getFlowControllerDeclaration();
+      enableFlowControllerGUI(null != fcd);
+      flowControllerChoice.setEnabled(true);
+      flowChoiceLabel.setEnabled(true);
+      int items = flowList.getItemCount();
+      int selection = flowList.getSelectionIndex();
+
+      if (items == 0 || selection == -1) {
+        editor.getAggregatePage().getAggregateSection().getRemoveFromFlowButton().setEnabled(false);
+        upButton.setEnabled(false);
+        downButton.setEnabled(false);
+
+      } else {
+        editor.getAggregatePage().getAggregateSection().getRemoveFromFlowButton().setEnabled(true);
+        // disable if first item is selected
+        upButton.setEnabled(!(selection == 0));
+        // disable if last item is selected
+        downButton.setEnabled(!(selection == items - 1));
+      }
+    }
+
+  }
+
+  /**
+   * Proofs if a node is contained in the list of nodes
+   * 
+   * @param node
+   * @return whether the node is in the list or not
+   */
+  public boolean containsNode(String node) {
+    String[] nodes = new FlowNodes(getModelFlow()).getFlow();
+    if (null == nodes)
+      return false;
+
+    for (int i = 0; i < nodes.length; i++) {
+      if (node.equals(nodes[i]))
+        return true;
+    }
+    return false;
+  }
+
+  /**
+   * @return
+   */
+  public Button getDownButton() {
+    return downButton;
+  }
+
+  /**
+   * @return
+   */
+  public Table getFlowList() {
+    return flowList;
+  }
+
+  /**
+   * @return
+   */
+  public Button getUpButton() {
+    return upButton;
+  }
+
+  public void removeAll() {
+    FlowConstraints flow = getModelFlow();
+    if (flow != null) {
+      flow.setAttributeValue("fixedFlow", new String[0]); //$NON-NLS-1$
+      editor.setFileDirty();
+      editor.getAggregatePage().getAggregateSection().refresh();
+    }
+  }
+
+  private static final String[] flowControllerHeadersLC = new String[] { "<flowcontrollerdescription" }; // don't
+
+  // end
+  // in a
+  // blank
+  // -
+  // could
+  // mismatch
+  // a
+  // cr/lf
+
+  private void handleFindFlowController() {
+    FindComponentDialog dialog1 = new FindComponentDialog(this, "Find a Flow Controller",
+            "Specify a name pattern and/or other constraints, and then push the Search button",
+            flowControllerHeadersLC);
+    if (Window.CANCEL == dialog1.open())
+      return;
+
+    List matchingDelegateComponentDescriptors = dialog1.getMatchingDelegateComponentDescriptors();
+    List matchingDelegateComponentDescriptions = dialog1.getMatchingDelegateComponentDescriptions();
+
+    if (matchingDelegateComponentDescriptors.size() == 0) {
+      Utility.popMessage("No matching Components",
+              "There are no Components matching your search criteria.", MessageDialog.ERROR);
+      return;
+    }
+
+    PickTaeForTypesDialog dialog2 = new PickTaeForTypesDialog(this, editor.getFile().getName(),
+            matchingDelegateComponentDescriptors, matchingDelegateComponentDescriptions);
+    if (Window.CANCEL == dialog2.open())
+      return;
+
+    String[] selectedDelegateComponentDescriptors = dialog2
+            .getSelectedDelegateComponentDescriptors();
+
+    if (selectedDelegateComponentDescriptors == null
+            || selectedDelegateComponentDescriptors.length == 0) {
+      return;
+    }
+    if (checkForOneSelection(selectedDelegateComponentDescriptors.length)) {
+      String fileName = selectedDelegateComponentDescriptors[0].replace('\\', '/');
+      int nLastSlashLoc = fileName.lastIndexOf('/');
+      String shortName;
+      if (nLastSlashLoc == -1) {
+        shortName = fileName;
+      } else {
+        shortName = fileName.substring(nLastSlashLoc + 1);
+      }
+      produceKeyAddFlowController(shortName,
+              editor.getFullPathFromDescriptorRelativePath(fileName), dialog2.isImportByName);
+    }
+  }
+
+  private void produceKeyAddFlowController(String shortName, String fullPathFileName,
+          boolean isImportByName) {
+    Import imp = createImport(fullPathFileName, isImportByName);
+
+    // key is shortName plus a suffix if needed to make it unique.
+    // The set of existing keys is obtained from the model,
+    // not from the GUI table (as was the case in earlier design)
+    FlowControllerDeclaration oldFcd = getFlowControllerDeclaration();
+    setFlowControllerDeclaration(null);
+
+    String keyName = produceUniqueComponentKey(shortName);
+    if (null == keyName) {
+      setFlowControllerDeclaration(oldFcd); // revert
+      return;
+    }
+
+    XMLizable inputDescription = readImport(imp, fullPathFileName, isImportByName);
+    if (null == inputDescription) {
+      setFlowControllerDeclaration(oldFcd); // revert
+      return;
+    }
+
+    if (!(inputDescription instanceof FlowControllerDescription)) {
+      Utility.popMessage("Invalid kind of descriptor", MessageFormat.format(
+              "Operation cancelled: The descriptor ''{0}'' being added is not a FlowController.",
+              new Object[] { maybeShortenFileName(fullPathFileName) }), MessageDialog.ERROR);
+      setFlowControllerDeclaration(oldFcd); // revert
+      return;
+    }
+
+    FlowControllerDeclaration fcd = new FlowControllerDeclaration_impl();
+    fcd.setKey(keyName);
+    fcd.setImport(imp);
+    setFlowControllerDeclaration(fcd);
+
+    // before adding the import, see if the merge type system is OK
+    if (!isValidAggregateChange()) {
+      setFlowControllerDeclaration(oldFcd); // revert
+      return;
+    }
+
+    finishAggregateChangeAction();
+    editor.addDirtyTypeName("<Aggregate>"); // force running jcasgen
+    refresh(); // refresh every time to capture the order of items added
+  }
+
+  private void handleSpecifyFlowController() {
+    MultiResourceSelectionDialog dialog = new MultiResourceSelectionDialog(getSection().getShell(),
+            editor.getFile().getProject().getParent(), "Flow Controller Selection", editor
+                    .getFile().getLocation(), editor);
+    dialog.setTitle("Flow Controller Selection");
+    dialog.setMessage("Select a Flow Controller descriptor from the workspace:");
+    dialog.open();
+    Object[] files = dialog.getResult();
+
+    if (files != null && checkForOneSelection(files.length)) {
+      FileAndShortName fsn = new FileAndShortName(files[0]);
+      produceKeyAddFlowController(fsn.shortName, fsn.fileName, dialog.isImportByName);
+    }
+  }
+
+  private boolean checkForOneSelection(int numberSelected) {
+    if (numberSelected > 1) {
+      Utility.popMessage("Error - Multiple selection",
+              "Only one Flow Controller can be selected. Please try again.", MessageDialog.ERROR);
+      return false;
+    }
+    return true;
+  }
+
+}
diff --git a/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/GeneralSection.java b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/GeneralSection.java
new file mode 100644
index 0000000..0b06af2
--- /dev/null
+++ b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/GeneralSection.java
@@ -0,0 +1,266 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.uima.taeconfigurator.editors.ui;
+
+import org.apache.uima.Constants;
+import org.apache.uima.UIMAFramework;
+import org.apache.uima.analysis_engine.metadata.FlowConstraints;
+import org.apache.uima.resource.ExternalResourceDependency;
+import org.apache.uima.resource.ExternalResourceDescription;
+import org.apache.uima.resource.ResourceInitializationException;
+import org.apache.uima.resource.metadata.ConfigurationParameter;
+import org.apache.uima.resource.metadata.ConfigurationParameterSettings;
+import org.apache.uima.resource.metadata.ExternalResourceBinding;
+import org.apache.uima.resource.metadata.FsIndexDescription;
+import org.apache.uima.resource.metadata.ResourceManagerConfiguration;
+import org.apache.uima.taeconfigurator.InternalErrorCDE;
+import org.apache.uima.taeconfigurator.editors.MultiPageEditor;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.window.Window;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.ui.forms.IManagedForm;
+
+public class GeneralSection extends AbstractSection {
+
+  public void enable() {
+  }
+
+  private Button cppButton;
+
+  private Button javaButton;
+
+  private Button primitiveButton;
+
+  private Button aggregateButton;
+
+  /**
+   * Creates a section to edit general information like primitive or aggregate and C++ or Java
+   * 
+   * @param editor
+   *          the referenced multipage editor
+   */
+  public GeneralSection(MultiPageEditor aEditor, Composite parent) {
+    super(aEditor, parent, "Implementation Details", null);
+  }
+
+  /*
+   * (non-Javadoc)
+   * 
+   * @see org.eclipse.ui.forms.IFormPart#initialize(org.eclipse.ui.forms.IManagedForm)
+   */
+  public void initialize(IManagedForm form) {
+    super.initialize(form);
+    ((GridData) this.getSection().getLayoutData()).grabExcessVerticalSpace = false;
+    Composite sectionClient = new2ColumnComposite(this.getSection());
+    ((GridData) sectionClient.getLayoutData()).grabExcessVerticalSpace = false;
+    // FrameworkImplementation choose, 2 radio buttons
+    if (isAeDescriptor() || isCasConsumerDescriptor()) {
+      toolkit.createLabel(sectionClient, "Implementation Language").setToolTipText(
+              "Choose the implementation language here.");
+
+      Composite buttons = new2ColumnComposite(sectionClient);
+      cppButton = newRadioButton(buttons, "C/C++", "C/C++", NOT_SELECTED);
+      javaButton = newRadioButton(buttons, "Java", "Java", SELECTED);
+
+      // DescriptorType choose, 2 radio buttons
+      toolkit.createLabel(sectionClient, "Engine Type").setToolTipText(
+              "Choose the type of the engine here.");
+
+      buttons = new2ColumnComposite(sectionClient);
+
+      primitiveButton = newRadioButton(buttons, "Primitive", S_, SELECTED);
+      aggregateButton = newRadioButton(buttons, "Aggregate", S_, NOT_SELECTED);
+    }
+  }
+
+  /*
+   * (non-Javadoc)
+   * 
+   * @see org.eclipse.ui.forms.IFormPart#refresh()
+   */
+  public void refresh() {
+    super.refresh();
+    boolean isPrimitive = isPrimitive();
+    // select primitive or aggregate
+    if (isAeDescriptor() || isCasConsumerDescriptor()) {
+      primitiveButton.setSelection(isPrimitive);
+      aggregateButton.setSelection(!isPrimitive);
+
+      // select C++ or Java
+      String implType = editor.getAeDescription().getFrameworkImplementation();
+      cppButton.setSelection(Constants.CPP_FRAMEWORK_NAME.equals(implType));
+      javaButton.setSelection(Constants.JAVA_FRAMEWORK_NAME.equals(implType));
+    }
+  }
+
+  /*
+   * (non-Javadoc)
+   * 
+   * @see org.eclipse.swt.widgets.Listener#handleEvent(org.eclipse.swt.widgets.Event)
+   */
+  public void handleEvent(Event event) {
+    if (event.widget == primitiveButton || event.widget == aggregateButton) {
+      boolean isPrimitive = primitiveButton.getSelection();
+      // Note: events occur when button is selected or deselected
+      if (event.widget == primitiveButton && !isPrimitive)
+        return; // deselecting
+      if (event.widget == aggregateButton && isPrimitive)
+        return; // deselecting
+      if (isPrimitive && isPrimitive())
+        return; // nothing changed
+      if (!isPrimitive && isAggregate())
+        return; // nothing changed
+      if (isPrimitive) {
+        if (Window.CANCEL == Utility.popOkCancel("Switching from Aggregate",
+                "This action will clear the capabilities, reset the delegates, "
+                        + "reset the flow, reset the parameters, reset any resource information "
+                        + "and start with an empty type system.  Are you sure?",
+                MessageDialog.WARNING)) {
+          aggregateButton.setSelection(true);
+          primitiveButton.setSelection(false);
+          return;
+        }
+        editor.getAeDescription().setAnnotatorImplementationName("");
+      } else {
+        // if (isLocalProcessingDescriptor() && !isAeDescriptor()) {
+        // Utility.popMessage("Not Allowed",
+        // "Cas Consumers, Cas Initializers, Collection Readers, and Flow Controllers cannot be
+        // Aggregates.",
+        // MessageDialog.ERROR);
+        // primitiveButton.setSelection(true);
+        // aggregateButton.setSelection(false);
+        // return;
+        // }
+        if (Window.CANCEL == Utility.popOkCancel("Switching from Primitive AE",
+                "This action will clear the capabilities, reset the delegates, "
+                        + "reset the parameters, reset any resource information "
+                        + "and reset the type system.  Are you sure?", MessageDialog.WARNING)) {
+          primitiveButton.setSelection(true);
+          aggregateButton.setSelection(false);
+          return;
+        }
+        editor.getAeDescription().setAnnotatorImplementationName(null);
+      }
+      editor.getAeDescription().setPrimitive(isPrimitive);
+      commonResets();
+      try {
+        editor.setAeDescription(editor.getAeDescription());
+      } catch (ResourceInitializationException e) {
+        throw new InternalErrorCDE("invalid state", e);
+      }
+      javaButton.setEnabled(isPrimitive);
+      cppButton.setEnabled(isPrimitive);
+      HeaderPage page = editor.getAggregatePage();
+      if (null != page)
+        page.markStale();
+      page = editor.getParameterPage();
+      if (null != page)
+        page.markStale();
+      page = editor.getSettingsPage();
+      if (null != page)
+        page.markStale();
+      page = editor.getTypePage();
+      if (null != page)
+        markRestOfPageStale(page.getManagedForm(), null);
+      page = editor.getCapabilityPage();
+      if (null != page)
+        page.markStale();
+      page = editor.getIndexesPage();
+      if (null != page)
+        page.markStale();
+      page = editor.getResourcesPage();
+      if (null != page)
+        page.markStale();
+    }
+    if (event.widget == javaButton || event.widget == cppButton) {
+      valueChanged = false;
+      if (cppButton.getSelection()) {
+        editor.getAeDescription().setFrameworkImplementation(
+                setValueChanged(Constants.CPP_FRAMEWORK_NAME, editor.getAeDescription()
+                        .getFrameworkImplementation()));
+      } else {
+        editor.getAeDescription().setFrameworkImplementation(
+                setValueChanged(Constants.JAVA_FRAMEWORK_NAME, editor.getAeDescription()
+                        .getFrameworkImplementation()));
+      }
+      if (!valueChanged)
+        return;
+    }
+    PrimitiveSection s = editor.getOverviewPage().getPrimitiveSection();
+    if (null != s) {
+      s.refresh();
+      // next line makes the bounding rectangle show up
+      s.getSection().getClient().redraw();
+    }
+    setFileDirty();
+  }
+
+  private void commonResets() {
+    // clear the delegates
+    getDelegateAnalysisEngineSpecifiersWithImports().clear();
+    editor.getResolvedDelegates().clear();
+    if (isAggregate()) {
+      // reset the flow to fixed flow with null as the set
+      FlowConstraints flowConstraints = UIMAFramework.getResourceSpecifierFactory()
+              .createFixedFlow();
+      flowConstraints.setAttributeValue("fixedFlow", stringArray0);
+      getAnalysisEngineMetaData().setFlowConstraints(flowConstraints);
+    } else
+      getAnalysisEngineMetaData().setFlowConstraints(null);
+    // clear capabilities
+    getAnalysisEngineMetaData().setCapabilities(capabilityArray0);
+    addCapabilitySet();
+    // reset parameters
+    // reset the parameters not declared in a group
+    getConfigurationParameterDeclarations().setConfigurationParameters(
+            new ConfigurationParameter[0]);
+    // reset groups
+    getConfigurationParameterDeclarations().setConfigurationGroups(
+            AbstractSection.configurationGroupArray0);
+    // reset common parameters
+    getConfigurationParameterDeclarations().setCommonParameters(new ConfigurationParameter[0]);
+    // reset default group name
+    getConfigurationParameterDeclarations().setDefaultGroupName("");
+    // reset search strategy
+    getConfigurationParameterDeclarations().setSearchStrategy("");
+
+    // reset the parm settings
+    ConfigurationParameterSettings configParmSettings = UIMAFramework.getResourceSpecifierFactory()
+            .createConfigurationParameterSettings();
+    getAnalysisEngineMetaData().setConfigurationParameterSettings(configParmSettings);
+    // reset typesystem, needed when going from primitive to aggregate
+    getAnalysisEngineMetaData().setTypeSystem(null);
+    // reset resources
+    editor.getAeDescription().setExternalResourceDependencies(new ExternalResourceDependency[0]);
+    ResourceManagerConfiguration rmc = editor.getAeDescription().getResourceManagerConfiguration();
+    if (null != rmc) {
+      rmc.setExternalResourceBindings(new ExternalResourceBinding[0]);
+      rmc.setExternalResources(new ExternalResourceDescription[0]);
+    }
+    // reset indexes
+    getAnalysisEngineMetaData().setFsIndexCollection(null);
+    getAnalysisEngineMetaData().setFsIndexes(new FsIndexDescription[0]);
+    // reset index type priorities
+    getAnalysisEngineMetaData().setTypePriorities(null);
+  }
+}
diff --git a/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/HeaderPage.java b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/HeaderPage.java
new file mode 100644
index 0000000..8c084be
--- /dev/null
+++ b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/HeaderPage.java
@@ -0,0 +1,304 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS 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.taeconfigurator.editors.ui;
+
+import org.apache.uima.analysis_engine.metadata.AnalysisEngineMetaData;
+import org.apache.uima.taeconfigurator.TAEConfiguratorPlugin;
+import org.apache.uima.taeconfigurator.editors.Form2Panel;
+import org.apache.uima.taeconfigurator.editors.MultiPageEditor;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.SashForm;
+import org.eclipse.swt.custom.ScrolledComposite;
+import org.eclipse.swt.events.ControlAdapter;
+import org.eclipse.swt.events.ControlEvent;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Listener;
+import org.eclipse.ui.forms.AbstractFormPart;
+import org.eclipse.ui.forms.IFormPart;
+import org.eclipse.ui.forms.IManagedForm;
+import org.eclipse.ui.forms.ManagedForm;
+import org.eclipse.ui.forms.editor.FormPage;
+import org.eclipse.ui.forms.widgets.FormToolkit;
+import org.eclipse.ui.forms.widgets.ScrolledForm;
+
+/**
+ * Common part of most pages
+ */
+public abstract class HeaderPage extends FormPage {
+
+  final public static boolean EQUAL_WIDTH = true;
+
+  protected SashForm sashForm;
+
+  protected MultiPageEditor editor;
+
+  protected FormToolkit toolkit;
+
+  protected Composite leftPanel;
+
+  protected Composite rightPanel;
+
+  protected int sashFormWidth;
+
+  protected float leftPanelPercent;
+
+  protected float rightPanelPercent;
+
+  protected int leftPanelWidth;
+
+  protected int rightPanelWidth;
+
+  public HeaderPage(MultiPageEditor formEditor, String id, String keyPageTitle) {
+    super(formEditor, id, keyPageTitle);
+    editor = formEditor;
+    toolkit = editor.getToolkit();
+  }
+
+  public HeaderPage(MultiPageEditor formEditor, String pageTitle) {
+    this(formEditor, "UID_" + pageTitle, pageTitle);
+  }
+
+  protected void maybeInitialize(IManagedForm managedForm) {
+    if (TAEConfiguratorPlugin.is30version)
+      ((ManagedForm) managedForm).initialize();
+  }
+
+  /*
+   * General methods to create sub areas on pages
+   */
+
+  public Composite newComposite(Composite parent) {
+    return newnColumnSection(parent, 1);
+  }
+
+  // this composite spans col 1 & 2, out of a 4 column (0, 1, 2, 3) grid layout
+  public Composite newCentered2SpanComposite(Composite parent) {
+    spacer(parent); // skip over col 0
+    Composite composite = newComposite(parent);
+    ((GridData) composite.getLayoutData()).horizontalSpan = 2;
+    return composite;
+  }
+
+  public Composite newnColumnSection(Composite parent, int cols) {
+    Composite section = toolkit.createComposite(parent, SWT.NONE);
+    GridLayout layout = new GridLayout();
+    layout.numColumns = cols;
+    layout.marginHeight = 0;
+    layout.marginWidth = 0;
+    section.setLayout(layout);
+    section.setLayoutData(new GridData(GridData.FILL_BOTH));
+    return section;
+  }
+
+  public Composite setup1ColumnLayout(IManagedForm managedForm) {
+    final ScrolledForm sform = managedForm.getForm();
+    final Composite form = sform.getBody();
+    form.setLayout(new GridLayout(1, false)); // this is required !
+    Composite xtra = toolkit.createComposite(form);
+    xtra.setLayout(new GridLayout(1, false));
+    xtra.setLayoutData(new GridData(GridData.FILL_BOTH));
+
+    Control c = form.getParent();
+    while (!(c instanceof ScrolledComposite))
+      c = c.getParent();
+    ((GridData) xtra.getLayoutData()).widthHint = c.getSize().x;
+    return xtra;
+  }
+
+  // this method creates no new composites.
+  public Composite setup2ColumnGrid(IManagedForm managedForm, boolean equalWidth) {
+    final ScrolledForm sform = managedForm.getForm();
+    final Composite form = sform.getBody();
+    GridLayout layout = new GridLayout(2, equalWidth);
+    form.setLayout(layout);
+    form.setLayoutData(new GridData(GridData.FILL_BOTH));
+    return form;
+  }
+
+  public Form2Panel setup2ColumnLayout(IManagedForm managedForm, int w1, int w2) {
+    final ScrolledForm sform = managedForm.getForm();
+    final Composite form = sform.getBody();
+    form.setLayout(new GridLayout(1, false)); // this is required !
+    Composite xtra = toolkit.createComposite(form);
+    xtra.setLayout(new GridLayout(1, false));
+    xtra.setLayoutData(new GridData(GridData.FILL_BOTH));
+    Control c = xtra.getParent();
+    while (!(c instanceof ScrolledComposite))
+      c = c.getParent();
+    ((GridData) xtra.getLayoutData()).widthHint = c.getSize().x;
+    ((GridData) xtra.getLayoutData()).heightHint = c.getSize().y;
+    sashForm = new SashForm(xtra, SWT.HORIZONTAL);
+
+    sashForm.setLayoutData(new GridData(GridData.FILL_BOTH)); // needed
+
+    leftPanel = newComposite(sashForm);
+    ((GridLayout) leftPanel.getLayout()).marginHeight = 5;
+    ((GridLayout) leftPanel.getLayout()).marginWidth = 5;
+    rightPanel = newComposite(sashForm);
+    ((GridLayout) rightPanel.getLayout()).marginHeight = 5;
+    ((GridLayout) rightPanel.getLayout()).marginWidth = 5;
+    sashForm.setWeights(new int[] { w1, w2 });
+    leftPanelPercent = (float) w1 / (float) (w1 + w2);
+    rightPanelPercent = (float) w2 / (float) (w1 + w2);
+
+    rightPanel.addControlListener(new ControlAdapter() {
+      public void controlResized(ControlEvent e) {
+        setSashFormWidths();
+      }
+    });
+
+    return new Form2Panel(form, leftPanel, rightPanel);
+  }
+
+  void setSashFormWidths() {
+
+    sashFormWidth = sashForm.getSize().x;
+    int[] ws = sashForm.getWeights();
+
+    leftPanelWidth = (int) (((float) ws[0] / (float) (ws[0] + ws[1])) * sashFormWidth);
+    rightPanelWidth = (int) (((float) ws[1] / (float) (ws[0] + ws[1])) * sashFormWidth);
+  }
+
+  /**
+   * Sash impl
+   * 
+   * @param managedForm
+   * @param equalWidth
+   * @return
+   */
+  public Form2Panel setup2ColumnLayout(IManagedForm managedForm, boolean equalWidth) {
+    if (equalWidth)
+      return setup2ColumnLayout(managedForm, 50, 50);
+    else
+      // a hack - based on first column more likely being wider
+      return setup2ColumnLayout(managedForm, 60, 40);
+  }
+
+  public Form2Panel setup2ColumnLayoutNotSash(IManagedForm managedForm, boolean equalWidth) {
+    final ScrolledForm sform = managedForm.getForm();
+    final Composite form = sform.getBody();
+    GridLayout layout = new GridLayout(2, equalWidth);
+    form.setLayout(layout);
+    form.setLayoutData(new GridData(GridData.FILL_BOTH));
+    leftPanel = newComposite(form);
+    rightPanel = newComposite(form);
+    // strategy for setting size hints of right and left panels
+    // Why set hints? Because they make the inner containing things
+    // scroll horiz. if they're too wide (useful for aggregates having
+    // long names).
+    // What hint to set? The hint should be the smallest size you want
+    // with child scrolling, before the tabbed page container itself
+    // gets a scroll bar.
+    // When in the life cycle to do this? Only need to do it once, but
+    // after the Grid Layout has happened. This can be the first resizing
+    // event (learned this by debugging)
+
+    sform.addListener(SWT.Resize, new Listener() {
+      public void handleEvent(Event event) {
+        float col1CurrentWidth = leftPanel.getSize().x;
+        float col2CurrentWidth = rightPanel.getSize().x;
+        final int minLeftPanelWidth = 250; // in pels
+        final int minRightPanelWidth = (int) (col2CurrentWidth * minLeftPanelWidth / col1CurrentWidth);
+        ((GridData) leftPanel.getLayoutData()).widthHint = minLeftPanelWidth;
+        ((GridData) rightPanel.getLayoutData()).widthHint = minRightPanelWidth;
+        sform.removeListener(SWT.Resize, this); // only do this one time
+      }
+    });
+    return new Form2Panel(form, leftPanel, rightPanel);
+  }
+
+  public Form2Panel setup2ColumnLayoutOn4Grid(IManagedForm managedForm, boolean equalWidth) {
+    Form2Panel f = setup2ColumnLayoutNotSash(managedForm, equalWidth);
+    ((GridLayout) f.form.getLayout()).numColumns = 4;
+    ((GridData) f.left.getLayoutData()).horizontalSpan = 2;
+    ((GridData) f.right.getLayoutData()).horizontalSpan = 2;
+    return f;
+  }
+
+  protected void spacer(Composite container) {
+    toolkit.createLabel(container, " ");
+  }
+
+  public void markStale() {
+    if (getManagedForm() != null) {
+      IFormPart[] parts = getManagedForm().getParts();
+      for (int i = 0; i < parts.length; i++) {
+        ((AbstractFormPart) parts[i]).markStale();
+      }
+    }
+  }
+
+  // **************************************************
+  // * Model Access
+  // **************************************************
+
+  protected boolean isPrimitive() {
+    return editor.getAeDescription().isPrimitive();
+  }
+
+  protected boolean isAeDescriptor() {
+    return editor.isAeDescriptor();
+  }
+
+  public boolean isTypeSystemDescriptor() {
+    return editor.isTypeSystemDescriptor();
+  }
+
+  public boolean isIndexDescriptor() {
+    return editor.isFsIndexCollection();
+  }
+
+  public boolean isTypePriorityDescriptor() {
+    return editor.isTypePriorityDescriptor();
+  }
+
+  public boolean isExtResAndBindingsDescriptor() {
+    return editor.isExtResAndBindingsDescriptor();
+  }
+
+  public boolean isCollectionReaderDescriptor() {
+    return editor.isCollectionReaderDescriptor();
+  }
+
+  public boolean isCasInitializerDescriptor() {
+    return editor.isCasInitializerDescriptor();
+  }
+
+  public boolean isCasConsumerDescriptor() {
+    return editor.isCasConsumerDescriptor();
+  }
+
+  public boolean isLocalProcessingDescriptor() {
+    return editor.isLocalProcessingDescriptor();
+  }
+
+  protected AnalysisEngineMetaData getAnalysisEngineMetaData() {
+    return editor.getAeDescription().getAnalysisEngineMetaData();
+  }
+
+  // **************************************************
+  // * Common Actions in Handlers
+  // **************************************************
+
+}
diff --git a/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/HeaderPageWithSash.java b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/HeaderPageWithSash.java
new file mode 100644
index 0000000..94f270d
--- /dev/null
+++ b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/HeaderPageWithSash.java
@@ -0,0 +1,89 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.uima.taeconfigurator.editors.ui;
+
+import org.apache.uima.taeconfigurator.TAEConfiguratorPlugin;
+import org.apache.uima.taeconfigurator.editors.MultiPageEditor;
+import org.eclipse.jface.action.Action;
+import org.eclipse.swt.SWT;
+import org.eclipse.ui.forms.IManagedForm;
+import org.eclipse.ui.forms.widgets.ScrolledForm;
+
+/**
+ */
+public class HeaderPageWithSash extends HeaderPage {
+
+  /**
+   * @param formEditor
+   * @param id
+   * @param keyPageTitle
+   */
+
+  protected Action haction;
+
+  protected Action vaction;
+
+  public HeaderPageWithSash(MultiPageEditor formEditor, String id, String keyPageTitle) {
+    super(formEditor, id, keyPageTitle);
+  }
+
+  /**
+   * @param formEditor
+   * @param pageTitle
+   */
+  public HeaderPageWithSash(MultiPageEditor formEditor, String pageTitle) {
+    super(formEditor, pageTitle);
+  }
+
+  protected void createToolBarActions(IManagedForm managedForm) {
+    final ScrolledForm form = managedForm.getForm();
+
+    haction = new Action("hor", Action.AS_RADIO_BUTTON) { //$NON-NLS-1$
+      public void run() {
+        sashForm.setOrientation(SWT.HORIZONTAL);
+        form.reflow(true);
+      }
+    };
+    haction.setChecked(true);
+    haction.setToolTipText("Horizontal Orientation");
+    haction.setImageDescriptor(TAEConfiguratorPlugin
+            .getImageDescriptor(TAEConfiguratorPlugin.IMAGE_TH_HORIZONTAL));
+    haction.setDisabledImageDescriptor(TAEConfiguratorPlugin
+            .getImageDescriptor(TAEConfiguratorPlugin.IMAGE_TH_HORIZONTAL));
+
+    vaction = new Action("ver", Action.AS_RADIO_BUTTON) { //$NON-NLS-1$
+      public void run() {
+        sashForm.setOrientation(SWT.VERTICAL);
+        form.reflow(true);
+      }
+    };
+    vaction.setChecked(false);
+    vaction.setToolTipText("Vertical Orientation");
+    vaction.setImageDescriptor(TAEConfiguratorPlugin
+            .getImageDescriptor(TAEConfiguratorPlugin.IMAGE_TH_VERTICAL));
+    vaction.setDisabledImageDescriptor(TAEConfiguratorPlugin
+            .getImageDescriptor(TAEConfiguratorPlugin.IMAGE_TH_VERTICAL));
+    form.getToolBarManager().add(haction);
+    form.getToolBarManager().add(vaction);
+    form.updateToolBar();
+    maybeInitialize(managedForm);
+  }
+
+}
diff --git a/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/ImportResBindSection.java b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/ImportResBindSection.java
new file mode 100644
index 0000000..6f15635
--- /dev/null
+++ b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/ImportResBindSection.java
@@ -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.
+ */
+
+package org.apache.uima.taeconfigurator.editors.ui;
+
+import org.apache.uima.resource.metadata.Import;
+import org.apache.uima.resource.metadata.ResourceManagerConfiguration;
+import org.apache.uima.resource.metadata.impl.ResourceManagerConfiguration_impl;
+import org.apache.uima.taeconfigurator.editors.MultiPageEditor;
+import org.apache.uima.util.InvalidXMLException;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ */
+public class ImportResBindSection extends ImportSection {
+
+  public ImportResBindSection(MultiPageEditor editor, Composite parent) {
+    super(editor, parent, "Imports for External Resources and Bindings",
+            "The following definitions are included:"); // or ! DESCRIPTION
+  }
+
+  // **************************************
+  // * Code to support type import section
+  // **************************************
+  protected boolean isAppropriate() {
+    return true; // always show
+  }
+
+  /**
+   * used when hovering
+   */
+  protected String getDescriptionFromImport(String source) {
+    return ""; // imports for resource bindings don't have descriptions
+  }
+
+  protected Import[] getModelImportArray() {
+    return getResourceManagerConfiguration().getImports();
+  }
+
+  protected void setModelImportArray(Import[] imports) {
+    getResourceManagerConfiguration().setImports(imports);
+  }
+
+  protected void clearModelBaseValue() {
+    getResourceManagerConfiguration().setExternalResourceBindings(externalResourceBinding0);
+    getResourceManagerConfiguration().setExternalResources(externalResourceDescription0);
+  }
+
+  // indexes are checked and merged when the CAS is built
+  protected boolean isValidImport(String title, String message) {
+    ResourceManagerConfiguration savedRmc = editor.getResolvedExternalResourcesAndBindings();
+    if (null != savedRmc)
+      savedRmc = (ResourceManagerConfiguration) ((ResourceManagerConfiguration_impl) savedRmc)
+              .clone();
+    try {
+      editor.setResolvedExternalResourcesAndBindings();
+    } catch (InvalidXMLException e) {
+      Utility.popMessage(title, message + editor.getMessagesToRootCause(e), Utility.ERROR);
+      revert(savedRmc);
+      return false;
+    }
+    if (!isValidAe()) {
+      revert(savedRmc);
+      return false;
+    }
+    return true;
+  }
+
+  private void revert(ResourceManagerConfiguration rmc) {
+    getResourceManagerConfiguration()
+            .setExternalResourceBindings(rmc.getExternalResourceBindings());
+    getResourceManagerConfiguration().setExternalResources(rmc.getExternalResources());
+    editor.setResolvedExternalResourcesAndBindings(rmc);
+  }
+
+  protected void finishImportChangeAction() {
+    editor.getResourcesPage().getResourceDependencySection().refresh(); // to change Binding flag
+  }
+
+  public void enable() {
+    super.enable();
+    addButton.setEnabled(true); // can add buttons even for aggregate
+  }
+
+}
diff --git a/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/ImportSection.java b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/ImportSection.java
new file mode 100644
index 0000000..b2f4dc4
--- /dev/null
+++ b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/ImportSection.java
@@ -0,0 +1,418 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS 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.taeconfigurator.editors.ui;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.text.MessageFormat;
+
+import org.apache.uima.resource.metadata.Import;
+import org.apache.uima.taeconfigurator.CDEpropertyPage;
+import org.apache.uima.taeconfigurator.InternalErrorCDE;
+import org.apache.uima.taeconfigurator.editors.MultiPageEditor;
+import org.apache.uima.taeconfigurator.editors.ui.dialogs.CommonInputDialog;
+import org.apache.uima.taeconfigurator.editors.ui.dialogs.ExportImportablePartDialog;
+import org.apache.uima.taeconfigurator.files.MultiResourceSelectionDialog;
+import org.apache.uima.util.InvalidXMLException;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.QualifiedName;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.window.Window;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.TableItem;
+import org.eclipse.ui.forms.IManagedForm;
+
+/**
+ * Imports - used by aggregates types type priorities indexes external resource specifications
+ */
+public abstract class ImportSection extends AbstractSection {
+
+  protected abstract Import[] getModelImportArray();
+
+  protected abstract void setModelImportArray(Import[] newImports);
+
+  protected abstract boolean isValidImport(String title, String message);
+
+  protected abstract void finishImportChangeAction();
+
+  protected abstract String getDescriptionFromImport(String source) throws InvalidXMLException,
+          IOException;
+
+  protected abstract boolean isAppropriate(); // if false, don't show section
+
+  protected abstract void clearModelBaseValue(); // used to clear exported value
+
+  protected static final long TABLE_HOVER_REQUERY_TIME = 15000;
+
+  protected TableItem lastTableHoverItem = null;
+
+  protected long lLastTableHoverMillis = -1;
+
+  protected String sLastTableHoverHelp = "";
+
+  protected boolean bDisableToolTipHelp = false;
+
+  private static final String TABLE_INDICATOR_BY_NAME = "By Name";
+
+  private static final String TABLE_INDICATOR_BY_LOCATION = "By Location";
+
+  protected Button addButton;
+
+  private Button removeButton;
+
+  private Button setDataPathButton;
+
+  Table importTable;
+
+  public ImportSection(MultiPageEditor aEditor, Composite parent, String title, String description) {
+    super(aEditor, parent, title, description);
+  }
+
+  public void initialize(IManagedForm form) {
+    super.initialize(form);
+
+    // set up Composite to hold widgets in the section
+    Composite sectionClient = newComposite(getSection());
+    enableBorders(sectionClient);
+
+    Composite buttonContainer = new2ColumnComposite(sectionClient);
+    ((GridData) buttonContainer.getLayoutData()).grabExcessVerticalSpace = false;
+    ((GridData) buttonContainer.getLayoutData()).grabExcessHorizontalSpace = false;
+    ((GridData) buttonContainer.getLayoutData()).horizontalAlignment = SWT.RIGHT;
+
+    addButton = newPushButton(buttonContainer, "Add...", "Click here to add an import");
+    removeButton = newPushButton(buttonContainer, "Remove",
+            "Click here to remove the selected import.");
+    setDataPathButton = newPushButton(buttonContainer, "Set DataPath",
+            "Click here to view or set the data path to use when resolving imports by name.");
+    importTable = newTable(sectionClient, SWT.FULL_SELECTION, NO_MIN_HEIGHT);
+
+    newTableColumn(importTable).setText("Kind");
+    newTableColumn(importTable).setText("Location/Name");
+
+    importTable.setHeaderVisible(true);
+    packTable(importTable);
+
+    // in addition to normal keyup and mouse up:
+    importTable.addListener(SWT.MouseHover, this);
+    importTable.addListener(SWT.MouseDown, this);
+
+    toolkit.paintBordersFor(sectionClient);
+  }
+
+  public void refresh() {
+    super.refresh();
+    importTable.removeAll();
+
+    if (isAppropriate()) {
+
+      Import[] importItems = getModelImportArray();
+      if (importItems != null) {
+        for (int i = 0; i < importItems.length; i++) {
+          if (importItems[i] != null) {
+            TableItem tableItem = new TableItem(importTable, SWT.NONE);
+            if (importItems[i].getLocation() != null) {
+              tableItem.setText(0, TABLE_INDICATOR_BY_LOCATION);
+              tableItem.setText(1, importItems[i].getLocation());
+            } else {
+              tableItem.setText(0, TABLE_INDICATOR_BY_NAME);
+              tableItem.setText(1, importItems[i].getName());
+            }
+          }
+        }
+        packTable(importTable);
+      }
+    }
+
+    enable();
+  }
+
+  /*
+   * (non-Javadoc)
+   * 
+   * @see org.apache.uima.taeconfigurator.editors.ui.AbstractTableSection#handleEvent(org.eclipse.swt.widgets.Event)
+   */
+  public void handleEvent(Event event) {
+
+    if (event.widget == addButton) {
+      handleAdd();
+    } else if (event.widget == removeButton) {
+      handleRemove();
+    } else if (event.widget == setDataPathButton) {
+      handleSetDataPath();
+    } else if (event.type == SWT.MouseDown && event.button == 3) {
+      handleTableContextMenuRequest(event);
+    } else if (event.type == SWT.MouseHover && !bDisableToolTipHelp) {
+      handleTableHoverHelp(event);
+    } else if (event.type == SWT.KeyUp) {
+      if (event.character == SWT.DEL) {
+        handleRemove();
+      }
+    } else if (event.widget == importTable && event.type == SWT.Selection) {
+      enable();
+    }
+  }
+
+  public void handleRemove() {
+    int nSelectedIndex = importTable.getSelectionIndex();
+
+    Import[] oldImports = getModelImportArray();
+
+    setModelImportArray((Import[]) Utility.removeElementFromArray(oldImports,
+            oldImports[nSelectedIndex], Import.class));
+
+    if (!isValidImport("Error Removing Import", "An error was caused by removing an import.")) {
+      setModelImportArray(oldImports);
+      // no refresh here: the remove action didn't happen, so leave the GUI alone
+      return;
+    }
+
+    refresh();
+    importTable.setSelection(nSelectedIndex - 1);
+    enable();
+    finishImportChangeAction();
+    setFileDirty();
+  }
+
+  private void handleSetDataPath() {
+    CommonInputDialog dialog = new CommonInputDialog(
+            this,
+            "Set DataPath",
+            "The DataPath is a series of locations which will be used when looking up imports and external resources.\nEnter a series of absolute path names, separated by the character used to separate classpath names on this platform.",
+            CommonInputDialog.ALLOK, CDEpropertyPage.getDataPath(editor.getProject()));
+    if (dialog.open() == Window.CANCEL)
+      return;
+    CDEpropertyPage.setDataPath(editor.getProject(), dialog.getValue());
+  }
+
+  private void handleAdd() {
+    Shell shell = getSection().getShell();
+    MultiResourceSelectionDialog dialog = new MultiResourceSelectionDialog(shell, editor.getFile()
+            .getProject().getParent(), "Select one or more descriptor files to import:", editor
+            .getFile().getLocation(), editor);
+    dialog.setTitle("Import File(s) Selection");
+    if (dialog.open() == Window.CANCEL)
+      return;
+    // results is an array of either IFile or File objects
+    // depending on if the file was from the Eclipse Workspace or from the file system
+    Object[] results = dialog.getResult();
+
+    if (results == null || results.length == 0)
+      return;
+
+    if (!addImports(results, dialog.isImportByName))
+      return;
+
+    refresh();
+    finishImportChangeAction();
+    setFileDirty();
+
+  }
+
+  /**
+   * Called with either byLocation non-null or byName non-null Adds multiple (by location) or one
+   * (by name)
+   * 
+   * @param location
+   *          objects returned from dialog
+   * @param true
+   *          if imports should be done by name
+   * @return false if any import caused an error, true of all OK
+   */
+  public boolean addImports(Object[] locations, boolean isByName) {
+    Import[] currentImports = getModelImportArray();
+    Import imp;
+
+    int nCountCurrentImports = (currentImports == null) ? 0 : currentImports.length;
+    int numberToAdd = locations.length;
+
+    Import[] newImports = new Import[nCountCurrentImports + numberToAdd];
+    if (null != currentImports)
+      System.arraycopy(currentImports, 0, newImports, 0, nCountCurrentImports);
+
+    for (int i = 0; i < locations.length; i++) {
+      FileAndShortName fsn = new FileAndShortName(locations[i]);
+      imp = createImport(fsn.fileName, isByName);
+      if (alreadyImported(imp))
+        return false;
+      newImports[nCountCurrentImports + i] = imp;
+    }
+
+    setModelImportArray(newImports);
+
+    if (!isValidImport(
+            "Error Adding Import(s)",
+            "An error was caused by adding Import(s); operation cancelled.  Please correct the error and retry.")) {
+      setModelImportArray(currentImports);
+      return false;
+    }
+    return true;
+  }
+
+  private boolean alreadyImported(Import imp) {
+    String currentFileBeingEdited = editor.getFile().getLocation().toString();
+    currentFileBeingEdited = editor.getDescriptorRelativePath(currentFileBeingEdited);
+    if (currentFileBeingEdited.equals(imp.getLocation())) {
+      Utility
+              .popMessage(
+                      "Error - importing self",
+                      MessageFormat
+                              .format(
+                                      "The import {0} is the same as the current file being edited. A file can''t be imported into itself.",
+                                      new Object[] { imp.getLocation() }), MessageDialog.ERROR);
+      return true;
+    }
+
+    Import[] currentImports = getModelImportArray();
+    if (null == currentImports)
+      return false;
+    for (int i = 0; i < currentImports.length; i++) {
+      if (currentImports[i].equals(imp)) {
+        Utility.popMessage("Error - duplicate import", MessageFormat.format(
+                "The import {0} is already present", new Object[] { null != imp.getName() ? imp
+                        .getName() : imp.getLocation() }), MessageDialog.ERROR);
+        return true;
+      }
+    }
+    return false;
+  }
+
+  public void enable() {
+    int nSelectionIndex = importTable.getSelectionIndex();
+    boolean addEnable = (this instanceof TypeImportSection) ? (!isAggregate()) : true;
+
+    addButton.setEnabled(addEnable);
+    removeButton.setEnabled(nSelectionIndex > -1);
+  }
+
+  private void handleTableContextMenuRequest(Event event) {
+    TableItem item = importTable.getItem(new Point(event.x, event.y));
+    int nSelectedIndex = getIndex(item);
+    bDisableToolTipHelp = true;
+    requestPopUpOverImport(getModelImportArray()[nSelectedIndex], importTable, event);
+    bDisableToolTipHelp = false;
+  }
+
+  private void handleTableHoverHelp(Event event) {
+    TableItem item = importTable.getItem(new Point(event.x, event.y));
+    if (null != item) {
+      String sDesc;
+
+      long lCurrentTimeInMillis = System.currentTimeMillis();
+      if (item == lastTableHoverItem
+              && lCurrentTimeInMillis - lLastTableHoverMillis < TABLE_HOVER_REQUERY_TIME) {
+        sDesc = sLastTableHoverHelp;
+      } else {
+        int itemIndex = (event.y - importTable.getHeaderHeight()) / importTable.getItemHeight();
+        String thisFile = item.getText(1);
+
+        sDesc = thisFile + ' ';
+        Import[] importItems = getModelImportArray();
+        if (itemIndex < 0 || itemIndex >= importItems.length) {
+          System.err.println("***ERROR Item index hover out of range" + itemIndex
+                  + ", size of array = " + importItems.length);
+          System.err.println(this.getClass().getName());
+          return;
+        }
+        Import importItem = getModelImportArray()[itemIndex];
+        // if by location, it's relative to the descriptor.
+        String absolutePath = editor.getAbsolutePathFromImport(importItem);
+
+        String description = null;
+        try {
+          description = getDescriptionFromImport(absolutePath);
+        } catch (InvalidXMLException e) {
+          // TODO Auto-generated catch block
+          e.printStackTrace();
+        } catch (IOException e) {
+          // TODO Auto-generated catch block
+          e.printStackTrace();
+        }
+        if ((null != description) && (!description.equals(""))) {
+          sDesc += "\n\n" + parseToFitInToolTips(description);
+        }
+
+        lastTableHoverItem = item;
+        lLastTableHoverMillis = System.currentTimeMillis();
+        sLastTableHoverHelp = sDesc;
+      }
+
+      importTable.setToolTipText(sDesc);
+    } else {
+      importTable.setToolTipText("");
+    }
+  }
+
+  /**
+   * 
+   * @param xmlStartElement
+   *          first element exported
+   * @param partTemplate
+   */
+  protected void exportImportablePart(String xmlStartElement, String partTemplate) {
+    String xmlEndElement = xmlStartElement.replaceFirst("<", "</");
+    ExportImportablePartDialog dialog = new ExportImportablePartDialog(this);
+    if (dialog.open() == Window.CANCEL)
+      return;
+    PrintWriter printWriter = setupToPrintFile(dialog.genFilePath);
+    if (null != printWriter) {
+      String wholeModel = editor.prettyPrintModel();
+      int start = wholeModel.indexOf(xmlStartElement);
+      int end = wholeModel.lastIndexOf(xmlEndElement);
+      if (start < 0 || end < 0)
+        throw new InternalErrorCDE("invalid state");
+      start += xmlStartElement.length();
+      printWriter.println(MessageFormat.format(partTemplate, new Object[] { dialog.baseFileName,
+          wholeModel.substring(start, end) + "\n" }));
+      printWriter.close();
+      clearModelBaseValue();
+
+      setFileDirty(); // do as soon as file changes, in case later error aborts processing
+      Import imp = createImport(dialog.genFilePath, dialog.isImportByName);
+      setModelImportArray((Import[]) Utility.addElementToArray(getModelImportArray(), imp,
+              Import.class));
+      isValidImport("Error Exporting a part and Importing it",
+              "An unexpected error was caused by the export operation");
+      refresh();
+      Object file = editor.getIFileOrFile(dialog.genFilePath);
+      if (file instanceof IFile) {
+        try {
+          IFile ifile = (IFile) file;
+          ifile.refreshLocal(1, null);
+          ((IFile) file).setPersistentProperty(
+                  new QualifiedName(PLUGIN_ID, IMPORTABLE_PART_CONTEXT), editor.getFile()
+                          .getLocation().toString());
+        } catch (CoreException e) {
+          throw new InternalErrorCDE("unexpected exception", e);
+        }
+      }
+
+    }
+  }
+
+}
diff --git a/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/IndexImportSection.java b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/IndexImportSection.java
new file mode 100644
index 0000000..3019357
--- /dev/null
+++ b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/IndexImportSection.java
@@ -0,0 +1,97 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.uima.taeconfigurator.editors.ui;
+
+import java.io.IOException;
+
+import org.apache.uima.UIMAFramework;
+import org.apache.uima.cas.CAS;
+import org.apache.uima.resource.ResourceInitializationException;
+import org.apache.uima.resource.metadata.FsIndexCollection;
+import org.apache.uima.resource.metadata.Import;
+import org.apache.uima.taeconfigurator.InternalErrorCDE;
+import org.apache.uima.taeconfigurator.editors.MultiPageEditor;
+import org.apache.uima.util.InvalidXMLException;
+import org.apache.uima.util.XMLInputSource;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ */
+public class IndexImportSection extends ImportSection {
+
+  public IndexImportSection(MultiPageEditor editor, Composite parent) {
+    super(editor, parent, "Index Imports",
+            "The following index definitions are included as part of this one."); // or !
+    // DESCRIPTION
+  }
+
+  // **************************************
+  // * Code to support type import section
+  // **************************************
+  protected boolean isAppropriate() {
+    return true; // always show
+  }
+
+  /**
+   * used when hovering
+   */
+  protected String getDescriptionFromImport(String source) throws InvalidXMLException, IOException {
+    FsIndexCollection parsedImportItem = UIMAFramework.getXMLParser().parseFsIndexCollection(
+            new XMLInputSource(source));
+    return parsedImportItem.getDescription();
+  }
+
+  protected Import[] getModelImportArray() {
+    return getFsIndexCollection().getImports();
+  }
+
+  protected void setModelImportArray(Import[] imports) {
+    if (imports == null)
+      throw new InternalErrorCDE("invalid state");
+    getFsIndexCollection().setImports(imports);
+  }
+
+  protected void clearModelBaseValue() {
+    getAnalysisEngineMetaData().setFsIndexes(fsIndexDescription0);
+  }
+
+  // indexes are checked and merged when the CAS is built
+  protected boolean isValidImport(String title, String message) {
+
+    FsIndexCollection savedIC = editor.getMergedFsIndexCollection();
+    if (null != savedIC)
+      savedIC = (FsIndexCollection) savedIC.clone();
+    CAS savedCAS = editor.getCurrentView();
+    try {
+      editor.setMergedFsIndexCollection();
+      editor.descriptorCAS.validate();
+    } catch (ResourceInitializationException e) {
+      revertMsg(title, message, editor.getMessagesToRootCause(e));
+      editor.setMergedFsIndexCollection(savedIC);
+      editor.descriptorCAS.set(savedCAS);
+      return false;
+    }
+    return true;
+  }
+
+  protected void finishImportChangeAction() {
+  }
+
+}
diff --git a/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/IndexSection.java b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/IndexSection.java
new file mode 100644
index 0000000..22b5076
--- /dev/null
+++ b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/IndexSection.java
@@ -0,0 +1,453 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS 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.taeconfigurator.editors.ui;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.uima.UIMAFramework;
+import org.apache.uima.cas.CAS;
+import org.apache.uima.cas.admin.FSIndexComparator;
+import org.apache.uima.resource.metadata.FsIndexDescription;
+import org.apache.uima.resource.metadata.FsIndexKeyDescription;
+import org.apache.uima.taeconfigurator.editors.MultiPageEditor;
+import org.apache.uima.taeconfigurator.editors.ui.dialogs.AddIndexDialog;
+import org.apache.uima.taeconfigurator.editors.ui.dialogs.AddIndexKeyDialog;
+import org.apache.uima.taeconfigurator.wizards.FsIndexCollectionNewWizard;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.window.Window;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.TableTree;
+import org.eclipse.swt.custom.TableTreeItem;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.ui.forms.IManagedForm;
+
+public class IndexSection extends AbstractSection {
+
+  public static final String ANNOTATION_INDEX_BUILT_IN = "Annotation Index (Built-in)";
+
+  public final static int INDEX_NAME_COL = 0;
+
+  public final static int INDEX_TYPE_COL = 1;
+
+  public final static int ASC_DES_COL = 1;
+
+  public final static int INDEX_KIND_COL = 2;
+
+  public TableTree tt; // accessed by inner class
+
+  private Button addIndexButton;
+
+  private Button addKeyButton;
+
+  private Button editButton;
+
+  private Button removeButton;
+
+  private Button upButton;
+
+  private Button downButton;
+
+  FsIndexDescription m_builtInIndexDescription = null;
+
+  private Button exportButton;
+
+  private IndexImportSection indexImportSection;
+
+  public IndexSection(MultiPageEditor editor, Composite parent) {
+    super(editor, parent, "Indexes",
+            "The following indexes are defined on the type system for this engine.");
+  }
+
+  public void initialize(IManagedForm form) {
+    super.initialize(form);
+
+    // set up Composite to hold widgets in the section
+    Composite sectionClient = new2ColumnComposite(getSection());
+    enableBorders(sectionClient);
+
+    tt = newTableTree(sectionClient, SWT.SINGLE | SWT.FULL_SELECTION);
+
+    final Table table = tt.getTable();
+    table.setHeaderVisible(true);
+    newTableColumn(table).setText("Name");
+    newTableColumn(table).setText("Type");
+    newTableColumn(table).setText("Kind");
+
+    final Composite buttonContainer = newButtonContainer(sectionClient);
+    addIndexButton = newPushButton(buttonContainer, "Add Index", "Click here to add a new index.");
+    addKeyButton = newPushButton(buttonContainer, "Add Key",
+            "Click here to add a new key for the selected index.");
+    editButton = newPushButton(buttonContainer, S_EDIT, S_EDIT_TIP);
+    removeButton = newPushButton(buttonContainer, S_REMOVE, S_REMOVE_TIP);
+    upButton = newPushButton(buttonContainer, S_UP, S_UP_TIP);
+    downButton = newPushButton(buttonContainer, S_DOWN, S_DOWN_TIP);
+    exportButton = newPushButton(buttonContainer, S_EXPORT, S_EXPORT_TIP);
+
+    // in addition to normal keyup and mouse up:
+    table.addListener(SWT.MouseHover, this);
+
+    toolkit.paintBordersFor(sectionClient);
+  }
+
+  /*
+   * (non-Javadoc)
+   * 
+   * @see org.eclipse.ui.forms.IFormPart#refresh()
+   */
+  public void refresh() {
+    if (null == indexImportSection)
+      indexImportSection = editor.getIndexesPage().getIndexImportSection();
+    super.refresh();
+    tt.removeAll();
+
+    // add built-in annotation index
+    updateIndexSpec(new TableTreeItem(tt, SWT.NONE), getBuiltInIndexDescription());
+
+    FsIndexDescription[] fsIndexes = getAnalysisEngineMetaData().getFsIndexes();
+
+    if (fsIndexes != null) {
+      for (int i = 0; i < fsIndexes.length; i++) {
+        updateIndexSpec(new TableTreeItem(tt, SWT.NONE), fsIndexes[i]);
+      }
+    }
+    packTable(tt.getTable());
+    enable();
+  }
+
+  private void updateIndexSpec(TableTreeItem item, FsIndexDescription ndx) {
+    item.setText(INDEX_NAME_COL, ndx.getLabel());
+    item.setText(INDEX_TYPE_COL, formatName(ndx.getTypeName()));
+    item.setText(INDEX_KIND_COL, handleDefaultIndexKind(ndx.getKind()));
+    item.setData(ndx);
+    removeChildren(item);
+    FsIndexKeyDescription[] keys = ndx.getKeys();
+    if (null != keys)
+      for (int i = 0; i < keys.length; i++) {
+        updateKeySpec(new TableTreeItem(item, SWT.NONE), keys[i]);
+      }
+  }
+
+  private void updateKeySpec(TableTreeItem item, FsIndexKeyDescription key) {
+    String name = key.getFeatureName();
+    item.setText(INDEX_NAME_COL, null == name ? "TYPE PRIORITY" : name);
+    item.setText(ASC_DES_COL,
+            key.getComparator() == FSIndexComparator.STANDARD_COMPARE ? "Standard" : "Reverse");
+    item.setData(key);
+  }
+
+  public FsIndexKeyDescription createFsIndexKeyDescription() {
+    return UIMAFramework.getResourceSpecifierFactory().createFsIndexKeyDescription();
+  }
+
+  public FsIndexDescription getBuiltInIndexDescription() {
+    if (m_builtInIndexDescription == null) {
+      m_builtInIndexDescription = UIMAFramework.getResourceSpecifierFactory()
+              .createFsIndexDescription();
+
+      m_builtInIndexDescription.setLabel(ANNOTATION_INDEX_BUILT_IN);
+      m_builtInIndexDescription.setTypeName(CAS.TYPE_NAME_ANNOTATION);
+      m_builtInIndexDescription.setKind("sorted");
+
+      FsIndexKeyDescription[] keys = new FsIndexKeyDescription[] { createFsIndexKeyDescription(),
+          createFsIndexKeyDescription(), createFsIndexKeyDescription() };
+
+      keys[0].setFeatureName("begin");
+      keys[0].setComparator(FSIndexComparator.STANDARD_COMPARE);
+      keys[1].setFeatureName("end");
+      keys[1].setComparator(FSIndexComparator.REVERSE_STANDARD_COMPARE);
+      keys[2].setTypePriority(true);
+
+      m_builtInIndexDescription.setKeys(keys);
+    }
+
+    return m_builtInIndexDescription;
+  }
+
+  private boolean notAllowed(String message) {
+    if (isIndexDescriptor() && !editor.getIsContextLoaded()) {
+      Utility
+              .popMessage(
+                      "Not Allowed",
+                      "Editing or Adding Indexes can't be done here because the information about the type system is missing.",
+                      MessageDialog.INFORMATION);
+      return true;
+    }
+    return false;
+  }
+
+  /*
+   * (non-Javadoc)
+   * 
+   * @see org.eclipse.swt.widgets.Listener#handleEvent(org.eclipse.swt.widgets.Event)
+   */
+  public void handleEvent(Event event) {
+
+    if (event.widget == addIndexButton) {
+      if (notAllowed("Adding an Index"))
+        return;
+      // creating the dialog and open it
+      AddIndexDialog dialog = new AddIndexDialog(this);
+      if (dialog.open() == Window.CANCEL)
+        return;
+
+      FsIndexDescription id = UIMAFramework.getResourceSpecifierFactory()
+              .createFsIndexDescription();
+
+      id.setLabel(dialog.indexName);
+      id.setTypeName(dialog.indexType);
+      id.setKeys(dialog.keys);
+      id.setKind(dialog.indexKind);
+
+      addFsIndexDescription(id);
+
+      updateIndexSpec(new TableTreeItem(tt, SWT.NONE), id);
+
+      tt.getTable().setSelection(tt.getTable().getItemCount() - 1);
+      packTable(tt.getTable());
+      setFileDirty();
+    } else if (event.widget == addKeyButton) {
+      if (notAllowed("Adding an Index"))
+        return;
+      TableTreeItem parent = tt.getSelection()[0];
+      if (null != parent.getParentItem())
+        parent = parent.getParentItem();
+      if (foolingAroundWithAnnotationIndex(parent))
+        return;
+      FsIndexDescription fsid = getFsIndexDescriptionFromTableTreeItem(parent);
+      AddIndexKeyDialog dialog = new AddIndexKeyDialog(this, fsid.getTypeName(),
+              handleDefaultIndexKind(fsid.getKind()), getAlreadyUsedFeatures(fsid));
+      FsIndexKeyDescription newKey = addOrEditIndexKey(dialog, null);
+      if (null != newKey) {
+        addFsIndexKeyDescription(fsid, newKey);
+        updateKeySpec(new TableTreeItem(parent, SWT.NONE), newKey);
+        parent.setExpanded(true);
+        setFileDirty();
+      }
+    } else if (event.widget == removeButton) {
+      TableTreeItem item = tt.getSelection()[0];
+      if (foolingAroundWithAnnotationIndex(item))
+        return;
+      Object o = item.getData();
+      if (o instanceof FsIndexDescription) {
+        if (Window.CANCEL == Utility.popOkCancel("Confirm Remove",
+                "Do you want to remove this index?", MessageDialog.WARNING))
+          return;
+        removeFsIndexDescription((FsIndexDescription) o);
+      } else {
+        if (Window.CANCEL == Utility.popOkCancel("Confirm Remove",
+                "Do you want to remove this key?", MessageDialog.WARNING))
+          return;
+        TableTreeItem parent = item.getParentItem();
+        FsIndexDescription fsid = getFsIndexDescriptionFromTableTreeItem(parent);
+        removeFsIndexKeyDescription(fsid, (FsIndexKeyDescription) o);
+      }
+      tt.getTable().setSelection(tt.getTable().getSelectionIndex() - 1);
+      item.dispose();
+      setFileDirty();
+    } else if (event.widget == editButton || event.type == SWT.MouseDoubleClick) {
+      if (notAllowed("Adding an Index"))
+        return;
+      if (tt.getSelectionCount() != 1)
+        return;
+      TableTreeItem item = tt.getSelection()[0];
+      if (foolingAroundWithAnnotationIndex(item))
+        return;
+      Object o = item.getData();
+      if (o instanceof FsIndexDescription) {
+        FsIndexDescription fsid = (FsIndexDescription) o;
+        AddIndexDialog dialog = new AddIndexDialog(this, fsid);
+        if (dialog.open() == Window.CANCEL)
+          return;
+
+        valueChanged = false;
+        fsid.setLabel(setValueChanged(dialog.indexName, fsid.getLabel()));
+        fsid.setTypeName(setValueChanged(dialog.indexType, fsid.getTypeName()));
+        fsid.setKeys(setValueChangedKeys(dialog.keys, fsid.getKeys()));
+        fsid.setKind(setValueChanged(dialog.indexKind, handleDefaultIndexKind(fsid.getKind())));
+
+        updateIndexSpec(item, fsid);
+
+        if (valueChanged) {
+          packTable(tt.getTable());
+          setFileDirty();
+        }
+      } else { // editing a key
+        if (notAllowed("Adding an Index"))
+          return;
+        FsIndexKeyDescription key = (FsIndexKeyDescription) o;
+        TableTreeItem parent = item.getParentItem();
+        FsIndexDescription fsid = getFsIndexDescriptionFromTableTreeItem(parent);
+        AddIndexKeyDialog dialog = new AddIndexKeyDialog(this, fsid.getTypeName(),
+                handleDefaultIndexKind(fsid.getKind()), getAlreadyUsedFeatures(fsid), key);
+        valueChanged = false;
+        addOrEditIndexKey(dialog, key);
+        if (valueChanged) {
+          updateKeySpec(item, key);
+          packTable(tt.getTable());
+          setFileDirty();
+        }
+      }
+    } else if (event.widget == upButton) {
+      int i = getIndex(tt.getSelection()[0]);
+      swapIndexKeys(tt.getSelection()[0], i - 1);
+      setFileDirty();
+    } else if (event.widget == downButton) {
+      int i = getIndex(tt.getSelection()[0]);
+
+      TableTreeItem[] items = tt.getSelection()[0].getParentItem().getItems();
+      swapIndexKeys(items[i + 1], i + 1);
+    } else if (event.widget == exportButton) {
+      try {
+        indexImportSection.exportImportablePart("<fsIndexCollection>",
+                FsIndexCollectionNewWizard.FSINDEXCOLLECTION_TEMPLATE);
+      } finally {
+        refresh(); // update in case of throw, even
+      }
+    }
+    enable();
+  }
+
+  private boolean foolingAroundWithAnnotationIndex(TableTreeItem item) {
+    while (null != item.getParentItem())
+      item = item.getParentItem();
+
+    if (ANNOTATION_INDEX_BUILT_IN.equals(item.getText(0))) {
+      Utility.popMessage("Not Allowed",
+              "You cannot edit or delete the built-in Annotation Index or its keys",
+              MessageDialog.ERROR);
+      return true;
+    }
+    return false;
+  }
+
+  public void addFsIndexKeyDescription(FsIndexDescription fsid, FsIndexKeyDescription key) {
+    FsIndexKeyDescription[] prevKeys = fsid.getKeys();
+    FsIndexKeyDescription[] newKeys = new FsIndexKeyDescription[prevKeys == null ? 1
+            : prevKeys.length + 1];
+    if (null != prevKeys)
+      System.arraycopy(prevKeys, 0, newKeys, 0, prevKeys.length);
+    newKeys[newKeys.length - 1] = key;
+    fsid.setKeys(newKeys);
+  }
+
+  public void addFsIndexDescription(FsIndexDescription fsid) {
+    FsIndexDescription[] oldFsIndexes = getAnalysisEngineMetaData().getFsIndexes();
+    FsIndexDescription[] newFsIndexes = new FsIndexDescription[oldFsIndexes == null ? 1
+            : oldFsIndexes.length + 1];
+    if (null != oldFsIndexes)
+      System.arraycopy(oldFsIndexes, 0, newFsIndexes, 0, oldFsIndexes.length);
+    newFsIndexes[newFsIndexes.length - 1] = fsid;
+    getAnalysisEngineMetaData().setFsIndexes(newFsIndexes);
+  }
+
+  public void removeFsIndexDescription(FsIndexDescription fsid) {
+    getAnalysisEngineMetaData().setFsIndexes(
+            (FsIndexDescription[]) Utility.removeElementFromArray(getAnalysisEngineMetaData()
+                    .getFsIndexes(), fsid, FsIndexDescription.class));
+  }
+
+  public void removeFsIndexKeyDescription(FsIndexDescription fsid, FsIndexKeyDescription key) {
+    fsid.setKeys((FsIndexKeyDescription[]) Utility.removeElementFromArray(fsid.getKeys(), key,
+            FsIndexKeyDescription.class));
+  }
+
+  public List getAlreadyUsedFeatures(FsIndexDescription ndx) {
+    List result = new ArrayList();
+    FsIndexKeyDescription[] items = ndx.getKeys();
+    if (null == items)
+      return result;
+    for (int i = 0; i < items.length; i++) {
+      result.add(items[i].getFeatureName());
+    }
+    return result;
+  }
+
+  public FsIndexKeyDescription addOrEditIndexKey(AddIndexKeyDialog dialog, FsIndexKeyDescription key) {
+    if (dialog.open() == Window.CANCEL) {
+      return null;
+    }
+    if (null == key)
+      key = UIMAFramework.getResourceSpecifierFactory().createFsIndexKeyDescription();
+    if (dialog.typePriority) {
+      key.setTypePriority(setValueChangedBoolean(true, key.isTypePriority()));
+      key.setFeatureName(null);
+    } else {
+      key.setFeatureName(setValueChanged(dialog.featureName, key.getFeatureName()));
+      key.setComparator(setValueChangedInt(dialog.direction, key.getComparator()));
+      key.setTypePriority(false);
+    }
+    return key;
+  }
+
+  /**
+   * This has to check the resolvedImports, mergedWithDelegates version of the fsindexes
+   * 
+   * @param indexLabel
+   * @return
+   */
+  public boolean isDuplicateIndexLabel(String indexLabel) {
+    FsIndexDescription[] indexes = getAnalysisEngineMetaData().getFsIndexes();
+    if (indexes == null) {
+      return false;
+    }
+    for (int i = 0; i < indexes.length; i++) {
+      if (indexes[i].getLabel().equals(indexLabel)) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  public void enable() {
+    boolean selected = tt.getSelectionCount() == 1;
+    TableTreeItem item = null;
+    TableTreeItem parent = null;
+    if (selected) {
+      item = tt.getSelection()[0];
+      parent = item.getParentItem();
+    }
+    boolean notBuiltInSelected = (selected && item != tt.getItems()[0]);
+    notBuiltInSelected &= !(null != parent && parent == tt.getItems()[0]);
+
+    addIndexButton.setEnabled(true);
+    addKeyButton.setEnabled(notBuiltInSelected
+            && (null != parent || /* null == parent && */!"bag".equals(item
+                    .getText(INDEX_KIND_COL))));
+    editButton.setEnabled(notBuiltInSelected);
+    removeButton.setEnabled(notBuiltInSelected);
+    exportButton.setEnabled(tt.getItemCount() > 1); // always one "built-in"
+
+    upButton.setEnabled(false);
+    downButton.setEnabled(false);
+    if (selected) {
+      if (null != parent && notBuiltInSelected) {
+        TableTreeItem firstItem = parent.getItems()[0];
+        TableTreeItem lastItem = parent.getItems()[parent.getItems().length - 1];
+        upButton.setEnabled(item != firstItem);
+        downButton.setEnabled(item != lastItem);
+      }
+    }
+
+  }
+}
diff --git a/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/IndexesPage.java b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/IndexesPage.java
new file mode 100644
index 0000000..d2d138a
--- /dev/null
+++ b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/IndexesPage.java
@@ -0,0 +1,78 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS 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.taeconfigurator.editors.ui;
+
+import org.apache.uima.taeconfigurator.editors.Form2Panel;
+import org.apache.uima.taeconfigurator.editors.MultiPageEditor;
+import org.eclipse.ui.forms.IManagedForm;
+
+/**
+ */
+public class IndexesPage extends HeaderPageWithSash {
+
+  private IndexSection indexSection;
+
+  private IndexImportSection indexImportSection;
+
+  private TypePriorityImportSection typePriorityImportSection;
+
+  private PriorityListSection priorityListSection;
+
+  public IndexesPage(MultiPageEditor editor) {
+    super(editor, "Indexes");
+  }
+
+  /**
+   * Called by the 3.0 framework to fill in the contents
+   */
+  protected void createFormContent(IManagedForm managedForm) {
+
+    final Form2Panel form2Panel = setup2ColumnLayout(managedForm, EQUAL_WIDTH);
+    managedForm.getForm().setText(
+            (isLocalProcessingDescriptor() || isIndexDescriptor()) ? "Indexes" : "Type Priorities");
+    if (!isTypePriorityDescriptor()) {
+      managedForm.addPart(indexSection = new IndexSection(editor, form2Panel.left));
+      managedForm.addPart(indexImportSection = new IndexImportSection(editor, form2Panel.right));
+    }
+    if (!isIndexDescriptor()) {
+      managedForm.addPart(priorityListSection = new PriorityListSection(editor, form2Panel.left));
+      managedForm.addPart(typePriorityImportSection = new TypePriorityImportSection(editor,
+              form2Panel.right));
+    }
+    createToolBarActions(managedForm);
+  }
+
+  public IndexSection getIndexSection() {
+    return indexSection;
+  }
+
+  public PriorityListSection getPriorityListSection() {
+    return priorityListSection;
+  }
+
+  public IndexImportSection getIndexImportSection() {
+    return indexImportSection;
+  }
+
+  public TypePriorityImportSection getTypePriorityImportSection() {
+    return typePriorityImportSection;
+  }
+
+}
diff --git a/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/MetaDataSection.java b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/MetaDataSection.java
new file mode 100644
index 0000000..0d93021
--- /dev/null
+++ b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/MetaDataSection.java
@@ -0,0 +1,115 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS 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.taeconfigurator.editors.ui;
+
+import org.apache.uima.taeconfigurator.editors.MultiPageEditor;
+import org.apache.uima.taeconfigurator.model.DescriptorMetaData;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.ui.forms.IManagedForm;
+
+public class MetaDataSection extends AbstractSection {
+
+  public void enable() {
+  }
+
+  private Text nameText;
+
+  private Text descriptionText;
+
+  private Text versionText;
+
+  private Text vendorText;
+
+  private DescriptorMetaData dmd = null;
+
+  /**
+   * Creates a section to enter meta data. Including a text field for name, description, version and
+   * vendor.
+   * 
+   * @param editor
+   *          the referenced multipage editor
+   */
+  public MetaDataSection(MultiPageEditor editor, Composite parent) {
+    super(editor, parent, "Overall Identification Information",
+            "This section specifies the basic identification information for this descriptor");
+  }
+
+  public void initialize(IManagedForm form) {
+    super.initialize(form);
+    Composite sectionClient = new2ColumnComposite(this.getSection());
+
+    nameText = newLabeledTextField(sectionClient, "Name", "NameTextToolTip", SWT.NULL);
+    versionText = newLabeledTextField(sectionClient, "Version", "VersionTextToolTip", SWT.NULL);
+    vendorText = newLabeledTextField(sectionClient, "Vendor", "VendorTextToolTip", SWT.NULL);
+
+    // description enter field
+    descriptionText = newDescriptionTextBox(sectionClient,
+            "Enter a description of this component here.");
+    toolkit.paintBordersFor(sectionClient);
+
+  }
+
+  /*
+   * (non-Javadoc)
+   * 
+   * @see org.eclipse.ui.forms.IFormPart#refresh()
+   */
+  public void refresh() {
+    if (null == dmd)
+      dmd = new DescriptorMetaData(editor);
+    super.refresh();
+    String name = null;
+    String version = null;
+    String description = null;
+    String vendor = null;
+
+    name = dmd.getName();
+    version = dmd.getVersion();
+    description = dmd.getDescription();
+    vendor = dmd.getVendor();
+
+    nameText.setText(convertNull(name));
+    versionText.setText(convertNull(version));
+    vendorText.setText(convertNull(vendor));
+    descriptionText.setText(convertNull(description));
+  }
+
+  /*
+   * (non-Javadoc)
+   * 
+   * @see org.eclipse.swt.widgets.Listener#handleEvent(org.eclipse.swt.widgets.Event)
+   */
+  public void handleEvent(Event event) {
+    valueChanged = false;
+
+    dmd.setName(setValueChanged(nameText.getText(), dmd.getName()));
+    dmd.setVersion(setValueChanged(versionText.getText(), dmd.getVersion()));
+    dmd.setVendor(setValueChanged(vendorText.getText(), dmd.getVendor()));
+    dmd.setDescription(setValueChanged(multiLineFix(descriptionText.getText()), dmd
+            .getDescription()));
+
+    if (valueChanged)
+      setFileDirty();
+  }
+
+}
diff --git a/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/OverviewPage.java b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/OverviewPage.java
new file mode 100644
index 0000000..07e234a
--- /dev/null
+++ b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/OverviewPage.java
@@ -0,0 +1,73 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.uima.taeconfigurator.editors.ui;
+
+import org.apache.uima.taeconfigurator.editors.Form2Panel;
+import org.apache.uima.taeconfigurator.editors.MultiPageEditor;
+import org.eclipse.swt.SWT;
+import org.eclipse.ui.forms.IManagedForm;
+
+/**
+ * 
+ */
+public class OverviewPage extends HeaderPageWithSash {
+
+  private PrimitiveSection primitiveSection;
+  
+  // should always exist
+  private MetaDataSection metadataSection;  
+
+  /**
+   */
+  public OverviewPage(MultiPageEditor aEditor) {
+    super(aEditor, "UID_OverviewPage", "Overview");
+  }
+
+  /**
+   * Called by the 3.0 framework to fill in the contents
+   */
+  protected void createFormContent(IManagedForm managedForm) {
+    final Form2Panel form = setup2ColumnLayout(managedForm, EQUAL_WIDTH);
+    managedForm.getForm().setText("Overview");
+
+    if (isLocalProcessingDescriptor()) {
+      managedForm.addPart(new GeneralSection(editor, form.left));
+      managedForm.addPart(primitiveSection = new PrimitiveSection(editor, form.left));
+      managedForm.addPart(metadataSection= new MetaDataSection(editor, form.right));
+    } else {
+      managedForm.addPart(metadataSection = new MetaDataSection(editor, form.left));
+    }
+    createToolBarActions(managedForm);
+    sashForm.setOrientation(SWT.HORIZONTAL);
+    vaction.setChecked(false);
+    haction.setChecked(true);
+    if (!isLocalProcessingDescriptor()) {
+      sashForm.setWeights(new int[] { 95, 5 });
+    }
+  }
+
+  public PrimitiveSection getPrimitiveSection() {
+    return primitiveSection;
+  }
+
+  public MetaDataSection getMetaDataSection() {
+    return metadataSection;
+  }
+}
diff --git a/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/ParameterDelegatesSection.java b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/ParameterDelegatesSection.java
new file mode 100644
index 0000000..3ae523e
--- /dev/null
+++ b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/ParameterDelegatesSection.java
@@ -0,0 +1,463 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS 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.taeconfigurator.editors.ui;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.uima.analysis_engine.AnalysisEngineDescription;
+import org.apache.uima.analysis_engine.metadata.FlowControllerDeclaration;
+import org.apache.uima.collection.CasConsumerDescription;
+import org.apache.uima.flow.FlowControllerDescription;
+import org.apache.uima.resource.ResourceCreationSpecifier;
+import org.apache.uima.resource.ResourceSpecifier;
+import org.apache.uima.resource.metadata.ConfigurationGroup;
+import org.apache.uima.resource.metadata.ConfigurationParameter;
+import org.apache.uima.resource.metadata.ConfigurationParameterDeclarations;
+import org.apache.uima.taeconfigurator.InternalErrorCDE;
+import org.apache.uima.taeconfigurator.editors.MultiPageEditor;
+import org.apache.uima.taeconfigurator.model.ConfigGroup;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.TreeItem;
+import org.eclipse.ui.forms.IManagedForm;
+
+public class ParameterDelegatesSection extends AbstractSectionParm {
+
+  private Composite sectionClient;
+
+  private ParameterSection parmSection;
+
+  private boolean createNonSharedOverride;
+
+  private Button createOverrideButton;
+
+  private Button createNonSharedOverrideButton;
+
+  public ParameterDelegatesSection(MultiPageEditor editor, Composite parent) {
+    super(
+            editor,
+            parent,
+            "Delegate Component Parameters",
+            "This section shows all delegate components by their Key names, and what parameters they have.\nDouble-click a parameter or a group if you want to specify overrides for these parameters in this aggregate; this will add a default Configuration Parameter in this Aggregate for that parameter, and set the overrides.");
+  }
+
+  /*
+   * Called by the page constructor after all sections are created, to initialize them.
+   * (non-Javadoc)
+   * 
+   * @see org.eclipse.ui.forms.IFormPart#initialize(org.eclipse.ui.forms.IManagedForm)
+   */
+  public void initialize(IManagedForm form) {
+
+    parmSection = editor.getParameterPage().getParameterSection();
+
+    super.initialize(form);
+    sectionClient = newComposite(getSection());
+
+    tree = newTree(sectionClient);
+    Composite buttonContainer = new2ColumnComposite(sectionClient);
+    ((GridData) buttonContainer.getLayoutData()).grabExcessVerticalSpace = false;
+    createOverrideButton = newPushButton(buttonContainer, "Create Override",
+            "Click here to create a new override for this parameter");
+    createNonSharedOverrideButton = newPushButton(buttonContainer, "Create non-shared Override",
+            "Click here to create a non-shared override for this parameter");
+
+    tree.addListener(SWT.MouseDoubleClick, this); // edit gesture
+    tree.addListener(SWT.MouseHover, this); // hover
+
+    enableBorders(sectionClient);
+    toolkit.paintBordersFor(sectionClient);
+  }
+
+  /*
+   * (non-Javadoc)
+   * 
+   * @see org.eclipse.ui.forms.IFormPart#refresh()
+   */
+  public void refresh() {
+    super.refresh();
+    parmSection = editor.getParameterPage().getParameterSection();
+
+    tree.removeAll();
+    if (!isAggregate()) {
+      getSection().setText("Not Used");
+      getSection().setDescription("This part is only used for Aggregate Descriptors");
+    } else {
+      getSection().setText("Delegate Component Parameters");
+      getSection()
+              .setDescription(
+                      "This section shows all delegate components by their Key names, and what parameters they have.\nDouble-click a parameter or a group if you want to specify overrides for these parameters in this aggregate; this will add a default Configuration Parameter in this Aggregate for that parameter, and set the overrides.");
+
+      cpd = getAnalysisEngineMetaData().getConfigurationParameterDeclarations();
+      for (Iterator it = editor.getResolvedDelegates().entrySet().iterator(); it.hasNext();) {
+        addDelegateToGUI((Map.Entry) it.next());
+      }
+      FlowControllerDeclaration fcd = editor.getResolvedFlowControllerDeclaration();
+      if (null != fcd) {
+        addDelegateToGUI(fcd.getKey(), fcd.getSpecifier());
+      }
+      TreeItem[] items = tree.getItems();
+      if (items.length > 0)
+        // scrolls to top, also
+        tree.setSelection(new TreeItem[] { items[0] });
+    }
+    enable();
+  }
+
+  private void addDelegateToGUI(Map.Entry entry) {
+    addDelegateToGUI((String) entry.getKey(), (ResourceSpecifier) entry.getValue());
+    // String key = (String) entry.getKey();
+    // ResourceSpecifier delegate = (ResourceSpecifier)entry.getValue();
+    // if (delegate instanceof AnalysisEngineDescription || delegate instanceof
+    // CasConsumerDescription) {
+    // TreeItem d = new TreeItem(tree, SWT.NONE);
+    // d.setText(DELEGATE_HEADER + key);
+    // d.setData(key);
+    // addDelegateGroupsToGUI(d, (ResourceCreationSpecifier)delegate);
+    // d.setExpanded(true);
+    // }
+  }
+
+  private void addDelegateToGUI(String key, ResourceSpecifier delegate) {
+    if (delegate instanceof AnalysisEngineDescription || delegate instanceof CasConsumerDescription
+            || delegate instanceof FlowControllerDescription) {
+      TreeItem d = new TreeItem(tree, SWT.NONE);
+      d.setText(((delegate instanceof FlowControllerDescription) ? FLOWCTLR_HEADER
+              : DELEGATE_HEADER)
+              + key);
+      d.setData(key);
+      addDelegateGroupsToGUI(d, (ResourceCreationSpecifier) delegate);
+      d.setExpanded(true);
+    }
+  }
+
+  private void addDelegateGroupsToGUI(TreeItem parent, ResourceCreationSpecifier delegate) {
+    ConfigurationParameterDeclarations cpd1 = delegate.getMetaData()
+            .getConfigurationParameterDeclarations();
+    // if (delegate instanceof AnalysisEngineDescription)
+    // cpd1 = ((AnalysisEngineDescription)delegate)
+    // .getAnalysisEngineMetaData().getConfigurationParameterDeclarations();
+    // else if (delegate instanceof CasConsumerDescription)
+    // cpd1 = ((CasConsumerDescription)delegate)
+    // .getMetaData().getConfigurationParameterDeclarations();
+    // else
+    // throw new InternalErrorCDE("Invalid state");
+
+    ConfigGroup noGroup = new ConfigGroup(cpd1, ConfigGroup.NOT_IN_ANY_GROUP);
+    ConfigGroup commonGroup = new ConfigGroup(cpd1, ConfigGroup.COMMON);
+
+    addDelegateGroupToGUI(parent, noGroup);
+    addDelegateGroupToGUI(parent, commonGroup);
+    ConfigurationGroup[] cgs = cpd1.getConfigurationGroups();
+    if (cgs != null) {
+      for (int i = 0; i < cgs.length; i++) {
+        addDelegateGroupToGUI(parent, new ConfigGroup(cpd1, cgs[i]));
+      }
+    }
+  }
+
+  private void addDelegateGroupToGUI(TreeItem parent, ConfigGroup cg) {
+    ConfigurationParameter[] cps = cg.getConfigParms();
+    if (null != cps && cps.length > 0) {
+      TreeItem d = new TreeItem(parent, SWT.NONE);
+      d.setData(cg);
+      setGroupText(d, cg.getName());
+      addDelegateParmsToGUI(d, cps);
+      d.setExpanded(true);
+    }
+  }
+
+  private void addDelegateParmsToGUI(TreeItem parent, ConfigurationParameter[] cps) {
+    if (null != cps) {
+      for (int i = 0; i < cps.length; i++) {
+        TreeItem d = new TreeItem(parent, SWT.NONE);
+        d.setData(cps[i]);
+        d.setText(parmGuiString(cps[i]));
+        String[] overrides = cps[i].getOverrides();
+        if (null != overrides && overrides.length > 0) {
+          addDelegateParmOverridesToGUI(d, overrides);
+          d.setExpanded(true);
+        }
+      }
+    }
+  }
+
+  private void addDelegateParmOverridesToGUI(TreeItem parent, String[] overrides) {
+    for (int i = 0; i < overrides.length; i++) {
+      TreeItem d = new TreeItem(parent, SWT.NONE);
+      d.setText(OVERRIDE_HEADER + overrides[i]);
+    }
+  }
+
+  /*
+   * (non-Javadoc)
+   * 
+   * @see org.eclipse.swt.widgets.Listener#handleEvent(org.eclipse.swt.widgets.Event)
+   */
+  public void handleEvent(Event event) {
+    if (event.type == SWT.MouseHover) {
+      showDescriptionAsToolTip(event);
+    } else if (event.type == SWT.MouseDoubleClick) {
+      addOverrides(0 != (event.stateMask & SWT.SHIFT));
+    } else if (event.widget == createOverrideButton) {
+      addOverrides(false);
+    } else if (event.widget == createNonSharedOverrideButton) {
+      addOverrides(true);
+    }
+  }
+
+  private void addOverrides(boolean nonShared) {
+    TreeItem item = tree.getSelection()[0];
+    createNonSharedOverride = nonShared;
+    if (isParameter(item))
+      addNewParameter(item);
+    else if (isGroup(item))
+      addAllParameters(item.getItems());
+    else if (isDelegate(item))
+      addAllGroups(item.getItems());
+  }
+
+  public ConfigurationParameter getConfigurationParameterFromTreeItem(TreeItem item) {
+    return (ConfigurationParameter) item.getData();
+  }
+
+  public ConfigGroup getConfigGroupFromTreeItem(TreeItem item) {
+    return (ConfigGroup) item.getData();
+  }
+
+  private String getKeyNameFromTreeItem(TreeItem item) {
+    return (String) item.getData();
+  }
+
+  private void addNewParameter(TreeItem item) {
+    addNewParameter(getConfigurationParameterFromTreeItem(item), getConfigGroupFromTreeItem(item
+            .getParentItem()), getKeyNameFromTreeItem(item.getParentItem().getParentItem()));
+  }
+
+  private void addAllParameters(TreeItem[] items) {
+    for (int i = 0; i < items.length; i++) {
+      addNewParameter(items[i]);
+    }
+  }
+
+  private void addAllGroups(TreeItem[] items) {
+    for (int i = 0; i < items.length; i++) {
+      addAllParameters(items[i].getItems());
+    }
+  }
+
+  private void addNewParameter(ConfigurationParameter parm, ConfigGroup delegateGroup, String key) {
+
+    ConfigGroup group = getCorrespondingModelGroup(delegateGroup);
+
+    if (null == group) {
+      group = parmSection.addGroup(delegateGroup);
+    }
+    ConfigurationParameter parmInGroup;
+    String override = key + "/" + parm.getName();
+    String overrideParmName;
+    if (null != (overrideParmName = getOverridingParmName(override, cpd))) {
+      Utility.popMessage("Only one override allowed",
+              "This delegate parameter already is being overridden by '" + overrideParmName
+                      + "'.  To override "
+                      + "with a different parameter, first remove this override",
+              MessageDialog.ERROR);
+      return;
+    }
+    if (null != (parmInGroup = getSameNamedParmInGroup(parm, group))) {
+      if ((!createNonSharedOverride) && parmSpecMatches(parm, parmInGroup)) {
+
+        if (0 <= getOverrideIndex(parmInGroup, override)) {
+          return; // trying to add existing override
+        } else {
+          parmSection.addOverride(parmInGroup, override);
+        }
+      } else {
+        String newName = generateUniqueName(parm.getName());
+        parmSection.addParm(newName, parm, group, override);
+      }
+    } else {
+      if (ParameterSection.parameterNameAlreadyDefinedNoMsg(parm.getName(),
+              getConfigurationParameterDeclarations())) {
+        // parm names must be unique across this descriptor, even among different groups
+        String newName = generateUniqueName(parm.getName());
+        parmSection.addParm(newName, parm, group, override);
+      } else {
+        parmSection.addParm(parm.getName(), parm, group, override);
+      }
+    }
+  }
+
+  public static String getOverridingParmName(String override, ConfigurationParameterDeclarations cpd) {
+    String result;
+
+    if (null != (result = getOverridingParmName(override, cpd.getConfigurationParameters())))
+      return result;
+    if (null != (result = getOverridingParmName(override, cpd.getCommonParameters())))
+      return result;
+    ConfigurationGroup[] groups = cpd.getConfigurationGroups();
+    if (null != groups)
+      for (int i = 0; i < groups.length; i++) {
+        if (null != (result = getOverridingParmName(override, groups[i]
+                .getConfigurationParameters())))
+          return result;
+      }
+    return null;
+  }
+
+  private static String getOverridingParmName(String override, ConfigurationParameter[] cps) {
+    if (null != cps)
+      for (int i = 0; i < cps.length; i++) {
+        String[] overrides = cps[i].getOverrides();
+        if (null != overrides)
+          for (int j = 0; j < overrides.length; j++) {
+            if (override.equals(overrides[j]))
+              return cps[i].getName();
+          }
+      }
+    return null;
+  }
+
+  /**
+   * Add a suffix to the name to make it unique within all parameters defined for the cpd
+   * 
+   * @param name
+   * @return
+   */
+  private String generateUniqueName(String name) {
+    List allNames = new ArrayList();
+    addParmNames(allNames, cpd.getConfigurationParameters());
+    addParmNames(allNames, cpd.getCommonParameters());
+    ConfigurationGroup[] cgs = cpd.getConfigurationGroups();
+    if (null != cgs) {
+      for (int i = 0; i < cgs.length; i++) {
+        addParmNames(allNames, cgs[i].getConfigurationParameters());
+      }
+    }
+    int suffix = 1;
+    String nameTry = name + suffix;
+    while (allNames.contains(nameTry))
+      nameTry = name + ++suffix;
+    return nameTry;
+  }
+
+  private void addParmNames(List list, ConfigurationParameter[] parms) {
+    if (null != parms) {
+      for (int i = 0; i < parms.length; i++) {
+        list.add(parms[i].getName());
+      }
+    }
+  }
+
+  private int getOverrideIndex(ConfigurationParameter parm, String override) {
+    String[] overrides = parm.getOverrides();
+    if (null == overrides)
+      return -1;
+    for (int i = 0; i < overrides.length; i++) {
+      if (overrides[i].equals(override))
+        return i;
+    }
+    return -1;
+  }
+
+  private ConfigurationParameter getSameNamedParmInGroup(ConfigurationParameter parm,
+          ConfigGroup group) {
+    ConfigurationParameter[] cps = group.getConfigParms();
+    String parmName = parm.getName();
+    for (int i = 0; i < cps.length; i++) {
+      if (cps[i].getName().equals(parmName))
+        return cps[i];
+    }
+    return null;
+  }
+
+  private boolean parmSpecMatches(ConfigurationParameter p, ConfigurationParameter q) {
+    if (!p.getType().equals(q.getType()))
+      return false;
+    if (p.isMandatory() != q.isMandatory())
+      return false;
+    if (p.isMultiValued() != q.isMultiValued())
+      return false;
+    return true;
+  }
+
+  private ConfigGroup getCorrespondingModelGroup(ConfigGroup delegateGroup) {
+    switch (delegateGroup.getKind()) {
+      case ConfigGroup.NOT_IN_ANY_GROUP:
+        return new ConfigGroup(cpd, ConfigGroup.NOT_IN_ANY_GROUP);
+      case ConfigGroup.COMMON:
+        return getCorrespondingModelGroup(getAllGroupNames(delegateGroup.getCPD()));
+      case ConfigGroup.NAMED_GROUP:
+        return getCorrespondingModelGroup(delegateGroup.getNameArray());
+    }
+    throw new InternalErrorCDE("invalid state");
+  }
+
+  private ConfigGroup getCorrespondingModelGroup(String[] nameArray) {
+    ConfigurationGroup[] cgs = cpd.getConfigurationGroups();
+    for (int i = 0; i < cgs.length; i++) {
+      if (setEquals(cgs[i].getNames(), nameArray)) {
+        return new ConfigGroup(cpd, cgs[i]);
+      }
+    }
+    return null;
+  }
+
+  /**
+   * Compare for set equals, assuming sets have no duplicates
+   * 
+   * @param a
+   * @param b
+   * @return
+   */
+  private boolean setEquals(Object[] a, Object[] b) {
+    if (null == a && null == b)
+      return true;
+    if (null == a || null == b)
+      return false;
+    if (a.length != b.length)
+      return false;
+    for (int i = 0; i < a.length; i++) {
+      boolean foundB = false;
+      for (int j = 0; j < b.length; j++) {
+        if (a[i].equals(b[j])) {
+          foundB = true;
+          break;
+        }
+      }
+      if (!foundB)
+        return false;
+    }
+    return true;
+  }
+
+  public void enable() {
+    createOverrideButton.setEnabled(tree.getSelectionCount() == 1);
+    createNonSharedOverrideButton.setEnabled(tree.getSelectionCount() == 1);
+  }
+
+}
diff --git a/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/ParameterPage.java b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/ParameterPage.java
new file mode 100644
index 0000000..3ccd217
--- /dev/null
+++ b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/ParameterPage.java
@@ -0,0 +1,56 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.uima.taeconfigurator.editors.ui;
+
+import org.apache.uima.taeconfigurator.editors.Form2Panel;
+import org.apache.uima.taeconfigurator.editors.MultiPageEditor;
+import org.eclipse.ui.forms.IManagedForm;
+
+public class ParameterPage extends HeaderPageWithSash {
+
+  private ParameterSection parameterSection;
+
+  private ParameterDelegatesSection parameterDelegatesSection;
+
+  public ParameterPage(MultiPageEditor editor) {
+    super(editor, "Configuration Parameters");
+  }
+
+  /**
+   * Called by the framework to fill in the contents
+   */
+  protected void createFormContent(IManagedForm managedForm) {
+    managedForm.getForm().setText("Parameter Definitions");
+    Form2Panel form2Panel = setup2ColumnLayout(managedForm, 55, 45);
+    managedForm.addPart(parameterSection = new ParameterSection(editor, form2Panel.left));
+    managedForm.addPart(parameterDelegatesSection = new ParameterDelegatesSection(editor,
+            form2Panel.right));
+    createToolBarActions(managedForm);
+  }
+
+  public ParameterDelegatesSection getParameterDelegatesSection() {
+    return parameterDelegatesSection;
+  }
+
+  public ParameterSection getParameterSection() {
+    return parameterSection;
+  }
+
+}
diff --git a/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/ParameterSection.java b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/ParameterSection.java
new file mode 100644
index 0000000..22aa62a
--- /dev/null
+++ b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/ParameterSection.java
@@ -0,0 +1,1145 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS 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.taeconfigurator.editors.ui;
+
+/*
+ * Created on 15.07.2003
+ * 
+ * Redesign Feb 7 2005 Redesign Feb 9 2005 Changed Description to hover style Feb 27
+ * 
+ * Add <Not in any group> Two case: primitive and aggregate Primitive: allow groups to be defined,
+ * including <Not in any group> <Common> Allow multi def of parmnames (with same decls) as long as
+ * they're in different groups. Same name not allowed in both <Common> and named group but are
+ * allowed in both <Common> and <Not in any group>
+ * 
+ * A parm name declared in different groups which don't overlap can have a different declaration.
+ * 
+ * Parm names are unique within a within the group-set formed by the union of all groups where the
+ * parm is defined. This means that a parm name P1 in group g1, g2 must match the definition of a
+ * parm name P1 in group g2, g3.
+ * 
+ * Two parm names with the same name, in different non-intersecting groups, are distinct.
+ * 
+ * Two parm names with the same name, in different delegates, even if in the same group, are
+ * distinct. They can have different definitions. They can be seperately overridden in each
+ * delegate. This allows separate development of primitives, with future combining.
+ * 
+ * Two parm names with the same name in the same primitive that is used twice in the delegates list
+ * are distinct. They can be separately overridden, with different values. In this case, though, the
+ * definitions (type, multi-value, mandatory) are the same.
+ * 
+ * Aggregate: groups are the union of immediate delegate groups, except <Common> Common at lower
+ * level defines parms that are in all named groups at that level.
+ * 
+ * Treatment of <Common>: <Common> in a delegate is translated into G1, G2, ... Gn (all groups
+ * defined in that delegate).
+ * 
+ * Common at aggregate level defines parms that are in all named groups at aggregate level. This is
+ * a bigger set of group names than exist at any lower delegate level. Note: Cannot add or remove
+ * groups at aggregate level: the groups are pre-defined based on the delegates
+ * 
+ * Check of the model done at first refresh to validate it. If model has extra groups (not in
+ * delegates) - these are removed. If model is missing groups (in delegates) - these are added.
+ * 
+ * 2 panel design for aggregate. Right panel is tree, delegate-keys, groups, parms Left panel is
+ * like primitive panel.
+ * 
+ * Operations: Adding an override: double click on right panel element. click on delegate: add all
+ * parms all groups click on group: add group and all parms click on parm: add parm
+ * 
+ * On left panel: add override - adds additional override. Edit - applies to override - change the
+ * override. Remove - applies to override, to param, to group
+ * 
+ * When adding overriding parm for a delegate, use as a default the same name as the name being
+ * overridden. Change name if there exists parm in the groups with same name but different def
+ * Change name if there exists parm but group membership is not equal.
+ * 
+ * User may change the name in any case. If user does this, check for name collision as above. This
+ * is useful, for instance, when more than one delegate defines that parameter name - to allow each
+ * delegate to have a different override.
+ * 
+ * Adding a parm under a group: set default, allow overtyping - auto fill in type, mandatory, and
+ * multivalue from picked parm name setting override: based on what was clicked
+ * 
+ * OK ToDo: When adding a parm, if it is an aggregate, include <overrides> OK ToDo; When adding a
+ * parm, have custom dialog, set multivalued, mandatory, and 1st override OK ToDo: add button add
+ * override (for case: aggregate) OK ToDo: make remove work for override, and edit too Later: ToDo:
+ * For overrides: lookup key names, lookup parm names in delegates. If delegate is another
+ * aggregate, do additional key All this done as optional - in case sub things not yet defined. What
+ * about a "browse" like file system? for descending thru aggr to parm?
+ * 
+ * Todos: MaybeNot 1) make model for all parmDefs following other models MaybeNot 2) make model for
+ * all parmSettings following other models 2a) Have all changes (add, edit, and remove) affect
+ * ParameterSettingsSection 2aa) For Edit of each kind including changing name consider effect on
+ * settings OK 3) Checking: if change type - what to do about existing setting? Message it will be
+ * deleted OK 4) Checking: if change MultiV - same as above. OK 5) Checking: overrides: only show
+ * parm names which match on type and mv and mandatory < override OK 6) Model for editing overrides:
+ * using same dialog, plus combo to select which override, autoselected when dbl-clicking / edit
+ * existing , or adding new. Make base parm info read-only to avoid accidents NO 7) detail window:
+ * for groups: has list of group names; line per name, editable. for parm: has description; editable
+ * for overrides: has override string; line per segment, editable. OK 8) Checking: overrides: last
+ * level must have parm style match. 9) add value fixups and change awareness; use change awareness
+ * to trigger model updates OK 10) add name character-set checking OK 11) Fix shash for borders, for
+ * initial ratio, move to HeaderSection. Note: not appropriate for things with centered import box
+ * on bottom.
+ * 
+ * March 24 2005 - finish impl of overrides for aggregates: Disallow editing of parameters or adding
+ * parameters (parameters only to be created via the double-click on the delegate parameter).
+ * 
+ * Have the double-click on the deletage handle Common properly by setting up a special group with
+ * all the groups for that delegate.
+ * 
+ * Allow adding additional overrides. Do in pickOverrides dialog.
+ * 
+ * 
+ */
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeSet;
+
+import org.apache.uima.analysis_engine.metadata.FlowControllerDeclaration;
+import org.apache.uima.resource.metadata.ConfigurationGroup;
+import org.apache.uima.resource.metadata.ConfigurationParameter;
+import org.apache.uima.resource.metadata.ConfigurationParameterDeclarations;
+import org.apache.uima.resource.metadata.ConfigurationParameterSettings;
+import org.apache.uima.resource.metadata.impl.ConfigurationGroup_impl;
+import org.apache.uima.resource.metadata.impl.ConfigurationParameter_impl;
+import org.apache.uima.taeconfigurator.InternalErrorCDE;
+import org.apache.uima.taeconfigurator.editors.MultiPageEditor;
+import org.apache.uima.taeconfigurator.editors.ui.dialogs.AddParameterDialog;
+import org.apache.uima.taeconfigurator.editors.ui.dialogs.CommonInputDialog;
+import org.apache.uima.taeconfigurator.files.PickOverrideKeysAndParmName;
+import org.apache.uima.taeconfigurator.model.ConfigGroup;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.window.Window;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.CCombo;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.swt.widgets.Tree;
+import org.eclipse.swt.widgets.TreeItem;
+import org.eclipse.ui.forms.IManagedForm;
+
+public class ParameterSection extends AbstractSectionParm {
+
+  public final static int NEW_OVERRIDE = -1;
+
+  public final static boolean REMOVE_FROM_GUI = true;
+
+  public final static boolean GIVE_WARNING_MESSAGE = true;
+
+  private Text defaultGroup;
+
+  private CCombo searchStrategy;
+
+  private Button addButton;
+
+  private Button addGroupButton;
+
+  private Button editButton;
+
+  private Button removeButton;
+
+  private Button usingGroupsButton;
+
+  private Composite groupingControl;
+
+  private boolean firstTime = true;
+
+  /**
+   * Creates a section to show a list of all parameters
+   * 
+   * @param editor
+   *          backpointer to the main multipage editor
+   * @param parent
+   *          the Composite where this section lives
+   */
+  public ParameterSection(MultiPageEditor editor, Composite parent) {
+    super(editor, parent, "Configuration Parameters",
+            "This section shows all configuration parameters defined for this engine.");
+  }
+
+  // This page shows the configuration parameters
+  // Organization: top section for switching between simple and groups, and
+  // for groups: default Group name, + search strat (combo)
+  // Main body: a tree, 2 hierarchies:
+  // 1) for groups
+  // 2) for aggregates: overrides
+  // Tree is one of 3 entries:
+  // parm entry: multi/single, req/opt, boolean/string/int/float, name
+  // group entry: <Group> , , , names
+  // (aggregates) <Overrides> key/key/.../key/parmname
+  // 
+  // Checking: parmNames are unique for primitive and each aggr level
+  // overrides: lookup valid keys and parmnames
+  // names: well-formed with proper char sets, like java pkg names
+  //
+  // Editing: via double click, or edit button + select.
+  // using same dialog as for create
+  //
+  // Tree and corresponding tree (if created) in ParameterSettings are
+  // both incrementally updated, so rebuild is not needed. This preserves
+  // user-specified expansion of nodes.
+
+  public void initialize(IManagedForm form) {
+    super.initialize(form);
+
+    Composite sectionClient = newComposite(getSection());
+
+    usingGroupsButton = newCheckBox(sectionClient, "Use Parameter Groups",
+            "Check this box if Groups are being used with Parameters");
+
+    groupingControl = new2ColumnComposite(sectionClient);
+    ((GridData) groupingControl.getLayoutData()).grabExcessVerticalSpace = false;
+    enableBorders(groupingControl);
+    toolkit.paintBordersFor(groupingControl);
+
+    defaultGroup = newLabeledTextField(groupingControl, "Default Group",
+            "Specify the name of the default group.");
+    newLabelWithData(groupingControl, "SearchStrategy");
+    searchStrategy = newCComboWithTip(groupingControl, "SearchStrategyToolTip");
+    searchStrategy.add("language_fallback");
+    searchStrategy.add("default_fallback");
+    searchStrategy.add("none");
+
+    // main table + buttons on left
+
+    Composite tableContainer = new2ColumnComposite(sectionClient);
+    enableBorders(tableContainer);
+    toolkit.paintBordersFor(tableContainer);
+
+    // SWT.SINGLE to support deselecting
+    // SWT.FULL_SELECTION to select whole row
+    parameterSectionTree = tree = newTree(tableContainer);
+
+    // Buttons
+    Composite buttonContainer = newButtonContainer(tableContainer);
+    addButton = newPushButton(buttonContainer, S_ADD, "Click here to add a new parameter");
+    addGroupButton = newPushButton(buttonContainer, "AddGroup",
+            "Click here to add a group specification.  A group specification names one or more group names.");
+    editButton = newPushButton(buttonContainer, S_EDIT, S_EDIT_TIP);
+    removeButton = newPushButton(buttonContainer, S_REMOVE, S_REMOVE_TIP);
+
+    tree.addListener(SWT.MouseDoubleClick, this); // for Editing
+    tree.addListener(SWT.MouseHover, this); // for Description
+  }
+
+  /*
+   * refresh() called when UI is stale with respect to the model. Updates the UI to be in sync with
+   * the model Not called when model updated thru UI interaction. Called initially, and called when
+   * switching from sourcePage because user may have arbitrarilly changed things. (non-Javadoc)
+   * 
+   * @see org.eclipse.ui.forms.IFormPart#refresh()
+   */
+
+  public void refresh() {
+    super.refresh(); // clears stale and dirty bits in AbstractFormPart
+    // superclass
+
+    cpd = getAnalysisEngineMetaData().getConfigurationParameterDeclarations();
+
+    if ((firstTime && isParmGroup()) || isAggregate()
+            || (!firstTime && usingGroupsButton.getSelection())) {
+      usingGroupsButton.setSelection(true);
+      groupingControl.setVisible(true);
+
+      defaultGroup.setText(convertNull(cpd.getDefaultGroupName()));
+      if (null == cpd.getSearchStrategy())
+        cpd.setSearchStrategy("language_fallback");
+      searchStrategy.setText(cpd.getSearchStrategy());
+    } else {
+      groupingControl.setVisible(false);
+      usingGroupsButton.setSelection(false);
+    }
+    firstTime = false;
+    showOverrides = true;
+    splitGroupNames = false;
+    clearAndRefillTree(usingGroupsButton.getSelection());
+
+    tree.setSelection(new TreeItem[] { tree.getItems()[0] });
+    enable();
+
+    // sync settings page to catch use case of switching from sourceEditor
+    // to this page after having shown settings page - may be out of date
+    ParameterSettingsSection settingsSection = editor.getSettingsPage()
+            .getParameterSettingsSection();
+
+    if (null != settingsSection) {
+      setSettings(settingsSection);
+      settings.refresh();
+    }
+  }
+
+  /*
+   * (non-Javadoc)
+   * 
+   * @see org.eclipse.swt.widgets.Listener#handleEvent(org.eclipse.swt.widgets.Event)
+   */
+  public void handleEvent(Event event) {
+    cpd = getAnalysisEngineMetaData().getConfigurationParameterDeclarations();
+
+    if (event.type == SWT.MouseHover) {
+      showDescriptionAsToolTip(event);
+    } else if (event.widget == usingGroupsButton) {
+      if (usingGroupsButton.getSelection()) {
+      } else {
+        if (Window.CANCEL == Utility
+                .popOkCancel(
+                        "Confirm Remove Groups",
+                        "This action will delete any group information that may be present in this descriptor.  Proceed?",
+                        MessageDialog.WARNING)) {
+          usingGroupsButton.setSelection(true);
+          return;
+        }
+        // remove all top level items (groups) except the 1st one,
+        // which is NOT_IN_ANY_GROUP
+        TreeItem[] items = tree.getItems();
+        TreeItem[] removeItems = new TreeItem[items.length - 1];
+        System.arraycopy(items, 1, removeItems, 0, removeItems.length);
+        removeItems(removeItems, !GIVE_WARNING_MESSAGE);
+        cpd.setCommonParameters(AbstractSection.configurationParameterArray0);
+        cpd.setConfigurationGroups(AbstractSection.configurationGroupArray0);
+      }
+      setFileDirty(); // maybe slightly overkill
+      refresh();
+    } else if (event.widget == searchStrategy) {
+      valueChanged = false;
+      cpd.setSearchStrategy(setValueChanged(searchStrategy.getText(), cpd.getSearchStrategy()));
+      if (valueChanged)
+        setFileDirty();
+    } else if (event.widget == defaultGroup) {
+      valueChanged = false;
+      cpd.setDefaultGroupName(setValueChanged(defaultGroup.getText(), cpd.getDefaultGroupName()));
+      if (valueChanged)
+        setFileDirty();
+    } else if (event.widget == addGroupButton) {
+      CommonInputDialog dialog = new CommonInputDialog(
+              this,
+              "Add Group",
+              "Specify one or more unique group names, separated by 1 space character, and press OK",
+              CommonInputDialog.GROUP_NAMES);
+
+      for (;;) { // stay in loop until get "true" return from add below
+        // used for looping while group name set is duplicate
+        if (dialog.open() == Window.CANCEL)
+          return;
+        if (addNewOrEditExistingGroup(dialog.getValue(), null))
+          break;
+      }
+      commonActionFinish();
+    } else if (event.widget == addButton) { // add parameter or add override action
+
+      boolean valid = tree.getSelectionCount() == 1;
+      if (isPrimitive())
+        valid = valid && (isGroupSelection() || isParmSelection());
+      else
+        valid = valid && (isParmSelection() || isOverrideSelection());
+
+      if (!valid) {
+        if (isPrimitive())
+          Utility.popMessage("Wrong item selected",
+                  "Please first select the group under which to add a parameter",
+                  MessageDialog.ERROR);
+        else
+          Utility.popMessage("Wrong item selected",
+                  "Please first select the parameter under which to add an override",
+                  MessageDialog.ERROR);
+        return;
+      }
+
+      if (isPrimitive()) { // adding a parameter
+        TreeItem parentGroup = tree.getSelection()[0];
+        if (isParmSelection())
+          parentGroup = parentGroup.getParentItem();
+
+        AddParameterDialog dialog = new AddParameterDialog(this);
+        if (dialog.open() == Window.CANCEL)
+          return;
+
+        addNewConfigurationParameter(dialog, parentGroup);
+
+        if (null != parentGroup)
+          parentGroup.setExpanded(true);
+        commonActionFinish();
+      } else { // is aggregate - add an override
+        TreeItem parentParm = tree.getSelection()[0];
+        if (isOverride(parentParm))
+          parentParm = parentParm.getParentItem();
+        addOrEditOverride(parentParm, -1);
+      }
+    } else if ((event.widget == editButton) || (event.type == SWT.MouseDoubleClick)) {
+
+      TreeItem editItem = tree.getSelection()[0];
+      if (isParameter(editItem) && isPrimitive()) {
+        AddParameterDialog dialog = new AddParameterDialog(this,
+                getCorrespondingModelParm(editItem));
+        if (dialog.open() == Window.CANCEL)
+          return;
+
+        // update the existing item
+        alterExistingConfigurationParameter(dialog, editItem);
+        // TODO consequences of changes in rest of model?
+        commonActionFinishDirtyIfChange();
+      } else if (isParameter(editItem) && isAggregate()) {
+        // can edit name and description, but not Type (set from override)
+        ConfigurationParameter existingCP = getCorrespondingModelParm(editItem);
+
+        AddParameterDialog dialog = new AddParameterDialog(this, existingCP);
+        if (dialog.open() == Window.CANCEL)
+          return;
+        alterExistingConfigurationParameter(dialog, editItem);
+        // TODO consequences of changes in rest of model?
+        commonActionFinishDirtyIfChange();
+
+      } else if (isOverride(editItem)) {
+        TreeItem parent = editItem.getParentItem();
+        int overrideIndex = getItemIndex(parent, editItem);
+        addOrEditOverride(parent, overrideIndex);
+      } else if (isGroup(editItem)) {
+        String groupNames = getName(editItem.getText());
+        if (groupNames.equals(COMMON_GROUP) || groupNames.equals(NOT_IN_ANY_GROUP))
+          return; // can't change the name of these groups
+
+        CommonInputDialog dialog = new CommonInputDialog(
+                this,
+                "Edit group",
+                "Specify one or more unique group names, separated by 1 space character, and press OK",
+                CommonInputDialog.GROUP_NAMES, groupNames);
+
+        for (;;) {
+          if (dialog.open() == Window.CANCEL)
+            return;
+
+          if (addNewOrEditExistingGroup(dialog.getValue(), editItem))
+            break;
+        }
+        commonActionFinishDirtyIfChange();
+      }
+    } else if ((event.widget == removeButton)
+            || (event.widget == tree && event.type == SWT.KeyUp && event.character == SWT.DEL)) {
+
+      // handle remove - of all selected items
+      // if a group is selected, removing the group also removes all the parms in the group
+      // Because this is dangerous, we issue an "are you sure?" prompt.
+
+      // Other side effects: Any parameter settings for the removed
+      // parameters are also removed.
+
+      valueChanged = removeItems(tree.getSelection(), GIVE_WARNING_MESSAGE);
+      commonActionFinishDirtyIfChange();
+
+      // TODO remove settings for any parameters removed
+    } // end of remove action
+
+    // handle selection changes
+    else if (event.widget == tree && event.type == SWT.Selection) {
+
+    }
+    enable();
+  }
+
+  private void addOrEditOverride(TreeItem parent, int overrideIndex) {
+    ConfigurationParameter cp = getCorrespondingModelParm(parent);
+
+    Map delegateMap1 = editor.getResolvedDelegates();
+    Map delegateMap = null;
+    if (null != delegateMap1) {
+      delegateMap = new HashMap(delegateMap1.size());
+      delegateMap.putAll(delegateMap1);
+      FlowControllerDeclaration fcd = editor.getResolvedFlowControllerDeclaration();
+      if (null != fcd) {
+        delegateMap.put(fcd.getKey(), fcd.getSpecifier());
+      }
+    }
+    // only picks one override key - but code is from earlier design where multiple keys were
+    // possible
+    PickOverrideKeysAndParmName dialog = new PickOverrideKeysAndParmName(this, delegateMap,
+            "Override Keys and Parameter Name Selection", cp, cpd, overrideIndex == -1);
+
+    dialog.setTitle("Delegate Keys and Parameter Name Selection");
+    dialog
+            .setMessage("Select the override key path from the left panel, and the overridden parameter from the right panel.\nOnly valid parameters will be shown.");
+    if (dialog.open() == Window.CANCEL)
+      return;
+
+    String delegateKeyName = dialog.delegateKeyName;
+    String delegateParameterName = dialog.delegateParameterName;
+    // update the existing item
+    // have to do a 3 step update because the getOverrides returns a
+    // cloned array
+    valueChanged = false;
+    String overrideSpec = delegateKeyName + '/' + delegateParameterName;
+    // updateOneOverride(cp, overrideIndex, dialog.overrideSpec);
+    if (overrideIndex < 0) {
+      addOverride(cp, overrideSpec);
+      valueChanged = true;
+    } else {
+      String[] overrides = cp.getOverrides();
+      overrides[overrideIndex] = setValueChanged(overrideSpec, overrides[overrideIndex]);
+      cp.setOverrides(overrides);
+      parent.getItems()[overrideIndex].setText(OVERRIDE_HEADER + overrideSpec);
+    }
+    // TODO consequences of changes in rest of model?
+    commonActionFinishDirtyIfChange();
+  }
+  
+
+  private boolean removeItems(TreeItem[] itemsToRemove, boolean giveWarningMsg) {
+    String[] namesToRemove = new String[itemsToRemove.length];
+    boolean[] isGroup = new boolean[itemsToRemove.length];
+    StringBuffer msgGroup = new StringBuffer();
+    StringBuffer msg = new StringBuffer();
+    StringBuffer oMsg = new StringBuffer();
+
+    for (int i = 0; i < itemsToRemove.length; i++) {
+      namesToRemove[i] = getName(itemsToRemove[i].getText());
+      isGroup[i] = isGroup(itemsToRemove[i]);
+      if (isGroup[i]) {
+        if (NOT_IN_ANY_GROUP.equals(namesToRemove[i]))
+          msgGroup
+                  .append("\nThis action removes all parameter descriptions in the <Not in any group> section.");
+        else {
+          if (i > 0)
+            msgGroup.append(", ");
+          else if (COMMON_GROUP.equals(namesToRemove[i]))
+            msgGroup
+                    .append("\nThis action removes all parameter descriptions in the <Common> section.");
+          else
+            msgGroup
+                    .append("\nGroups being removed, together with their parameter definitions defined here: \n");
+          if (!COMMON_GROUP.equals(namesToRemove[i]))
+            msgGroup.append(namesToRemove[i]);
+        }
+      } else if (isParameter(itemsToRemove[i])) {
+        if (i > 0)
+          msg.append(", ");
+        else
+          msg.append("\nParameters being removed: \n");
+        msg.append(namesToRemove[i]);
+      } else if (isOverride(itemsToRemove[i])) {
+        if (i > 0)
+          oMsg.append(", ");
+        else
+          oMsg.append("\nOverride being removed: \n");
+        oMsg.append(namesToRemove[i]);
+      } else
+        throw new InternalErrorCDE("invalid state");
+    }
+
+    if (giveWarningMsg
+            && Window.CANCEL == Utility.popOkCancel("Confirm Remove",
+                    "Please confirm remove, or Cancel.\n" + msgGroup.toString() + msg.toString()
+                            + oMsg.toString(), MessageDialog.WARNING))
+      return false;
+
+    // loop thru all things being removed, and remove them
+    for (int i = 0; i < itemsToRemove.length; i++) {
+      if (isGroup[i]) {
+        removeGroup(itemsToRemove[i], namesToRemove[i]);
+      } else if (isParameter(itemsToRemove[i])) { // just a plain parameter being
+        // removed
+        removeParameter(itemsToRemove[i], namesToRemove[i]);
+      } else if (isOverride(itemsToRemove[i])) {
+        TreeItem parentItem = itemsToRemove[i].getParentItem();
+        ConfigurationParameter cp = getCorrespondingModelParm(parentItem);
+        cp.setOverrides(removeOverride(cp, getItemIndex(parentItem, itemsToRemove[i])));
+        itemsToRemove[i].dispose();
+        if (cp.getOverrides().length == 0) {
+          removeParameter(parentItem, getName(parentItem));
+        }
+      } else
+        throw new InternalErrorCDE("Invalid state");
+    }
+    return true;
+  }
+
+  private void removeParameter(TreeItem itemToRemove, String nameToRemove) {
+    TreeItem parentItem = itemToRemove.getParentItem();
+    ConfigurationGroup cg = null;
+    String parentGroupName = getName(parentItem.getText());
+    if (parentGroupName.equals(NOT_IN_ANY_GROUP))
+      cpd.setConfigurationParameters(removeConfigurationParameter(cpd.getConfigurationParameters(),
+              nameToRemove));
+    else if (parentGroupName.equals(COMMON_GROUP))
+      cpd.setCommonParameters(commonParms = removeConfigurationParameter(cpd.getCommonParameters(),
+              nameToRemove));
+    else {
+      cg = getConfigurationGroup(parentGroupName);
+      cg.setConfigurationParameters(removeConfigurationParameter(cg.getConfigurationParameters(),
+              nameToRemove));
+
+    }
+    removeParmSettingFromMultipleGroups(itemToRemove, REMOVE_FROM_GUI);
+    itemToRemove.dispose();
+
+    if (null != cg && cg.getConfigurationParameters().length == 0) {
+      removeGroup(parentItem, getName(parentItem));
+    }
+  }
+
+  private void removeGroup(TreeItem itemToRemove, String nameToRemove) {
+    if (nameToRemove.equals(COMMON_GROUP)) {
+      removeCommonParmSettingsFromMultipleGroups();
+      cpd.setCommonParameters(configurationParameterArray0);
+      commonParms = configurationParameterArray0;
+      // can't really remove the <Common> group so remove all the parms
+      disposeAllChildItems(itemToRemove);
+
+    } else if (nameToRemove.equals(NOT_IN_ANY_GROUP)) {
+      // remove settings for all non-group parm definitions
+      removeIncludedParmSettingsFromSingleGroup(NOT_IN_ANY_GROUP, null);
+      cpd.setConfigurationParameters(configurationParameterArray0);
+      // remove all non-group parm definitions
+      disposeAllChildItems(itemToRemove);
+
+    } else {
+      ConfigurationGroup cg = getConfigurationGroup(nameToRemove);
+      // remove settings for all parms in the group too
+      // also updates the settings GUI if the GUI is initialized
+      removeIncludedParmSettingsFromMultipleGroups(cg.getNames(), cg.getConfigurationParameters());
+
+      // remove group
+      cpd.setConfigurationGroups(removeConfigurationGroup(cpd.getConfigurationGroups(), cg));
+      itemToRemove.dispose(); // also disposes children of group in
+      // GUI
+    }
+  }
+
+  public void addParm(String name, ConfigurationParameter modelParm, ConfigGroup group,
+          String override) {
+    TreeItem parentGroup = getTreeItemGroup(group);
+    AddParameterDialog dialog = new AddParameterDialog(this);
+    dialog.parmName = name;
+    dialog.description = modelParm.getDescription();
+    dialog.mandatory = modelParm.isMandatory();
+    dialog.multiValue = modelParm.isMultiValued();
+    dialog.parmType = modelParm.getType();
+    // dialog.overrideSpec = override;
+    ConfigurationParameter parmInGroup = addNewConfigurationParameter(dialog, parentGroup);
+    addOverride(parmInGroup, override);
+    parentGroup.setExpanded(true);
+    commonActionFinish();
+  }
+
+  private ConfigurationGroup getConfigurationGroup(String groupName) {
+    if (groupName.equals(COMMON_GROUP))
+      throw new InternalErrorCDE("invalid call");
+    ConfigurationGroup[] groups = cpd.getConfigurationGroups();
+    for (int i = 0; i < groups.length; i++) {
+      if (groupName.equals(groupNameArrayToString(groups[i].getNames())))
+        return groups[i];
+    }
+    throw new InternalErrorCDE("invalid state");
+  }
+
+  private ConfigurationGroup[] removeConfigurationGroup(ConfigurationGroup[] groups,
+          ConfigurationGroup cg) {
+    return (ConfigurationGroup[]) Utility.removeElementFromArray(groups, cg,
+            ConfigurationGroup.class);
+  }
+
+  private ConfigurationParameter[] removeConfigurationParameter(ConfigurationParameter[] parms,
+          String nameToRemove) {
+    ConfigurationParameter[] newParms = new ConfigurationParameter[parms.length - 1];
+    for (int i = 0, j = 0; i < newParms.length; i++, j++) {
+      if (parms[j].getName().equals(nameToRemove))
+        j++;
+      newParms[i] = parms[j];
+    }
+    return newParms;
+  }
+
+  private String[] removeOverride(ConfigurationParameter cp, int i) {
+    String[] oldOverrides = cp.getOverrides();
+    String[] newOverrides = new String[oldOverrides.length - 1];
+    if (i - 1 > 0)
+      System.arraycopy(oldOverrides, 0, newOverrides, 0, i - 1);
+    if (oldOverrides.length - 1 - i > 0)
+      System.arraycopy(oldOverrides, i + 1, newOverrides, i, oldOverrides.length - 1 - i);
+    return newOverrides;
+  }
+
+  /**
+   * Called to add group to aggregate parm decl based on delegate group
+   * 
+   * @param group
+   *          the delegate group needing to be added to the aggregate
+   */
+  public ConfigGroup addGroup(ConfigGroup group) {
+    String groupName = group.getName();
+    String[] groupNameArray = group.getNameArray();
+    if (group.getKind() == ConfigGroup.COMMON) {
+      groupNameArray = getAllGroupNames(group.getCPD());
+      groupName = groupNameArrayToString(groupNameArray);
+    }
+    ConfigurationGroup cg = new ConfigurationGroup_impl();
+    cg.setConfigurationParameters(configurationParameterArray0);
+    TreeItem item = addGroupToGUI(groupName, cg);
+    // fill(commonParms, item); // don't add common parsm, they're added by definition
+    addGroupToModel(cg);
+    cg.setNames(groupNameArray);
+    tree.setSelection(new TreeItem[] { item });
+    return new ConfigGroup(cpd, cg);
+  }
+
+  // existing, if not null, doesn't point to <Common> which can't be edited
+  /**
+   * @param names -
+   *          a sequence of group names separated by blanks
+   * @param existing -
+   *          null or an existing tree item being edited
+   */
+  private boolean addNewOrEditExistingGroup(String names, TreeItem existing) {
+    valueChanged = true; // preset
+    ConfigGroup mcg = null;
+    String[] oldGroupNames = stringArray0;
+    String[] newGroupNames = groupNamesToArray(names);
+    String[] groupNamesToAdd;
+    String[] groupNamesToDrop = stringArray0;
+
+    if (null != existing) {
+      mcg = getCorrespondingModelGroup(existing);
+      oldGroupNames = mcg.getNameArray();
+
+      groupNamesToDrop = setDiff(oldGroupNames, newGroupNames);
+      groupNamesToAdd = setDiff(newGroupNames, oldGroupNames);
+    } else {
+      groupNamesToAdd = newGroupNames;
+    }
+
+    // it is legal to define a group name more than once, but the same set of group names
+    // shouldn't be defined more than once
+    if (groupNameAlreadyDefined(newGroupNames)) {
+      Utility.popMessage("Group Already Defined",
+              "This set of group names has already been defined." + "\n\nGroup: " + names,
+              MessageDialog.ERROR);
+      return false;
+    }
+
+    TreeItem item;
+    if (existing == null) {
+      ConfigurationGroup cg = new ConfigurationGroup_impl();
+      cg.setConfigurationParameters(configurationParameterArray0);
+      cg.setNames(groupNamesToArray(names));
+      item = addGroupToGUI(names, cg);
+      addGroupToModel(cg);
+    } else { // editing existing group
+      valueChanged = groupNamesToDrop.length != 0 || groupNamesToAdd.length != 0;
+      item = existing;
+      setGroupText(item, names);
+
+      for (int i = 0; i < groupNamesToDrop.length; i++) {
+        removeIncludedParmSettingsFromSingleGroup(groupNamesToDrop[i], mcg.getConfigParms());
+      }
+      mcg.setNameArray(groupNamesToArray(names));
+      if (null != settings) {
+        for (int i = 0; i < groupNamesToAdd.length; i++) {
+          TreeItem settingsItem = getSettingsTreeGroup(groupNamesToAdd[i]);
+          if (null == settingsItem) {
+            settingsItem = new TreeItem(settingsTree, SWT.NONE);
+            setGroupText(settingsItem, groupNamesToAdd[i]);
+            settingsItem.setData(null);
+            fill(mcg.getConfigParms(), settingsItem);
+            fill(commonParms, settingsItem);
+          } else {
+            fillInFrontOfCommon(mcg.getConfigParms(), settingsItem);
+          }
+        }
+      }
+
+    }
+
+    tree.setSelection(new TreeItem[] { item });
+    return true;
+  }
+
+  private void fillInFrontOfCommon(ConfigurationParameter[] parms, TreeItem settingsTreeGroup) {
+    if (parms != null) {
+      for (int i = parms.length - 1; i >= 0; i--) {
+        fillParmItem(new TreeItem(settingsTreeGroup, SWT.NONE, 0), parms[i]);
+      }
+    }
+  }
+
+  /**
+   * Calculate s1 - s2 set
+   * 
+   * @param s1
+   * @param s2
+   * @return
+   */
+  private String[] setDiff(String[] s1, String[] s2) {
+    Set result = new TreeSet();
+    for (int i = 0; i < s1.length; i++)
+      result.add(s1[i]);
+    for (int i = 0; i < s2.length; i++)
+      result.remove(s2[i]);
+    return (String[]) result.toArray(stringArray0);
+  }
+
+  private boolean setEqual(String[] s1, String[] s2) {
+    if (null == s1 && null == s2)
+      return true;
+    if (null == s1 || null == s2)
+      return false;
+    if (s1.length != s2.length)
+      return false;
+    if (setDiff(s1, s2).length == 0)
+      return true;
+    return false;
+  }
+
+  /**
+   * Called from ParameterDelegatesSection to add an override
+   * 
+   * @param parmInGroup
+   * @param override
+   */
+  public void addOverride(ConfigurationParameter parmInGroup, String override) {
+    addOverride(override, getTreeItemParm(parmInGroup), parmInGroup);
+  }
+
+  /**
+   * add an override item
+   * 
+   * @param parent
+   * @param override
+   */
+  private void addOverrideToGUI(TreeItem parent, String override) {
+    // addOverride(dialog.overrideSpec, parent, cp);
+    TreeItem item = new TreeItem(parent, SWT.NONE);
+    item.setText(OVERRIDE_HEADER + override);
+  }
+
+  /**
+   * Called by addNewConfigurationParameter, and fill (via refresh) to add overrides to the tree
+   * list
+   * 
+   * @param parent
+   * @param modelCP
+   */
+  protected void fillOverrides(TreeItem parent, ConfigurationParameter modelCP) {
+    if (isAggregate()) {
+      String[] overrides = modelCP.getOverrides();
+      if (overrides != null) {
+        for (int i = 0; i < overrides.length; i++) {
+          addOverrideToGUI(parent, overrides[i]);
+        }
+        parent.setExpanded(true); // show added overrides
+      }
+    }
+  }
+
+  /**
+   * called from add Override action
+   * 
+   * @param dialog
+   * @param parent
+   * @param cp
+   */
+  private void addOverride(String override, TreeItem parent, ConfigurationParameter cp) {
+    cp.setOverrides(addOverrideToArray(cp.getOverrides(), override));
+    addOverrideToGUI(parent, override);
+    parent.setExpanded(true);
+  }
+
+  private void alterExistingConfigurationParameter(AddParameterDialog dialog,
+          TreeItem existingTreeItem) {
+    ConfigurationParameter existingCP = getCorrespondingModelParm(existingTreeItem);
+    ConfigurationParameter previousCP = existingCP;
+    previousCP = (ConfigurationParameter) previousCP.clone();
+    fillModelParm(dialog, existingCP);
+    fillParmItem(existingTreeItem, existingCP);
+
+    // the following may have changed in an existing param spec, that could
+    // affect the setting:
+    // 1) the name, 2) the type, 3) the multi-value aspect
+    // Description or mandatory changes have no effect on the settings
+
+    // If the multi-value aspect changes, drop all the settings
+    // If the type changes, drop all the settings
+    // If the name changes, change existing settings for that parm name in all groups
+
+    if ((!previousCP.getType().equals(existingCP.getType()))
+            || (previousCP.isMultiValued() != existingCP.isMultiValued())) {
+      removeParmSettingFromMultipleGroups(existingTreeItem, !REMOVE_FROM_GUI);
+    }
+
+    commonParmUpdate(existingTreeItem, existingCP, previousCP.getName());
+  }
+
+  private void commonParmUpdate(TreeItem existingTreeItem, ConfigurationParameter existingCP,
+          String prevName) {
+    updateParmInSettingsGUI(existingCP, existingTreeItem, prevName);
+
+    String newName = existingCP.getName();
+    if (!newName.equals(prevName)) {
+      // name changed; update the settings model
+      ConfigurationParameterSettings cps = getModelSettings();
+      String[] allGroupNames = new String[] { null };
+      if (usingGroupsButton.getSelection()) {
+        allGroupNames = (String[]) Utility
+                .addElementToArray(getAllGroupNames(), null, String.class);
+      }
+      Object value;
+
+      for (int i = 0; i < allGroupNames.length; i++) {
+        if (null != (value = cps.getParameterValue(allGroupNames[i], prevName))) {
+          cps.setParameterValue(allGroupNames[i], newName, value);
+          cps.setParameterValue(allGroupNames[i], prevName, null);
+        }
+      }
+    }
+  }
+
+  /**
+   * Fills in the model Configuration Parm from the Add/Edit dialog. called from
+   * addNewConfigurationParameter, and alterExistingConfigurationParameter
+   * 
+   * @param dialog
+   * @param existingCP
+   */
+  private void fillModelParm(AddParameterDialog dialog, ConfigurationParameter existingCP) {
+    valueChanged = false;
+    existingCP.setName(setValueChanged(dialog.parmName, existingCP.getName()));
+    existingCP.setDescription(setValueChanged(multiLineFix(dialog.description), existingCP
+            .getDescription()));
+    existingCP.setMandatory(setValueChangedBoolean(dialog.mandatory, existingCP.isMandatory()));
+    existingCP
+            .setMultiValued(setValueChangedBoolean(dialog.multiValue, existingCP.isMultiValued()));
+    existingCP.setType(setValueChanged(dialog.parmType, existingCP.getType()));
+    if (valueChanged)
+      setFileDirty();
+  }
+
+  /**
+   * Called from UI when adding a new Configuraton Parameter Called from refresh when filling params
+   * Called when adding override to new parm
+   * 
+   * @param dialog
+   * @param group
+   * @return
+   */
+  private ConfigurationParameter addNewConfigurationParameter(AddParameterDialog dialog,
+          TreeItem group) {
+    ConfigurationParameter newCP = new ConfigurationParameter_impl();
+    fillModelParm(dialog, newCP);
+
+    if (null != group) {
+      String groupName = getName(group.getText());
+      if (groupName.equals(COMMON_GROUP)) {
+        cpd.setCommonParameters(commonParms = addParmToArray(cpd.getCommonParameters(), newCP));
+      } else if (groupName.equals(NOT_IN_ANY_GROUP)) {
+        cpd.setConfigurationParameters(addParmToArray(cpd.getConfigurationParameters(), newCP));
+      } else {
+        ConfigurationGroup cg = getConfigurationGroup(groupName);
+        cg.setConfigurationParameters(addParmToArray(cg.getConfigurationParameters(), newCP));
+      }
+    } else { // no groups
+      throw new InternalErrorCDE("invalid state");
+    }
+    addNewConfigurationParameterToGUI(newCP, group);
+    return newCP;
+  }
+
+  private void addGroupToModel(ConfigurationGroup newCg) {
+    ConfigurationGroup[] oldCgs = cpd.getConfigurationGroups();
+    ConfigurationGroup[] newCgs;
+    if (null == oldCgs) {
+      newCgs = new ConfigurationGroup[1];
+    } else {
+      newCgs = new ConfigurationGroup[oldCgs.length + 1];
+      System.arraycopy(oldCgs, 0, newCgs, 0, oldCgs.length);
+    }
+    newCgs[newCgs.length - 1] = newCg;
+    cpd.setConfigurationGroups(newCgs);
+  }
+
+  private String[] addOverrideToArray(String[] overrides, String newOverride) {
+    if (null == overrides)
+      return new String[] { newOverride };
+    String[] newOverrides = new String[overrides.length + 1];
+    System.arraycopy(overrides, 0, newOverrides, 0, overrides.length);
+    newOverrides[overrides.length] = newOverride;
+    return newOverrides;
+  }
+
+  private ConfigurationParameter[] addParmToArray(ConfigurationParameter[] cps,
+          ConfigurationParameter newCP) {
+
+    if (null == cps) {
+      return new ConfigurationParameter[] { newCP };
+    }
+    ConfigurationParameter[] newCps = new ConfigurationParameter[cps.length + 1];
+    System.arraycopy(cps, 0, newCps, 0, cps.length);
+    newCps[cps.length] = newCP;
+    return newCps;
+  }
+
+  /**
+   * 
+   * @param names
+   * @return true if there is a group whose names are the same set
+   */
+  private boolean groupNameAlreadyDefined(String[] names) {
+    ConfigurationGroup[] cgs = cpd.getConfigurationGroups();
+    if (null != cgs) {
+      for (int i = 0; i < cgs.length; i++) {
+        if (setEqual(names, cgs[i].getNames()))
+          return true;
+      }
+    }
+    return false;
+  }
+
+  public static boolean parameterNameAlreadyDefinedNoMsg(String name,
+          ConfigurationParameterDeclarations pCpd) {
+    if (pCpd.getCommonParameters() != null) {
+      if (parameterInArray(name, pCpd.getCommonParameters()))
+        return true;
+    }
+    if (pCpd.getConfigurationParameters() != null) {
+      if (parameterInArray(name, pCpd.getConfigurationParameters()))
+        return true;
+    }
+    ConfigurationGroup[] groups;
+    if ((groups = pCpd.getConfigurationGroups()) != null) {
+      for (int i = 0; i < groups.length; i++) {
+        if (parameterInArray(name, groups[i].getConfigurationParameters()))
+          return true;
+      }
+    }
+    return false;
+  }
+
+  public boolean parameterNameAlreadyDefined(String name) {
+    boolean alreadyDefined = parameterNameAlreadyDefinedNoMsg(name, cpd);
+    if (alreadyDefined) {
+      Utility.popMessage("Parameter Already Defined",
+              "The following parameter is already defined in the list. Parameter names must be unique."
+                      + "\n\nParameter: " + name, MessageDialog.ERROR);
+    }
+    return alreadyDefined;
+  }
+
+  private static boolean parameterInArray(String name, ConfigurationParameter[] cps) {
+    for (int i = 0; i < cps.length; i++) {
+      if (name.equals(cps[i].getName()))
+        return true;
+    }
+    return false;
+  }
+
+  private void commonActionFinish() {
+    valueChanged = true;
+    commonActionFinishDirtyIfChange();
+  }
+
+  /**
+   * called by Edit operations which might not make any changes They set the dirty state if any
+   * changes occur, so don't set it here.
+   * 
+   */
+  private void commonActionFinishDirtyIfChange() {
+    if (valueChanged)
+      setFileDirty();
+    enable();
+  }
+
+  public void enable() {
+
+    usingGroupsButton.setEnabled(!isAggregate());
+    boolean usingGroups = usingGroupsButton.getSelection();
+    groupingControl.setVisible(usingGroups);
+
+    addButton.setEnabled(isPrimitive() || tree.getSelectionCount() == 1
+            && (isParmSelection() || isOverrideSelection()));
+
+    addGroupButton.setEnabled(isPrimitive() && usingGroups);
+
+    removeButton.setEnabled(tree.getSelectionCount() == 1
+            && (isParmSelection() || isGroupSelection() || isOverrideSelection()));
+
+    editButton
+            .setEnabled(tree.getSelectionCount() == 1
+                    && ((/* isPrimitive() && */isParmSelection()) || isOverrideSelection() || (isPrimitive()
+                            && isGroupSelection() && !isCommonGroupSelection())));
+  }
+
+  public Tree getTree() {
+    return tree;
+  }
+
+  /**
+   * Given a ConfigurationParameter, find the corresponding item in the tree. Note: parameters with
+   * the same name can exist in different groups, so we don't match using the parm name, but rather
+   * do an "EQ" test
+   * 
+   * @param p
+   * @return
+   */
+  private TreeItem getTreeItemParm(ConfigurationParameter p) {
+    TreeItem[] groups = tree.getItems();
+    for (int i = 0; i < groups.length; i++) {
+      TreeItem[] parms = groups[i].getItems();
+      for (int j = 0; j < parms.length; j++) {
+        if (getCorrespondingModelParm(parms[j]) == p)
+          return parms[j];
+      }
+    }
+    throw new InternalErrorCDE("invalid state");
+  }
+
+  /**
+   * Given a ConfigGroup - find the corresponding tree item. Match is done against the display form
+   * of the name(s), with special casing for the not-in-any-group and common.
+   * 
+   * @param g
+   * @return
+   */
+  private TreeItem getTreeItemGroup(ConfigGroup g) {
+    switch (g.getKind()) {
+      case ConfigGroup.NOT_IN_ANY_GROUP:
+        return tree.getItems()[0];
+      case ConfigGroup.COMMON:
+        return tree.getItems()[1];
+    }
+    TreeItem[] items = tree.getItems();
+    for (int i = 2; i < items.length; i++) {
+      if (getName(items[i].getText()).equals(g.getName()))
+        return items[i];
+    }
+    throw new InternalErrorCDE("invalid state");
+  }
+
+  private TreeItem getSettingsTreeGroup(String groupName) {
+    TreeItem[] items = settingsTree.getItems();
+    for (int i = 0; i < items.length; i++) {
+      if (groupName.equals(getName(items[i].getText())))
+        return items[i];
+    }
+    return null;
+  }
+
+}
diff --git a/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/ParameterSettingsSection.java b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/ParameterSettingsSection.java
new file mode 100644
index 0000000..e4d379d
--- /dev/null
+++ b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/ParameterSettingsSection.java
@@ -0,0 +1,158 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.uima.taeconfigurator.editors.ui;
+
+import org.apache.uima.resource.metadata.ConfigurationParameter;
+import org.apache.uima.resource.metadata.ConfigurationParameterDeclarations;
+import org.apache.uima.taeconfigurator.InternalErrorCDE;
+import org.apache.uima.taeconfigurator.editors.MultiPageEditor;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Tree;
+import org.eclipse.swt.widgets.TreeItem;
+import org.eclipse.ui.forms.IManagedForm;
+
+/**
+ * display parameters on the settings page. If groups, show by groups (using Tree metaphor) Note:
+ * The tree displayed here is an expanded version of the ParameterSection Tree. It differs in 3
+ * ways, when Groups are being used: 1) no "overrides" info 2) Groups with multiple names are split;
+ * each group name has a different setting
+ * 
+ */
+public class ParameterSettingsSection extends AbstractSectionParm {
+
+  public ParameterSettingsSection(MultiPageEditor editor, Composite parent) {
+    super(
+            editor,
+            parent,
+            "Configuration Parameters",
+            "This section list all configuration parameters, either as plain parameters, or as part of one or more groups.  Select one to show, or set the value in the right hand panel.");
+  }
+
+  /*
+   * Called by the page constructor after all sections are created, to initialize them.
+   * (non-Javadoc)
+   * 
+   * @see org.eclipse.ui.forms.IFormPart#initialize(org.eclipse.ui.forms.IManagedForm)
+   */
+  public void initialize(IManagedForm form) {
+    super.initialize(form);
+    Composite sectionClient = new2ColumnComposite(this.getSection());
+    enableBorders(sectionClient);
+    toolkit.paintBordersFor(sectionClient);
+    tree = newTree(sectionClient);
+
+    ParameterSection ps = editor.getParameterPage().getParameterSection();
+    if (null != ps)
+      ps.setSettings(this);
+    tree.addListener(SWT.MouseHover, this); // for Description
+  }
+
+  /*
+   * (non-Javadoc)
+   * 
+   * @see org.eclipse.ui.forms.IFormPart#refresh()
+   */
+
+  public void refresh() {
+    super.refresh();
+
+    // only called at beginning.
+    // Subsequently, incrementally updated as parameters and groups
+    // change.
+    // 
+    showOverrides = false;
+    splitGroupNames = true;
+    clearAndRefillTree(isParmGroup());
+  }
+
+  // public void enable() {}
+
+  /*
+   * (non-Javadoc)
+   * 
+   * @see org.eclipse.swt.widgets.Listener#handleEvent(org.eclipse.swt.widgets.Event)
+   */
+  public void handleEvent(Event event) {
+    if (event.type == SWT.MouseHover) {
+      showDescriptionAsToolTip(event);
+    } else if (event.widget == tree && event.type == SWT.Selection) {
+      editor.getSettingsPage().getValueSection().refresh();
+    }
+  }
+
+  public Tree getTree() {
+    return tree;
+  }
+
+  /**
+   * called by the Values section
+   * 
+   * @return
+   */
+  public String getSelectedParamName() {
+    TreeItem[] items = tree.getSelection();
+    if (items.length == 0)
+      return null;
+
+    TreeItem item = items[0];
+    if (isParameter(item))
+      return getName(item.getText());
+    return null;
+  }
+
+  public String getSelectedParamGroupName() {
+    TreeItem[] items = tree.getSelection();
+    if (items.length == 0)
+      return null;
+
+    TreeItem item = items[0];
+    if (isParameter(item)) {
+      TreeItem parent = item.getParentItem();
+      if (null == parent)
+        throw new InternalErrorCDE("invalid state");
+      return getName(parent.getText());
+    }
+    return null;
+  }
+
+  /**
+   * 
+   * @return
+   */
+  public ConfigurationParameter getSelectedModelParameter() {
+    TreeItem[] items = tree.getSelection();
+    if (items.length == 0)
+      return null;
+
+    TreeItem item = items[0];
+    if (isParameter(item)) {
+      TreeItem group = item.getParentItem();
+      ConfigurationParameterDeclarations cpds = getConfigurationParameterDeclarations();
+      String groupName = (null == group) ? null : getName(group.getText());
+      if (NOT_IN_ANY_GROUP.equals(groupName))
+        return cpds.getConfigurationParameter(null, getName(item.getText()));
+      return cpds.getConfigurationParameter(groupName, getName(item.getText()));
+    }
+    return null;
+  }
+
+}
diff --git a/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/PrimitiveSection.java b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/PrimitiveSection.java
new file mode 100644
index 0000000..360352a
--- /dev/null
+++ b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/PrimitiveSection.java
@@ -0,0 +1,224 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS 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.taeconfigurator.editors.ui;
+
+import java.text.MessageFormat;
+
+import org.apache.uima.Constants;
+import org.apache.uima.resource.metadata.OperationalProperties;
+import org.apache.uima.taeconfigurator.InternalErrorCDE;
+import org.apache.uima.taeconfigurator.editors.MultiPageEditor;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.jdt.core.IType;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.ui.IJavaElementSearchConstants;
+import org.eclipse.jdt.ui.JavaUI;
+import org.eclipse.jface.window.Window;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.FileDialog;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.ui.dialogs.SelectionDialog;
+import org.eclipse.ui.forms.IManagedForm;
+
+/**
+ * This class is misnamed - refers really to Runtime Information
+ * 
+ */
+public class PrimitiveSection extends AbstractSection {
+
+  public void enable() {
+  }
+
+  private Label implNameLabel;
+
+  private Text implName;
+
+  private Button findButton;
+
+  private Button multipleDeploymentAllowed;
+
+  private Button modifiesCas;
+
+  private Button outputsNewCASes;
+
+  /**
+   * Creates a section with a text field for the name of the annotator. Only enabled if annotator is
+   * primitive Also has the operational parameters
+   */
+  public PrimitiveSection(MultiPageEditor editor, Composite parent) {
+    super(editor, parent, "Runtime Information",
+            "This section describes information about how to run this component");
+  }
+
+  public void initialize(IManagedForm form) {
+    super.initialize(form);
+
+    Composite sectionClient = new2ColumnComposite(getSection());
+    enableBorders(sectionClient);
+
+    modifiesCas = newCheckBox(sectionClient, "updates the CAS",
+            "check this if this component updates the CAS");
+    spacer(sectionClient);
+    if (isAeDescriptor() || isCasConsumerDescriptor() || isFlowControllerDescriptor()) {
+      multipleDeploymentAllowed = newCheckBox(sectionClient, "multiple deployment allowed",
+              "check this to allow multiple instances of this engine to be deployed that can run in parallel");
+      spacer(sectionClient);
+    }
+    if (isAeDescriptor()) {
+      outputsNewCASes = newCheckBox(sectionClient, "Outputs new CASes",
+              "check this for primitive components that output new CASes, "
+                      + "or for aggregates which contain a CAS Multiplier, "
+                      + "where the new CASes are returned out of the aggregate.");
+      spacer(sectionClient);
+    }
+
+    implNameLabel = newLabelWithData(sectionClient, "");
+    implName = newTextWithTip(sectionClient, "", "");
+
+    spacer(sectionClient); // skip first column
+
+    findButton = newPushButton(sectionClient, "Browse", "", true, SWT.RIGHT);
+    // next line makes the browse button just big enough for the text,
+    // otherwise it's very long...
+    findButton.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_END));
+
+    toolkit.paintBordersFor(sectionClient);
+  }
+
+  /*
+   * (non-Javadoc)
+   * 
+   * @see org.eclipse.ui.forms.IFormPart#refresh()
+   */
+  public void refresh() {
+    super.refresh();
+
+    // set description for enter field (either .class or .dll file)
+    String implKind = editor.getAeDescription().getFrameworkImplementation();
+    if (Constants.CPP_FRAMEWORK_NAME.equals(implKind)) {
+      implNameLabel.setText("Name of the .dll file");
+      implName.setToolTipText("Enter the name of the .dll file here.");
+      findButton.setToolTipText("Browse the file system for the .dll file.");
+    } else {
+      implNameLabel.setText("Name of the Java class file");
+      implName.setToolTipText("Enter the name of the Java class that implements this component.");
+      findButton.setToolTipText("Browse for the Java class that implmenets this component.");
+    }
+
+    if (isPrimitive()) {
+      setEnabled(true);
+
+      // AnnotatorImplementationName may be null
+      // due to change from aggregate to primitive
+      String modelImplName = editor.getAeDescription().getAnnotatorImplementationName();
+      implName.setText(convertNull(modelImplName));
+      this.getSection().layout();
+    } else {
+      implName.setText("");
+      setEnabled(false);
+    }
+    OperationalProperties ops = getOperationalProperties();
+    if (null != ops) {
+      setButtonSelection(modifiesCas, ops.getModifiesCas());
+      setButtonSelection(multipleDeploymentAllowed, ops.isMultipleDeploymentAllowed());
+      setButtonSelection(outputsNewCASes, ops.getOutputsNewCASes());
+    } else {
+      setButtonSelection(modifiesCas, true);
+      setButtonSelection(multipleDeploymentAllowed, false);
+      setButtonSelection(outputsNewCASes, false);
+    }
+  }
+
+  /*
+   * (non-Javadoc)
+   * 
+   * @see org.eclipse.swt.widgets.Listener#handleEvent(org.eclipse.swt.widgets.Event)
+   */
+  public void handleEvent(Event event) {
+    valueChanged = false;
+    OperationalProperties ops = getOperationalProperties();
+    if (event.widget == findButton) {
+      String className = null;
+      try {
+        String implKind = editor.getAeDescription().getFrameworkImplementation();
+        if (Constants.CPP_FRAMEWORK_NAME.equals(implKind)) {
+          FileDialog dialog = new FileDialog(getSection().getShell(), SWT.NONE);
+          String[] extensions = { "*.dll" };
+          dialog.setFilterExtensions(extensions);
+          String sStartDir = Platform.getLocation().toString();
+          dialog.setFilterPath(sStartDir);
+          className = dialog.open();
+
+        } else {
+          SelectionDialog typeDialog = JavaUI.createTypeDialog(getSection().getShell(), editor
+                  .getEditorSite().getWorkbenchWindow(), editor.getSearchScopeForDescriptorType(),
+                  IJavaElementSearchConstants.CONSIDER_CLASSES, false, "*");
+          typeDialog.setTitle(MessageFormat.format("Choose the {0} implementation class",
+                  new Object[] { editor.descriptorTypeString() }));
+          typeDialog.setMessage("Filter/mask:");
+          if (typeDialog.open() == Window.CANCEL)
+            return;
+          Object[] result = typeDialog.getResult();
+          if (result != null && result.length > 0)
+            className = ((IType) result[0]).getFullyQualifiedName();
+        }
+        if (className == null || className.equals("")) //$NON-NLS-1$
+          return;
+        implName.setText(className);
+        editor.getAeDescription().setAnnotatorImplementationName(className);
+        valueChanged = true;
+      } catch (JavaModelException e) {
+        throw new InternalErrorCDE("unexpected Exception", e);
+      }
+    } else if (event.widget == modifiesCas) {
+      ops.setModifiesCas(setValueChangedBoolean(modifiesCas.getSelection(), ops.getModifiesCas()));
+    } else if (event.widget == multipleDeploymentAllowed) {
+      ops.setMultipleDeploymentAllowed(setValueChangedBoolean(multipleDeploymentAllowed
+              .getSelection(), ops.isMultipleDeploymentAllowed()));
+    } else if (event.widget == outputsNewCASes) {
+      ops.setOutputsNewCASes(setValueChangedBoolean(outputsNewCASes.getSelection(), ops
+              .getOutputsNewCASes()));
+    } else if (event.widget == implName) {
+      editor.getAeDescription().setAnnotatorImplementationName(
+              setValueChanged(implName.getText(), editor.getAeDescription()
+                      .getAnnotatorImplementationName()));
+    }
+    if (valueChanged)
+      editor.setFileDirty();
+  }
+
+  /**
+   * @param enabled
+   *          indicator for the section to be enabled.
+   */
+  public void setEnabled(boolean enabled) {
+    implNameLabel.setEnabled(enabled);
+    implName.setEnabled(enabled);
+    findButton.setEnabled(enabled);
+    enableCtrl(modifiesCas, true);
+    enableCtrl(multipleDeploymentAllowed, true);
+    enableCtrl(outputsNewCASes, true);
+  }
+}
diff --git a/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/PriorityListSection.java b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/PriorityListSection.java
new file mode 100644
index 0000000..3fc5d14
--- /dev/null
+++ b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/PriorityListSection.java
@@ -0,0 +1,275 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS 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.taeconfigurator.editors.ui;
+
+import org.apache.uima.UIMAFramework;
+import org.apache.uima.resource.metadata.TypePriorities;
+import org.apache.uima.resource.metadata.TypePriorityList;
+import org.apache.uima.taeconfigurator.editors.MultiPageEditor;
+import org.apache.uima.taeconfigurator.editors.ui.dialogs.AddTypeToPriorityListDialog;
+import org.apache.uima.taeconfigurator.wizards.TypePrioritiesNewWizard;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.window.Window;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Tree;
+import org.eclipse.swt.widgets.TreeItem;
+import org.eclipse.ui.forms.IManagedForm;
+
+public class PriorityListSection extends AbstractSection {
+
+  public static final String PRIORITY_LIST = "<Priority List>";
+
+  private Tree tree;
+
+  private Button addSetButton;
+
+  private Button addButton;
+
+  private Button removeButton;
+
+  private Button upButton;
+
+  private Button downButton;
+
+  private TypePriorityImportSection typePriorityImportSection;
+
+  private Button exportButton;
+
+  public PriorityListSection(MultiPageEditor editor, Composite parent) {
+    super(editor, parent, "Priority Lists", "This section shows the defined Prioirity Lists");
+  }
+
+  public void initialize(IManagedForm form) {
+    super.initialize(form);
+
+    Composite sectionClient = new2ColumnComposite(getSection());
+    enableBorders(sectionClient);
+
+    tree = newTree(sectionClient);
+
+    final Composite buttonContainer = newButtonContainer(sectionClient);
+    addSetButton = newPushButton(buttonContainer, "Add Set",
+            "Click here to add another priority list.");
+    addButton = newPushButton(buttonContainer, S_ADD, "Click here to add a type");
+    removeButton = newPushButton(buttonContainer, S_REMOVE, S_REMOVE_TIP);
+    new Button(buttonContainer, SWT.PUSH).setVisible(false); // spacer
+    upButton = newPushButton(buttonContainer, S_UP,
+            "Click here to move the selected item up in the priority order.");
+    downButton = newPushButton(buttonContainer, S_DOWN,
+            "Click here to move the selected item down in the priority order");
+    exportButton = newPushButton(buttonContainer, S_EXPORT, S_EXPORT_TIP);
+
+    toolkit.paintBordersFor(sectionClient);
+  }
+
+  /*
+   * (non-Javadoc)
+   * 
+   * @see org.eclipse.ui.forms.IFormPart#refresh()
+   */
+  public void refresh() {
+    if (null == typePriorityImportSection)
+      typePriorityImportSection = editor.getIndexesPage().getTypePriorityImportSection();
+
+    super.refresh();
+    tree.removeAll();
+
+    TypePriorities typePriorities = getTypePriorities();
+
+    if (typePriorities != null) {
+      TypePriorityList[] priorityLists = typePriorities.getPriorityLists();
+      for (int i = 0; i < priorityLists.length; i++) {
+        TreeItem item = new TreeItem(tree, SWT.NONE);
+        item.setText(PRIORITY_LIST);
+        String[] types = priorityLists[i].getTypes();
+        if (null != types) {
+          for (int j = 0; j < types.length; j++) {
+            TreeItem tItem = new TreeItem(item, SWT.NONE);
+            tItem.setText(formatName(types[j]));
+          }
+        }
+        item.setExpanded(true);
+      }
+    }
+    if (tree.getItemCount() > 0)
+      tree.setSelection(new TreeItem[] { tree.getItems()[0] });
+    enable();
+  }
+
+  public TypePriorityList getTypePriorityListFromTreeItem(TreeItem item) {
+    TypePriorityList[] typePriorityLists = getAnalysisEngineMetaData().getTypePriorities()
+            .getPriorityLists();
+    return typePriorityLists[tree.indexOf(item)];
+  }
+
+  public void handleEvent(Event event) {
+    if (event.widget == addSetButton) {
+      TypePriorityList typePriorityList = UIMAFramework.getResourceSpecifierFactory()
+              .createTypePriorityList();
+
+      TypePriorities typePriorities = getTypePriorities();
+      if (typePriorities == null) {
+        typePriorities = UIMAFramework.getResourceSpecifierFactory().createTypePriorities();
+        getAnalysisEngineMetaData().setTypePriorities(typePriorities);
+      }
+
+      getTypePriorities().addPriorityList(typePriorityList);
+
+      TreeItem item = new TreeItem(tree, SWT.NONE);
+      item.setText(PRIORITY_LIST);
+
+      tree.setSelection(new TreeItem[] { item });
+      setFileDirty();
+    } else if (event.widget == addButton) { // add type to set
+      if (editor.isTypePriorityDescriptor() && !editor.getIsContextLoaded()) {
+        Utility
+                .popMessage(
+                        "Can''t add types here",
+                        "Types cannot be added here, because there is no loaded context type system to pick the types from",
+                        MessageDialog.WARNING);
+        return;
+      }
+      TreeItem parent = tree.getSelection()[0];
+      if (null != parent.getParentItem())
+        parent = parent.getParentItem();
+      AddTypeToPriorityListDialog dialog = new AddTypeToPriorityListDialog(this,
+              editor.definedTypesWithSupers.get(), // types
+              getTypePriorityListFromTreeItem(parent).getTypes()); // types already in list
+
+      if (dialog.open() == Window.CANCEL)
+        return;
+
+      TypePriorityList typePriorityList = getTypePriorityListFromTreeItem(parent);
+
+      String[] newTypeNames = dialog.getSelectedTypeNames();
+      for (int i = 0; i < newTypeNames.length; i++) {
+        typePriorityList.addType(newTypeNames[i]);
+        TreeItem item = new TreeItem(parent, SWT.NONE);
+        item.setText(formatName(newTypeNames[i]));
+      }
+
+      setFileDirty();
+    } else if (event.widget == removeButton) {
+      TreeItem item = tree.getSelection()[0];
+      TreeItem parent = item.getParentItem();
+
+      if (null == parent) { // removing a priority set
+        if (Window.CANCEL == Utility.popOkCancel("ConfirmRemove", "ConfirmRemoveSet",
+                MessageDialog.WARNING))
+          return;
+        TypePriorityList removedTypePriorityList = getTypePriorityListFromTreeItem(item);
+        TypePriorityList[] oldPriorityLists = getAnalysisEngineMetaData().getTypePriorities()
+                .getPriorityLists();
+        TypePriorityList[] newPriorityLists = new TypePriorityList[oldPriorityLists.length - 1];
+
+        for (int i = 0, j = 0; i < oldPriorityLists.length; i++) {
+          if (oldPriorityLists[i] != removedTypePriorityList) {
+            newPriorityLists[j++] = oldPriorityLists[i];
+          }
+        }
+
+        getAnalysisEngineMetaData().getTypePriorities().setPriorityLists(newPriorityLists);
+
+      } else { // removing a type
+        if (Window.CANCEL == Utility.popOkCancel("ConfirmRemove", "ConfirmRemoveType",
+                MessageDialog.WARNING))
+          return;
+        TypePriorityList typePriorityList = getTypePriorityListFromTreeItem(parent);
+        typePriorityList.removeType(item.getText());
+      }
+
+      TreeItem previousSelection = getPreviousSelection(parent == null ? tree.getItems() : parent
+              .getItems(), item);
+      if (null != previousSelection)
+        tree.setSelection(new TreeItem[] { previousSelection });
+      item.dispose();
+      setFileDirty();
+    }
+    // only enabled for types
+    else if (event.widget == downButton || event.widget == upButton) {
+      TreeItem item = tree.getSelection()[0];
+      TreeItem parent = item.getParentItem();
+      TreeItem[] items = parent.getItems();
+      int i = getItemIndex(items, item);
+
+      TypePriorityList typePriorityList = getTypePriorityListFromTreeItem(parent);
+      String[] types = typePriorityList.getTypes();
+      String temp = types[i];
+      if (event.widget == downButton) {
+        types[i] = types[i + 1];
+        types[i + 1] = temp;
+        typePriorityList.setTypes(types);
+
+        new TreeItem(parent, SWT.NONE, i).setText(formatName(types[i]));
+        TreeItem t = new TreeItem(parent, SWT.NONE, i + 1);
+        t.setText(formatName(types[i + 1]));
+        tree.setSelection(new TreeItem[] { t });
+
+        items[i].dispose();
+        items[i + 1].dispose();
+      } else {
+        types[i] = types[i - 1];
+        types[i - 1] = temp;
+        typePriorityList.setTypes(types);
+
+        TreeItem t = new TreeItem(parent, SWT.NONE, i - 1);
+        t.setText(formatName(types[i - 1]));
+        tree.setSelection(new TreeItem[] { t });
+        new TreeItem(parent, SWT.NONE, i).setText(formatName(types[i]));
+
+        items[i - 1].dispose();
+        items[i].dispose();
+        setFileDirty();
+      }
+      TypePriorityList[] tpl = getTypePriorities().getPriorityLists();
+      tpl[tree.indexOf(parent)] = typePriorityList;
+      getTypePriorities().setPriorityLists(tpl);
+    } else if (event.widget == exportButton) {
+      typePriorityImportSection.exportImportablePart("<typePriorities>",
+              TypePrioritiesNewWizard.TYPEPRIORITIES_TEMPLATE);
+      refresh();
+    }
+    enable();
+  }
+
+  public void enable() {
+
+    if (tree.getSelectionCount() == 1) {
+      addButton.setEnabled(true);
+      TreeItem item = tree.getSelection()[0];
+      removeButton.setEnabled(true);
+      if (null != item.getParentItem()) {
+        TreeItem[] items = item.getParentItem().getItems();
+        int i = getItemIndex(items, item);
+        upButton.setEnabled(i > 0);
+        downButton.setEnabled(i < (items.length - 1));
+      }
+    } else {
+      addButton.setEnabled(false);
+      removeButton.setEnabled(false);
+      upButton.setEnabled(false);
+      downButton.setEnabled(false);
+    }
+    exportButton.setEnabled(tree.getItemCount() > 0);
+  }
+}
diff --git a/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/ResourceDependencySection.java b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/ResourceDependencySection.java
new file mode 100644
index 0000000..76f659e
--- /dev/null
+++ b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/ResourceDependencySection.java
@@ -0,0 +1,357 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS 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.taeconfigurator.editors.ui;
+
+import java.text.MessageFormat;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.apache.uima.analysis_engine.AnalysisEngineDescription;
+import org.apache.uima.analysis_engine.metadata.FlowControllerDeclaration;
+import org.apache.uima.resource.ExternalResourceDependency;
+import org.apache.uima.resource.ResourceCreationSpecifier;
+import org.apache.uima.resource.ResourceSpecifier;
+import org.apache.uima.resource.impl.ExternalResourceDependency_impl;
+import org.apache.uima.resource.metadata.ExternalResourceBinding;
+import org.apache.uima.taeconfigurator.editors.MultiPageEditor;
+import org.apache.uima.taeconfigurator.editors.ui.dialogs.AddExternalResourceDependencyDialog;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.window.Window;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.TableItem;
+import org.eclipse.ui.forms.IManagedForm;
+
+/**
+ * Declaration of primitive external resource dependencies A 4 col table: bound/unbound, keys, opt
+ * flag, and interface name
+ */
+
+public class ResourceDependencySection extends AbstractSection {
+
+  public final static int KEY_COL = 2;
+
+  public final static int OPT_COL = 1;
+
+  private final static String BOUND = "Bound";
+
+  public Table table; // accessed by inner class
+
+  private Button addButton;
+
+  private Button editButton;
+
+  private Button removeButton;
+
+  public ResourceDependencySection(MultiPageEditor editor, Composite parent) {
+    super(editor, parent, "Resource Dependencies",
+            "Primitives declare what resources they need. A primitive can only bind to one external resource.");
+  }
+
+  public void initialize(IManagedForm form) {
+    super.initialize(form);
+
+    // set up Composite to hold widgets in the section
+    Composite sectionClient = new2ColumnComposite(getSection());
+    enableBorders(sectionClient);
+
+    table = newTable(sectionClient, SWT.SINGLE | SWT.FULL_SELECTION, 50, 0);
+    table.setHeaderVisible(true);
+    newTableColumn(table).setText(BOUND);
+    newTableColumn(table).setText("Optional?");
+    newTableColumn(table).setText("Keys");
+    newTableColumn(table).setText("Interface Name");
+
+    if (isPrimitive()) {
+      final Composite buttonContainer = newButtonContainer(sectionClient);
+      addButton = newPushButton(buttonContainer, S_ADD, "Click here to add a dependency.");
+      editButton = newPushButton(buttonContainer, S_EDIT, S_EDIT_TIP);
+      removeButton = newPushButton(buttonContainer, S_REMOVE, S_REMOVE_TIP);
+    }
+
+    // in addition to normal keyup and mouse up:
+    table.addListener(SWT.MouseHover, this);
+    if (isPrimitive()) // only primitives can edit
+      table.addListener(SWT.MouseDoubleClick, this);
+
+    toolkit.paintBordersFor(sectionClient);
+  }
+
+  public void refresh() {
+    super.refresh();
+    table.getParent().setRedraw(false);
+    table.removeAll();
+    if (isPrimitive())
+      addPrimitiveToGUI("", editor.getAeDescription());
+    else { // is aggregate
+      for (Iterator it = editor.getResolvedDelegates().entrySet().iterator(); it.hasNext();) {
+        Map.Entry item = (Map.Entry) it.next();
+        addDelegateToGUI("", (String) item.getKey(), (ResourceSpecifier) item.getValue());
+      }
+      FlowControllerDeclaration fcd = editor.getResolvedFlowControllerDeclaration();
+      if (null != fcd) {
+        addDelegateToGUI("", fcd.getKey(), fcd.getSpecifier());
+      }
+    }
+    enable();
+    table.getParent().setRedraw(true);
+  }
+
+  private void addDelegateToGUI(String keys, String newKey, ResourceSpecifier o) {
+    if (o instanceof AnalysisEngineDescription) {
+      AnalysisEngineDescription aeDescription = (AnalysisEngineDescription) o;
+      if (aeDescription.isPrimitive())
+        addPrimitiveToGUI(keys + newKey + "/", aeDescription);
+      else {
+        for (Iterator it = editor.getDelegateAEdescriptions(aeDescription).entrySet().iterator(); it
+                .hasNext();) {
+          Map.Entry item = (Map.Entry) it.next();
+          addDelegateToGUI(keys + newKey + "/", (String) item.getKey(), (ResourceSpecifier) item
+                  .getValue());
+        }
+        FlowControllerDeclaration fcd = getFlowControllerDeclaration();
+        if (null != fcd) {
+          addPrimitiveToGUI(keys + fcd.getKey() + "/", ((ResourceCreationSpecifier) editor
+                  .getResolvedFlowControllerDeclaration().getSpecifier()));
+        }
+      }
+    }
+  }
+
+  private void addPrimitiveToGUI(String keys, ResourceCreationSpecifier aeDescription) {
+    ExternalResourceDependency[] xrd = aeDescription.getExternalResourceDependencies();
+    if (null != xrd) {
+      for (int i = 0; i < xrd.length; i++) {
+        addXrdToGUI(keys, xrd[i]);
+      }
+    }
+  }
+
+  private void updateXrdToGUI(TableItem item, ExternalResourceDependency xrd, String keys) {
+    String key = keys + xrd.getKey();
+    item.setText(0, isBound(key) ? BOUND : "");
+    item.setText(KEY_COL, key);
+    item.setText(OPT_COL, (xrd.isOptional()) ? "optional" : "required");
+    item.setText(3, convertNull(xrd.getInterfaceName()));
+    item.setData(xrd);
+  }
+
+  private boolean isBound(String key) {
+    ExternalResourceBinding[] xrb = editor.getResolvedExternalResourcesAndBindings()
+            .getExternalResourceBindings();
+    if (null != xrb)
+      for (int i = 0; i < xrb.length; i++) {
+        if (key.equals(xrb[i].getKey()))
+          return true;
+      }
+    return false;
+  }
+
+  private void propagateKeyChange(String newKey, String oldKey) {
+    ExternalResourceBinding[] xrb = getExternalResourceBindings();
+    if (null != xrb)
+      for (int i = 0; i < xrb.length; i++) {
+        if (oldKey.equals(xrb[i].getKey())) {
+          xrb[i].setKey(newKey);
+          editor.getResourcesPage().getResourceBindingsSection().markStale();
+          return; // only 1 binding at most
+        }
+      }
+  }
+
+  /**
+   * 
+   * @param keys
+   *          either "" or key/key/
+   * @param xrd
+   */
+  private void addXrdToGUI(String keys, ExternalResourceDependency xrd) {
+    TableItem item = new TableItem(table, SWT.NONE);
+    updateXrdToGUI(item, xrd, keys);
+  }
+
+  /*
+   * (non-Javadoc)
+   * 
+   * @see org.eclipse.swt.widgets.Listener#handleEvent(org.eclipse.swt.widgets.Event)
+   */
+  public void handleEvent(Event event) {
+    if (event.widget == addButton) {
+      handleAdd();
+    } else if (event.widget == removeButton
+            || (event.type == SWT.KeyUp && event.character == SWT.DEL)) {
+      handleRemove();
+    } else if (event.widget == editButton || event.type == SWT.MouseDoubleClick) {
+      handleEdit();
+    }
+    // else if (event.type == SWT.MouseDown && event.button == 3) {
+    // handleTableContextMenuRequest(event);
+    // }
+    else if (event.type == SWT.MouseHover) {
+      handleTableHoverHelp(event);
+    } else if (event.type == SWT.Selection) {
+      editor.getResourcesPage().getResourceBindingsSection().enable();
+    }
+    enable();
+  }
+
+  public ExternalResourceDependency getXRDependencyFromTableItem(TableItem item) {
+    return (ExternalResourceDependency) item.getData();
+  }
+
+  // *****************************************************
+  // * When hovering over an item in the table, show the
+  // * description
+  // *****************************************************
+  private void handleTableHoverHelp(Event event) {
+    TableItem item = table.getItem(new Point(event.x, event.y));
+    if (null != item) {
+      ExternalResourceDependency xrd = getXRDependencyFromTableItem(item);
+      setToolTipText(table, xrd.getDescription());
+    } else {
+      table.setToolTipText(""); // not needed? - tool tip goes away by itself
+    }
+  }
+
+  private void handleEdit() {
+    TableItem item = table.getSelection()[0];
+    ExternalResourceDependency xrd = getXRDependencyFromTableItem(item);
+    AddExternalResourceDependencyDialog dialog = new AddExternalResourceDependencyDialog(this, xrd);
+    if (dialog.open() == Window.CANCEL)
+      return;
+
+    alterExistingExternalResourceDependency(xrd, dialog);
+    updateXrdToGUI(item, xrd, "");
+  }
+
+  private void finishAction() {
+    packChangingColumns();
+    setFileDirty();
+  }
+
+  private void packChangingColumns() {
+    table.getColumn(KEY_COL).pack();
+    table.getColumn(3).pack();
+  }
+
+  private void handleRemove() {
+    TableItem item = table.getSelection()[0];
+    editor.getAeDescription().setExternalResourceDependencies(
+            (ExternalResourceDependency[]) Utility.removeElementFromArray(
+                    getExternalResourceDependencies(), getXRDependencyFromTableItem(item),
+                    ExternalResourceDependency.class));
+
+    table.setSelection(table.getSelectionIndices()[0] - 1);
+    item.dispose();
+    finishAction();
+  }
+
+  /**
+   * add a external resource dependency to the model
+   * 
+   */
+  private void handleAdd() {
+    AddExternalResourceDependencyDialog dialog = new AddExternalResourceDependencyDialog(this);
+
+    if (dialog.open() == Window.CANCEL)
+      return;
+
+    ExternalResourceDependency xrd = addNewExternalResourceDependency(dialog);
+    addXrdToGUI("", xrd);
+  }
+
+  private void alterExistingExternalResourceDependency(ExternalResourceDependency xrd,
+          AddExternalResourceDependencyDialog dialog) {
+    valueChanged = false;
+    String oldKey = xrd.getKey();
+    xrd.setKey(setValueChanged(dialog.keyName, xrd.getKey()));
+    if (valueChanged)
+      propagateKeyChange(dialog.keyName, oldKey);
+    xrd.setDescription(setValueChanged(multiLineFix(dialog.description), xrd.getDescription()));
+    xrd.setInterfaceName(setValueChanged(dialog.interfaceName, xrd.getInterfaceName()));
+    if (dialog.optional != xrd.isOptional()) {
+      xrd.setOptional(dialog.optional);
+      valueChanged = true;
+    }
+    if (valueChanged)
+      finishAction();
+  }
+
+  private ExternalResourceDependency addNewExternalResourceDependency(
+          AddExternalResourceDependencyDialog dialog) {
+    ExternalResourceDependency[] xrds = getExternalResourceDependencies();
+
+    ExternalResourceDependency xrd = new ExternalResourceDependency_impl();
+    alterExistingExternalResourceDependency(xrd, dialog);
+
+    if (null == xrds)
+      editor.getAeDescription().setExternalResourceDependencies(
+              new ExternalResourceDependency[] { xrd });
+    else {
+      ExternalResourceDependency[] newXrds = new ExternalResourceDependency[xrds.length + 1];
+      System.arraycopy(xrds, 0, newXrds, 0, xrds.length);
+      newXrds[newXrds.length - 1] = xrd;
+      editor.getAeDescription().setExternalResourceDependencies(newXrds);
+    }
+    return xrd;
+  }
+
+  /*
+   * (non-Javadoc)
+   * 
+   * @see org.apache.uima.taeconfigurator.editors.ui.AbstractSection#enable()
+   */
+  public void enable() {
+    packTable(table);
+    if (isPrimitive()) {
+      addButton.setEnabled(true);
+      editButton.setEnabled(table.getSelectionCount() == 1);
+      removeButton.setEnabled(table.getSelectionCount() > 0);
+    }
+  }
+
+  public boolean keyNameAlreadyDefined(String key) {
+    ExternalResourceDependency[] xrds = getExternalResourceDependencies();
+    if (null != xrds) {
+      for (int i = 0; i < xrds.length; i++) {
+        if (key.equals(xrds[i].getKey())) {
+          Utility
+                  .popMessage(
+                          "Key Already Defined",
+                          MessageFormat
+                                  .format(
+                                          "The key name you specified, ''{0}'', is already defined.  Please pick a different key name.",
+                                          new String[] { key }), MessageDialog.ERROR);
+          return true;
+        }
+
+      }
+    }
+    return false;
+  }
+
+  public Table getTable() {
+    return table;
+  }
+}
diff --git a/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/ResourcesPage.java b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/ResourcesPage.java
new file mode 100644
index 0000000..2606233
--- /dev/null
+++ b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/ResourcesPage.java
@@ -0,0 +1,73 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.uima.taeconfigurator.editors.ui;
+
+import org.apache.uima.taeconfigurator.editors.Form2Panel;
+import org.apache.uima.taeconfigurator.editors.MultiPageEditor;
+import org.eclipse.ui.forms.IManagedForm;
+
+public class ResourcesPage extends HeaderPageWithSash {
+
+  private ResourceDependencySection resourceDependencySection;
+
+  // private ExternalResourceSection externalResourceSection;
+  private ExtnlResBindSection extnlResBindSection;
+
+  private ImportResBindSection resBindImportSection;
+
+  public ResourcesPage(MultiPageEditor editor) {
+    super(editor, "Resource Definitions and Bindings");
+  }
+
+  /**
+   * Called by the framework to fill in the contents
+   */
+  protected void createFormContent(IManagedForm managedForm) {
+
+    // Only primitive engines can declare Resource Dependencies
+    // Both Primitive and aggregates can delcare External Resources and their bindings
+    // Bindings always refer to a primitive, if needed via
+    // annotatorkey / key / key ... / declaredDependencyName
+    // Bindings for same dependencyName at multiple levels:
+    // outer ones override inner ones.
+
+    managedForm.getForm().setText("Resources");
+    Form2Panel form2panel = setup2ColumnLayout(managedForm, 50, 50);
+
+    managedForm.addPart(extnlResBindSection = new ExtnlResBindSection(editor, form2panel.left));
+    managedForm.addPart(resBindImportSection = new ImportResBindSection(editor, form2panel.left));
+    managedForm.addPart(resourceDependencySection = new ResourceDependencySection(editor,
+            form2panel.right));
+    createToolBarActions(managedForm);
+  }
+
+  public ResourceDependencySection getResourceDependencySection() {
+    return resourceDependencySection;
+  }
+
+  public ExtnlResBindSection getResourceBindingsSection() {
+    return extnlResBindSection;
+  }
+
+  public ImportResBindSection getResBindImportSection() {
+    return resBindImportSection;
+  }
+
+}
diff --git a/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/SettingsPage.java b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/SettingsPage.java
new file mode 100644
index 0000000..d73093b
--- /dev/null
+++ b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/SettingsPage.java
@@ -0,0 +1,64 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.uima.taeconfigurator.editors.ui;
+
+import org.apache.uima.taeconfigurator.editors.Form2Panel;
+import org.apache.uima.taeconfigurator.editors.MultiPageEditor;
+import org.eclipse.ui.forms.IManagedForm;
+
+public class SettingsPage extends HeaderPageWithSash {
+
+  private ParameterSettingsSection parameterSettingsSection;
+
+  private ValueSection valueSection;
+
+  public SettingsPage(MultiPageEditor editor) {
+    super(editor, "Parameter Value Settings");
+  }
+
+  /**
+   * Called by the framework to fill in the contents
+   */
+  protected void createFormContent(IManagedForm managedForm) {
+
+    final Form2Panel form2Panel = setup2ColumnLayout(managedForm, EQUAL_WIDTH);
+
+    managedForm.getForm().setText("Parameter Settings");
+    managedForm.addPart(parameterSettingsSection = new ParameterSettingsSection(editor,
+            form2Panel.left));
+    managedForm.addPart(valueSection = new ValueSection(editor, form2Panel.right));
+    createToolBarActions(managedForm);
+  }
+
+  /**
+   * @return
+   */
+  public ParameterSettingsSection getParameterSettingsSection() {
+    return parameterSettingsSection;
+  }
+
+  /**
+   * @return
+   */
+  public ValueSection getValueSection() {
+    return valueSection;
+  }
+
+}
diff --git a/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/SofaMapSection.java b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/SofaMapSection.java
new file mode 100644
index 0000000..3a97d7f
--- /dev/null
+++ b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/SofaMapSection.java
@@ -0,0 +1,522 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS 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.taeconfigurator.editors.ui;
+
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeMap;
+import java.util.TreeSet;
+
+import org.apache.uima.UIMAFramework;
+import org.apache.uima.analysis_engine.AnalysisEngineDescription;
+import org.apache.uima.analysis_engine.metadata.FlowControllerDeclaration;
+import org.apache.uima.analysis_engine.metadata.SofaMapping;
+import org.apache.uima.collection.CasConsumerDescription;
+import org.apache.uima.flow.FlowControllerDescription;
+import org.apache.uima.resource.ResourceCreationSpecifier;
+import org.apache.uima.resource.ResourceSpecifier;
+import org.apache.uima.taeconfigurator.editors.MultiPageEditor;
+import org.apache.uima.taeconfigurator.editors.ui.dialogs.EditSofaBindingsDialog;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.window.Window;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Tree;
+import org.eclipse.swt.widgets.TreeItem;
+import org.eclipse.ui.forms.IManagedForm;
+
+public class SofaMapSection extends AbstractSection {
+
+  private Composite sectionClient;
+
+  private Button addButton;
+
+  private Button editButton;
+
+  private Button removeButton;
+
+  private Tree tree;
+
+  private static final String INPUTS = "Inputs";
+
+  private static final String OUTPUTS = "Outputs";
+
+  private static final boolean INPUT = true;
+
+  private static final boolean OUTPUT = false;
+
+  private static final String titleMsg = "This section shows all defined Sofas for an Aggregate and their mappings to the component Sofas.\n"
+          + "Add Aggregate Sofa Names using the Capabilities section; Select an Aggregate Sofa Name and Add/Edit mappings for that Sofa in this section.\n";
+
+  public SofaMapSection(MultiPageEditor aEditor, Composite parent) {
+    super(aEditor, parent, "Sofa Mappings (Only used in aggregate Descriptors)", titleMsg);
+  }
+
+  /*
+   * Called by the page constructor after all sections are created, to initialize them.
+   * (non-Javadoc)
+   * 
+   * @see org.eclipse.ui.forms.IFormPart#initialize(org.eclipse.ui.forms.IManagedForm)
+   */
+  public void initialize(IManagedForm form) {
+
+    super.initialize(form);
+    sectionClient = new2ColumnComposite(getSection());
+
+    tree = newTree(sectionClient);
+    Composite buttonContainer = newButtonContainer(sectionClient);
+    addButton = newPushButton(buttonContainer, S_ADD, "Click here to add a component Sofa binding.");
+    editButton = newPushButton(buttonContainer, S_EDIT, S_EDIT_TIP);
+    removeButton = newPushButton(buttonContainer, S_REMOVE, S_REMOVE_TIP);
+
+    tree.addListener(SWT.MouseDoubleClick, this); // edit gesture
+
+    enableBorders(sectionClient);
+    toolkit.paintBordersFor(sectionClient);
+    if (!isAggregate())
+      getSection().setExpanded(false);
+  }
+
+  /*
+   * (non-Javadoc)
+   * 
+   * @see org.eclipse.ui.forms.IFormPart#refresh()
+   */
+  public void refresh() {
+    super.refresh();
+    tree.removeAll();
+    if (!isAggregate()) {
+      getSection().setText("Sofa Mappings (Only used in aggregate Descriptors)");
+      getSection().setDescription("This part is only used for Aggregate Descriptors");
+      getSection().setExpanded(false);
+    } else {
+      getSection().setDescription(titleMsg);
+
+      String[][] sns = getCapabilitySofaNames();
+      String[] inputSofaNames = sns[0];
+      String[] outputSofaNames = sns[1];
+      // getAggrSofas the names declared in the capability
+      // plus any undeclared names in the mappings
+      // sorted... alphabetically
+      String[] inputAggrSofas = getAggrSofas(inputSofaNames, outputSofaNames);
+
+      fillMap(inputAggrSofas, INPUT);
+      fillMap(outputSofaNames, OUTPUT);
+      tree.setSelection(new TreeItem[] { tree.getItems()[0] });
+
+      if (0 == (inputAggrSofas.length + outputSofaNames.length)) {
+        getSection().setText("Sofa Mappings (No Sofas are defined)");
+        getSection().setExpanded(false);
+      } else {
+        getSection().setText("Sofa Mappings");
+        getSection().setExpanded(true);
+      }
+
+    }
+    enable();
+  }
+
+  private String[] getAggrSofas(String[] inputCapabilityNames, String[] outputCapabilityNames) {
+    SofaMapping[] allMappings = getSofaMappings();
+    Set names = new TreeSet();
+    Set undeclaredNames = new TreeSet();
+    if (null != inputCapabilityNames)
+      for (int i = 0; i < inputCapabilityNames.length; i++)
+        names.add(inputCapabilityNames[i]);
+    if (null != allMappings) {
+      for (int i = 0; i < allMappings.length; i++) {
+        String sofaName = allMappings[i].getAggregateSofaName();
+        if (0 > Arrays.binarySearch(inputCapabilityNames, sofaName)
+                && 0 > Arrays.binarySearch(outputCapabilityNames, sofaName))
+          undeclaredNames.add(sofaName);
+      }
+    }
+
+    // It is an error to have a mapping without having the aggregate name
+    // declared as either an input our output. If the name is not
+    // declared, (silently) consider it to have been an input.
+    if (undeclaredNames.size() > 0)
+      names.addAll(undeclaredNames);
+
+    return (String[]) names.toArray(stringArray0);
+  }
+
+  private void fillMap(String[] aggrKeys, boolean isInput) {
+
+    TreeItem d = new TreeItem(tree, SWT.NONE);
+    d.setText(isInput ? INPUTS : OUTPUTS);
+    for (int i = 0; i < aggrKeys.length; i++) {
+      TreeItem a = new TreeItem(d, SWT.NONE);
+      a.setText(aggrKeys[i]);
+      fillBindings(a, aggrKeys[i]);
+      a.setExpanded(true);
+    }
+    d.setExpanded(true);
+  }
+
+  private void fillBindings(TreeItem parent, String aggrSofa) {
+    // bindings are a string of key-name / sofa-name or "<default>"
+    String[] bindings = getSofaBindingsForAggrSofa(aggrSofa);
+    for (int j = 0; j < bindings.length; j++) {
+      TreeItem b = new TreeItem(parent, SWT.NONE);
+      b.setText(bindings[j]);
+    }
+  }
+
+  private String[] getSofaBindingsForAggrSofa(String aggrSofa) {
+    SofaMapping[] sofaMappings = getSofaMappings();
+    if (null == sofaMappings)
+      return stringArray0;
+    Set bindings = new TreeSet();
+    for (int i = 0; i < sofaMappings.length; i++) {
+      SofaMapping sofaMapping = sofaMappings[i];
+      if (sofaMapping.getAggregateSofaName().equals(aggrSofa))
+        if (null != sofaMapping.getComponentSofaName()
+                && !"".equals(sofaMapping.getComponentSofaName()))
+          bindings.add(sofaMapping.getComponentKey() + '/' + sofaMapping.getComponentSofaName());
+        else
+          bindings.add(sofaMapping.getComponentKey());
+    }
+    String[] results = (String[]) bindings.toArray(stringArray0);
+    Arrays.sort(results);
+    return results;
+  }
+
+  /*
+   * (non-Javadoc)
+   * 
+   * @see org.eclipse.swt.widgets.Listener#handleEvent(org.eclipse.swt.widgets.Event)
+   */
+  public void handleEvent(Event event) {
+    // Note: to add aggrSofa names, use capabilitySection.
+    // Updates there are propagated here.
+
+    // only enabled when one existing AggrSofa
+    // or its child is selected
+    if (event.widget == editButton || event.type == SWT.MouseDoubleClick) {
+      if (!editButton.getEnabled())
+        return;
+      // Edit a map: a new aggr capability + a delegate sofa, or
+      // a delegate sofa to an existing map.
+      TreeItem selected = tree.getSelection()[0];
+      TreeItem parent = selected.getParentItem();
+      if (null != parent.getParentItem()) {
+        selected = parent;
+      }
+      editAggrMap(selected);
+    } else if (event.widget == addButton) {
+      // Add one or more new mappings
+      TreeItem selected = tree.getSelection()[0];
+      TreeItem parent = selected.getParentItem();
+      if (null != parent.getParentItem()) {
+        selected = parent;
+      }
+      addAggrMap(selected);
+    } else if (event.widget == removeButton) {
+      // only enabled for aggr or component
+      TreeItem selected = tree.getSelection()[0];
+      TreeItem parent = selected.getParentItem();
+      if (null == parent.getParentItem())
+        removeAggr(selected);
+      else
+        removeComponentFromAggr(selected);
+    }
+    enable();
+  }
+
+  private static final boolean AVAIL_ONLY = true;
+
+  private void editAggrMap(TreeItem selected) {
+    // pop up window: shows all available component mappings
+    // plus current mappings for this aggrSofa
+    // Available: a) not mapped
+    // User selects mappings to update
+    // update model: add (multiple) mappings
+    // Remove all under item
+    // update model.
+    String aggrSofa = selected.getText();
+    Map availAndBoundSofas = getAvailAndBoundSofas(aggrSofa, !AVAIL_ONLY);
+    if (availAndBoundSofas.size() == 0) {
+      Utility
+              .popMessage(
+                      "No available sofas",
+                      "Because there are no sofas in the delegates that are not already bound, no sofa mapping can be created.",
+                      MessageDialog.WARNING);
+      return;
+    }
+
+    EditSofaBindingsDialog dialog = new EditSofaBindingsDialog(this, aggrSofa, availAndBoundSofas);
+    if (dialog.open() == Window.CANCEL)
+      return;
+    removeAggr(aggrSofa);
+    addAggr(aggrSofa, dialog.selectedSofaNames);
+    removeChildren(selected);
+    fillBindings(selected, aggrSofa);
+    selected.setExpanded(true);
+    setFileDirty();
+  }
+
+  private void addAggrMap(TreeItem selected) {
+    // pop up window: shows all available component mappings
+    // minus current mappings for this aggrSofa
+    // Available: a) not mapped,
+    // User selects mappings to add
+    String aggrSofa = selected.getText();
+    Map availAndBoundSofas = getAvailAndBoundSofas(aggrSofa, AVAIL_ONLY);
+    if (availAndBoundSofas.size() == 0) {
+      Utility
+              .popMessage(
+                      "No available sofas",
+                      "Because there are no sofas in the delegates that are not already bound, no sofa mapping can be created.",
+                      MessageDialog.WARNING);
+      return;
+    }
+
+    EditSofaBindingsDialog dialog = new EditSofaBindingsDialog(this, aggrSofa, availAndBoundSofas);
+    if (dialog.open() == Window.CANCEL)
+      return;
+    addAggr(aggrSofa, dialog.selectedSofaNames);
+    removeChildren(selected);
+    fillBindings(selected, aggrSofa);
+    selected.setExpanded(true);
+    setFileDirty();
+  }
+
+  private void addSofasToAllComponentSofaMap(Map allComponentSofas, String key,
+          ResourceSpecifier delegate, boolean isInput) {
+    // delegates can be AnalysisEngines, CasConsmers, flowControllers, or remotes
+    if (delegate instanceof AnalysisEngineDescription || delegate instanceof CasConsumerDescription
+            || delegate instanceof FlowControllerDescription) {
+      Set[] inAndOut = getCapabilitySofaNames((ResourceCreationSpecifier) delegate, key);
+      Set inOut = inAndOut[isInput ? 0 : 1];
+      if (!isInput) { // Aggr "output" can be mapped to delegate "input"
+        inOut.addAll(inAndOut[0]);
+      }
+      if (inOut.size() == 0) {
+        // no sofas defined in this delegate
+        // create default sofa
+        allComponentSofas.put(key, null);
+      }
+      for (Iterator i2 = inOut.iterator(); i2.hasNext();) {
+        allComponentSofas.put(i2.next(), null);
+      }
+    }
+  }
+
+  /**
+   * 
+   * @param aggrSofa
+   * @return a Map, keys = component/sofaname, value = aggrsofa or null
+   */
+  private Map getAvailAndBoundSofas(String aggrSofa, boolean availOnly) {
+    boolean isInput = isInput(aggrSofa);
+    Map allComponentSofas = new TreeMap(); // key = component/sofa, value = AggrSofa bound to
+
+    // put all delegate component/sofa items in a Map
+    for (Iterator it = editor.getResolvedDelegates().entrySet().iterator(); it.hasNext();) {
+      Map.Entry entry = (Map.Entry) it.next();
+      addSofasToAllComponentSofaMap(allComponentSofas, (String) entry.getKey(),
+              (ResourceSpecifier) entry.getValue(), isInput);
+    }
+    // pick up any sofa info from flow controller
+    FlowControllerDeclaration fcd = editor.getResolvedFlowControllerDeclaration();
+    if (null != fcd) {
+      addSofasToAllComponentSofaMap(allComponentSofas, fcd.getKey(), fcd.getSpecifier(), isInput);
+    }
+
+    // mark the bound ones with a value which is the aggr sofa they're bound to
+    // also, add any that were not spec'd in the delegates (because
+    // for instance, they were remote)
+    SofaMapping[] sofaMappings = getSofaMappings();
+    for (int i = 0; i < sofaMappings.length; i++) {
+      SofaMapping sm = sofaMappings[i];
+      String key = sm.getComponentKey();
+      if (null != sm.getComponentSofaName())
+        key = key + '/' + sm.getComponentSofaName();
+      if (availOnly)
+        allComponentSofas.remove(key);
+      else
+        allComponentSofas.put(key, sm.getAggregateSofaName());
+    }
+
+    // remove all that are bound to other Aggr sofa names
+    // because although an Aggr sofa can be bound to many delegate sofas,
+    // a delegate sofa can only be bound to one aggr one.
+
+    for (Iterator i3 = allComponentSofas.entrySet().iterator(); i3.hasNext();) {
+      Map.Entry entry = (Map.Entry) i3.next();
+      String boundAggrSofa = (String) entry.getValue();
+      if (null != boundAggrSofa && !boundAggrSofa.equals(aggrSofa))
+        i3.remove();
+    }
+
+    return allComponentSofas;
+  }
+
+  private boolean isInput(String sofaName) {
+    String[][] sns = getCapabilitySofaNames();
+    for (int i = 0; i < sns[0].length; i++) {
+      if (sofaName.equals(sns[0][i]))
+        return true;
+    }
+    return false;
+  }
+
+  private void addAggr(String aggrSofa, String[] sofaNames) {
+    SofaMapping[] newSofas = new SofaMapping[sofaNames.length];
+    for (int i = 0; i < sofaNames.length; i++) {
+      newSofas[i] = UIMAFramework.getResourceSpecifierFactory().createSofaMapping();
+      newSofas[i].setAggregateSofaName(aggrSofa);
+      newSofas[i].setComponentKey(getComponentOnly(sofaNames[i]));
+      newSofas[i].setComponentSofaName(getSofaOnly(sofaNames[i]));
+    }
+    SofaMapping[] oldSofas = getSofaMappings();
+    SofaMapping[] result = new SofaMapping[oldSofas.length + newSofas.length];
+    System.arraycopy(oldSofas, 0, result, 0, oldSofas.length);
+    System.arraycopy(newSofas, 0, result, oldSofas.length, newSofas.length);
+    editor.getAeDescription().setSofaMappings(result);
+  }
+
+  private void removeAggr(String aggrSofa) {
+    Comparator comparator = new Comparator() {
+      public int compare(Object aggrSofaName, Object o2) {
+        SofaMapping sofaMapping = (SofaMapping) o2;
+        if (sofaMapping.getAggregateSofaName().equals(aggrSofaName))
+          return 0;
+        else
+          return -1;
+      }
+    };
+    editor.getAeDescription().setSofaMappings(
+            (SofaMapping[]) Utility.removeElementsFromArray(getSofaMappings(), aggrSofa,
+                    SofaMapping.class, comparator));
+  }
+
+  private void removeAggr(TreeItem selected) {
+    if (Window.CANCEL == Utility
+            .popOkCancel(
+                    "Confirm delete of sofa mappings",
+                    "Please confirm deletion of all sofa mappings for this Aggregate Sofa name.  Note this will not delete the Sofa name.  To do that, remove the name from the Component Capabilities panel (the other panel on this page).",
+                    MessageDialog.WARNING))
+      return;
+    removeAggr(selected.getText());
+    removeChildren(selected);
+    setFileDirty();
+  }
+
+  /**
+   * Removes a delegate map from a particular aggr sofa mapping.
+   * 
+   * @param selected
+   */
+  private void removeComponentFromAggr(TreeItem selected) {
+    final String aggrName = selected.getParentItem().getText();
+    Comparator comparator = new Comparator() {
+      public int compare(Object componentAndSofa, Object o2) {
+        SofaMapping sofaMapping = (SofaMapping) o2;
+        if (!sofaMapping.getAggregateSofaName().equals(aggrName))
+          return -1;
+        String component = getComponentOnly((String) componentAndSofa);
+        if (!sofaMapping.getComponentKey().equals(component))
+          return -1;
+        String sofa = getSofaOnly((String) componentAndSofa);
+        if (null == sofa || sofa.equals(""))
+          if (null == sofaMapping.getComponentSofaName()
+                  || "".equals(sofaMapping.getComponentSofaName()))
+            return 0;
+          else
+            return -1;
+        else if (sofa.equals(sofaMapping.getComponentSofaName()))
+          return 0;
+        else
+          return -1;
+      }
+    };
+
+    editor.getAeDescription().setSofaMappings(
+            (SofaMapping[]) Utility.removeElementsFromArray(getSofaMappings(), selected.getText(),
+                    SofaMapping.class, comparator));
+    selected.dispose();
+    setFileDirty();
+  }
+
+  /**
+   * Called when removing a delegate from the aggr. Removes from the sofaMappings, any and all
+   * mappings associated with the delegate.
+   * 
+   * @param componentSofa
+   */
+  public static void removeSofaMappings(String componentKey, ResourceSpecifier delegate,
+          MultiPageEditor pEditor) {
+    if (delegate instanceof AnalysisEngineDescription || delegate instanceof CasConsumerDescription) {
+      Set[] inOut = getCapabilitySofaNames((ResourceCreationSpecifier) delegate, componentKey);
+      inOut[0].addAll(inOut[1]);
+      final Set allDelegateComponentSofas = inOut[0];
+      Comparator comparator = new Comparator() {
+        public int compare(Object ignore, Object elementOfArray) {
+          SofaMapping sofaMapping = (SofaMapping) elementOfArray;
+          String key = sofaMapping.getComponentKey();
+          if (null != sofaMapping.getComponentSofaName())
+            key = key + '/' + sofaMapping.getComponentSofaName();
+          if (allDelegateComponentSofas.contains(key)) {
+            return 0;
+          }
+          return -1;
+        }
+      };
+
+      pEditor.getAeDescription().setSofaMappings(
+              (SofaMapping[]) Utility.removeElementsFromArray(getSofaMappings(pEditor), null,
+                      SofaMapping.class, comparator));
+    }
+  }
+
+  private String getSofaOnly(String componentAndSofa) {
+    int locOfSlash = componentAndSofa.indexOf('/');
+    if (locOfSlash < 0)
+      return null;
+    return componentAndSofa.substring(locOfSlash + 1);
+  }
+
+  private String getComponentOnly(String componentAndSofa) {
+    int locOfSlash = componentAndSofa.indexOf('/');
+    if (locOfSlash < 0)
+      return componentAndSofa;
+    return componentAndSofa.substring(0, locOfSlash);
+  }
+
+  public void enable() {
+    boolean oneSelected = tree.getSelectionCount() == 1;
+    boolean topLevelSelected = false;
+    if (oneSelected) {
+      TreeItem selected = tree.getSelection()[0];
+      topLevelSelected = (null == selected.getParentItem());
+    }
+    addButton.setEnabled(oneSelected && !topLevelSelected);
+    editButton.setEnabled(oneSelected && !topLevelSelected);
+    removeButton.setEnabled(oneSelected && !topLevelSelected);
+  }
+
+}
diff --git a/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/TypeImportSection.java b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/TypeImportSection.java
new file mode 100644
index 0000000..be17e91
--- /dev/null
+++ b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/TypeImportSection.java
@@ -0,0 +1,126 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS 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.taeconfigurator.editors.ui;
+
+import java.io.IOException;
+
+import org.apache.uima.UIMAFramework;
+import org.apache.uima.cas.CAS;
+import org.apache.uima.resource.ResourceInitializationException;
+import org.apache.uima.resource.metadata.Import;
+import org.apache.uima.resource.metadata.TypeSystemDescription;
+import org.apache.uima.taeconfigurator.editors.MultiPageEditor;
+import org.apache.uima.util.InvalidXMLException;
+import org.apache.uima.util.XMLInputSource;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.window.Window;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ */
+public class TypeImportSection extends ImportSection {
+
+  private CAS savedCAS;
+
+  private boolean importWasRemoved;
+
+  public TypeImportSection(MultiPageEditor editor, Composite parent) {
+    super(editor, parent, "Imported Type Systems",
+            "The following type systems are included as part of this one.");
+  }
+
+  // **************************************
+  // * Code to support type import section
+  // **************************************
+
+  protected boolean isAppropriate() {
+    if (isAggregate()) {
+      getSection().setText("Not Used");
+      getSection().setDescription("Types can't be imported in an Aggregate Descriptor");
+      return false;
+    }
+    getSection().setText("Imported Type Systems");
+    getSection().setDescription("The following type systems are included as part of this one.");
+    return true;
+  }
+
+  protected String getDescriptionFromImport(String source) throws InvalidXMLException, IOException {
+    TypeSystemDescription parsedImportItem = UIMAFramework.getXMLParser()
+            .parseTypeSystemDescription(new XMLInputSource(source));
+    return parsedImportItem.getDescription();
+  }
+
+  protected Import[] getModelImportArray() {
+    return getTypeSystemDescription().getImports();
+  }
+
+  protected void setModelImportArray(Import[] imports) {
+    savedCAS = editor.getCurrentView();
+    Import[] oldImports = getTypeSystemDescription().getImports();
+    importWasRemoved = (null != oldImports) && (oldImports.length > imports.length);
+    getTypeSystemDescription().setImports(imports);
+  }
+
+  protected void clearModelBaseValue() {
+    getTypeSystemDescription().setTypes(typeDescription0);
+  }
+
+  protected boolean isValidImport(String title, String msg) {
+    TypeSystemDescription savedTSD = getMergedTypeSystemDescription();
+    TypeSystemDescription savedITSD = editor.getImportedTypeSystemDesription();
+
+    try {
+      editor.setMergedTypeSystemDescription();
+      editor.descriptorCAS.validate();
+    } catch (ResourceInitializationException e1) {
+      revertMsg(title, msg, editor.getMessagesToRootCause(e1));
+      editor.setMergedTypeSystemDescription(savedTSD);
+      editor.setImportedTypeSystemDescription(savedITSD);
+      editor.descriptorCAS.set(savedCAS);
+      return false;
+    }
+    if (importWasRemoved)
+      if (Window.CANCEL == Utility.popOkCancel("May need to remove dependencies",
+              "A type import is being removed.  If this would removed some types or features in the"
+                      + " merged type system, which are referenced in the Capabilities or Indexes "
+                      + "section, you will need to update those sections as appropriate.",
+              MessageDialog.INFORMATION)) {
+        revertMsg(title, msg, "Cancelled by user.");
+        editor.setMergedTypeSystemDescription(savedTSD);
+        editor.setImportedTypeSystemDescription(savedITSD);
+        editor.descriptorCAS.set(savedCAS);
+        return false;
+      }
+
+    return true;
+  }
+
+  /**
+   * At this point, the basic type system description is updated. and validated. Validation has
+   * updated the merged type system description, and updated the CAS.
+   */
+  protected void finishImportChangeAction() {
+
+    // at this point, the tsd validation has updated the resolved version
+    editor.getTypePage().getTypeSection().refresh();
+    editor.addDirtyTypeName("<import>");
+  }
+
+}
diff --git a/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/TypePage.java b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/TypePage.java
new file mode 100644
index 0000000..22ffa4c
--- /dev/null
+++ b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/TypePage.java
@@ -0,0 +1,56 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.uima.taeconfigurator.editors.ui;
+
+import org.apache.uima.taeconfigurator.editors.Form2Panel;
+import org.apache.uima.taeconfigurator.editors.MultiPageEditor;
+import org.eclipse.ui.forms.IManagedForm;
+
+public class TypePage extends HeaderPageWithSash {
+
+  private TypeSection typeSection;
+
+  private TypeImportSection typeImportSection;
+
+  public TypePage(MultiPageEditor editor) {
+    super(editor, "Type Definitions");
+  }
+
+  /**
+   * Called by the framework to fill in the contents
+   */
+  protected void createFormContent(IManagedForm managedForm) {
+    // always show same screen layout - user could dynamically switch
+    managedForm.getForm().setText("Type System Definition");
+    Form2Panel form2Panel = setup2ColumnLayout(managedForm, 60, 40);
+    managedForm.addPart(typeSection = new TypeSection(editor, form2Panel.left));
+    managedForm.addPart(typeImportSection = new TypeImportSection(editor, form2Panel.right));
+    createToolBarActions(managedForm);
+  }
+
+  public TypeSection getTypeSection() {
+    return typeSection;
+  }
+
+  public TypeImportSection getTypeImportSection() {
+    return typeImportSection;
+  }
+
+}
diff --git a/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/TypePriorityImportSection.java b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/TypePriorityImportSection.java
new file mode 100644
index 0000000..693a7c7
--- /dev/null
+++ b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/TypePriorityImportSection.java
@@ -0,0 +1,93 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.uima.taeconfigurator.editors.ui;
+
+import java.io.IOException;
+
+import org.apache.uima.UIMAFramework;
+import org.apache.uima.cas.CAS;
+import org.apache.uima.resource.ResourceInitializationException;
+import org.apache.uima.resource.metadata.Import;
+import org.apache.uima.resource.metadata.TypePriorities;
+import org.apache.uima.taeconfigurator.editors.MultiPageEditor;
+import org.apache.uima.util.InvalidXMLException;
+import org.apache.uima.util.XMLInputSource;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ */
+public class TypePriorityImportSection extends ImportSection {
+
+  public TypePriorityImportSection(MultiPageEditor editor, Composite parent) {
+    super(editor, parent, "Type Priority Imports",
+            "The following type priority imports are included as part of the type priorities:");
+  }
+
+  // **************************************
+  // * Code to support type import section
+  // **************************************
+  protected boolean isAppropriate() {
+    return true; // always show
+  }
+
+  /**
+   * used when hovering
+   */
+  protected String getDescriptionFromImport(String source) throws InvalidXMLException, IOException {
+    TypePriorities parsedImportItem = UIMAFramework.getXMLParser().parseTypePriorities(
+            new XMLInputSource(source));
+    return parsedImportItem.getDescription();
+  }
+
+  protected Import[] getModelImportArray() {
+    return getTypePriorities().getImports();
+  }
+
+  protected void setModelImportArray(Import[] imports) {
+    getTypePriorities().setImports(imports);
+  }
+
+  protected void clearModelBaseValue() {
+    getTypePriorities().setPriorityLists(typePriorityList0);
+  }
+
+  // indexes are checked and merged when the CAS is built
+  protected boolean isValidImport(String title, String message) {
+    CAS savedCAS = editor.getCurrentView();
+    TypePriorities savedTP = editor.getMergedTypePriorities();
+    if (null != savedTP)
+      savedTP = (TypePriorities) savedTP.clone();
+    try {
+      editor.setMergedTypePriorities();
+      editor.descriptorCAS.validate();
+    } catch (ResourceInitializationException e1) {
+      revertMsg(title, message, editor.getMessagesToRootCause(e1));
+      editor.setMergedTypePriorities(savedTP);
+      editor.descriptorCAS.set(savedCAS);
+      return false;
+    }
+    return true;
+  }
+
+  protected void finishImportChangeAction() {
+
+  }
+
+}
diff --git a/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/TypeSection.java b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/TypeSection.java
new file mode 100644
index 0000000..78f4484
--- /dev/null
+++ b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/TypeSection.java
@@ -0,0 +1,1638 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS 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.taeconfigurator.editors.ui;
+
+/*
+ * The types shown are those that are explicitly defined; in other words, built-in types are not
+ * shown, unless there is an explicit extending of some built-in type. In this case, the "merged"
+ * type system is updated to include the features from the built-in type.
+ * 
+ * Redesign 2/17/05 Two panels: This one and an "Import" panel This panel: A TreeTable with buttons
+ * Items (top level) are Types Nested 1 down: Features col 0 = Type or Feature name col 1 =
+ * SuperType or Range Name or allowed value
+ * 
+ * Hover shows Description
+ * 
+ * Types that are imported are shown in grey font color Hover shows type system they were imported
+ * from, plus description, right click to open it
+ * 
+ * Types for aggregates are "read-only". No right-click on hover - is ambiguous where type came
+ * from.
+ * 
+ * Double-click or press Edit button to edit
+ * 
+ */
+
+import java.util.ArrayList;
+import java.util.Comparator;
+import java.util.List;
+
+import org.apache.uima.analysis_engine.TypeOrFeature;
+import org.apache.uima.cas.CAS;
+import org.apache.uima.cas.Type;
+import org.apache.uima.cas.TypeSystem;
+import org.apache.uima.impl.UIMAFramework_impl;
+import org.apache.uima.resource.ResourceInitializationException;
+import org.apache.uima.resource.metadata.AllowedValue;
+import org.apache.uima.resource.metadata.Capability;
+import org.apache.uima.resource.metadata.FeatureDescription;
+import org.apache.uima.resource.metadata.FsIndexCollection;
+import org.apache.uima.resource.metadata.FsIndexDescription;
+import org.apache.uima.resource.metadata.FsIndexKeyDescription;
+import org.apache.uima.resource.metadata.TypeDescription;
+import org.apache.uima.resource.metadata.TypePriorities;
+import org.apache.uima.resource.metadata.TypePriorityList;
+import org.apache.uima.resource.metadata.TypeSystemDescription;
+import org.apache.uima.taeconfigurator.InternalErrorCDE;
+import org.apache.uima.taeconfigurator.TAEConfiguratorPlugin;
+import org.apache.uima.taeconfigurator.editors.MultiPageEditor;
+import org.apache.uima.taeconfigurator.editors.ui.dialogs.AddAllowedValueDialog;
+import org.apache.uima.taeconfigurator.editors.ui.dialogs.AddFeatureDialog;
+import org.apache.uima.taeconfigurator.editors.ui.dialogs.AddTypeDialog;
+import org.apache.uima.taeconfigurator.wizards.TypeSystemNewWizard;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.window.Window;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.TableTree;
+import org.eclipse.swt.custom.TableTreeItem;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.TableColumn;
+import org.eclipse.ui.forms.IManagedForm;
+
+public class TypeSection extends AbstractImportablePartSection {
+  public static final String CASCADE_MESSAGE = "This will cause a cascading deletion of an associated "
+          + "input, output, index, or type priority, unless this deletion exposes a "
+          + "built-in or imported type or feature of the same name.  Ok to continue?";
+
+  public static final String CASCADE_DELETE_WARNING = "Cascade Delete Warning";
+
+  public static final int NAME_COL = 0;
+
+  public static final int SUPER_COL = 1;
+
+  public static final int RANGE_COL = 1;
+
+  public static final int MULTIPLE_REF_OK_COL = 2;
+
+  public static final int ELEMENT_TYPE_COL = 3;
+
+  public static final int AV_COL = 1;
+
+  public static final String HEADER_ALLOWED_VALUE = "Allowed Value:";
+
+  private TableTree tt;
+
+  private Button addTypeButton;
+
+  private Button addButton;
+
+  private Button editButton;
+
+  private Button removeButton;
+
+  private Button jcasGenButton;
+
+  private Button exportButton;
+
+  // private TypeSystemDescription tsdLocal; // for this descriptor, no imports
+
+  private static final boolean ALLOWED = true;
+
+  public TypeSection(MultiPageEditor editor, Composite parent) {
+    super(
+            editor,
+            parent,
+            "Types (or Classes)",
+            "The following types (classes) are defined in this analysis engine descriptor.\nThe grayed out items are imported or merged from other descriptors, and cannot be edited here. (To edit them, edit their source files).");
+  }
+
+  // **********************************************************************
+  // * Called by the page constructor after all sections are created, to
+  // initialize them.
+  // * (non-Javadoc)
+  // * @see
+  // org.eclipse.ui.forms.IFormPart#initialize(org.eclipse.ui.forms.IManagedForm)
+  // **********************************************************************/
+  public void initialize(IManagedForm form) {
+    super.initialize(form);
+
+    Composite sectionClient = new2ColumnComposite(getSection());
+    enableBorders(sectionClient);
+    toolkit.paintBordersFor(sectionClient);
+
+    tt = newTableTree(sectionClient, SWT.SINGLE | SWT.FULL_SELECTION);
+    new TableColumn(tt.getTable(), SWT.NONE).setText("Type Name or Feature Name");
+    new TableColumn(tt.getTable(), SWT.NONE).setText("SuperType or Range");
+    new TableColumn(tt.getTable(), SWT.NONE).setText(" "); // space for icon
+    new TableColumn(tt.getTable(), SWT.NONE).setText("Element Type");
+    tt.getTable().setHeaderVisible(true);
+
+    tt.getTable().addListener(SWT.MouseHover, this); // to show description and more
+
+    Composite buttonContainer = newButtonContainer(sectionClient);
+    addTypeButton = newPushButton(buttonContainer, "Add Type", "Click here to add a new type.");
+    addButton = newPushButton(buttonContainer, S_ADD,
+            "Click here to add a feature or allowed-value to the selected type.");
+    editButton = newPushButton(buttonContainer, S_EDIT, S_EDIT_TIP);
+    removeButton = newPushButton(buttonContainer, S_REMOVE, S_REMOVE_TIP);
+    exportButton = newPushButton(buttonContainer, S_EXPORT, S_EXPORT_TIP);
+
+    spacer(buttonContainer);
+    jcasGenButton = newPushButton(buttonContainer, "JCasGen",
+            "Click here to run JCasGen on this type system.");
+  }
+
+  /*
+   * (non-Javadoc)
+   * 
+   * @see org.apache.uima.taeconfigurator.editors.ui.AbstractTableSection#update()
+   */
+  public void refresh() {
+    super.refresh();
+
+    tt.removeAll();
+
+    TypeSystemDescription tsdFull = getMergedTypeSystemDescription();
+
+    TypeDescription[] tdsFull = tsdFull.getTypes();
+    if (null != tdsFull) {
+      for (int i = 0; i < tdsFull.length; i++) {
+        addTypeToGUI(tdsFull[i]);
+      }
+    }
+
+    if (tt.getItemCount() > 0)
+      tt.setSelection(new TableTreeItem[] { tt.getItems()[0] });
+    packTable(tt.getTable());
+    enable();
+  }
+
+  private FeatureDescription[] setDifference(FeatureDescription[] all, FeatureDescription[] subset) {
+    if (null == all)
+      return featureDescriptionArray0;
+    if (null == subset)
+      return all;
+    List result = new ArrayList();
+
+    outer: for (int i = 0; i < all.length; i++) {
+      String name = all[i].getName();
+      for (int j = 0; j < subset.length; j++) {
+        if (subset[j].getName().equals(name))
+          continue outer;
+      }
+      result.add(all[i]);
+    }
+    return (FeatureDescription[]) result.toArray(new FeatureDescription[result.size()]);
+  }
+
+  private void addTypeToGUI(TypeDescription td) {
+    TableTreeItem item = new TableTreeItem(tt, SWT.NONE);
+    item.setText(NAME_COL, formatName(td.getName()));
+    item.setText(SUPER_COL, formatName(td.getSupertypeName()));
+    item.setData(td);
+    setItemColor(item, isLocalType(td));
+
+    FeatureDescription[] features = td.getFeatures();
+    addFeaturesToGui(td, item, features);
+
+    TypeDescription builtInTd = getBuiltInTypeDescription(td);
+    if (null != builtInTd) {
+      FeatureDescription[] additionalBuiltInFeatures = setDifference(builtInTd.getFeatures(), td
+              .getFeatures());
+      addFeaturesToGui(td, item, additionalBuiltInFeatures);
+    }
+
+    AllowedValue[] avs = td.getAllowedValues();
+    if (null != avs) {
+      for (int i = 0; i < avs.length; i++) {
+        TableTreeItem avItem = new TableTreeItem(item, SWT.NONE);
+        avItem.setText(NAME_COL, HEADER_ALLOWED_VALUE);
+        avItem.setText(AV_COL, convertNull(avs[i].getString()));
+        avItem.setData(avs[i]);
+        setItemColor(avItem, null != getLocalAllowedValue(td, avs[i]));
+      }
+    }
+    // No built-ins have "allowed values" so we don't have to add any
+    item.setExpanded(true);
+  }
+
+  private void addFeaturesToGui(TypeDescription td, TableTreeItem item,
+          FeatureDescription[] features) {
+    if (null != features) {
+      for (int i = 0; i < features.length; i++) {
+        TableTreeItem fItem = new TableTreeItem(item, SWT.NONE);
+        updateGuiFeature(fItem, features[i], td);
+      }
+    }
+  }
+
+  private void updateGuiFeature(TableTreeItem fItem, FeatureDescription fd, TypeDescription td) {
+    String rangeType;
+    fItem.setText(NAME_COL, fd.getName());
+    fItem.setText(RANGE_COL, formatName(rangeType = fd.getRangeTypeName()));
+    fItem.setData(fd);
+    setItemColor(fItem, null != getLocalFeatureDefinition(td, fd));
+    if (isArrayOrListType(rangeType)) {
+      Boolean mra = fd.getMultipleReferencesAllowed();
+      fItem.setImage(MULTIPLE_REF_OK_COL,
+              (null != mra && mra.booleanValue()) ? TAEConfiguratorPlugin
+                      .getImage(TAEConfiguratorPlugin.IMAGE_MREFOK) : TAEConfiguratorPlugin
+                      .getImage(TAEConfiguratorPlugin.IMAGE_NOMREF));
+    } else {
+      fItem.setImage(MULTIPLE_REF_OK_COL, null);
+    }
+
+    String ert = fd.getElementType();
+    fItem.setText(ELEMENT_TYPE_COL,
+            (isFSArrayOrListType(rangeType) && ert != null) ? formatName(ert) : "");
+
+  }
+
+  private void setItemColor(TableTreeItem item, boolean isLocal) {
+    if (isLocal)
+      return;
+    item.setForeground(editor.getFadeColor());
+  }
+
+  /*
+   * (non-Javadoc)
+   * 
+   * @see org.apache.uima.taeconfigurator.editors.ui.AbstractTableSection#handleEvent(org.eclipse.swt.widgets.Event)
+   */
+  public void handleEvent(Event event) {
+    if (event.widget == addTypeButton) {
+      handleAddType();
+    } else if (event.widget == addButton) {
+      TableTreeItem parent = tt.getSelection()[0];
+      if (null != parent.getParentItem())
+        parent = parent.getParentItem();
+
+      if (isSubtypeOfString(parent))
+        handleAddAllowedValue(parent);
+      else
+        handleAddFeature(parent);
+
+    } else if (event.widget == editButton) {
+      handleEdit();
+    } else if (event.type == SWT.MouseDoubleClick && (!isAggregate()) && // can't edit aggregates
+            isLocalItem(tt.getSelection()[0])) {
+      handleEdit();
+    } else if (event.widget == removeButton) {
+      handleRemove();
+    } else if (event.widget == exportButton) {
+      editor.getTypePage().getTypeImportSection().exportImportablePart("<typeSystemDescription>",
+              TypeSystemNewWizard.TYPESYSTEM_TEMPLATE);
+      refresh();
+    } else if (event.widget == jcasGenButton) {
+      editor.doJCasGenChkSrc(null);
+    } else if (event.type == SWT.MouseHover) {
+      handleHover(event);
+    }
+    enable();
+  }
+
+  public void handleHover(Event event) {
+    // next getItem call requires that table have SWT.FULL_SELECTION Style
+    TableTreeItem item = tt.getItem(new Point(event.x, event.y));
+    if (null != item) {
+      Object o = item.getData();
+      if (null == o)
+        throw new InternalErrorCDE("invalid state");
+
+      if (o instanceof TypeDescription) {
+        setToolTipText(tt, ((TypeDescription) o).getDescription());
+      } else if (o instanceof FeatureDescription) {
+        FeatureDescription fd = (FeatureDescription) o;
+        if (item.getBounds(MULTIPLE_REF_OK_COL).contains(event.x, event.y)
+                && isArrayOrListType(fd.getRangeTypeName())) {
+          Boolean mra = fd.getMultipleReferencesAllowed();
+          setToolTipText(tt, (mra != null && mra.booleanValue()) ? "Multiple References Allowed"
+                  : "Multiple References Not Allowed");
+        } else
+          setToolTipText(tt, fd.getDescription());
+      } else if (o instanceof AllowedValue) {
+        setToolTipText(tt, ((AllowedValue) o).getDescription());
+      }
+    } else
+      tt.setToolTipText("");
+  }
+
+  public TypeDescription getTypeDescriptionFromTableTreeItem(TableTreeItem item) {
+    return (TypeDescription) item.getData();
+  }
+
+  // disabled unless type having String as supertype is selected
+  public void handleAddAllowedValue(TableTreeItem parent) {
+    boolean refreshNeeded = false;
+
+    TypeDescription td = getTypeDescriptionFromTableTreeItem(parent);
+    // guaranteed non-null - otherwise can't add an allowed value
+    TypeDescription localTd = getLocalTypeDefinition(td);
+
+    AddAllowedValueDialog dialog = new AddAllowedValueDialog(this, null);
+    if (dialog.open() == Window.CANCEL) {
+      return;
+    }
+
+    AllowedValue av = UIMAFramework_impl.getResourceSpecifierFactory().createAllowedValue();
+    allowedValueUpdate(av, dialog);
+    addAllowedValue(localTd, av);
+
+    if (!Utility.arrayContains(td.getAllowedValues(), av))
+      addAllowedValue(td, (AllowedValue) av.clone());
+    else
+      refreshNeeded = true;
+
+    // update the GUI
+    if (refreshNeeded)
+      refresh();
+    else {
+      TableTreeItem item = new TableTreeItem(parent, SWT.NONE);
+      item.setText(NAME_COL, HEADER_ALLOWED_VALUE);
+      item.setText(AV_COL, convertNull(av.getString()));
+      item.setData(av);
+
+      parent.setExpanded(true);
+    }
+
+    editor.addDirtyTypeName(td.getName());
+    finishActionPack();
+  }
+
+  private void addAllowedValue(TypeDescription td, AllowedValue av) {
+    td.setAllowedValues((AllowedValue[]) Utility.addElementToArray(td.getAllowedValues(), av,
+            AllowedValue.class));
+  }
+
+  /**
+   * 
+   * @param td -
+   *          local or merged (2 callers)
+   * @param av
+   */
+  private void removeAllowedValue(TypeDescription td, AllowedValue av) {
+    td.setAllowedValues((AllowedValue[]) Utility.removeEqualElementFromArray(td.getAllowedValues(),
+            av, AllowedValue.class));
+  }
+
+  // disabled unless type is selected
+  public void handleAddFeature(TableTreeItem parent) {
+
+    TypeDescription td = getTypeDescriptionFromTableTreeItem(parent);
+    // guaranteed non-null - otherwise add button disabled
+    TypeDescription localTd = getLocalTypeDefinition(td);
+    //
+    AddFeatureDialog dialog = new AddFeatureDialog(this, td, null);
+    if (dialog.open() == Window.CANCEL) {
+      return;
+    }
+
+    FeatureDescription fd = localTd.addFeature(null, null, null);
+    featureUpdate(fd, dialog);
+
+    editor.addDirtyTypeName(td.getName());
+
+    // update the GUI
+
+    // if this type is merged with an import or with a built-in,
+    // need to "refresh"
+    if (isImportedType(td) || isBuiltInType(td)) {
+      if (!isImportedFeature(dialog.featureName, td)) {
+        // don't need to check builtin Feature because gui doesn't let you
+        // define a built-in feature again
+        fd = td.addFeature(null, null, null);
+        featureUpdate(fd, dialog);
+      }
+      refresh();
+
+      selectTypeInGui(td);
+
+      finishAction();
+    } else {
+      fd = td.addFeature(null, null, null);
+      featureUpdate(fd, dialog);
+      TableTreeItem item = new TableTreeItem(parent, SWT.NONE);
+      updateGuiFeature(item, fd, td);
+      parent.setExpanded(true);
+      finishActionPack();
+    }
+  }
+
+  private void selectTypeInGui(TypeDescription td) {
+    TableTreeItem[] items = tt.getItems();
+    for (int i = 0; i < items.length; i++) {
+      if (td.getName().equals(((TypeDescription) items[i].getData()).getName())) {
+        tt.setSelection(new TableTreeItem[] { items[i] });
+        return;
+      }
+    }
+  }
+
+  public void allowedValueUpdate(AllowedValue av, AddAllowedValueDialog dialog) {
+    valueChanged = false;
+    av.setString(setValueChanged(dialog.allowedValue, av.getString()));
+    av.setDescription(setValueChanged(dialog.description, av.getDescription()));
+  }
+
+  public void featureUpdate(FeatureDescription fd, AddFeatureDialog dialog) {
+    valueChanged = false;
+    String v = setValueChanged(dialog.featureName, fd.getName());
+    fd.setName(v);
+    v = setValueChanged(multiLineFix(dialog.description), fd.getDescription());
+    fd.setDescription(v);
+    String range = setValueChanged(dialog.featureRangeName, fd.getRangeTypeName());
+    fd.setRangeTypeName(range);
+    if (isArrayOrListType(range)) {
+      Boolean b = setValueChangedCapitalBoolean(dialog.multiRef, fd.getMultipleReferencesAllowed());
+      fd.setMultipleReferencesAllowed(b);
+      if (isFSArrayOrListType(range)) {
+        v = setValueChanged(dialog.elementRangeName, fd.getElementType());
+        fd.setElementType(v);
+      } else {
+        fd.setElementType(null);
+      }
+    } else {
+      fd.setMultipleReferencesAllowed(null);
+      fd.setElementType(null);
+    }
+  }
+
+  public void handleAddType() {
+    AddTypeDialog dialog = new AddTypeDialog(this);
+    if (dialog.open() == Window.CANCEL)
+      return;
+
+    TypeSystemDescription tsd = getMergedTypeSystemDescription();
+    TypeSystemDescription localTsd = getTypeSystemDescription();
+
+    TypeDescription td = localTsd.addType(dialog.typeName, multiLineFix(dialog.description),
+            dialog.supertypeName);
+
+    if (!isImportedType(dialog.typeName)) {
+      td = tsd.addType(dialog.typeName, multiLineFix(dialog.description), dialog.supertypeName);
+      addTypeToGUI(td);
+    } else {
+      rebuildMergedTypeSystem();
+    }
+
+    if (isImportedType(dialog.typeName) || isBuiltInType(dialog.typeName)) {
+      refresh();
+      selectTypeInGui(td);
+    }
+
+    editor.addDirtyTypeName(dialog.typeName);
+    finishActionPack();
+  }
+
+  private void finishActionPack() {
+    packTable(tt.getTable());
+    finishAction();
+  }
+
+  private void finishAction() {
+
+    if (isLocalProcessingDescriptor()) {
+      editor.getIndexesPage().markStale();
+      editor.getCapabilityPage().markStale();
+    }
+    setFileDirty();
+  }
+
+  private void handleEdit() {
+    TableTreeItem item = tt.getSelection()[0];
+    TableTreeItem parentType = item.getParentItem();
+
+    if (null == parentType) { // editing a type, not a feature
+      editType(item);
+    } else if (item.getText(NAME_COL).equals(HEADER_ALLOWED_VALUE)) {
+      editAllowedValue(item, parentType);
+    } else {
+      editFeature(item, parentType);
+    }
+  }
+
+  public FeatureDescription getFeatureDescriptionFromTableTreeItem(TableTreeItem item) {
+    return (FeatureDescription) item.getData();
+  }
+
+  private void editFeature(TableTreeItem item, TableTreeItem parent) {
+    boolean remergeNeeded = false;
+    boolean refreshNeeded = false;
+    TypeDescription td = getTypeDescriptionFromTableTreeItem(parent);
+    FeatureDescription fd = getFeatureDescriptionFromTableTreeItem(item);
+    FeatureDescription localFd = getLocalFeatureDefinition(td, fd);
+    String oldFeatureName = fd.getName();
+    AddFeatureDialog dialog = new AddFeatureDialog(this, td, fd);
+    if (dialog.open() == Window.CANCEL)
+      return;
+
+    featureUpdate(localFd, dialog);
+    if (!valueChanged)
+      return;
+
+    if (!dialog.featureName.equals(oldFeatureName)) {
+      if (isImportedFeature(oldFeatureName, td)) {
+        Utility
+                .popMessage(
+                        "Imported Feature not changed",
+                        "Changing the feature name from '"
+                                + oldFeatureName
+                                + "' to '"
+                                + dialog.featureName
+                                + "' will not affect the corresponding imported type with the previous feature name.  "
+                                + "Both features will be included in the type.",
+                        MessageDialog.INFORMATION);
+        remergeNeeded = true;
+        refreshNeeded = true;
+      }
+      if (isBuiltInFeature(oldFeatureName, td)) {
+        Utility
+                .popMessage(
+                        "BuiltIn Feature not changed",
+                        "Changing the feature name from '"
+                                + oldFeatureName
+                                + "' to '"
+                                + dialog.featureName
+                                + "' will not affect the corresponding built-in type with the previous feature name.  "
+                                + "Both features will be included in the type.",
+                        MessageDialog.INFORMATION);
+        refreshNeeded = true; // no remerge needed - builtins not merged
+      }
+    }
+    if (remergeNeeded)
+      rebuildMergedTypeSystem();
+    else
+      featureUpdate(fd, dialog);
+
+    if (refreshNeeded)
+      refresh();
+    else {
+      // update the GUI
+      updateGuiFeature(item, fd, td);
+    }
+    alterFeatureMentions(oldFeatureName, fd.getName(), td.getName());
+    editor.addDirtyTypeName(td.getName());
+    finishActionPack();
+  }
+
+  public AllowedValue getAllowedValueFromTableTreeItem(TableTreeItem item) {
+    return (AllowedValue) item.getData();
+  }
+
+  private void editAllowedValue(TableTreeItem item, TableTreeItem parent) {
+
+    TypeDescription td = getTypeDescriptionFromTableTreeItem(parent);
+    AllowedValue av = getAllowedValueFromTableTreeItem(item);
+    AllowedValue localAv = getLocalAllowedValue(td, av); // must use unmodified value of "av"
+    AddAllowedValueDialog dialog = new AddAllowedValueDialog(this, av);
+    if (dialog.open() == Window.CANCEL)
+      return;
+
+    allowedValueUpdate(av, dialog);
+    allowedValueUpdate(localAv, dialog);
+    if (!valueChanged)
+      return;
+
+    // update the GUI
+    item.setText(AV_COL, av.getString());
+
+    editor.addDirtyTypeName(td.getName());
+    finishActionPack();
+  }
+
+  /**
+   * New Feature test: return null if OK, error message otherwise
+   * 
+   * @param td
+   * @param dialog
+   * @return
+   */
+  private String newFeatureTests(TypeDescription td, AddFeatureDialog dialog) {
+    FeatureDescription fd;
+
+    if (isLocalFeature(dialog.featureName, td))
+      return "Duplicate Feature Name in this Descriptor";
+    if (isBuiltInFeature(dialog.featureName, td))
+      return "Feature Name duplicates built-in feature for this type";
+
+    if (null != (fd = getFeature(td, dialog.featureName)))
+      // verify the range is the same
+      if (!fd.getRangeTypeName().equals(dialog.featureRangeName))
+        return "Range Name not the same as the range from an imported type/feature description";
+    return null;
+  }
+
+  /**
+   * verify a new or edited feature is valid. For new features: The name must be unique locally. It
+   * may duplicate a non-local feature that isn't also built-in. (We presume built-in features are
+   * fixed). (We allow dupl non-local feature in case this type system is used without the import,
+   * in some other context?) We don't use the TCas because it isn't necessarily being updated
+   * 
+   * For edited features: If the name changed, do "new" test above on new name If the name changed,
+   * do "remove" test on old name: If used in an index or capability, but merged/built-in name not
+   * still there, warn about index being invalidated (not done here - done during feature update
+   * itself). If name used in index, and range is not indexable - error
+   * 
+   * @param dialog
+   * @return
+   */
+  public String checkFeature(AddFeatureDialog dialog, TypeDescription td, FeatureDescription oldFd) {
+    if (null == oldFd) { // adding new feature
+      return newFeatureTests(td, dialog);
+    }
+
+    String errMsg = null;
+    // modifying existing feature
+    if (!oldFd.getName().equals(dialog.featureName)) { // name changed
+      errMsg = newFeatureTests(td, dialog);
+      if (null != errMsg)
+        return errMsg;
+      return null;
+    }
+
+    // Note: this test is different from above: it tests current name, not old name
+    if (isFeatureUsedInIndex(td, dialog.featureName))
+      if (!isIndexableRange(dialog.featureRangeName))
+        return ("This feature is used in an index - it must have an indexable Range");
+    return null;
+  }
+
+  public String checkAllowedValue(AddAllowedValueDialog dialog, TypeDescription td, AllowedValue av) {
+    if (isLocalAllowedValue(dialog.allowedValue, td)) {
+      return "Duplicate Allowed Value in this Descriptor";
+    }
+    return null;
+  }
+
+  // type is always local; could be merging with import(s) or built-in
+  private void editType(TableTreeItem item) {
+
+    boolean mergeAndRefreshNeeded = false;
+    boolean refreshNeeded = false;
+    TypeDescription td = getTypeDescriptionFromTableTreeItem(item);
+    AddTypeDialog dialog = new AddTypeDialog(this, td);
+    if (dialog.open() == Window.CANCEL)
+      return;
+
+    // dialog disallows supertype specs inconsistent with existing features or allowed values
+    // dialog has already checked for dup type name
+    String newTypeName = dialog.typeName;
+    String oldTypeName = td.getName();
+    String[] typesRequiringThisOne = stringArray0;
+    if (!oldTypeName.equals(newTypeName)) {
+      typesRequiringThisOne = showTypesRequiringThisOneMessage(oldTypeName, ALLOWED);
+      if (null == typesRequiringThisOne) // null is cancel signal
+        return;
+
+      if (isImportedType(oldTypeName)
+              && MessageDialog.CANCEL == Utility
+                      .popOkCancel(
+                              "Type define via Import",
+                              "The type '"
+                                      + oldTypeName
+                                      + "' is also defined in 1 or more imports.  Changing the type name here will not change it in the imported type file, causing both types to be in the type system, together. Please confirm this is what you intend.",
+                              MessageDialog.WARNING))
+        return;
+      if (isBuiltInType(oldTypeName)
+              && MessageDialog.CANCEL == Utility
+                      .popOkCancel(
+                              "Type was extending a built-in",
+                              "The type '"
+                                      + oldTypeName
+                                      + "' was extending a builtin type of the same name. Changing the type name here will not change the built-in type, causing both types to be in the type system, together. Please confirm this is what you intend.",
+                              MessageDialog.WARNING))
+        return;
+      if (isImportedType(oldTypeName) || isImportedType(newTypeName) || isBuiltInType(oldTypeName)
+              || isBuiltInType(newTypeName))
+        mergeAndRefreshNeeded = true;
+    }
+    valueChanged = false;
+
+    // guaranteed non-null because otherwise edit not allowed
+    TypeDescription localTd = getLocalTypeDefinition(td);
+    typeUpdate(localTd, dialog);
+    if (!valueChanged)
+      return;
+    if (mergeAndRefreshNeeded) {
+      rebuildMergedTypeSystem();
+      td = getMergedTypeSystemDescription().getType(newTypeName);
+    } else {
+      typeUpdate(td, dialog);
+      updateGuiType(item, td);
+    }
+
+    editor.removeDirtyTypeName(oldTypeName);
+    editor.addDirtyTypeName(td.getName());
+    // interesting case: renaming a type causes another type
+    // which has a shadow to get a new super (should cause merge error)
+    // or which has a shadow to get a new range (should cause merge error)
+    // or which has a shadow of a built-in to get new range or super
+    // (should cause error) (but only if that feature is defined in the
+    // non-local version)
+
+    refreshNeeded |= alterTypeMentionsInOtherTypes(oldTypeName, td.getName());
+    if (refreshNeeded || mergeAndRefreshNeeded)
+      refresh();
+    alterTypeMentions(oldTypeName, td.getName());
+
+    finishActionPack();
+  }
+
+  private void updateGuiType(TableTreeItem item, TypeDescription td) {
+    item.setText(NAME_COL, formatName(td.getName()));
+    item.setText(SUPER_COL, formatName(td.getSupertypeName()));
+  }
+
+  private void rebuildMergedTypeSystem() {
+    try {
+      editor.setMergedTypeSystemDescription();
+    } catch (ResourceInitializationException e) {
+      throw new InternalErrorCDE(e);
+    }
+  }
+
+  private void typeUpdate(TypeDescription td, AddTypeDialog dialog) {
+    td.setName(setValueChanged(dialog.typeName, td.getName()));
+    td.setDescription(setValueChanged(multiLineFix(dialog.description), td.getDescription()));
+    td.setSupertypeName(setValueChanged(dialog.supertypeName, td.getSupertypeName()));
+
+  }
+
+  /**
+   * returns null or error message about a duplicate type name Cases: Dupl type in local descriptor
+   * not allowed. Type that duplicates imported type is OK. Type that duplicates built-in type is
+   * OK.
+   */
+  public String checkDuplTypeName(String newTypeName) {
+    if (isLocalType(newTypeName)) {
+      return "The type '" + newTypeName + "' is already defined locally in this descriptor.";
+    }
+    return null;
+  }
+
+  /*
+   * Note that the Remove action is disabled if the item selected is imported only
+   */
+  private void handleRemove() {
+    TableTreeItem item = tt.getSelection()[0];
+    TableTreeItem parent = item.getParentItem();
+
+    if (null == parent)
+      handleRemoveType(item);
+    else if (item.getText(NAME_COL).equals(HEADER_ALLOWED_VALUE))
+      handleRemoveAllowedValue(item);
+    else
+      handleRemoveFeature(item);
+  }
+
+  private void handleRemoveAllowedValue(TableTreeItem item) {
+    TypeDescription td = getTypeDescriptionFromTableTreeItem(item.getParentItem());
+    AllowedValue av = getAllowedValueFromTableTreeItem(item);
+    // guaranteed non-null -otherwise remove button disabled
+    removeAllowedValue(getLocalTypeDefinition(td), av);
+    if (!isImportedAllowedValue(td, av)) {
+      removeAllowedValue(td, av);
+
+      // update GUI
+      tt.getTable().setSelection(tt.getTable().getSelectionIndex() - 1);
+      item.dispose();
+    } else {
+      refresh();
+    }
+
+    editor.addDirtyTypeName(td.getName());
+    finishAction();
+  }
+
+  // cases: removing a feature which is merged with an identical named imported feature
+  // same - for built-in <could be created outside of the CDE>
+  private void handleRemoveFeature(TableTreeItem item) {
+    TypeDescription td = getTypeDescriptionFromTableTreeItem(item.getParentItem());
+    FeatureDescription fd = getFeatureDescriptionFromTableTreeItem(item);
+
+    String featureName = fd.getName();
+
+    boolean bFeatureInUseElsewhere = isFeatureInUseElsewhere(td, featureName);
+    if (bFeatureInUseElsewhere) {
+      String sCascadeDeleteTitle = CASCADE_DELETE_WARNING;
+      String sCascadeDeleteMessage = CASCADE_MESSAGE;
+      boolean bContinue = MessageDialog.openConfirm(getSection().getShell(), sCascadeDeleteTitle,
+              sCascadeDeleteMessage);
+      if (!bContinue)
+        return;
+    }
+    TypeDescription localTd = getLocalTypeDefinition(td);
+    FeatureDescription localFd = getLocalFeatureDefinition(td, fd);
+
+    removeFeature(localTd, localFd);
+    if (isImportedFeature(featureName, td))
+      refresh(); // don't remove from merged set
+    else {
+      removeFeature(td, fd);
+      if (isBuiltInFeature(featureName, td))
+        refresh();
+      else {
+        // update GUI
+        tt.getTable().setSelection(tt.getTable().getSelectionIndex() - 1);
+        item.dispose();
+      }
+    }
+
+    if (bFeatureInUseElsewhere && !isImportedFeature(featureName, td)
+            && !isBuiltInFeature(featureName, td)) {
+      deleteTypeOrFeatureMentions(featureName, FEATURES, localTd.getName());
+    }
+
+    editor.addDirtyTypeName(td.getName());
+    finishAction();
+  }
+
+  private static class TypeFeature {
+    String typeName;
+
+    String featureName; // short feature name
+
+    TypeFeature(String type, String feat) {
+      typeName = type;
+      featureName = feat;
+    }
+  }
+
+  private static final TypeFeature[] typeFeature0 = new TypeFeature[0];
+
+  /**
+   * CALL THIS FN after removing and remerging. Assuming the localTd is removed, it may result in
+   * the mergedTd having fewer features. Compute the features that would be removed. Do it not just
+   * for this type, but for all subtypes of this type. NOTE: if mergeTd is null, it means the type
+   * is removed completely (no shadowing of built-in or imported types), so no special feature
+   * removal is needed.
+   * 
+   * @param localTd
+   * @param mergedTd
+   *          The "remerged" value of the type.
+   * @return array of string names of features to be removed
+   */
+
+  private TypeFeature[] computeFeaturesToRemove(TypeDescription localTd, TypeDescription mergedTd) {
+    if (null == mergedTd)
+      return typeFeature0;
+    FeatureDescription[] locallyDefinedFeatures = localTd.getFeatures();
+    if (null == locallyDefinedFeatures || locallyDefinedFeatures.length == 0)
+      return typeFeature0;
+
+    FeatureDescription[] remainingFeatures = mergedTd.getFeatures();
+    ArrayList deletedFeatures = new ArrayList();
+
+    outer: for (int i = 0; i < locallyDefinedFeatures.length; i++) {
+      String fname = locallyDefinedFeatures[i].getName();
+      if (null != remainingFeatures)
+        for (int j = 0; j < remainingFeatures.length; j++) {
+          if (fname.equals(remainingFeatures[j].getName()))
+            continue outer;
+        }
+      deletedFeatures.add(fname);
+    }
+
+    // have list of features really disappearing (not kept present by imports or built-ins)
+    // return all types/features of these for types which are subtypes of the passed-in type
+
+    CAS tcas = editor.getCurrentView();
+    TypeSystem typeSystem = tcas.getTypeSystem();
+    Type thisType = typeSystem.getType(localTd.getName());
+    List subsumedTypesList = typeSystem.getProperlySubsumedTypes(thisType);
+    subsumedTypesList.add(thisType);
+    Type[] subsumedTypes = (Type[]) subsumedTypesList.toArray(new Type[0]);
+
+    String[] featNameArray = (String[]) deletedFeatures.toArray(new String[deletedFeatures.size()]);
+    ArrayList result = new ArrayList();
+    for (int i = 0; i < subsumedTypes.length; i++) {
+      Type t = subsumedTypes[i];
+      for (int j = 0; j < featNameArray.length; j++) {
+        if (null != t.getFeatureByBaseName(featNameArray[j]))
+          result.add(new TypeFeature(t.getName(), featNameArray[j]));
+      }
+    }
+    return (TypeFeature[]) result.toArray(typeFeature0);
+  }
+
+  private void handleRemoveType(TableTreeItem item) {
+
+    TypeDescription td = getTypeDescriptionFromTableTreeItem(item);
+
+    String sTypeNameToRemove = td.getName();
+
+    // pop a dialog mentioning typesRequiringThisOne, saying that others must be
+    // deleted first....
+    if (null == showTypesRequiringThisOneMessage(sTypeNameToRemove, !ALLOWED))
+      return;
+
+    boolean bTypeInUseElsewhere = isTypeInUseElsewhere(sTypeNameToRemove);
+    if (bTypeInUseElsewhere) {
+      String sCascadeDeleteTitle = CASCADE_DELETE_WARNING;
+      String sCascadeDeleteMessage = CASCADE_MESSAGE;
+      boolean bContinue = MessageDialog.openConfirm(getSection().getShell(), sCascadeDeleteTitle,
+              sCascadeDeleteMessage);
+      if (!bContinue) {
+        return;
+      }
+    }
+
+    TypeDescription localTd = getLocalTypeDefinition(td);
+    removeType(localTd, getTypeSystemDescription());
+
+    if (isImportedType(td)) {
+      // although the type itself still remains in the merged type system,
+      // features may be removed by this action, so
+      // a remerge is needed
+      rebuildMergedTypeSystem();
+      refresh();
+    } else {
+      removeType(td, getMergedTypeSystemDescription());
+      // update GUI
+      tt.getTable().setSelection(tt.getTable().getSelectionIndex() - 1);
+      item.dispose();
+    }
+
+    TypeFeature[] featuresToRemove = computeFeaturesToRemove(localTd,
+            getMergedTypeSystemDescription().getType(td.getName()));
+
+    if (bTypeInUseElsewhere && !isImportedType(td) && !isBuiltInType(td)) {
+      deleteTypeOrFeatureMentions(sTypeNameToRemove, TYPES, null);
+    }
+
+    // if removing a type which is also imported or built-in, which is a supertype of something
+    // this action can change the feature set.
+
+    if (null != featuresToRemove)
+      for (int i = 0; i < featuresToRemove.length; i++) {
+        deleteTypeOrFeatureMentions(featuresToRemove[i].featureName, FEATURES,
+                featuresToRemove[i].typeName);
+      }
+
+    editor.removeDirtyTypeName(sTypeNameToRemove);
+    finishAction();
+  }
+
+  /**
+   * Called when removing a type (or renaming a type - treating old value like remove)
+   * 
+   * @param existingTypeName
+   * @param allowed
+   * @return null means "cancel", stringArray0 means no problem, stringArrayN = dependent types
+   */
+  private String[] showTypesRequiringThisOneMessage(String existingTypeName, boolean allowed) {
+    // if type is imported or built-in, in addition to being defined in this
+    // descriptor, removing it won't make the type unavailable.
+    if (isImportedType(existingTypeName) || isBuiltInType(existingTypeName))
+      return stringArray0; // imported or built-in type will remain
+    String[] typesRequiringThisOne = getTypesRequiringThisOne(existingTypeName);
+    if (typesRequiringThisOne != null && typesRequiringThisOne.length > 0) {
+      String sMsg = existingTypeName + " has the following dependent type(s): ";
+      for (int i = 0; i < typesRequiringThisOne.length; i++) {
+        if (i > 0) {
+          sMsg += ", ";
+        }
+        sMsg += typesRequiringThisOne[i];
+      }
+      if (!allowed) {
+        sMsg += ".  Please delete dependent types first.";
+        Utility.popMessage("Can''t Remove Needed Type", sMsg, MessageDialog.WARNING);
+        return null;
+      }
+      sMsg += ".  If you proceed, the dependent types which are updatable will be updated."
+              + " Non-updatable types (imported, etc.) you will have to update manually.  Please confirm.";
+      if (MessageDialog.OK == Utility.popOkCancel("Confirm renaming type update actions", sMsg,
+              MessageDialog.WARNING))
+        return typesRequiringThisOne;
+      return null;
+    }
+    return stringArray0;
+  }
+
+  private void removeType(TypeDescription td, TypeSystemDescription tsd) {
+    tsd.setTypes((TypeDescription[]) Utility.removeElementFromArray(tsd.getTypes(), td,
+            TypeDescription.class));
+  }
+
+  private void removeFeature(TypeDescription td, FeatureDescription fd) {
+    td.setFeatures((FeatureDescription[]) Utility.removeElementFromArray(td.getFeatures(), fd,
+            FeatureDescription.class));
+  }
+
+  private String[] getTypesRequiringThisOne(String typeName) {
+    List upstreamTypeNames = new ArrayList();
+
+    TypeSystemDescription typeSystem = getMergedTypeSystemDescription();
+
+    TypeDescription[] types = typeSystem.getTypes();
+    for (int i = 0; i < types.length; i++) {
+      if (!types[i].getName().equals(typeName)) {
+        if (typeRequiresType(types[i], typeName)) {
+          upstreamTypeNames.add(types[i].getName());
+        }
+      }
+    }
+    return (String[]) upstreamTypeNames.toArray(new String[upstreamTypeNames.size()]);
+  }
+
+  private boolean typeRequiresType(TypeDescription upstreamType, String typeName) {
+    if (null == typeName)
+      return false;
+    if (typeName.equals(upstreamType.getSupertypeName())) {
+      return true;
+    }
+
+    FeatureDescription[] features = upstreamType.getFeatures();
+    if (features == null) {
+      return false;
+    }
+
+    for (int i = 0; i < features.length; i++) {
+      if (typeName.equals(features[i].getRangeTypeName())) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  public void enable() {
+    jcasGenButton.setEnabled(tt.getItemCount() > 0);
+    TypeSystemDescription tsd = getTypeSystemDescription();
+    exportButton.setEnabled(false);
+    if (null != tsd) {
+      TypeDescription[] tsa = tsd.getTypes();
+      if (null != tsa)
+        exportButton.setEnabled(tsa.length > 0);
+    }
+    if (isAggregate()) {
+      addTypeButton.setEnabled(false);
+      addButton.setEnabled(false);
+      editButton.setEnabled(false);
+      removeButton.setEnabled(false);
+    } else {
+      addTypeButton.setEnabled(true);
+      boolean editable = tt.getSelectionCount() == 1 && isLocalItem(tt.getSelection()[0]);
+      addButton.setEnabled(editable);
+      editButton.setEnabled(editable);
+      removeButton.setEnabled(editable);
+    }
+
+  }
+
+  private boolean isSubtypeOfString(TableTreeItem item) {
+    TypeDescription td = getTypeDescriptionFromTableTreeItem(item);
+    return CAS.TYPE_NAME_STRING.equals(td.getSupertypeName());
+  }
+
+  private boolean isTypeInUseElsewhere(final String sTypeName) {
+    if (!isLocalProcessingDescriptor()) {
+      return false;
+    }
+    final String sTypeName_Colon = sTypeName + ":";
+
+    CapabilityVisitor cv = new CapabilityVisitor() {
+      boolean visit(TypeOrFeature i_o) {
+        if (i_o.isType() && i_o.getName().equals(sTypeName))
+          return true;
+        else if (i_o.getName().startsWith(sTypeName_Colon))
+          return true;
+        return false;
+      }
+    };
+    if (capabilityVisit(cv))
+      return true;
+
+    FsIndexDescription[] indexes = getAnalysisEngineMetaData().getFsIndexes();
+
+    if (indexes != null) {
+      for (int i = 0; i < indexes.length; i++) {
+        if (indexes[i].getTypeName().equals(sTypeName)) {
+          return true;
+        }
+      }
+    }
+
+    return typePriorityListsVisit(FIND_EQUAL_TYPE, sTypeName);
+  }
+
+  private final static int FIND_EQUAL_TYPE = 1;
+
+  private final static int REMOVE_EQUAL_TYPE = 2;
+
+  private final static int UPDATE_TYPE_NAME = 4;
+
+  private boolean typePriorityListsVisit(int kind, String typeName) {
+    return typePriorityListsVisit(kind, typeName, null);
+  }
+
+  /**
+   * 
+   * @param kind
+   * @param typeName
+   * @param newTypeName
+   * @return FIND_EQUAL_TYPE: true if found, false otherwise REMOVE_EQUAL_TYPE: true if found, false
+   *         if nothing done UPDATE_TYPE_NAME: true if found & updated, false if nothing done
+   */
+  private boolean typePriorityListsVisit(int kind, String typeName, String newTypeName) {
+    boolean returnValue = false;
+    TypePriorities priorities = getAnalysisEngineMetaData().getTypePriorities();
+    if (priorities != null) {
+      TypePriorityList[] priorityLists = priorities.getPriorityLists();
+      if (priorityLists != null) {
+        for (int i = 0; i < priorityLists.length; i++) {
+          String[] typeNames = priorityLists[i].getTypes();
+          if (typeNames != null) {
+            if (kind == FIND_EQUAL_TYPE) {
+              for (int j = 0; j < typeNames.length; j++) {
+                if (typeNames[j].equals(typeName))
+                  return true;
+              }
+            } else if (kind == UPDATE_TYPE_NAME) {
+              boolean bChanged = false;
+              for (int j = 0; j < typeNames.length; j++) {
+                if (typeNames[j].equals(typeName)) {
+                  typeNames[j] = newTypeName;
+                  bChanged = true;
+                  break;
+                }
+              }
+              if (bChanged) {
+                priorityLists[i].setTypes(typeNames);
+                returnValue = true;
+              }
+            } else if (kind == REMOVE_EQUAL_TYPE) {
+              Object[] newTypeNames = Utility.removeElementsFromArray(typeNames, typeName,
+                      String.class);
+              if (newTypeNames != typeNames) {
+                priorityLists[i].setTypes((String[]) newTypeNames);
+                returnValue = true;
+              }
+            } else
+              throw new InternalErrorCDE("invalid argument");
+          }
+        }
+      }
+    }
+    return returnValue;
+  }
+
+  private TypeOrFeature[] deleteTypeOrFeatureFromCapability(TypeOrFeature[] io_s,
+          final boolean isType, String name, String typeName) {
+
+    if (!isType) // is feature
+      name = typeName + ':' + name;
+    return (TypeOrFeature[]) Utility.removeElementsFromArray(io_s, name, TypeOrFeature.class,
+            isType ? capabilityTypeCompare : capabilityFeatureCompare);
+  }
+
+  private final static boolean TYPES = true;
+
+  private final static boolean FEATURES = false;
+
+  private static final Comparator fsIndexDescCompare = new Comparator() {
+    public int compare(Object o1, Object o2) {
+      return ((FsIndexDescription) o2).getTypeName().equals(o1) ? 0 : 1;
+    }
+  };
+
+  private static final Comparator fsIndexKeyDescCompare = new Comparator() {
+    public int compare(Object o1, Object o2) {
+      return (o1.equals(((FsIndexKeyDescription) o2).getFeatureName())) ? 0 : 1;
+    }
+  };
+
+  private static final Comparator capabilityTypeCompare = new Comparator() {
+    public int compare(Object o1, Object o2) {
+      TypeOrFeature tf = (TypeOrFeature) o2;
+      return ((tf.isType() == true && tf.getName().equals(o1)) ||
+      // remove features belong to type if type is removed
+      tf.getName().startsWith(((String) o1) + ':')) ? 0 : 1;
+    }
+  };
+
+  private static final Comparator capabilityFeatureCompare = new Comparator() {
+    public int compare(Object o1, Object o2) {
+      TypeOrFeature tf = (TypeOrFeature) o2;
+      return (tf.isType() == false && tf.getName().equals(o1)) ? 0 : 1;
+    }
+  };
+
+  /**
+   * feature name if used, is short-name
+   * 
+   * @param typeOrFeatureName -
+   *          if feature is short feature name
+   * @param isType
+   * @param String
+   *          type name (used when feature name passed above
+   */
+  private void deleteTypeOrFeatureMentions(final String typeOrFeatureName, boolean isType,
+          final String typeName) {
+    if (!isLocalProcessingDescriptor()) {
+      return;
+    }
+    Capability[] c = getCapabilities();
+    for (int ic = 0; ic < c.length; ic++) {
+      c[ic].setInputs(deleteTypeOrFeatureFromCapability(c[ic].getInputs(), isType,
+              typeOrFeatureName, typeName));
+      c[ic].setOutputs(deleteTypeOrFeatureFromCapability(c[ic].getOutputs(), isType,
+              typeOrFeatureName, typeName));
+    }
+
+    CapabilityPage p = editor.getCapabilityPage();
+    if (null != p)
+      p.markStale();
+
+    final FsIndexCollection indexCollection = editor.getFsIndexCollection();
+
+    FsIndexDescription[] indexes = (null == indexCollection) ? null : indexCollection
+            .getFsIndexes();
+
+    boolean somethingChanged = false;
+    if (indexes != null) {
+      if (isType) {
+        FsIndexDescription[] newFsid = (FsIndexDescription[]) Utility.removeElementsFromArray(
+                indexes, typeOrFeatureName, FsIndexDescription.class, fsIndexDescCompare);
+        if (newFsid != indexes) {
+          somethingChanged = true;
+          indexCollection.setFsIndexes(newFsid);
+        }
+      } else { // is feature
+        for (int i = 0; i < indexes.length; i++) {
+          if (typeName.equals(indexes[i].getTypeName())) {
+            FsIndexKeyDescription[] newFsKeys = (FsIndexKeyDescription[]) Utility
+                    .removeElementsFromArray(indexes[i].getKeys(), typeOrFeatureName,
+                            FsIndexKeyDescription.class, fsIndexKeyDescCompare);
+            if (newFsKeys != indexes[i].getKeys()) {
+              somethingChanged = true;
+              indexes[i].setKeys(newFsKeys);
+            }
+          }
+        }
+      }
+
+      if (somethingChanged) {
+        try {
+          editor.setMergedFsIndexCollection();
+        } catch (ResourceInitializationException e) {
+          throw new InternalErrorCDE("unexpected exception", e);
+        }
+        if (null != editor.getIndexesPage())
+          editor.getIndexesPage().markStale();
+      }
+    }
+
+    if (isType) {
+      if (typePriorityListsVisit(REMOVE_EQUAL_TYPE, typeOrFeatureName)) {
+        try {
+          editor.setMergedTypePriorities();
+        } catch (ResourceInitializationException e) {
+          throw new InternalErrorCDE("unexpected exception");
+        }
+        if (null != editor.getIndexesPage())
+          editor.getIndexesPage().markStale();
+      }
+    }
+  }
+
+  /**
+   * return true if refresh is needed
+   * 
+   * @param oldTypeName
+   * @param newTypeName
+   * @return
+   */
+  private boolean alterTypeMentionsInOtherTypes(String oldTypeName, String newTypeName) {
+    // only modify locally modifiable types, but scan all types to give appropriate error msgs
+    TypeSystemDescription typeSystem = getMergedTypeSystemDescription();
+    boolean refreshNeeded = false;
+    boolean remergeNeeded = false;
+    TypeDescription[] types = typeSystem.getTypes();
+    for (int i = 0; i < types.length; i++) {
+      TypeDescription td = types[i];
+      TypeDescription localTd = getLocalTypeDefinition(td);
+      String typeName = td.getName();
+      if (td.getSupertypeName().equals(oldTypeName)) {
+        if (null != localTd) { // is a local type
+          if (isImportedType(typeName)) {
+            Utility
+                    .popMessage(
+                            "Imported type won't be changed",
+                            "There is both a local and imported version of type, '"
+                                    + typeName
+                                    + "', which has a supertype which is the item being renamed.  Although the local version will be updated, but the imported one won't."
+                                    + "This may cause an error when you save.",
+                            MessageDialog.WARNING);
+          }
+          if (isBuiltInType(typeName)) {
+            // invalid: changed some type name which was a supertype of a built in - but
+            // all the supertypes of built-ins are unchangable.
+            throw new InternalErrorCDE("invalid state");
+          }
+        } else { // is not a local type
+          // can't be a built-in type because all the supertypes of built-ins are unchangeable
+          Utility
+                  .popMessage(
+                          "Imported type not changed",
+                          "There is an imported type, '"
+                                  + typeName
+                                  + "', which has a supertype which is the item being renamed.  It won't be updated - this may cause an error when you save this descriptor."
+                                  + "  If it does, you will need to edit the imported type to change it.",
+                          MessageDialog.WARNING);
+          continue;
+        }
+        // guaranteed to have local type def here
+        localTd.setSupertypeName(newTypeName);
+
+        if (isImportedType(typeName)) {
+          remergeNeeded = true;
+          refreshNeeded = true;
+        } else {
+          td.setSupertypeName(newTypeName);
+          updateGuiType(tt.getItems()[i], td);
+        }
+      }
+      FeatureDescription fds[] = td.getFeatures();
+      FeatureDescription localFds[] = (null == localTd) ? null : localTd.getFeatures();
+      if (null != fds) {
+        for (int j = 0; j < fds.length; j++) {
+          FeatureDescription fd = fds[j];
+          if (oldTypeName.equals(fd.getRangeTypeName())) {
+            if (warnAndSkipIfImported(typeName))
+              continue; // skipped if feature not present in local td, or no local td.
+
+            setNamedFeatureDescriptionRange(localFds, fd.getName(), newTypeName);
+            if (isImportedType(typeName)) {
+              remergeNeeded = true;
+              refreshNeeded = true;
+            } else {
+              fd.setRangeTypeName(newTypeName);
+              updateGuiFeature(tt.getItems()[i].getItems()[j], fd, td);
+            }
+          }
+        }
+      }
+    }
+    if (remergeNeeded)
+      rebuildMergedTypeSystem();
+    return refreshNeeded;
+  }
+
+  // this function to set the corresponding feature in the "local" type's fd array
+  private void setNamedFeatureDescriptionRange(FeatureDescription[] localFds, String featureName,
+          final String rangeName) {
+    if (null != localFds) {
+      for (int i = 0; i < localFds.length; i++) {
+        FeatureDescription fd = localFds[i];
+        if (fd.getName().equals(featureName)) {
+          fd.setRangeTypeName(rangeName);
+          return;
+        }
+      }
+    }
+  }
+
+  private boolean warnAndSkipIfImported(String typeName) {
+    if (isLocalType(typeName)) {
+      if (isImportedType(typeName)) {
+        Utility
+                .popMessage(
+                        "Imported type won't be changed",
+                        "There is both a local and imported version of type, '"
+                                + typeName
+                                + "', which has a feature whose range type is the item being renamed.  Although the local version will be updated, but the imported one won't."
+                                + "This may cause an error when you save.", MessageDialog.WARNING);
+      }
+      return false;
+    } else { // is not a local type
+      Utility
+              .popMessage(
+                      "Imported feature range not changed",
+                      "There is an imported type, '"
+                              + typeName
+                              + "', which has a a feature whose range which is the item being renamed.  It won't be updated - this may cause an error when you save this descriptor."
+                              + "  If it does, you will need to edit the imported type to change it.",
+                      MessageDialog.WARNING);
+      return true;
+    }
+  }
+
+  private void alterTypeMentions(final String sOldTypeName, final String sNewTypeName) {
+    if (sOldTypeName.equals(sNewTypeName) || (!isLocalProcessingDescriptor()))
+      return;
+
+    // update types (which are locally editable)
+    // that reference the old type name, either as
+    // ranges of features or
+    // supertype
+    final boolean[] capabilityChanged = new boolean[1];
+    capabilityChanged[0] = false;
+    final String oldTypeName_colon = sOldTypeName + ':';
+    CapabilityVisitor cv = new CapabilityVisitor() {
+      boolean visit(TypeOrFeature i_o) {
+        if (i_o.isType() && i_o.getName().equals(sOldTypeName)) {
+          capabilityChanged[0] = true;
+          i_o.setName(sNewTypeName);
+        } else if (!i_o.isType() && i_o.getName().startsWith(oldTypeName_colon)) {
+          capabilityChanged[0] = true;
+          i_o.setName(sNewTypeName + ':' + i_o.getName().substring(oldTypeName_colon.length()));
+        }
+        return false;
+      }
+    };
+
+    capabilityVisit(cv);
+    if (capabilityChanged[0])
+      if (null != editor.getCapabilityPage())
+        editor.getCapabilityPage().markStale();
+
+    FsIndexCollection indexCollection = getAnalysisEngineMetaData().getFsIndexCollection();
+
+    FsIndexDescription[] indexes = (null == indexCollection) ? null : indexCollection
+            .getFsIndexes();
+
+    boolean somethingChanged = false;
+    boolean markStale = false;
+
+    if (indexes != null) {
+      for (int i = 0; i < indexes.length; i++) {
+        if (indexes[i].getTypeName().equals(sOldTypeName)) {
+          indexes[i].setTypeName(sNewTypeName);
+          somethingChanged = true;
+        }
+      }
+    }
+
+    if (somethingChanged) {
+      markStale = true;
+      try {
+        editor.setMergedFsIndexCollection();
+      } catch (ResourceInitializationException e) {
+        throw new InternalErrorCDE("unexpected exception");
+      }
+    }
+
+    // interesting use case not handled:
+    // changing a type name to another type name which
+    // already exists (in an import).
+    if (typePriorityListsVisit(UPDATE_TYPE_NAME, sOldTypeName, sNewTypeName)) {
+      markStale = true;
+      try {
+        editor.setMergedTypePriorities();
+      } catch (ResourceInitializationException e) {
+        throw new InternalErrorCDE("unexpected exception");
+      }
+    }
+
+    if (markStale) {
+      editor.getIndexesPage().markStale();
+    }
+
+  }
+
+  private boolean isFeatureUsedInIndex(TypeDescription td, String featureName) {
+    return isFeatureUsedInIndex(td.getName() + ":" + featureName);
+  }
+
+  private boolean isFeatureUsedInIndex(String fullFeatureName) {
+    if (!isLocalProcessingDescriptor()) {
+      return false;
+    }
+
+    FsIndexCollection indexCollection = editor.getMergedFsIndexCollection();
+    FsIndexDescription[] fsid = (null == indexCollection) ? null : indexCollection.getFsIndexes();
+    if (null != fsid) {
+      for (int i = 0; i < fsid.length; i++) {
+        FsIndexKeyDescription[] keys = fsid[i].getKeys();
+        if (null != keys) {
+          for (int j = 0; j < keys.length; j++) {
+            if (keys[j].getFeatureName().equals(fullFeatureName))
+              return true;
+          }
+        }
+      }
+    }
+    return false;
+  }
+
+  private boolean isFeatureInUseElsewhere(TypeDescription td, String featureName) {
+    return isFeatureInUseElsewhere(td.getName() + ':' + featureName);
+  }
+
+  private boolean isFeatureInUseElsewhere(final String typePlusFeature) {
+    if (!isLocalProcessingDescriptor()) { // not strictly true for imports....
+      return false;
+    }
+    CapabilityVisitor v = new CapabilityVisitor() {
+      boolean visit(TypeOrFeature i_o) {
+        if ((!i_o.isType()) && i_o.getName().equals(typePlusFeature)) {
+          return true;
+        }
+        return false;
+      }
+    };
+
+    if (capabilityVisit(v))
+      return true;
+
+    return isFeatureUsedInIndex(typePlusFeature);
+  }
+
+  private abstract class CapabilityVisitor {
+    abstract boolean visit(TypeOrFeature i_o);
+  }
+
+  private boolean capabilityVisit(CapabilityVisitor v) {
+    Capability[] c = getCapabilities();
+    for (int ic = 0; ic < c.length; ic++) {
+      TypeOrFeature[] inputs = c[ic].getInputs();
+
+      for (int i = 0; i < inputs.length; i++) {
+        if (v.visit(inputs[i]))
+          return true;
+      }
+
+      TypeOrFeature[] outputs = c[ic].getOutputs();
+
+      for (int i = 0; i < outputs.length; i++) {
+        if (v.visit(outputs[i]))
+          return true;
+      }
+    }
+    return false;
+  }
+
+  private void alterFeatureMentions(final String sOldFeatureName, final String sNewFeatureName,
+          final String typeName) {
+    final boolean[] somethingChanged = new boolean[1];
+    somethingChanged[0] = false;
+    if (sOldFeatureName.equals(sNewFeatureName) || (!isLocalProcessingDescriptor()))
+      return;
+    final String oldFullFeatureName = typeName + ':' + sOldFeatureName;
+    final String newFullFeatureName = typeName + ':' + sNewFeatureName;
+    CapabilityVisitor v = new CapabilityVisitor() {
+      boolean visit(TypeOrFeature i_o) {
+        if (!i_o.isType() && i_o.getName().equals(oldFullFeatureName)) {
+          somethingChanged[0] = true;
+          i_o.setName(newFullFeatureName);
+        }
+        return false;
+      }
+    };
+
+    capabilityVisit(v);
+    if (somethingChanged[0])
+      if (null != editor.getCapabilityPage())
+        editor.getCapabilityPage().markStale();
+
+    somethingChanged[0] = false;
+    FsIndexDescription[] fsid = getAnalysisEngineMetaData().getFsIndexes();
+    if (null != fsid) {
+      for (int i = 0; i < fsid.length; i++) {
+        if (typeName.equals(fsid[i].getTypeName())) {
+          FsIndexKeyDescription[] keys = fsid[i].getKeys();
+          if (null != keys) {
+            for (int j = 0; j < keys.length; j++) {
+              if (keys[j].getFeatureName().equals(sOldFeatureName)) {
+                somethingChanged[0] = true;
+                keys[j].setFeatureName(sNewFeatureName);
+              }
+            }
+          }
+        }
+      }
+    }
+
+    if (somethingChanged[0]) {
+      try {
+        editor.setMergedFsIndexCollection(); // overkill
+      } catch (ResourceInitializationException e) {
+        // TODO Auto-generated catch block
+        e.printStackTrace();
+      }
+      if (null != editor.getIndexesPage())
+        editor.getIndexesPage().markStale();
+    }
+  }
+
+}
diff --git a/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/Utility.java b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/Utility.java
new file mode 100644
index 0000000..23bcf11
--- /dev/null
+++ b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/Utility.java
@@ -0,0 +1,201 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS 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.taeconfigurator.editors.ui;
+
+import java.lang.reflect.Array;
+import java.util.Comparator;
+
+import org.apache.uima.taeconfigurator.InternalErrorCDE;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.window.Window;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Shell;
+
+// MessageDialog extended only to enable resize
+public class Utility extends MessageDialog {
+
+  /**
+   * @param parentShell
+   * @param dialogTitle
+   * @param dialogTitleImage
+   * @param dialogMessage
+   * @param dialogImageType
+   * @param dialogButtonLabels
+   * @param defaultIndex
+   */
+  public Utility(Shell parentShell, String dialogTitle, Image dialogTitleImage,
+          String dialogMessage, int dialogImageType, String[] dialogButtonLabels, int defaultIndex) {
+    super(parentShell, dialogTitle, dialogTitleImage, dialogMessage, dialogImageType,
+            dialogButtonLabels, defaultIndex);
+    // TODO Auto-generated constructor stub
+  }
+
+  final private static String[] OK_CANCEL = { "OK", "Cancel" };
+
+  final private static String[] OKstring = { "OK" };
+
+  /**
+   * Pops up a warning message with an "OK" and "Cancel" button
+   * 
+   * @param title
+   *          of the warning
+   * @param message
+   * @param type
+   *          one of MessageDialog.NONE for a dialog with no image MessageDialog.ERROR for a dialog
+   *          with an error image MessageDialog.INFORMATION for a dialog with an information image
+   *          MessageDialog.QUESTION for a dialog with a question image MessageDialog.WARNING for a
+   *          dialog with a warning image
+   */
+  public static int popOkCancel(String title, String message, int type) {
+    return popMessage(title, message, type, OK_CANCEL);
+  }
+
+  /**
+   * Pops up a warning message with an "OK" button
+   * 
+   * @param title
+   *          of the warning
+   * @param message
+   * @param type
+   *          one of MessageDialog.NONE for a dialog with no image MessageDialog.ERROR for a dialog
+   *          with an error image MessageDialog.INFORMATION for a dialog with an information image
+   *          MessageDialog.QUESTION for a dialog with a question image MessageDialog.WARNING for a
+   *          dialog with a warning image
+   * @return Window.OK or Window.CANCEL. If window is closed, Window.CANCEL is returned.
+   */
+
+  public static void popMessage(String title, String message, int type) {
+    popMessage(title, message, type, OKstring);
+  }
+
+  public static int popMessage(String title, String message, int type, String[] buttons) {
+    Utility dialog = new Utility(new Shell(), title, null, message, type, buttons, 0);
+    dialog.setShellStyle(SWT.DIALOG_TRIM | SWT.APPLICATION_MODAL | SWT.RESIZE);
+    int returnCode = dialog.open();
+    if (returnCode == -1)
+      returnCode = Window.CANCEL; // Cancel code
+    return returnCode;
+  }
+
+  /**
+   * remove 1 element (must be present) use == test
+   * 
+   * @param source
+   * @param element
+   * @param componentClass
+   * @return
+   */
+
+  public static Object[] removeElementFromArray(Object[] source, Object element,
+          Class componentClass) {
+    Object[] result = (Object[]) Array.newInstance(componentClass, source.length - 1);
+    for (int i = 0, j = 0; i < source.length; i++) {
+      if (element != source[i])
+        result[j++] = source[i];
+    }
+    return result;
+  }
+
+  /**
+   * remove 1 element (must be present) use == test
+   * 
+   * @param source
+   * @param element
+   * @param componentClass
+   * @return
+   */
+
+  public static Object[] removeEqualElementFromArray(Object[] source, Object element,
+          Class componentClass) {
+    Object[] result = (Object[]) Array.newInstance(componentClass, source.length - 1);
+    for (int i = 0, j = 0; i < source.length; i++) {
+      if (element == null && source[i] == null)
+        continue;
+      if (null != element && element.equals(source[i]))
+        continue;
+      result[j++] = source[i];
+    }
+    return result;
+  }
+
+  public static Object[] removeElementsFromArray(Object[] source, Object element,
+          Class componentClass) {
+    if (null == source)
+      return null;
+    int count = 0;
+    for (int i = 0; i < source.length; i++) {
+      if (!element.equals(source[i]))
+        count++;
+    }
+    if (count == source.length)
+      return source;
+
+    Object[] result = (Object[]) Array.newInstance(componentClass, count);
+    for (int i = 0, j = 0; i < source.length; i++) {
+      if (!element.equals(source[i]))
+        result[j++] = source[i];
+    }
+    return result;
+  }
+
+  public static Object[] removeElementsFromArray(Object[] source, Object element,
+          Class componentClass, Comparator comp) {
+    if (null == source)
+      return null;
+    int count = 0;
+    for (int i = 0; i < source.length; i++) {
+      if (0 != comp.compare(element, source[i]))
+        count++;
+    }
+    if (count == source.length)
+      return source;
+
+    Object[] result = (Object[]) Array.newInstance(componentClass, count);
+    for (int i = 0, j = 0; i < source.length; i++) {
+      if (0 != comp.compare(element, source[i]))
+        result[j++] = source[i];
+    }
+    return result;
+  }
+
+  public static Object[] addElementToArray(Object[] source, Object element, Class componentClass) {
+    final int newLength = (null == source) ? 1 : source.length + 1;
+    Object[] result = (Object[]) Array.newInstance(componentClass, newLength);
+    System.arraycopy(source, 0, result, 0, newLength - 1);
+    result[newLength - 1] = element;
+    return result;
+  }
+
+  public static boolean arrayContains(Object[] array, Object element) {
+    if (null == element)
+      throw new InternalErrorCDE("null not allowed as an argument");
+    if (null == array)
+      return false;
+    for (int i = 0; i < array.length; i++) {
+      if (null == array[i])
+        continue;
+      if (array[i].equals(element))
+        return true;
+    }
+    return false;
+  }
+
+}
diff --git a/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/ValueSection.java b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/ValueSection.java
new file mode 100644
index 0000000..7ba1279
--- /dev/null
+++ b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/ValueSection.java
@@ -0,0 +1,428 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS 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.taeconfigurator.editors.ui;
+
+import java.util.Arrays;
+
+import org.apache.uima.resource.metadata.ConfigurationGroup;
+import org.apache.uima.resource.metadata.ConfigurationParameter;
+import org.apache.uima.resource.metadata.ConfigurationParameterSettings;
+import org.apache.uima.taeconfigurator.InternalErrorCDE;
+import org.apache.uima.taeconfigurator.editors.MultiPageEditor;
+import org.apache.uima.taeconfigurator.editors.ui.dialogs.CommonInputDialog;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.window.Window;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.CCombo;
+import org.eclipse.swt.custom.StackLayout;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.TableItem;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.ui.forms.IManagedForm;
+
+public class ValueSection extends AbstractSectionParm {
+
+  private Composite valueTextStack;
+
+  private StackLayout valueTextStackLayout;
+
+  private Text valueText;
+
+  private CCombo valueTextCombo;
+
+  private Composite vtc1;
+
+  private Composite vtc2;
+
+  private Table valueTable;
+
+  private ParameterSettingsSection master;
+
+  private Button addButton;
+
+  private Button editButton;
+
+  private Button removeButton;
+
+  private Button upButton;
+
+  private Button downButton;
+
+  private Composite buttonContainer;
+
+  private ConfigurationParameter selectedCP;
+
+  private ConfigurationParameterSettings modelSettings;
+
+  public ValueSection(MultiPageEditor editor, Composite parent) {
+    super(editor, parent, "Values", "Specify the value of the selected configuration parameter.");
+  }
+
+  /*
+   * Called by the page constructor after all sections are created, to initialize them.
+   * (non-Javadoc)
+   * 
+   * @see org.eclipse.ui.forms.IFormPart#initialize(org.eclipse.ui.forms.IManagedForm)
+   */
+  public void initialize(IManagedForm form) {
+    super.initialize(form);
+
+    master = editor.getSettingsPage().getParameterSettingsSection();
+
+    Composite sectionClient = new3ColumnComposite(this.getSection());
+    enableBorders(sectionClient);
+    toolkit.paintBordersFor(sectionClient);
+
+    valueTextStack = newComposite(sectionClient);
+    valueTextStack.setLayoutData(new GridData(GridData.FILL_HORIZONTAL
+            + GridData.VERTICAL_ALIGN_FILL));
+    ((GridData) valueTextStack.getLayoutData()).horizontalSpan = 2;
+    valueTextStack.setLayout(valueTextStackLayout = new StackLayout());
+    valueTextStackLayout.marginHeight = 5;
+    valueTextStackLayout.marginWidth = 5;
+    vtc1 = new2ColumnComposite(valueTextStack);
+    vtc2 = new2ColumnComposite(valueTextStack);
+    enableBorders(vtc1);
+    enableBorders(vtc2);
+    toolkit.paintBordersFor(vtc1);
+    toolkit.paintBordersFor(vtc2);
+    valueText = newLabeledTextField(vtc1, "Value", "Specify the value",
+            SWT.NONE);
+    valueTextCombo = newLabeledCComboWithTip(vtc2, "Value",
+            "Use the combo pulldown to pick True or False");
+    valueTextCombo.add("true");
+    valueTextCombo.add("false");
+
+    spacer(sectionClient);
+
+    Label valueListLabel = toolkit.createLabel(sectionClient, "Value list:");
+    valueListLabel.setLayoutData(new GridData(SWT.TOP));
+    valueTable = newTable(sectionClient, SWT.MULTI, 0);
+
+    // no column spec in table is an idiom that makes it a fancy list
+
+    // Buttons
+    buttonContainer = newButtonContainer(sectionClient);
+
+    addButton = newPushButton(buttonContainer, S_ADD, "Click here to add a value to the list.");
+    editButton = newPushButton(buttonContainer, S_EDIT, S_EDIT_TIP);
+    removeButton = newPushButton(buttonContainer, S_REMOVE, S_REMOVE_TIP);
+    upButton = newPushButton(buttonContainer, S_UP, S_UP_TIP);
+    downButton = newPushButton(buttonContainer, S_DOWN, S_DOWN_TIP);
+  }
+
+  /*
+   * (non-Javadoc)
+   * 
+   * @see org.eclipse.ui.forms.IFormPart#refresh()
+   */
+  public void refresh() {
+    super.refresh();
+    master = editor.getSettingsPage().getParameterSettingsSection();
+    valueTextStackLayout.topControl = vtc1;
+
+    selectedCP = master.getSelectedModelParameter();
+
+    if (selectedCP == null) { // no param selected
+      valueText.setText("");
+      valueTable.removeAll();
+    } else { // parm selected in master view
+      Object modelValue;
+      modelSettings = getModelSettings();
+      String groupName = master.getSelectedParamGroupName();
+      String parmName = selectedCP.getName();
+
+      modelValue = (NOT_IN_ANY_GROUP.equals(groupName)) ? modelSettings.getParameterValue(parmName)
+              : modelSettings.getParameterValue(groupName, parmName);
+
+      if (selectedCP.isMultiValued()) {
+        // use list, not text field
+        valueText.setText("");
+        valueTable.removeAll();
+        if (modelValue != null && modelValue instanceof Object[]) {
+          Object[] valArr = (Object[]) modelValue;
+          for (int i = 0; i < valArr.length; i++) {
+            TableItem item = new TableItem(valueTable, SWT.NONE);
+            item.setText(valArr[i].toString());
+          }
+        }
+      } else { // single-valued parameter - use Text field
+        valueTable.removeAll();
+        valueText.setText((modelValue == null) ? "" : modelValue.toString());
+        if ("Boolean".equals(selectedCP.getType())) {
+          valueTextCombo.setText((modelValue == null) ? "" : modelValue.toString());
+          valueTextStackLayout.topControl = vtc2;
+        } else {
+          valueText.setText((modelValue == null) ? "" : modelValue.toString());
+          valueTextStackLayout.topControl = vtc1;
+        }
+      }
+    }
+    valueTextStack.layout();
+    enable();
+  }
+
+  public void enable() {
+
+    boolean mvValue = (null != selectedCP) && (selectedCP.isMultiValued());
+    valueText.setVisible((null != selectedCP) && (!selectedCP.isMultiValued()));
+    valueTextCombo.setVisible((null != selectedCP) && (!selectedCP.isMultiValued()));
+
+    addButton.setEnabled(mvValue);
+    int selected = valueTable.getSelectionIndex();
+    editButton.setEnabled(mvValue && selected > -1);
+    removeButton.setEnabled(mvValue && selected > -1);
+    upButton.setEnabled(mvValue && selected > 0);
+    downButton.setEnabled(mvValue && (selected > -1)
+            && (selected < (valueTable.getItemCount() - 1)));
+    valueText.getParent().redraw();
+  }
+
+  /*
+   * (non-Javadoc)
+   * 
+   * @see org.eclipse.swt.widgets.Listener#handleEvent(org.eclipse.swt.widgets.Event)
+   */
+  public void handleEvent(Event event) {
+
+    if (event.widget == valueText) {
+      setParmValue(valueText.getText());
+    }
+
+    else if (event.widget == valueTextCombo) {
+      setParmValue(valueTextCombo.getText());
+    }
+
+    else if (event.widget == addButton) {
+      // open dialog to enter value
+      String dataType = selectedCP.getType();
+      int validationFilter = "Boolean".equals(dataType) ? CommonInputDialog.TRUE_FALSE : "Integer"
+              .equals(dataType) ? CommonInputDialog.INTEGER
+              : "Float".equals(dataType) ? CommonInputDialog.FLOAT : CommonInputDialog.ALLOK;
+
+      CommonInputDialog dialog = new CommonInputDialog(this, "Add value", "Enter a value",
+              validationFilter);
+
+      if (dialog.open() == Window.CANCEL)
+        return;
+      TableItem item = new TableItem(valueTable, SWT.NONE);
+      item.setText(dialog.getValue());
+      // update model
+      setCurrentParameterValue(valueTable.getItems());
+    }
+
+    else if (event.widget == editButton) {
+      // open dialog to enter value
+      TableItem item = valueTable.getItems()[valueTable.getSelectionIndex()];
+      CommonInputDialog dialog = new CommonInputDialog(this, "Add value", "Enter a value",
+              CommonInputDialog.ALLOK, item.getText());
+
+      if (dialog.open() == Window.CANCEL)
+        return;
+
+      item.setText(dialog.getValue());
+      // update model
+      setCurrentParameterValue(valueTable.getItems());
+    }
+
+    else if (event.widget == upButton) {
+      // update both model and gui: swap nodes
+      int selection = valueTable.getSelectionIndex();
+      TableItem[] items = valueTable.getItems();
+      String temp = items[selection - 1].getText();
+      items[selection - 1].setText(items[selection].getText());
+      items[selection].setText(temp);
+      valueTable.setSelection(selection - 1);
+      setCurrentParameterValue(valueTable.getItems());
+    } else if (event.widget == downButton) {
+      // update both model and gui: swap nodes
+      int selection = valueTable.getSelectionIndex();
+      TableItem[] items = valueTable.getItems();
+      String temp = items[selection + 1].getText();
+      items[selection + 1].setText(items[selection].getText());
+      items[selection].setText(temp);
+      valueTable.setSelection(selection + 1);
+      setCurrentParameterValue(valueTable.getItems());
+    }
+
+    else if (event.widget == removeButton
+            || (event.widget == valueTable && event.character == SWT.DEL)) {
+      handleRemove(event);
+    }
+
+    enable();
+  }
+
+  private void setParmValue(String value) {
+    if (null != value) {
+      if ("".equals(value))
+        value = null; // means clear the value
+      setCurrentParameterValue(value);
+    }
+  }
+
+  public void handleRemove(Event event) {
+    valueTable.remove(valueTable.getSelectionIndices());
+    // update model
+    setCurrentParameterValue(valueTable.getItems());
+  }
+
+  public Button getAddButton() {
+    return addButton;
+  }
+
+  public Button getRemoveButton() {
+    return removeButton;
+  }
+
+  public Table getValueTable() {
+    return valueTable;
+  }
+
+  public Text getValueText() {
+    return valueText;
+  }
+
+  /**
+   * Sets the currently selected parameter to the specified value. The string value will be
+   * converted to the appropriate data type. This method works only for single-valued parameters.
+   * 
+   * @param aValueString
+   */
+  private void setCurrentParameterValue(String aValueString) {
+
+    Object value = null;
+    if (null != aValueString) {
+      String paramType = selectedCP.getType();
+      try {
+        if (ConfigurationParameter.TYPE_STRING.equals(paramType)) {
+          value = aValueString;
+        } else if (ConfigurationParameter.TYPE_INTEGER.equals(paramType)) {
+          value = Integer.valueOf(aValueString);
+        } else if (ConfigurationParameter.TYPE_FLOAT.equals(paramType)) {
+          value = Float.valueOf(aValueString);
+        } else if (ConfigurationParameter.TYPE_BOOLEAN.equals(paramType)) {
+          value = Boolean.valueOf(aValueString);
+        }
+      } catch (NumberFormatException e) {
+        Utility
+                .popMessage(
+                        "Invalid Number",
+                        "If typing a floating point exponent, please complete the exponent.\nOtherwise, please retype the proper kind of number",
+                        MessageDialog.ERROR);
+        return;
+      }
+    }
+    setModelValue(value);
+  }
+
+  /**
+   * Sets the currently selected parameter to the specified value. This method works only for
+   * multi-valued parameters. The Table Items will be converted to the appropriate data type.
+   * 
+   * @param aValues
+   *          Table Items, one for each value of the multi-valued param
+   */
+  private void setCurrentParameterValue(TableItem[] aValues) {
+
+    Object[] valueArr = null;
+    String paramType = selectedCP.getType();
+    try {
+      if (ConfigurationParameter.TYPE_STRING.equals(paramType)) {
+        valueArr = new String[aValues.length];
+        for (int i = 0; i < valueArr.length; i++) {
+          valueArr[i] = aValues[i].getText();
+        }
+      } else if (ConfigurationParameter.TYPE_INTEGER.equals(paramType)) {
+        valueArr = new Integer[aValues.length];
+        for (int i = 0; i < valueArr.length; i++) {
+          valueArr[i] = Integer.valueOf(aValues[i].getText());
+        }
+      } else if (ConfigurationParameter.TYPE_FLOAT.equals(paramType)) {
+        valueArr = new Float[aValues.length];
+        for (int i = 0; i < valueArr.length; i++) {
+          valueArr[i] = Float.valueOf(aValues[i].getText());
+        }
+      } else if (ConfigurationParameter.TYPE_BOOLEAN.equals(paramType)) {
+        valueArr = new Boolean[aValues.length];
+        for (int i = 0; i < valueArr.length; i++) {
+          valueArr[i] = Boolean.valueOf(aValues[i].getText());
+        }
+      } else
+        throw new InternalErrorCDE("invalid state");
+    } catch (NumberFormatException e) {
+      Utility.popMessage("Invalid Number",
+              "One or more values is not of the proper kind of number."
+                      + " If this entry is the only one with the wrong numeric type,"
+                      + " Please retype the proper kind of number. Otherwise,"
+                      + " use the source page to change all the values to the proper type.",
+              MessageDialog.ERROR);
+      return;
+    }
+    setModelValue(valueArr);
+  }
+
+  private void setModelValue(Object value) {
+    String groupName = master.getSelectedParamGroupName();
+    boolean changed = false;
+    if (COMMON_GROUP.equals(groupName)) {
+      ConfigurationGroup[] groups = getConfigurationParameterDeclarations()
+              .getConfigurationGroups();
+      for (int i = 0; i < groups.length; i++) {
+        String[] groupNames = groups[i].getNames();
+        for (int j = 0; j < groupNames.length; j++) {
+          if (isSameValue(value, modelSettings.getParameterValue(groupNames[j], selectedCP
+                  .getName())))
+            continue;
+          modelSettings.setParameterValue(groupNames[j], selectedCP.getName(), value);
+          changed = true;
+        }
+      }
+    } else if (NOT_IN_ANY_GROUP.equals(groupName)) {
+      if (!isSameValue(value, modelSettings.getParameterValue(selectedCP.getName()))) {
+        modelSettings.setParameterValue(selectedCP.getName(), value);
+        changed = true;
+      }
+    } else {
+      if (!isSameValue(value, modelSettings.getParameterValue(groupName, selectedCP.getName()))) {
+        modelSettings.setParameterValue(groupName, selectedCP.getName(), value);
+        changed = true;
+      }
+    }
+    if (changed)
+      editor.setFileDirty();
+  }
+
+  private boolean isSameValue(Object v1, Object v2) {
+    if (v1 instanceof Object[]) {
+      return (Arrays.equals((Object[]) v1, (Object[]) v2));
+    } else {
+      if (null == v1)
+        return null == v2;
+      return v1.equals(v2);
+    }
+  }
+
+}
diff --git a/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/dialogs/AbstractDialog.java b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/dialogs/AbstractDialog.java
new file mode 100644
index 0000000..ce37b0b
--- /dev/null
+++ b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/dialogs/AbstractDialog.java
@@ -0,0 +1,492 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS 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.taeconfigurator.editors.ui.dialogs;
+
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.Set;
+
+import org.apache.uima.taeconfigurator.StandardStrings;
+import org.apache.uima.taeconfigurator.editors.MultiPageEditor;
+import org.apache.uima.taeconfigurator.editors.MultiPageEditorContributor;
+import org.apache.uima.taeconfigurator.editors.ui.AbstractSection;
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.CCombo;
+import org.eclipse.swt.events.KeyEvent;
+import org.eclipse.swt.events.KeyListener;
+import org.eclipse.swt.graphics.FontData;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Listener;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.TableItem;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.swt.widgets.Tree;
+
+public abstract class AbstractDialog extends Dialog implements Listener, StandardStrings {
+ 
+  private final static boolean contentAssistAvailable;
+  static {
+    boolean contentAssistIsOK = false;
+    try {
+      Class.forName("org.eclipse.ui.fieldassist.ContentAssistField");
+      contentAssistIsOK = true;
+    } catch (ClassNotFoundException e) {
+    }
+    contentAssistAvailable = contentAssistIsOK;
+  }
+ 
+  protected MultiPageEditor editor;
+
+  protected AbstractSection section;
+
+  protected Button okButton;
+
+  protected Label errorMessageUI;
+
+  protected String title;
+
+  protected String dialogDescription;
+
+  /**
+   * @param parentShell
+   */
+  protected AbstractDialog(AbstractSection section, String title, String description) {
+    // maintainers: don't use new shell; see comment in Dialog class
+    super(section.getSection().getShell());
+    commonInit(section, title, description);
+  }
+  
+  protected AbstractDialog(Shell shell, String title, String description) {
+    super(shell);
+    commonInit(null, title, description);
+  }
+  
+  private void commonInit(AbstractSection aSection, String aTitle, String aDescription) {
+    section = aSection;
+    editor = (null == section)? null : section.editor;
+    setShellStyle(getShellStyle() | SWT.RESIZE);
+    title = aTitle;
+    dialogDescription = aDescription;
+  }
+  
+  public void setTitle(String title) {
+    this.title = title;
+  }
+
+  public void setMessage(String msg) {
+    this.dialogDescription = msg;
+  }
+  protected Control createDialogArea(Composite parent) {
+    // create composite
+    Composite composite = (Composite) super.createDialogArea(parent);
+    createWideLabel(composite, dialogDescription);
+    return composite;
+  }
+
+  protected Control createDialogArea(Composite parent, Object existing) {
+    Composite composite = (Composite) super.createDialogArea(parent);
+    createWideLabel(composite, dialogDescription);
+    if (null != existing)
+      getShell().setText(getShell().getText().replaceFirst("Add", "Edit"));
+    return composite;
+  }
+
+  protected void configureShell(Shell shell) {
+    super.configureShell(shell);
+    shell.setText(title);
+  }
+
+  protected Label createWideLabel(Composite parent, String message) {
+    Label label = null;
+
+    label = new Label(parent, SWT.WRAP);
+    label.setText(null != message ? message : "");
+    GridData data = new GridData(GridData.FILL_HORIZONTAL);
+    data.widthHint = convertHorizontalDLUsToPixels(IDialogConstants.MINIMUM_MESSAGE_AREA_WIDTH);
+    label.setLayoutData(data);
+    return label;
+  }
+
+  protected void createButtonsForButtonBar(Composite parent) {
+    super.createButtonsForButtonBar(parent);
+    okButton = getButton(IDialogConstants.OK_ID);
+    okButton.setEnabled(false);
+  }
+
+  public static final String[] stringArray0 = new String[0];
+
+  protected void setTextAndTip(Button c, String label, String tip) {
+    c.setText(label);
+    c.setToolTipText(tip);
+  }
+
+  protected void setTextAndTip(CCombo c, String label, String tip) {
+    c.setText(label);
+    c.setToolTipText(tip);
+  }
+
+  protected void setTextAndTip(Label c, String label, String tip) {
+    c.setText(label);
+    c.setToolTipText(tip);
+  }
+
+  protected Composite new2ColumnComposite(Composite parent) {
+    Composite twoCol = new Composite(parent, SWT.NONE);
+    twoCol.setLayout(new GridLayout(2, false)); // false = not equal width
+    ((GridLayout) twoCol.getLayout()).marginHeight = 0;
+    ((GridLayout) twoCol.getLayout()).marginWidth = 0;
+    twoCol.setLayoutData(new GridData(GridData.FILL_BOTH));
+    return twoCol;
+  }
+
+  protected Text newDescription(Composite twoCol, String tip) {
+    setTextAndTip(new Label(twoCol, SWT.NONE), S_DESCRIPTION, tip);
+    Text t = new Text(twoCol, SWT.BORDER | SWT.MULTI | SWT.WRAP | SWT.V_SCROLL);
+    t.setLayoutData(new GridData(GridData.FILL_BOTH));
+    ((GridData) t.getLayoutData()).heightHint = 100;
+    t.setToolTipText(tip);
+    return t;
+  }
+
+  protected CCombo newLabeledCCombo(Composite parent, String label, String tip) {
+    setTextAndTip(new Label(parent, SWT.NONE), label, tip);
+    return newCCombo(parent, tip);
+  }
+
+  protected CCombo newCCombo(Composite parent, String tip) {
+    final CCombo cc = new CCombo(parent, SWT.FLAT | SWT.BORDER | SWT.READ_ONLY);
+    cc.setBackground(getShell().getDisplay().getSystemColor(SWT.COLOR_WHITE));
+    cc.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+    // without these next lines, the height of the ccombo is too small
+    // especially on a Mac
+    FontData [] fontData = cc.getFont().getFontData();
+    ((GridData) cc.getLayoutData()).heightHint = 2 * fontData[0].getHeight();
+    cc.addListener(SWT.Selection, this);
+    cc.setToolTipText(tip);
+    cc.addKeyListener(new KeyListener() {
+      private final StringBuffer b = new StringBuffer();
+
+      public void keyPressed(KeyEvent e) {
+      }
+
+      public void keyReleased(KeyEvent e) {
+        if (e.keyCode == SWT.BS) {
+          if (b.length() > 0)
+            b.deleteCharAt(b.length() - 1);
+        } else if (Character.isJavaIdentifierPart(e.character) || e.character == '.')
+          b.append(e.character);
+        else
+          return;
+        final String[] ccItems = cc.getItems();
+        final String partial = b.toString();
+        int iBefore = -1;
+        for (int i = 0; i < ccItems.length; i++) {
+          if (ccItems[i].startsWith(partial)) {
+            iBefore = i;
+            break;
+          }
+        }
+        if (iBefore >= 0)
+          cc.setText(cc.getItem(iBefore));
+      }
+    });
+    return cc;
+  }
+
+  protected Button newButton(Composite parent, int style, String name, String tip) {
+    Button b = new Button(parent, style);
+    setTextAndTip(b, name, tip);
+    b.addListener(SWT.Selection, this);
+    return b;
+  }
+
+  protected Text newText(Composite parent, int style, String tip) {
+    Text t = new Text(parent, style | SWT.BORDER);
+    t.setToolTipText(tip);
+    t.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+    t.addListener(SWT.KeyUp, this);
+    t.addListener(SWT.MouseUp, this); // for paste operation
+    return t;
+  }
+
+  protected Text newLabeledText(Composite parent, int style, String label, String tip) {
+    setTextAndTip(new Label(parent, SWT.NONE), label, tip);
+    return newText(parent, style, tip);
+  }
+
+  protected Tree newTree(Composite parent, int style) {
+    Tree tree = new Tree(parent, style | SWT.BORDER);
+    GridData gd = new GridData(GridData.FILL_BOTH);
+    tree.setLayoutData(gd);
+    return tree;
+  }
+
+  /**
+   * Styles = SWT.SINGLE / MULTI / CHECK / FULL_SELECTION / HIDE_SELECTION
+   * 
+   * @param parent
+   * @param style
+   * @return the new table widget
+   */
+  protected Table newTable(Composite parent, int style) {
+    Table table = new Table(parent, style | SWT.BORDER);
+    GridData gd = new GridData(GridData.FILL_BOTH);
+    table.setLayoutData(gd);
+    table.addListener(SWT.Selection, this);
+    table.addListener(SWT.KeyUp, this); // delete key
+    return table;
+  }
+
+  public int getHitColumn(TableItem item, Point p) {
+    for (int i = item.getParent().getColumnCount() - 1; i >= 0; i--) {
+      Rectangle columnBounds = item.getBounds(i);
+      if (columnBounds.contains(p))
+        return i;
+    }
+    return -1;
+  }
+
+  public Composite newButtonContainer(Composite parent) {
+    Composite buttonContainer = new Composite(parent, SWT.NONE);
+    buttonContainer.setLayout(new GridLayout());
+    buttonContainer.setLayoutData(new GridData(GridData.VERTICAL_ALIGN_BEGINNING
+            | GridData.HORIZONTAL_ALIGN_FILL));
+    return buttonContainer;
+  }
+
+  public Button newPushButton(Composite parent, String label, String tip) {
+    Button button = new Button(parent, SWT.PUSH);
+    button.setText(label);
+    button.setLayoutData(new GridData(GridData.VERTICAL_ALIGN_BEGINNING
+            | GridData.HORIZONTAL_ALIGN_FILL));
+    // button.pack();
+    button.setToolTipText(tip);
+    button.addListener(SWT.Selection, this);
+    return button;
+  }
+
+  protected void newErrorMessage(Composite c) {
+    newErrorMessage(c, 1);
+  }
+
+  protected void newErrorMessage(Composite twoCol, int span) {
+    Label m = new Label(twoCol, SWT.WRAP);
+    m.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+    ((GridData) m.getLayoutData()).horizontalSpan = span;
+    ((GridData) m.getLayoutData()).widthHint = convertHorizontalDLUsToPixels(IDialogConstants.MINIMUM_MESSAGE_AREA_WIDTH);
+    errorMessageUI = m;
+  }
+
+  protected void setErrorMessage(String msg) {
+    errorMessageUI.setText(msg);
+    Composite shell = errorMessageUI.getParent();
+    while (!(shell instanceof Shell))
+      shell = shell.getParent();
+    shell.setSize(shell.computeSize(-1, -1));
+  }
+
+  // subclasses override, and often use super.handleEvent to call this
+  public void handleEvent(Event event) {
+    if (okButton != null)  // may be null if handler called from 
+                           // main area setText event, during construction
+                           // because button bar is constructed after main area
+      enableOK();
+  }
+
+  protected void superButtonPressed(int buttonId) {
+    super.buttonPressed(buttonId);
+  }
+
+  // overridden where needed
+  protected void buttonPressed(int buttonId) {
+    if (buttonId == IDialogConstants.OK_ID) {
+      copyValuesFromGUI();
+      if (!isValid())
+        return; // keeps dialog open
+    }
+    super.buttonPressed(buttonId);
+  }
+
+  public abstract void copyValuesFromGUI();
+
+  public abstract boolean isValid();
+
+  protected Control createButtonBar(Composite c) {
+    Control returnValue = super.createButtonBar(c);
+    enableOK();
+    return returnValue;
+  }
+
+  public abstract void enableOK();
+
+  public boolean useQualifiedTypes() {
+    return MultiPageEditorContributor.getUseQualifiedTypes();
+  }
+
+  protected String[] getAllTypesAsSortedArray() {
+    String[] allTypes = (String[]) section.editor.allTypes.get().keySet().toArray(stringArray0);
+    Arrays.sort(allTypes, new Comparator() {
+      public int compare(Object o1, Object o2) {
+        String shortName1 = AbstractSection.getShortName((String) o1);
+        String shortName2 = AbstractSection.getShortName((String) o2);
+        if (!shortName1.equals(shortName2))
+          return shortName1.compareTo(shortName2);
+
+        String namespace1 = AbstractSection.getNameSpace((String) o1);
+        String namespace2 = AbstractSection.getNameSpace((String) o2);
+        return namespace1.compareTo(namespace2);
+      }
+    });
+    return allTypes;
+  }
+
+  protected Text newLabeledTypeInput(AbstractSection aSection, Composite parent, String label, String tip) {
+    setTextAndTip(new Label(parent, SWT.NONE), label, tip);
+    return newTypeInput(aSection, parent);
+  }
+
+  /**
+   * @param twoCol
+   */
+  protected Text newTypeInput(AbstractSection aSection, Composite twoCol) {
+    Composite tc = new2ColumnComposite(twoCol);
+    final TypesWithNameSpaces candidatesToPickFrom = getTypeSystemInfoList(); // provide an ArrayList of
+
+    final Text text;
+    if (contentAssistAvailable) {
+      ContentAssistField32 caf = new ContentAssistField32(tc, candidatesToPickFrom);
+      text = caf.getControl();
+    } else {
+      text = newText(tc, SWT.BORDER, "");
+    }
+      
+    text.setToolTipText("Enter a Type name." + (contentAssistAvailable ? 
+            "Content Assist is available (press Ctrl + Space)" : ""));
+    text.getParent().setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+    text.addListener(SWT.KeyUp, this);
+    text.addListener(SWT.MouseUp, this); // for paste operation
+    text.addListener(SWT.Modify, this);  // for content assist
+    
+//    newText(tc, SWT.NONE,
+//    "Enter a Type name. Content Assist is available on Eclipse 3.2 and beyond (press Ctrl + Space)");
+
+//    ContentProposalAdapter adapter = new ContentProposalAdapter(
+//            text, new TextContentAdapter(),
+//            candidatesToPickFrom,
+//            contentAssistActivationKey, 
+//            contentAssistActivationChars);
+//    adapter.setProposalAcceptanceStyle(ContentProposalAdapter.PROPOSAL_REPLACE);
+    
+    Button browseButton = newPushButton(tc, "Browse", "Click here to browse possible types");
+    browseButton.removeListener(SWT.Selection, this);
+    final AbstractSection finalSection = aSection;
+    browseButton.addListener(SWT.Selection, new Listener() {
+      public void handleEvent(Event event) {
+        errorMessageUI.setText("");
+        SelectTypeDialog dialog = new SelectTypeDialog(finalSection, candidatesToPickFrom); 
+//          OpenTypeSystemSelectionDialog dialog = 
+//              new OpenTypeSystemSelectionDialog(getShell(), typeList);
+        if (dialog.open() != IDialogConstants.OK_ID)
+          return;
+        
+        text.setText((null == dialog.nameSpaceName || 
+                "".equals(dialog.nameSpaceName)) ? 
+                dialog.typeName :
+                dialog.nameSpaceName + "." + dialog.typeName);
+        if (okButton != null)
+          enableOK();
+    /*
+        Object[] types = dialog.getResult();
+        if (types != null && types.length > 0) {
+          ITypeSystemInfo selectedType = (ITypeSystemInfo) types[0];
+          text.setText(selectedType.getFullName());
+          enableOK();
+        }
+    */
+      }
+    });
+    /*
+    TypeSystemCompletionProcessor processor = new TypeSystemCompletionProcessor(
+            candidatesToPickFrom);
+    ControlContentAssistHelper.createTextContentAssistant(text, processor);
+    text.addListener(SWT.KeyDown, new Listener() {
+      public void handleEvent(Event e) {
+        errorMessageUI.setText("");
+      }
+    });
+    text.addListener(SWT.Modify, new Listener() {
+      public void handleEvent(Event e) {
+        textModifyCallback(e);
+      }
+    });
+    */
+    return text;
+  }
+
+  public void textModifyCallback(Event e) {
+  }
+ 
+  // default implementation - always overridden when used
+  public TypesWithNameSpaces getTypeSystemInfoList() {
+    return new TypesWithNameSpaces();
+  }
+
+  protected boolean typeContainedInTypeSystemInfoList(String fullTypeName, TypesWithNameSpaces types) {
+    String key = AbstractSection.getShortName(fullTypeName);
+    String nameSpace = AbstractSection.getNameSpace(fullTypeName);
+    
+    Set s = (Set)types.sortedNames.get(key);
+    
+    if (null == s) 
+      return false;
+    
+    return s.contains(nameSpace);
+  }
+
+  /**
+   * In XML, a 0 - length string is represented as <xxx/>, while a null value causes the element to
+   * be omitted. Fix up values to be null if empty.
+   * 
+   * @param v
+   * @return null for 0 length string
+   */
+  public static String nullIf0lengthString(String v) {
+    if ("".equals(v))
+      return null;
+    return v;
+  }
+
+  public static String convertNull(String v) {
+    if (null == v)
+      return "";
+    return v;
+  }
+}
diff --git a/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/dialogs/AbstractDialogKeyVerify.java b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/dialogs/AbstractDialogKeyVerify.java
new file mode 100644
index 0000000..9d24873
--- /dev/null
+++ b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/dialogs/AbstractDialogKeyVerify.java
@@ -0,0 +1,71 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS 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.taeconfigurator.editors.ui.dialogs;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.StyledText;
+import org.eclipse.swt.custom.VerifyKeyListener;
+import org.eclipse.swt.events.VerifyEvent;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Label;
+
+import org.apache.uima.taeconfigurator.editors.ui.AbstractSection;
+
+public abstract class AbstractDialogKeyVerify extends AbstractDialog implements VerifyKeyListener {
+
+  protected AbstractDialogKeyVerify(AbstractSection aSection, String title, String description) {
+    super(aSection, title, description);
+  }
+
+  protected StyledText newLabeledSingleLineStyledText(Composite twoCol, String label, String tip) {
+    setTextAndTip(new Label(twoCol, SWT.NONE), label, tip);
+    return newSingleLineStyledText(twoCol, tip);
+  }
+
+  protected StyledText newSingleLineStyledText(Composite parent, String tip) {
+    StyledText w = new StyledText(parent, SWT.SINGLE | SWT.BORDER);
+    w.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+    w.setToolTipText(tip);
+    w.addListener(SWT.KeyUp, this);
+    w.addVerifyKeyListener(this);
+    w.addListener(SWT.MouseUp, this); // for paste operation
+    return w;
+  }
+
+  public void verifyKey(VerifyEvent event) {
+    event.doit = true;
+    errorMessageUI.setText("");
+    if (verifyKeyChecks(event))
+      return;
+    event.doit = false;
+    setErrorMessage("An invalid key press was ignored. Please try again.");
+    return;
+  }
+
+  // overridden in methods needing other key checks
+  /**
+   * Default verify key checks
+   */
+  public boolean verifyKeyChecks(VerifyEvent event) {
+    return true;
+  }
+
+}
diff --git a/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/dialogs/AbstractDialogKeyVerifyJavaNames.java b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/dialogs/AbstractDialogKeyVerifyJavaNames.java
new file mode 100644
index 0000000..47cc0a0
--- /dev/null
+++ b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/dialogs/AbstractDialogKeyVerifyJavaNames.java
@@ -0,0 +1,102 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.uima.taeconfigurator.editors.ui.dialogs;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.StyledText;
+import org.eclipse.swt.custom.VerifyKeyListener;
+import org.eclipse.swt.events.VerifyEvent;
+import org.eclipse.swt.events.VerifyListener;
+import org.eclipse.swt.widgets.Composite;
+
+import org.apache.uima.taeconfigurator.editors.ui.AbstractSection;
+
+public abstract class AbstractDialogKeyVerifyJavaNames extends AbstractDialogKeyVerify implements
+        VerifyKeyListener, VerifyListener {
+
+  protected StyledText newSingleLineStyledText(Composite parent, String tip) {
+    StyledText w = super.newSingleLineStyledText(parent, tip);
+    w.addVerifyListener(this);
+    return w;
+  }
+
+  protected AbstractDialogKeyVerifyJavaNames(AbstractSection aSection, String title,
+          String description) {
+    super(aSection, title, description);
+  }
+
+  /**
+   * Java name space names verify key checks for java identifier and periods
+   */
+  public boolean verifyKeyChecks(VerifyEvent event) {
+    if (event.keyCode == SWT.CR || event.keyCode == SWT.TAB)
+      return true;
+    if (Character.isJavaIdentifierPart(event.character))
+      return true;
+    StyledText w = (StyledText) event.widget;
+    String text = w.getText();
+    int len = text.length();
+    if (event.character == '.') {
+      if (len == 0)
+        return false;
+      return true;
+    }
+    return false;
+  }
+
+  /**
+   * @param event
+   *          the text change event.
+   *          <ul>
+   *          <li>event.start - the replace start offset</li>
+   *          <li>event.end - the replace end offset</li>
+   *          <li>event.text - the new text</li>
+   *          </ul>
+   */
+  public void verifyText(VerifyEvent event) {
+    event.doit = true;
+    String oldStr = ((StyledText) event.widget).getText();
+    String newStr = oldStr.substring(0, event.start) + event.text + oldStr.substring(event.end);
+    if (newStr.indexOf("..") >= 0) {
+      event.doit = false;
+      setErrorMessage("You cannot have two periods in a row.");
+      return;
+    }
+    if (namePartStartsWithDigit(newStr)) {
+      event.doit = false;
+      setErrorMessage("Name parts cannot start with a digit.");
+      return;
+    }
+  }
+
+  private boolean namePartStartsWithDigit(final String s) {
+    if (null == s || s.length() == 0)
+      return false;
+    int testloc = 0;
+    if (Character.isDigit(s.charAt(testloc)))
+      return true;
+    for (testloc = 1 + s.indexOf('.', testloc); testloc > 0 && testloc < s.length(); testloc = 1 + s
+            .indexOf('.', testloc))
+      if (Character.isDigit(s.charAt(testloc)))
+        return true;
+    return false;
+  }
+
+}
diff --git a/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/dialogs/AbstractDialogMultiColTable.java b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/dialogs/AbstractDialogMultiColTable.java
new file mode 100644
index 0000000..61b3551
--- /dev/null
+++ b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/dialogs/AbstractDialogMultiColTable.java
@@ -0,0 +1,115 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS 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.taeconfigurator.editors.ui.dialogs;
+
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.TableItem;
+
+import org.apache.uima.taeconfigurator.editors.ui.AbstractSection;
+import org.apache.uima.taeconfigurator.editors.ui.Utility;
+
+public abstract class AbstractDialogMultiColTable extends AbstractDialog {
+
+  protected String checkedIndicator(int col) {
+    if (col == 1)
+      return "In";
+    else
+      return "Out";
+  }
+
+  protected static final String UNCHECKED = "";
+
+  Table table;
+
+  protected boolean enableCol1 = true;
+
+  protected boolean enableCol2 = true;
+
+  protected int numberChecked = 0;
+
+  protected AbstractDialogMultiColTable(AbstractSection aSection, String title, String description) {
+    super(aSection, title, description);
+  }
+
+  public void handleEvent(Event event) {
+    if (event.type == SWT.MouseDown && event.widget == table) {
+      Point mousePosition = new Point(event.x, event.y);
+      TableItem item = table.getItem(mousePosition);
+      if (null == item) {
+        jitHowTo();
+        return;
+      }
+
+      int col = getHitColumn(item, mousePosition);
+      if (col != 1 && col != 2) {
+        jitHowTo();
+        return;
+      }
+      if (col == 1 && !enableCol1) {
+        setErrorMessage("This resource can't be marked as input");
+        return;
+      }
+      if (col == 2 && !enableCol2) {
+        setErrorMessage("This resource can't be marked as output");
+        return;
+      }
+      errorMessageUI.setText("");
+      toggleValue(item, col);
+    }
+    super.handleEvent(event);
+  }
+
+  private void jitHowTo() {
+    Utility.popMessage("Where to mouse click",
+            "Please click the mouse in the input or output columns to toggle the selection.",
+            MessageDialog.INFORMATION);
+  }
+
+  protected void toggleValue(TableItem item, int col) {
+    item.setText(col, item.getText(col).equals(checkedIndicator(col)) ? UNCHECKED
+            : checkedIndicator(col));
+    if (item.getText(col).equals(checkedIndicator(col)))
+      numberChecked++;
+    else
+      numberChecked--;
+  }
+
+  public boolean isValid() {
+    return true;
+  }
+
+  public void enableOK() {
+    errorMessageUI.setText("");
+    okButton.setEnabled(numberChecked > 0);
+  }
+
+  protected void setChecked(TableItem item, int col, boolean value) {
+    boolean prevChecked = checkedIndicator(col).equals(item.getText(col));
+    item.setText(col, value ? checkedIndicator(col) : UNCHECKED);
+    if (value && !prevChecked)
+      numberChecked++;
+    else if (!value && prevChecked)
+      numberChecked--;
+  }
+}
diff --git a/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/dialogs/AddAllowedValueDialog.java b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/dialogs/AddAllowedValueDialog.java
new file mode 100644
index 0000000..7f5d24a
--- /dev/null
+++ b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/dialogs/AddAllowedValueDialog.java
@@ -0,0 +1,92 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS 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.taeconfigurator.editors.ui.dialogs;
+
+import org.eclipse.swt.custom.StyledText;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Text;
+
+import org.apache.uima.resource.metadata.AllowedValue;
+import org.apache.uima.taeconfigurator.editors.ui.AbstractSection;
+
+public class AddAllowedValueDialog extends AbstractDialogKeyVerify {
+  private StyledText allowedValueUI;
+
+  private Text descriptionUI;
+
+  public String allowedValue;
+
+  public String description;
+
+  private AllowedValue existingAv;
+
+  /**
+   * Constructor for Adding or Editing an Allowed Value.
+   * 
+   * @param aSection
+   * @param aExistingTd
+   */
+  public AddAllowedValueDialog(AbstractSection aSection, AllowedValue aExistingAv) {
+    super(aSection, "Add an Allowed Value for a String subtype",
+            "Use this panel to add or edit an allowed value.  The allowed value is any string.");
+    existingAv = aExistingAv;
+  }
+
+  protected Control createDialogArea(Composite parent) {
+    Composite mainArea = (Composite) super.createDialogArea(parent, existingAv);
+
+    // This part of the form looks like this sketch
+    //   
+    // Allowed Value: Text field << in 2 grid composite
+    // description: Text field << in 2 grid composite
+
+    Composite twoCol = new2ColumnComposite(mainArea);
+
+    allowedValueUI = newLabeledSingleLineStyledText(twoCol, "Allowed Value",
+            "A literal string value which this string is allowed to have");
+    descriptionUI = newDescription(twoCol, "Description of the allowed value");
+    newErrorMessage(twoCol, 2);
+
+    if (null != existingAv) {
+      descriptionUI.setText(convertNull(existingAv.getDescription()));
+      allowedValueUI.setText(convertNull(existingAv.getString()));
+    }
+
+    return mainArea;
+  }
+
+  public void copyValuesFromGUI() {
+    allowedValue = allowedValueUI.getText();
+    description = nullIf0lengthString(descriptionUI.getText());
+  }
+
+  public boolean isValid() {
+    if (allowedValue.length() == 0)
+      return false;
+    return true;
+  }
+
+  public void enableOK() {
+    copyValuesFromGUI();
+    okButton.setEnabled(allowedValue.length() > 0);
+  }
+
+}
diff --git a/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/dialogs/AddCapabilityFeatureDialog.java b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/dialogs/AddCapabilityFeatureDialog.java
new file mode 100644
index 0000000..4644181
--- /dev/null
+++ b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/dialogs/AddCapabilityFeatureDialog.java
@@ -0,0 +1,179 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS 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.taeconfigurator.editors.ui.dialogs;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.TableColumn;
+import org.eclipse.swt.widgets.TableItem;
+
+import org.apache.uima.analysis_engine.TypeOrFeature;
+import org.apache.uima.cas.Feature;
+import org.apache.uima.cas.Type;
+import org.apache.uima.resource.metadata.Capability;
+import org.apache.uima.taeconfigurator.editors.ui.AbstractSection;
+import org.apache.uima.taeconfigurator.editors.ui.CapabilitySection;
+import org.apache.uima.taeconfigurator.editors.ui.Utility;
+
+public class AddCapabilityFeatureDialog extends AbstractDialogMultiColTable {
+
+  public String[] features; // this is the selection
+
+  public boolean[] inputs;
+
+  public boolean[] outputs;
+
+  public boolean allFeaturesInput = false;
+
+  public boolean allFeaturesOutput = false;
+
+  private Feature[] allFeatures;
+
+  private Capability capability;
+
+  private Type selectedType;
+
+  private boolean inputNotAllowed = true;
+
+  private static Feature[] featureArray0 = new Feature[0];
+
+  public AddCapabilityFeatureDialog(AbstractSection aSection, Type aSelectedType, Capability c) {
+    super(
+            aSection,
+            "Specify features input and / or output",
+            "Designate by mouse clicking one or more features in the Input and/or Output column, to designate as Input and/or Output press \"OK\"");
+    selectedType = aSelectedType;
+    allFeatures = (Feature[]) selectedType.getFeatures().toArray(featureArray0);
+    Arrays.sort(allFeatures);
+
+    capability = c;
+    TypeOrFeature[] localInputs = c.getInputs();
+    String typeName = selectedType.getName();
+    if (null != localInputs) {
+      for (int i = 0; i < localInputs.length; i++) {
+        if (localInputs[i].isType() && typeName.equals(localInputs[i].getName())) {
+          inputNotAllowed = false;
+          break;
+        }
+      }
+    }
+  }
+
+  protected Control createDialogArea(Composite parent) {
+    Composite composite = (Composite) super.createDialogArea(parent);
+
+    table = newTable(composite, SWT.MULTI | SWT.BORDER | SWT.V_SCROLL | SWT.FULL_SELECTION);
+    ((GridData) table.getLayoutData()).heightHint = 100;
+    table.setHeaderVisible(true);
+    table.setLinesVisible(true);
+    new TableColumn(table, SWT.NONE).setText("Feature Name");
+    new TableColumn(table, SWT.NONE).setText("Input");
+    new TableColumn(table, SWT.NONE).setText("Output");
+
+    TableItem item = new TableItem(table, SWT.NONE);
+    item.setText(0, CapabilitySection.ALL_FEATURES);
+    TypeOrFeature tof = CapabilitySection.getTypeOrFeature(capability.getInputs(), selectedType
+            .getName());
+    setChecked(item, 1, null == tof ? false : tof.isAllAnnotatorFeatures());
+    tof = CapabilitySection.getTypeOrFeature(capability.getOutputs(), selectedType.getName());
+    setChecked(item, 2, null == tof ? false : tof.isAllAnnotatorFeatures());
+
+    for (int i = 0; i < allFeatures.length; i++) {
+      item = new TableItem(table, SWT.NONE);
+      item.setText(0, allFeatures[i].getShortName());
+      setChecked(item, 1, CapabilitySection.isInput(getTypeFeature(allFeatures[i]), capability));
+      setChecked(item, 2, CapabilitySection.isOutput(getTypeFeature(allFeatures[i]), capability));
+    }
+
+    table.removeListener(SWT.Selection, this);
+    table.addListener(SWT.MouseDown, this); // for i / o toggling
+    section.packTable(table);
+    newErrorMessage(composite);
+    return composite;
+  }
+
+  /**
+   * return the actual type name : short-feature-name
+   * 
+   * @param feature
+   * @return
+   */
+  protected String getTypeFeature(Feature feature) {
+    return selectedType.getName() + ':' + feature.getShortName();
+  }
+
+  protected void toggleValue(TableItem item, int col) {
+    if (1 == col && inputNotAllowed) {
+      Utility.popMessage("Input not allowed",
+              "Input not allowed unless the type itself is also marked as an input.",
+              MessageDialog.ERROR);
+      return;
+    }
+    super.toggleValue(item, col); // updates numberChecked for this item
+    if (item.getText(col).equals(checkedIndicator(col)))
+      if (item.getText(0).equals(CapabilitySection.ALL_FEATURES))
+        uncheckAllOtherFeatures(col);
+      else
+        setChecked(table.getItem(0), col, false); // uncheck all-features
+  }
+
+  private void uncheckAllOtherFeatures(int column) {
+    TableItem[] items = table.getItems();
+    for (int i = 1; i < items.length; i++) {
+      setChecked(items[i], column, false);
+    }
+  }
+
+  public void copyValuesFromGUI() {
+    List names = new ArrayList();
+    List ins = new ArrayList();
+    List outs = new ArrayList();
+
+    for (int i = table.getItemCount() - 1; i >= 1; i--) {
+      TableItem item = table.getItem(i);
+      if (item.getText(1).equals(checkedIndicator(1))
+              || item.getText(2).equals(checkedIndicator(2))) {
+        names.add(item.getText(0));
+        ins.add(Boolean.valueOf(item.getText(1).equals(checkedIndicator(1))));
+        outs.add(Boolean.valueOf(item.getText(2).equals(checkedIndicator(2))));
+      }
+    }
+
+    features = (String[]) names.toArray(stringArray0);
+    inputs = new boolean[features.length];
+    outputs = new boolean[features.length];
+    for (int i = 0; i < features.length; i++) {
+      inputs[i] = ((Boolean) ins.get(i)).booleanValue();
+      outputs[i] = ((Boolean) outs.get(i)).booleanValue();
+    }
+
+    TableItem item = table.getItem(0);
+    allFeaturesInput = item.getText(1).equals(checkedIndicator(1));
+    allFeaturesOutput = item.getText(2).equals(checkedIndicator(2));
+  }
+
+}
diff --git a/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/dialogs/AddCapabilityTypeDialog.java b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/dialogs/AddCapabilityTypeDialog.java
new file mode 100644
index 0000000..b34c8b1
--- /dev/null
+++ b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/dialogs/AddCapabilityTypeDialog.java
@@ -0,0 +1,241 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS 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.taeconfigurator.editors.ui.dialogs;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.TableTreeItem;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.TableColumn;
+import org.eclipse.swt.widgets.TableItem;
+
+import org.apache.uima.analysis_engine.TypeOrFeature;
+import org.apache.uima.cas.CAS;
+import org.apache.uima.resource.metadata.Capability;
+import org.apache.uima.taeconfigurator.editors.ui.AbstractSection;
+import org.apache.uima.taeconfigurator.editors.ui.CapabilitySection;
+
+public class AddCapabilityTypeDialog extends AbstractDialogMultiColTable {
+
+  public String[] types; // this is the selection
+
+  public boolean[] inputs;
+
+  public boolean[] outputs;
+
+  private static final int NAME = 0;
+
+  private static final int INPUT = 1;
+
+  private static final int OUTPUT = 2;
+
+  private static final int NAMESPACE = 3;
+
+  CapabilitySection capabilitySection;
+
+  private Capability capability;
+
+  private TableTreeItem existing = null;
+
+  private static List excludedTypes = new ArrayList();
+  {
+    excludedTypes.add(CAS.TYPE_NAME_ARRAY_BASE);
+    excludedTypes.add(CAS.TYPE_NAME_EMPTY_FS_LIST);
+    excludedTypes.add(CAS.TYPE_NAME_EMPTY_FLOAT_LIST);
+    excludedTypes.add(CAS.TYPE_NAME_EMPTY_INTEGER_LIST);
+    excludedTypes.add(CAS.TYPE_NAME_EMPTY_STRING_LIST);
+    excludedTypes.add(CAS.TYPE_NAME_FS_ARRAY);
+    excludedTypes.add(CAS.TYPE_NAME_FS_LIST);
+    excludedTypes.add(CAS.TYPE_NAME_FLOAT);
+    excludedTypes.add(CAS.TYPE_NAME_FLOAT_ARRAY);
+    excludedTypes.add(CAS.TYPE_NAME_FLOAT_LIST);
+    excludedTypes.add(CAS.TYPE_NAME_INTEGER);
+    excludedTypes.add(CAS.TYPE_NAME_INTEGER_ARRAY);
+    excludedTypes.add(CAS.TYPE_NAME_INTEGER_LIST);
+    excludedTypes.add(CAS.TYPE_NAME_BOOLEAN);
+    excludedTypes.add(CAS.TYPE_NAME_BOOLEAN_ARRAY);
+    excludedTypes.add(CAS.TYPE_NAME_BYTE);
+    excludedTypes.add(CAS.TYPE_NAME_BYTE_ARRAY);
+    excludedTypes.add(CAS.TYPE_NAME_SHORT);
+    excludedTypes.add(CAS.TYPE_NAME_SHORT_ARRAY);
+    excludedTypes.add(CAS.TYPE_NAME_LONG);
+    excludedTypes.add(CAS.TYPE_NAME_LONG_ARRAY);
+    excludedTypes.add(CAS.TYPE_NAME_DOUBLE);
+    excludedTypes.add(CAS.TYPE_NAME_DOUBLE_ARRAY);
+    excludedTypes.add(CAS.TYPE_NAME_LIST_BASE);
+    excludedTypes.add(CAS.TYPE_NAME_NON_EMPTY_FS_LIST);
+    excludedTypes.add(CAS.TYPE_NAME_NON_EMPTY_FLOAT_LIST);
+    excludedTypes.add(CAS.TYPE_NAME_NON_EMPTY_INTEGER_LIST);
+    excludedTypes.add(CAS.TYPE_NAME_NON_EMPTY_STRING_LIST);
+    excludedTypes.add(CAS.TYPE_NAME_SOFA);
+    excludedTypes.add(CAS.TYPE_NAME_STRING);
+    excludedTypes.add(CAS.TYPE_NAME_STRING_ARRAY);
+    excludedTypes.add(CAS.TYPE_NAME_STRING_LIST);
+    excludedTypes.add(CAS.TYPE_NAME_TOP);
+  }
+
+  public AddCapabilityTypeDialog(AbstractSection aSection, Capability c) {
+    super(aSection, "Add Types to a Capability Set", "Mark one or more types as "
+            + ((aSection.isCasConsumerDescriptor()) ? "Input"
+                    : (aSection.isCasInitializerDescriptor() || aSection
+                            .isCollectionReaderDescriptor()) ? "Output" : "Input and/or Output")
+            + " by clicking the mouse in the corresponding column, and press OK");
+    capabilitySection = (CapabilitySection) aSection;
+    capability = c;
+    enableCol1 = !aSection.isCasInitializerDescriptor() && !aSection.isCollectionReaderDescriptor();
+    enableCol2 = !aSection.isCasConsumerDescriptor();
+  }
+
+  public AddCapabilityTypeDialog(AbstractSection aSection, Capability c, TableTreeItem aExisting) {
+    this(aSection, c);
+    existing = aExisting;
+  }
+
+  protected Control createDialogArea(Composite parent) {
+    Composite composite = (Composite) super.createDialogArea(parent, existing);
+
+    table = newTable(composite, SWT.MULTI | SWT.BORDER | SWT.V_SCROLL | SWT.FULL_SELECTION);
+    // ((GridData)table.getLayoutData()).heightHint = 100;
+    table.setHeaderVisible(true);
+    table.setLinesVisible(true);
+    new TableColumn(table, SWT.NONE).setText("Type Name");
+    new TableColumn(table, SWT.NONE).setText("Input");
+    new TableColumn(table, SWT.NONE).setText("Output");
+    new TableColumn(table, SWT.NONE).setText("Type Namespace");
+
+    if (null == existing) {
+      String[] allTypes = getAllTypesAsSortedArray();
+
+      for (int i = 0; i < allTypes.length; i++) {
+        if (!excludedTypes.contains(allTypes[i]) && !hasType(capability.getInputs(), allTypes[i])
+                && !hasType(capability.getOutputs(), allTypes[i])) {
+          TableItem item = new TableItem(table, SWT.NONE);
+          setGuiTypeName(item, allTypes[i]);
+        }
+      }
+    } else { // existing item being edited - just show one item
+      TableItem item = new TableItem(table, SWT.NONE);
+      item.setText(NAME, existing.getText(CapabilitySection.NAME_COL));
+      item.setText(NAMESPACE, existing.getText(CapabilitySection.NAMESPACE_COL));
+      TypeOrFeature tof = CapabilitySection.getTypeOrFeature(capability.getInputs(),
+              capabilitySection.getFullyQualifiedName(existing));
+      setChecked(item, 1, null != tof);
+      tof = CapabilitySection.getTypeOrFeature(capability.getOutputs(), capabilitySection
+              .getFullyQualifiedName(existing));
+      setChecked(item, 2, null != tof);
+    }
+
+    section.packTable(table);
+    // can't use selection event because it doesn't return mouse position
+    table.removeListener(SWT.Selection, this);
+    table.addListener(SWT.MouseDown, this); // for i / o toggling
+    newErrorMessage(composite);
+    return composite;
+  }
+
+  private boolean hasType(TypeOrFeature[] items, String name) {
+    if (null == items)
+      return false;
+    for (int i = 0; i < items.length; i++) {
+      if (items[i].isType() && items[i].getName().equals(name))
+        return true;
+    }
+    return false;
+  }
+
+  /**
+   * Return values having at least one of input or output selected
+   */
+  public void copyValuesFromGUI() {
+    List names = new ArrayList();
+    List ins = new ArrayList();
+    List outs = new ArrayList();
+
+    for (int i = table.getItemCount() - 1; i >= 0; i--) {
+      TableItem item = table.getItem(i);
+      if (item.getText(INPUT).equals(checkedIndicator(INPUT))
+              || item.getText(OUTPUT).equals(checkedIndicator(OUTPUT))) {
+        names.add(capabilitySection.getFullyQualifiedName(item.getText(NAMESPACE), item
+                .getText(NAME)));
+        ins.add(Boolean.valueOf(item.getText(INPUT).equals(checkedIndicator(INPUT))));
+        outs.add(Boolean.valueOf(item.getText(OUTPUT).equals(checkedIndicator(OUTPUT))));
+      }
+    }
+
+    types = (String[]) names.toArray(stringArray0);
+    inputs = new boolean[types.length];
+    outputs = new boolean[types.length];
+
+    for (int i = 0; i < types.length; i++) {
+      inputs[i] = ((Boolean) ins.get(i)).booleanValue();
+      outputs[i] = ((Boolean) outs.get(i)).booleanValue();
+    }
+  }
+
+  // used by dialog
+  public void setGuiTypeName(TableItem item, String typeName) {
+    item.setText(NAME, AbstractSection.getShortName(typeName));
+    item.setText(NAMESPACE, AbstractSection.getNameSpace(typeName));
+  }
+
+  public boolean isValid() {
+    for (int i = 0; i < types.length; i++) {
+      if (!inputs[i]) {
+        if (someFeatureOnType(types[i], INPUT)) {
+          setErrorMessage("This type has one or more features marked for input and can''t be removed as an Input.\nIf you want to do this, first remove the Input designation for all features on this type.");
+          return false;
+        }
+        // Use case: You can have
+        // a Type with output features, where the type itself is not output.
+        // In this case, the type must be in an input. The meaning is that
+        // the AE sets or populates features on existing types.
+        if (!outputs[i] && someFeatureOnType(types[i], OUTPUT) && !inputs[i]) {
+          setErrorMessage("This type has features which are output, and so must either be specified as INPUT (meaning features are populated or \"outputted\" on existing instances), or OUTPUT (meaning new instances of this type are created).  It can't be removed completely.\nIf you want to do this, first remove the features which are output for this type.");
+          return false;
+        }
+      }
+    }
+    return true;
+  }
+
+  /**
+   * return true if the type has a feature (except all-features) marked as INPUT (OUTPUT)
+   * 
+   * @param typeName
+   * @param IO
+   * @return
+   */
+  private boolean someFeatureOnType(String typeName, int IO) {
+    // special case for all-features
+    TypeOrFeature[] tofs = (IO == INPUT) ? capability.getInputs() : capability.getOutputs();
+    // you can remove the "INPUT" or "OUTPUT" designation from a type
+    // even if it has the all-features flag on.
+    String typeNamePlusColon = typeName + ':';
+    for (int i = 0; i < tofs.length; i++) {
+      if (!tofs[i].isType() && tofs[i].getName().startsWith(typeNamePlusColon))
+        return true;
+    }
+    return false;
+  }
+
+}
diff --git a/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/dialogs/AddExternalResourceDependencyDialog.java b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/dialogs/AddExternalResourceDependencyDialog.java
new file mode 100644
index 0000000..c0dd03e
--- /dev/null
+++ b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/dialogs/AddExternalResourceDependencyDialog.java
@@ -0,0 +1,134 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS 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.taeconfigurator.editors.ui.dialogs;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.StyledText;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Text;
+
+import org.apache.uima.resource.ExternalResourceDependency;
+import org.apache.uima.taeconfigurator.editors.ui.AbstractSection;
+import org.apache.uima.taeconfigurator.editors.ui.ResourceDependencySection;
+
+public class AddExternalResourceDependencyDialog extends AbstractDialogKeyVerifyJavaNames {
+
+  private StyledText keyNameUI;
+
+  public Button optionalUI;
+
+  private StyledText interfaceNameUI;
+
+  private Text descriptionUI;
+
+  public String keyName;
+
+  private String originalKeyName;
+
+  public boolean optional;
+
+  public String interfaceName;
+
+  public String description;
+
+  private ResourceDependencySection rdSection;
+
+  private ExternalResourceDependency existingXRD;
+
+  public AddExternalResourceDependencyDialog(AbstractSection aSection) {
+    super(aSection, "Add External Resource Dependency", "Add an External Resource Dependency");
+    rdSection = (ResourceDependencySection) aSection;
+  }
+
+  /**
+   * Constructor for Editing an existing XRD
+   * 
+   * @param aSection
+   * @param aExistingXRD
+   */
+  public AddExternalResourceDependencyDialog(AbstractSection aSection,
+          ExternalResourceDependency aExistingXRD) {
+    this(aSection);
+    existingXRD = aExistingXRD;
+  }
+
+  protected Control createDialogArea(Composite parent) {
+    Composite mainArea = (Composite) super.createDialogArea(parent, existingXRD);
+    createWideLabel(
+            mainArea,
+            "The only required field is the key name,\nwhich must be unique within this primitive Analysis Engine descriptor.");
+
+    // This part of the form looks like this sketch
+    //   
+    // keyName: Text field << in 2 grid composite
+    // description: Text field << in 2 grid composite
+    // impl Name: Text field << in 2 grid composite
+    // (checkbox) is Optional
+    // 
+
+    Composite twoCol = new2ColumnComposite(mainArea);
+
+    keyNameUI = newLabeledSingleLineStyledText(twoCol, "Key",
+            "Name used by the Primitive Analysis Engine to refer to the resource");
+
+    descriptionUI = newDescription(twoCol, "(Optional)Describes this resource dependency");
+
+    interfaceNameUI = newLabeledSingleLineStyledText(
+            twoCol,
+            "Interface",
+            "The fully qualified name of the Java Interface class used by the Analysis Engine to refer to the External Resource");
+
+    newErrorMessage(twoCol, 2);
+
+    optionalUI = newButton(mainArea, SWT.CHECK, "Check this box if this resource is optional",
+            "Uncheck if this resource is required");
+
+    if (null != existingXRD) {
+      descriptionUI.setText(convertNull(existingXRD.getDescription()));
+      optionalUI.setSelection(existingXRD.isOptional());
+      keyNameUI.setText(originalKeyName = existingXRD.getKey());
+      interfaceNameUI.setText(convertNull(existingXRD.getInterfaceName()));
+    }
+
+    return mainArea;
+  }
+
+  public void copyValuesFromGUI() {
+    keyName = keyNameUI.getText();
+    optional = optionalUI.getSelection();
+    description = nullIf0lengthString(descriptionUI.getText());
+    interfaceName = nullIf0lengthString(interfaceNameUI.getText());
+  }
+
+  public boolean isValid() {
+    if (keyName.length() == 0)
+      return false;
+    if (!keyName.equals(originalKeyName) && rdSection.keyNameAlreadyDefined(keyName))
+      return false;
+    return true;
+  }
+
+  public void enableOK() {
+    copyValuesFromGUI();
+    okButton.setEnabled(keyName.length() > 0);
+  }
+}
diff --git a/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/dialogs/AddExternalResourceDialog.java b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/dialogs/AddExternalResourceDialog.java
new file mode 100644
index 0000000..d130141
--- /dev/null
+++ b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/dialogs/AddExternalResourceDialog.java
@@ -0,0 +1,172 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.uima.taeconfigurator.editors.ui.dialogs;
+
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.StyledText;
+import org.eclipse.swt.events.VerifyEvent;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Text;
+
+import org.apache.uima.resource.ExternalResourceDescription;
+import org.apache.uima.resource.FileLanguageResourceSpecifier;
+import org.apache.uima.resource.FileResourceSpecifier;
+import org.apache.uima.resource.ResourceSpecifier;
+import org.apache.uima.taeconfigurator.editors.ui.AbstractSection;
+import org.apache.uima.taeconfigurator.editors.ui.ExtnlResBindSection;
+import org.apache.uima.taeconfigurator.editors.ui.Utility;
+
+public class AddExternalResourceDialog extends AbstractDialogKeyVerify {
+
+  private ExternalResourceDescription existingXRD = null;
+
+  private StyledText xrNameUI;
+
+  private String originalXrName;
+
+  private Text xrDescriptionUI;
+
+  private StyledText xrUrlUI;
+
+  private StyledText xrUrlSuffixUI;
+
+  private StyledText xrImplementationUI;
+
+  private ExtnlResBindSection extnlResBindSection;
+
+  public String xrName;
+
+  public String xrDescription;
+
+  public String xrUrl;
+
+  public String xrUrlSuffix;
+
+  public String xrImplementation;
+
+  public AddExternalResourceDialog(AbstractSection aSection) {
+    super(aSection, "Add an External Resource Definition", "Define and name an external resource");
+    extnlResBindSection = (ExtnlResBindSection) aSection;
+  }
+
+  public AddExternalResourceDialog(AbstractSection aSection,
+          ExternalResourceDescription aExistingXRD) {
+    this(aSection);
+    existingXRD = aExistingXRD;
+    originalXrName = existingXRD.getName();
+  }
+
+  protected Control createDialogArea(Composite parent) {
+    Composite composite = (Composite) super.createDialogArea(parent, existingXRD);
+
+    // name: styledText name
+    // description: Text multi-line
+    // URL or
+    // URL_Prefix: styledText URL
+    // (optional)
+    //
+    // URL_Suffix: styledText URL_Suffix
+    // (optional)
+    //
+    // Implementation: styledText
+    // (optional)
+
+    createWideLabel(
+            composite,
+            "The first URL field is used to identify the external resource.\nIf both URL fields are used, they form a name by concatenating the first with the document language and then with the second (suffix) URL.\nThe (optional) Implementation specifies a Java class which implements the interface used by the Analysis Engine to access the resource.");
+
+    Composite twoCol = new2ColumnComposite(composite);
+
+    xrNameUI = newLabeledSingleLineStyledText(twoCol, "Name:",
+            "(Required) The name of this resource; it must be unique in this Analysis Engine.");
+    xrDescriptionUI = newDescription(twoCol, "(Optional) Description of the External Resource");
+    xrUrlUI = newLabeledSingleLineStyledText(twoCol, "URL:",
+            "(Required) A URL for this resource, or the URL prefix if a suffix is being used");
+    xrUrlSuffixUI = newLabeledSingleLineStyledText(
+            twoCol,
+            "URL Suffix",
+            "(Optional) A URL part that will be suffixed to the prefix with the language being used inserted in-between");
+    xrImplementationUI = newLabeledSingleLineStyledText(
+            twoCol,
+            "Implementation",
+            "(Optional) The name of a Java class implementing the interface used by the Analysis Engine to access this resource.");
+    newErrorMessage(twoCol, 2);
+
+    if (null != existingXRD) {
+      xrNameUI.setText(existingXRD.getName());
+      xrDescriptionUI.setText(convertNull(existingXRD.getDescription()));
+      ResourceSpecifier rs = existingXRD.getResourceSpecifier();
+      if (rs instanceof FileResourceSpecifier)
+        xrUrlUI.setText(((FileResourceSpecifier) rs).getFileUrl());
+      else if (rs instanceof FileLanguageResourceSpecifier) {
+        xrUrlUI.setText(((FileLanguageResourceSpecifier) rs).getFileUrlPrefix());
+        xrUrlSuffixUI.setText(((FileLanguageResourceSpecifier) rs).getFileUrlSuffix());
+      } else {
+        Utility.popMessage("Unknown resource type", "The resource type '" + rs.getClass().getName()
+                + "' is unknown.  Editing should be done by hand in the source view.",
+                MessageDialog.WARNING);
+      }
+      String impName = existingXRD.getImplementationName();
+      xrImplementationUI.setText(convertNull(impName));
+    }
+    return composite;
+  }
+
+  public void copyValuesFromGUI() {
+    xrName = xrNameUI.getText();
+    xrDescription = nullIf0lengthString(xrDescriptionUI.getText());
+    xrUrl = xrUrlUI.getText();
+    xrUrlSuffix = nullIf0lengthString(xrUrlSuffixUI.getText());
+    xrImplementation = nullIf0lengthString(xrImplementationUI.getText());
+  }
+
+  /**
+   * Called for many widgets
+   */
+  public boolean verifyKeyChecks(VerifyEvent event) {
+    if (event.keyCode == SWT.CR || event.keyCode == SWT.TAB)
+      return true;
+
+    if (Character.isJavaIdentifierPart(event.character) || event.character == '.')
+      return true;
+
+    if ((event.widget == xrUrlUI || event.widget == xrUrlSuffixUI)
+            && (event.character == '/' || event.character == ':'))
+      return true;
+    return false;
+  }
+
+  public boolean isValid() {
+    if (xrName.length() == 0)
+      return false;
+    if (!xrName.equals(originalXrName) && extnlResBindSection.resourceNameAlreadyDefined(xrName))
+      return false;
+    if (xrUrl.length() == 0)
+      return false;
+    return true;
+  }
+
+  public void enableOK() {
+    copyValuesFromGUI();
+    okButton.setEnabled(xrName.length() > 0 && xrUrl.length() > 0);
+  }
+}
diff --git a/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/dialogs/AddFeatureDialog.java b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/dialogs/AddFeatureDialog.java
new file mode 100644
index 0000000..eed1072
--- /dev/null
+++ b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/dialogs/AddFeatureDialog.java
@@ -0,0 +1,247 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS 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.taeconfigurator.editors.ui.dialogs;
+
+import org.apache.uima.cas.Type;
+import org.apache.uima.resource.metadata.FeatureDescription;
+import org.apache.uima.resource.metadata.TypeDescription;
+import org.apache.uima.taeconfigurator.editors.ui.AbstractSection;
+import org.apache.uima.taeconfigurator.editors.ui.TypeSection;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.CCombo;
+import org.eclipse.swt.custom.StyledText;
+import org.eclipse.swt.events.VerifyEvent;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Text;
+
+public class AddFeatureDialog extends AbstractDialogKeyVerify {
+
+  private static final int ONLY_NON_PRIMITIVE_TYPES = 0;
+
+  private static final int ALL_TYPES = 1;
+
+  private StyledText featureNameUI;
+
+  private Text featureRangeNameUI;
+
+  private Text descriptionUI;
+
+  public String featureName;
+
+  private String originalFeatureName;
+
+  public String featureRangeName;
+
+  public String description;
+
+  public String elementRangeName;
+
+  public Boolean multiRef;
+
+  private TypeSection typeSection;
+
+  private TypeDescription td;
+
+  private FeatureDescription existingFd;
+
+  private TypesWithNameSpaces allTypesList;
+
+  private Composite multiRefComposite;
+
+  private CCombo multiRefUI;
+
+  private Composite elementTypeComposite;
+
+  private Text elementRangeNameUI;
+
+  private int typeFilter;
+
+  /**
+   * @param aSection
+   * @param aExistingTd
+   */
+  public AddFeatureDialog(AbstractSection aSection, TypeDescription aTd,
+          FeatureDescription aExistingFd) {
+    super(aSection, "Add a Feature", "Use this panel to add or edit a feature");
+    typeSection = (TypeSection) aSection;
+    td = aTd;
+    existingFd = aExistingFd;
+  }
+
+  protected Control createDialogArea(Composite parent) {
+    Composite mainArea = (Composite) super.createDialogArea(parent, existingFd);
+    createWideLabel(mainArea, "The feature name must be unique within this type");
+
+    // This part of the form looks like this sketch
+    //   
+    // Feature Name: Text field << in 2 grid composite
+    // Range Type: CCombo << in 2 grid composite
+    // checkbox: multiple references allowed (hidden if not applicable)
+    // Element Type: same as above (hidden if not applicable)
+    // description: Text field << in 2 grid composite
+
+    Composite twoCol = new2ColumnComposite(mainArea);
+
+    featureNameUI = newLabeledSingleLineStyledText(twoCol, "Feature Name", S_);
+
+    typeFilter = ALL_TYPES;
+    featureRangeNameUI = newLabeledTypeInput(section, twoCol, "Range Type:",
+            "The range type specifies the type of value this feature can hold.");
+
+    multiRefComposite = new2ColumnComposite(twoCol);
+    ((GridData) multiRefComposite.getLayoutData()).horizontalSpan = 2;
+    multiRefUI = newLabeledCCombo(multiRefComposite, "References:",
+            "Specify if this reference is the only reference to the collection object");
+    multiRefUI.add("Not Specified - defaults to multiple references not allowed");
+    multiRefUI.add("Multiple references not allowed");
+    multiRefUI.add("Multiple references allowed");
+    multiRefUI.select(0);
+
+    elementTypeComposite = new2ColumnComposite(twoCol);
+    ((GridData) elementTypeComposite.getLayoutData()).horizontalSpan = 2;
+    typeFilter = ONLY_NON_PRIMITIVE_TYPES;
+    elementRangeNameUI = newLabeledTypeInput(section, elementTypeComposite, "Element Type:",
+            "The element type of each element in the Array or List object");
+
+    descriptionUI = newDescription(twoCol, S_);
+    newErrorMessage(twoCol, 2);
+
+    if (null != existingFd) {
+      descriptionUI.setText(convertNull(existingFd.getDescription()));
+      featureNameUI.setText(originalFeatureName = existingFd.getName());
+      featureRangeNameUI.setText(existingFd.getRangeTypeName());
+      Boolean mra = existingFd.getMultipleReferencesAllowed();
+      multiRefUI.select((null == mra) ? 0 : (mra.booleanValue()) ? 2 : 1);
+      String ert = existingFd.getElementType();
+      elementRangeNameUI.setText((null == ert) ? "" : ert);
+
+    }
+    manageVisibleFields();
+    return mainArea;
+  }
+
+  private void manageVisibleFields() {
+    String range = featureRangeNameUI.getText();
+    if (AbstractSection.isArrayOrListType(range)) {
+      multiRefComposite.setVisible(true);
+      if (AbstractSection.isFSArrayOrListType(range)) {
+        elementTypeComposite.setVisible(true);
+      } else {
+        elementTypeComposite.setVisible(false);
+      }
+    } else {
+      multiRefComposite.setVisible(false);
+      elementTypeComposite.setVisible(false);
+    }
+  }
+  
+  
+
+  public void handleEvent(Event event) {
+    super.handleEvent(event);
+    if (event.type == SWT.Modify && event.widget == featureRangeNameUI)
+      manageVisibleFields();
+  }
+
+  public TypesWithNameSpaces getTypeSystemInfoList() {
+    TypesWithNameSpaces result = super.getTypeSystemInfoList();
+    Type[] allTypes = (Type[]) editor.allTypes.get().values().toArray(new Type[0]);
+/*    Arrays.sort(allTypes, new Comparator() {
+
+      public int compare(Object o1, Object o2) {
+        Type t1 = (Type) o1;
+        Type t2 = (Type) o2;
+        return t1.getShortName().compareTo(t2.getShortName());
+      }
+    });
+    */
+    for (int i = 0; i < allTypes.length; i++) {
+      Type type = allTypes[i];
+      if (typeFilter == ONLY_NON_PRIMITIVE_TYPES) {
+        if (!type.isPrimitive()) {
+          result.add(type.getName());
+        }
+      } else {
+        result.add(type.getName());
+      }
+    }
+    if (typeFilter == ALL_TYPES)
+      allTypesList = result;
+    return result;
+  }
+
+  public void copyValuesFromGUI() {
+    featureName = featureNameUI.getText();
+    description = nullIf0lengthString(descriptionUI.getText());
+    featureRangeName = featureRangeNameUI.getText();
+    multiRef = (1 == multiRefUI.getSelectionIndex()) ? Boolean.FALSE : (2 == multiRefUI
+            .getSelectionIndex()) ? Boolean.TRUE : null;
+    if (TypeSection.isFSArrayOrListType(featureRangeName)) {
+      elementRangeName = elementRangeNameUI.getText();
+      if ("".equals(elementRangeName)) {
+        elementRangeName = null;
+      }
+    } else {
+      elementRangeName = null;
+    }
+  }
+
+  public boolean verifyKeyChecks(VerifyEvent event) {
+    if (event.keyCode == SWT.CR || event.keyCode == SWT.TAB)
+      return true;
+    if (Character.isJavaIdentifierPart(event.character))
+      return true;
+    if (event.widget == featureRangeNameUI && event.character == '.')
+      return true;
+    return false;
+  }
+
+  public boolean isValid() {
+
+    if (featureName.length() == 0 || featureRangeName.length() == 0)
+      return false;
+    if (!featureName.equals(originalFeatureName)) {
+      String errMsg = typeSection.checkFeature(this, td, existingFd);
+      if (null != errMsg) {
+        setErrorMessage(errMsg);
+        return false;
+      }
+    }
+    if (!typeContainedInTypeSystemInfoList(featureRangeName, allTypesList)) {
+      setErrorMessage("RangeType '" + featureRangeName
+              + "' is unknown. If this is intended, please define it first.");
+      return false;
+    }
+    return true;
+  }
+
+  public void textModifyCallback(Event e) {
+    manageVisibleFields();
+  }
+
+  public void enableOK() {
+    copyValuesFromGUI();
+    okButton.setEnabled(featureName.length() > 0 && featureRangeName.length() > 0);
+  }
+
+}
diff --git a/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/dialogs/AddIndexDialog.java b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/dialogs/AddIndexDialog.java
new file mode 100644
index 0000000..d13af7a
--- /dev/null
+++ b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/dialogs/AddIndexDialog.java
@@ -0,0 +1,302 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS 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.taeconfigurator.editors.ui.dialogs;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.uima.UIMAFramework;
+import org.apache.uima.cas.admin.FSIndexComparator;
+import org.apache.uima.resource.metadata.FsIndexDescription;
+import org.apache.uima.resource.metadata.FsIndexKeyDescription;
+import org.apache.uima.taeconfigurator.editors.ui.AbstractSection;
+import org.apache.uima.taeconfigurator.editors.ui.IndexSection;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.CCombo;
+import org.eclipse.swt.custom.StyledText;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.TableColumn;
+import org.eclipse.swt.widgets.TableItem;
+import org.eclipse.swt.widgets.Text;
+
+public class AddIndexDialog extends AbstractDialogKeyVerifyJavaNames {
+
+  private static final String TYPE_PRIORITY = "Type Priority";
+
+  private static final String STANDARD = "Standard";
+
+  private static final String REVERSE = "Reverse";
+
+  private StyledText indexNameUI;
+
+  private Text indexTypeUI;
+
+  private CCombo indexKindUI;
+
+  private Table table;
+
+  private Button addButton;
+
+  private Button editButton;
+
+  private Button removeButton;
+
+  private Button upButton;
+
+  private Button downButton;
+
+  private Composite tableContainer;
+
+  private Label keyTable;
+
+  public String indexName;
+
+  public String indexType;
+
+  public String indexKind;
+
+  public FsIndexKeyDescription[] keys;
+
+  private String originalIndexName;
+
+  private IndexSection indexSection;
+
+  private FsIndexDescription existingNDX;
+
+  public AddIndexDialog(AbstractSection aSection) {
+    super(aSection, "Add an index", "Add or Edit an index specification");
+    indexSection = (IndexSection) aSection;
+  }
+
+  /**
+   * Constructor for Editing an existing XRD
+   * 
+   * @param aSection
+   * @param aExistingXRD
+   */
+  public AddIndexDialog(AbstractSection aSection, FsIndexDescription aExistingNDX) {
+    this(aSection);
+    existingNDX = aExistingNDX;
+  }
+
+  protected Control createDialogArea(Composite parent) {
+    Composite mainArea = (Composite) super.createDialogArea(parent, existingNDX);
+    createWideLabel(mainArea, "The Index name must be globally unique.");
+
+    // This part of the form looks like this sketch
+    //   
+    // IndexName: Text field << in 2 grid composite
+    // IndexKind: combo
+    // IndexType: Text field << assisted <browse button>
+    // description: Text field << in 2 grid composite
+    // keys: first is text field assisted <browseButton>
+    // 2nd is combo asc/desc/typePriority
+
+    Composite twoCol = new2ColumnComposite(mainArea);
+
+    indexNameUI = newLabeledSingleLineStyledText(twoCol, "Index Name:",
+            "The globally unique index name");
+
+    indexKindUI = newLabeledCCombo(twoCol, "Index Kind:",
+            "Specify the kind of index - sorted, set, or bag");
+    indexKindUI.add("sorted");
+    indexKindUI.add("bag");
+    indexKindUI.add("set");
+
+    new Label(twoCol, SWT.NONE).setText("CAS Type");
+    indexTypeUI = newTypeInput(section, twoCol);
+
+    setTextAndTip(
+            keyTable = new Label(twoCol, SWT.NONE),
+            "Index Keys:",
+            "For Set and Sorted index kinds, specify the keys; for Sorted indexes specify also the sort direction.");
+    tableContainer = new2ColumnComposite(twoCol);
+    table = newTable(tableContainer, SWT.SINGLE | SWT.FULL_SELECTION);
+    table.setHeaderVisible(true);
+    new TableColumn(table, SWT.NONE).setText("Feature Name");
+    new TableColumn(table, SWT.NONE).setText("Sorting Direction");
+    table.addListener(SWT.MouseDoubleClick, this);
+
+    Composite buttonContainer = newButtonContainer(tableContainer);
+    addButton = newPushButton(buttonContainer, S_ADD, "Click here to add an Index key");
+    editButton = newPushButton(buttonContainer, S_EDIT, S_EDIT_TIP);
+    removeButton = newPushButton(buttonContainer, S_REMOVE, S_REMOVE_TIP);
+    upButton = newPushButton(buttonContainer, S_UP, S_UP_TIP);
+    downButton = newPushButton(buttonContainer, S_DOWN, S_DOWN_TIP);
+
+    newErrorMessage(twoCol, 2);
+
+    if (null == existingNDX) {
+      // set up defaults
+      indexNameUI.setText("some.default.Name");
+      indexKindUI.setText(indexKindUI.getItem(0));
+
+    } else {
+      indexNameUI.setText(originalIndexName = existingNDX.getLabel());
+      indexKindUI.setText(AbstractSection.handleDefaultIndexKind(existingNDX.getKind()));
+      indexTypeUI.setText(existingNDX.getTypeName());
+
+      keys = existingNDX.getKeys();
+      if (null != keys) {
+        for (int i = 0; i < keys.length; i++) {
+          addKey(keys[i]);
+        }
+      }
+    }
+    section.packTable(table);
+    indexKindUI.addListener(SWT.Modify, this);
+    boolean showKeys = "sorted".equals(indexKindUI.getText())
+            || "set".equals(indexKindUI.getText());
+    tableContainer.setVisible(showKeys);
+    keyTable.setVisible(showKeys);
+    return mainArea;
+  }
+
+  public TypesWithNameSpaces getTypeSystemInfoList() {
+    TypesWithNameSpaces result = super.getTypeSystemInfoList();
+    String[] allTypes = getAllTypesAsSortedArray();
+    for (int i = 0; i < allTypes.length; i++) {
+      result.add(allTypes[i]);
+    }
+    return result;
+  }
+
+  private void addKey(FsIndexKeyDescription key) {
+    if (null == key)
+      return;
+    TableItem item = new TableItem(table, SWT.NONE);
+    updateKey(item, key);
+  }
+
+  private void updateKey(TableItem item, FsIndexKeyDescription key) {
+    if (null == key)
+      return;
+    if (key.isTypePriority()) {
+      item.setText(0, S_);
+      item.setText(1, TYPE_PRIORITY);
+    } else {
+      item.setText(0, key.getFeatureName());
+      item.setText(1, key.getComparator() == FSIndexComparator.STANDARD_COMPARE ? STANDARD
+              : REVERSE);
+    }
+  }
+
+  public void handleEvent(Event event) {
+    if (event.widget == indexKindUI) {
+      boolean showKeys = "sorted".equals(indexKindUI.getText())
+              || "set".equals(indexKindUI.getText());
+      tableContainer.setVisible(showKeys);
+      keyTable.setVisible(showKeys);
+    } else if (event.widget == addButton) {
+      AddIndexKeyDialog dialog = new AddIndexKeyDialog(section, indexTypeUI.getText(), indexKindUI
+              .getText(), alreadyDefined(table.getItems()));
+      addKey(indexSection.addOrEditIndexKey(dialog, null));
+      section.packTable(table);
+    } else if (event.widget == editButton || event.type == SWT.MouseDoubleClick) {
+      TableItem item = table.getItem(table.getSelectionIndex());
+      AddIndexKeyDialog dialog = new AddIndexKeyDialog(section, indexTypeUI.getText(), indexKindUI
+              .getText(), alreadyDefined(table.getItems()), makeKey(item));
+      FsIndexKeyDescription key = indexSection.addOrEditIndexKey(dialog, null);
+      updateKey(item, key);
+      section.packTable(table);
+    } else if (event.widget == removeButton) {
+      TableItem item = table.getItem(table.getSelectionIndex());
+      table.setSelection(table.getSelectionIndex() - 1);
+      item.dispose();
+      section.packTable(table);
+    } else if (event.widget == upButton) {
+      AbstractSection.swapTableItems(table.getSelection()[0], table.getSelectionIndex() - 1);
+    } else if (event.widget == downButton) {
+      int i = table.getSelectionIndex();
+      TableItem[] items = table.getItems();
+      AbstractSection.swapTableItems(items[i + 1], i + 1);
+    }
+    super.handleEvent(event);
+  }
+
+  public List alreadyDefined(TableItem[] items) {
+    List result = new ArrayList();
+    if (null == items)
+      return result;
+    for (int i = 0; i < items.length; i++) {
+      result.add(items[i].getText(0));
+    }
+    return result;
+  }
+
+  public void copyValuesFromGUI() {
+    indexName = indexNameUI.getText();
+    indexKind = indexKindUI.getText();
+    indexType = indexTypeUI.getText();
+    TableItem[] items = table.getItems();
+    if (null != items) {
+      keys = new FsIndexKeyDescription[items.length];
+      for (int i = 0; i < items.length; i++) {
+        keys[i] = makeKey(items[i]);
+      }
+    } else
+      keys = null;
+  }
+
+  private FsIndexKeyDescription makeKey(TableItem item) {
+    FsIndexKeyDescription key = UIMAFramework.getResourceSpecifierFactory()
+            .createFsIndexKeyDescription();
+    boolean typePriority = TYPE_PRIORITY.equals(item.getText(1));
+    key.setTypePriority(typePriority);
+    if (!typePriority) {
+      key.setFeatureName(item.getText(0));
+      key.setComparator(STANDARD.equals(item.getText(1)) ? FSIndexComparator.STANDARD_COMPARE
+              : FSIndexComparator.REVERSE_STANDARD_COMPARE);
+    }
+    return key;
+  }
+
+  public boolean isValid() {
+    if (indexName.length() == 0 || indexType.length() == 0)
+      return false;
+    if (!indexName.equals(originalIndexName) && indexSection.isDuplicateIndexLabel(indexName)) {
+      errorMessageUI
+              .setText("The name on this index duplicates anexisting name.  Please specify a globally unique name.");
+      return false;
+    }
+    return true;
+  }
+
+  public void enableOK() {
+    copyValuesFromGUI();
+    okButton.setEnabled(indexName.length() > 0);
+    boolean keysUsed = "sorted".equals(indexKind) || "set".equals(indexKind);
+    addButton.setEnabled(indexName.length() != 0 && indexType.length() != 0 && keysUsed);
+    boolean selected = table.getSelectionCount() == 1;
+    removeButton.setEnabled(selected);
+    editButton.setEnabled(selected);
+    upButton.setEnabled(false);
+    downButton.setEnabled(false);
+    if (selected) {
+      upButton.setEnabled(table.getSelectionIndex() != 0);
+      downButton.setEnabled(table.getSelectionIndex() != (table.getItemCount() - 1));
+    }
+  }
+}
diff --git a/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/dialogs/AddIndexKeyDialog.java b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/dialogs/AddIndexKeyDialog.java
new file mode 100644
index 0000000..d9c33f6
--- /dev/null
+++ b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/dialogs/AddIndexKeyDialog.java
@@ -0,0 +1,186 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS 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.taeconfigurator.editors.ui.dialogs;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.CCombo;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Label;
+
+import org.apache.uima.cas.Feature;
+import org.apache.uima.cas.Type;
+import org.apache.uima.cas.admin.FSIndexComparator;
+import org.apache.uima.resource.metadata.FsIndexKeyDescription;
+import org.apache.uima.taeconfigurator.editors.ui.AbstractSection;
+
+public class AddIndexKeyDialog extends AbstractDialog {
+
+  static private final String ASCENDING = "Ascending (Standard)";
+
+  static private final String DESCENDING = "Descending (Reverse)";
+
+  static private final String TYPE_PRIORITY = "Type Priority";
+
+  public boolean typePriority;
+
+  public String featureName;
+
+  public int direction;
+
+  private String[] features;
+
+  private FsIndexKeyDescription existingKey = null;
+
+  private List alreadyUsedKeys;
+
+  private String indexKind; // bag, sorted, set
+
+  private CCombo featureUI;
+
+  // private Button browseButton;
+  private CCombo kindUI;
+
+  private Label featureLabel;
+
+  // private Composite tc;
+
+  public AddIndexKeyDialog(AbstractSection aSection, String typeName, String indexKind,
+          List alreadyUsedKeys) {
+    super(aSection, "Add index key", "Add or edit an index key for a type");
+    this.indexKind = indexKind;
+    this.alreadyUsedKeys = alreadyUsedKeys;
+    features = getSortableFeatureNames(typeName);
+  }
+
+  public AddIndexKeyDialog(AbstractSection aSection, String typeName, String indexKind,
+          List alreadyUsedKeys, FsIndexKeyDescription existingKey) {
+    this(aSection, typeName, indexKind, alreadyUsedKeys);
+    this.existingKey = existingKey;
+  }
+
+  /**
+   * 
+   * @param taeDescription
+   * @param selectedType
+   * @return an array of features whose range is primitive
+   */
+  private String[] getSortableFeatureNames(String selectedTypeName) {
+    Type selectedType = section.editor.getCurrentView().getTypeSystem().getType(selectedTypeName);
+    List feats = selectedType.getFeatures();
+    Collection sortableFeatureNames = new ArrayList();
+
+    for (int i = 0; i < feats.size(); i++) {
+      Feature feature = (Feature) feats.get(i);
+      Type rangeType = feature.getRange();
+      if (AbstractSection.isIndexableRange(rangeType.getName())) {
+        if (!alreadyUsedKeys.contains(feature.getShortName()))
+          sortableFeatureNames.add(feature.getShortName());
+      }
+    }
+    String[] result = (String[]) sortableFeatureNames.toArray(stringArray0);
+    Arrays.sort(result);
+    return result;
+  }
+
+  // Kind: combo (up, down, or typePriority)
+  // Feature: text with assist <browse>
+
+  protected Control createDialogArea(Composite parent) {
+    // create composite
+    Composite mainComposite = (Composite) super.createDialogArea(parent, existingKey);
+    Composite twoCol = new2ColumnComposite(mainComposite);
+
+    if ("sorted".equals(indexKind)) {
+      kindUI = newLabeledCCombo(twoCol, "Sort order, or Type Priority",
+              "Specify the sort direction, or specify Type Priorities");
+      kindUI.add(ASCENDING);
+      kindUI.add(DESCENDING);
+      kindUI.add(TYPE_PRIORITY);
+    }
+
+    featureLabel = new Label(twoCol, SWT.NONE);
+    featureLabel.setText("Feature Name");
+    featureUI = newCCombo(twoCol, "Pick a feature to use as a key from the available features");
+    for (int i = 0; i < features.length; i++) {
+      featureUI.add(features[i]);
+    }
+
+    if (null == existingKey) { // default initialization
+      if ("sorted".equals(indexKind))
+        kindUI.setText(kindUI.getItem(0));
+    } else if ("sorted".equals(indexKind)) {
+      kindUI.setText(existingKey.isTypePriority() ? TYPE_PRIORITY
+              : existingKey.getComparator() == FSIndexComparator.STANDARD_COMPARE ? ASCENDING
+                      : DESCENDING);
+      if (!existingKey.isTypePriority())
+        featureUI.setText(existingKey.getFeatureName());
+    } else
+      featureUI.setText(existingKey.getFeatureName());
+
+    boolean makeFeatureVisible = "set".equals(indexKind) || !TYPE_PRIORITY.equals(kindUI.getText());
+    featureUI.setVisible(makeFeatureVisible);
+    featureLabel.setVisible(makeFeatureVisible);
+    if ("sorted".equals(indexKind))
+      kindUI.addListener(SWT.Modify, this);
+    return mainComposite;
+  }
+
+  public void handleEvent(Event event) {
+    if (event.widget == kindUI) {
+      boolean makeFeatureVisible = "set".equals(indexKind)
+              || !TYPE_PRIORITY.equals(kindUI.getText());
+      featureUI.setVisible(makeFeatureVisible);
+      featureLabel.setVisible(makeFeatureVisible);
+    }
+    super.handleEvent(event);
+  }
+
+  public void enableOK() {
+    copyValuesFromGUI();
+    okButton.setEnabled(typePriority || !(null != featureName && "".equals(featureName)));
+  }
+
+  public void copyValuesFromGUI() {
+    if ("sorted".equals(indexKind) && TYPE_PRIORITY.equals(kindUI.getText())) {
+      typePriority = true;
+      featureName = "";
+    } else {
+      typePriority = false;
+      if ("sorted".equals(indexKind)) {
+        direction = ASCENDING.equals(kindUI.getText()) ? FSIndexComparator.STANDARD_COMPARE
+                : FSIndexComparator.REVERSE_STANDARD_COMPARE;
+      } else
+        direction = FSIndexComparator.STANDARD_COMPARE;
+      featureName = featureUI.getText();
+    }
+  }
+
+  public boolean isValid() {
+    return true;
+  }
+
+}
diff --git a/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/dialogs/AddParameterDialog.java b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/dialogs/AddParameterDialog.java
new file mode 100644
index 0000000..455e17b
--- /dev/null
+++ b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/dialogs/AddParameterDialog.java
@@ -0,0 +1,159 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS 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.taeconfigurator.editors.ui.dialogs;
+
+/*
+ * Collects the following information parm name (suggests they must be unique within the descriptor)
+ * MultiValued Mandatory (for aggregates:) 1st overrides
+ * 
+ * For overrides, uses common code in section to allow use of a hierarchical browser that will go
+ * thru defined/available keys, with parms at the bottom. Next sentence I think is false: This is
+ * optional - user may not have fully defined things below. So won't be an error, here, but will be
+ * when validated.
+ */
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.CCombo;
+import org.eclipse.swt.custom.StyledText;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Text;
+
+import org.apache.uima.resource.metadata.ConfigurationParameter;
+import org.apache.uima.taeconfigurator.editors.ui.AbstractSection;
+import org.apache.uima.taeconfigurator.editors.ui.ParameterSection;
+
+public class AddParameterDialog extends AbstractDialogKeyVerifyJavaNames {
+  private StyledText parmNameUI;
+
+  public Button multiValueUI;
+
+  private Button mandatoryUI;
+
+  public CCombo parmTypeUI;
+
+  private Text descriptionUI;
+
+  public String parmName;
+
+  public boolean multiValue;
+
+  public boolean mandatory;
+
+  public String parmType;
+
+  public String description;
+
+  private ParameterSection parmSection;
+
+  private ConfigurationParameter existingCP;
+
+  private String originalParmName;
+
+  public AddParameterDialog(AbstractSection aSection) {
+    super(aSection, "Add Parameter", "Specify a parameter name and press OK");
+    parmSection = (ParameterSection) section;
+  }
+
+  /**
+   * Constructor for Editing an existing parameter
+   * 
+   * @param aSection
+   * @param aExistingCP
+   */
+  public AddParameterDialog(AbstractSection aSection, ConfigurationParameter aExistingCP) {
+    this(aSection);
+    existingCP = aExistingCP;
+  }
+
+  protected Control createDialogArea(Composite parent) {
+    Composite mainArea = (Composite) super.createDialogArea(parent, existingCP);
+    createWideLabel(mainArea, "Parameter names must be unique within this descriptor");
+
+    // This part of the form looks like this sketch
+    //   
+    // parmName: Text field << in 2 grid composite
+    // parmType: CCombo << in 2 grid composite
+    // description: Text field << in 2 grid composite
+    // (checkbox) is MultiValued
+    // (checkbox) is Mandatory
+    // 
+
+    Composite twoCol = new2ColumnComposite(mainArea);
+
+    parmNameUI = newLabeledSingleLineStyledText(twoCol, "Parameter Name",
+            "The unique name of the parameter");
+
+    parmTypeUI = newLabeledCCombo(twoCol, "Parameter Type",
+            "Select the type of the parameter from the pull-down list");
+    parmTypeUI.add("String");
+    parmTypeUI.add("Float");
+    parmTypeUI.add("Integer");
+    parmTypeUI.add("Boolean");
+
+    descriptionUI = newDescription(twoCol, S_);
+
+    multiValueUI = newButton(mainArea, SWT.CHECK, "Parameter is multi-valued",
+            "Check the box if the parameter is multi-valued");
+
+    mandatoryUI = newButton(mainArea, SWT.CHECK, "Parameter is mandatory",
+            "Check the box if the parameter is mandatory");
+
+    if (section.isAggregate()) {
+      multiValueUI.setEnabled(false); // can't change this
+      parmTypeUI.setEnabled(false);
+    }
+
+    newErrorMessage(mainArea);
+
+    if (null != existingCP) {
+      descriptionUI.setText(convertNull(existingCP.getDescription()));
+      multiValueUI.setSelection(existingCP.isMultiValued());
+      mandatoryUI.setSelection(existingCP.isMandatory());
+      parmNameUI.setText(convertNull(existingCP.getName()));
+      parmTypeUI.setText(convertNull(existingCP.getType()));
+    }
+    originalParmName = parmNameUI.getText(); // for validity testing in edit case
+    return mainArea;
+  }
+
+  public void copyValuesFromGUI() {
+    parmName = parmNameUI.getText();
+    multiValue = multiValueUI.getSelection();
+    mandatory = mandatoryUI.getSelection();
+    description = nullIf0lengthString(descriptionUI.getText());
+    parmType = parmTypeUI.getText();
+  }
+
+  public boolean isValid() {
+    if (parmName.length() == 0)
+      return false;
+    if (!parmName.equals(originalParmName) && parmSection.parameterNameAlreadyDefined(parmName))
+      return false;
+    if (parmType.length() == 0)
+      return false;
+    return true;
+  }
+
+  public void enableOK() {
+    copyValuesFromGUI();
+    okButton.setEnabled((parmName.length() > 0) && (parmType.length() > 0));
+  }
+}
diff --git a/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/dialogs/AddRemoteServiceDialog.java b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/dialogs/AddRemoteServiceDialog.java
new file mode 100644
index 0000000..2a09e3c
--- /dev/null
+++ b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/dialogs/AddRemoteServiceDialog.java
@@ -0,0 +1,280 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS 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.taeconfigurator.editors.ui.dialogs;
+
+import java.text.MessageFormat;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.CCombo;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.events.VerifyEvent;
+import org.eclipse.swt.events.VerifyListener;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Text;
+
+import org.apache.uima.taeconfigurator.CDEpropertyPage;
+import org.apache.uima.taeconfigurator.editors.ui.AbstractSection;
+
+public class AddRemoteServiceDialog extends AbstractDialog {
+
+  private String m_selectedServiceTypeName = null;
+
+  private String m_selectedUri = null;
+
+  private String m_selectedKey = null;
+
+  private boolean m_bAutoAddToFlow;
+
+  public String vnsPort;
+
+  public String vnsHost;
+
+  public String timeout;
+
+  public String aeOrCc;
+
+  private CCombo serviceTypeCombo;
+
+  private Text uriText;
+
+  private Text keyText;
+
+  private Text timeoutText;
+
+  private Button autoAddToFlowButton;
+
+  private Button importByNameUI;
+
+  private Button importByLocationUI;
+
+  public boolean isImportByName;
+
+  private String rootPath;
+
+  private DialogModifyListener m_dialogModifyListener = new DialogModifyListener();
+
+  private Text genFilePathUI;
+
+  public String genFilePath;
+
+  private String keyTextPrev;
+
+  private Label vnsHostLabel;
+
+  private Text vnsHostUI;
+
+  private Label vnsPortLabel;
+
+  private Text vnsPortUI;
+
+  private boolean portNumberWasBad;
+
+  private boolean portNumberIsOK;
+
+  private CCombo aeOrCcCombo;
+
+  private class DialogModifyListener implements ModifyListener {
+    public void modifyText(ModifyEvent e) {
+      String text = genFilePathUI.getText();
+      int pos = text.lastIndexOf(keyTextPrev);
+      if (pos == -1)
+        pos = text.length();
+      keyTextPrev = keyText.getText() + ".xml";
+      genFilePathUI.setText(text.substring(0, pos) + keyTextPrev);
+      if (okButton != null)
+        enableOK();
+    }
+  }
+
+  private class DialogVerifyListener implements VerifyListener {
+    public void verifyText(VerifyEvent e) {
+      if (0 <= e.text.indexOf('.')) {
+        setErrorMessage(MessageFormat.format("invalid character(s): ''{0}''",
+                new Object[] { e.text }));
+        e.doit = false;
+      } else
+        setErrorMessage("");
+    }
+  }
+
+  public AddRemoteServiceDialog(AbstractSection aSection, String aRootPath) {
+    super(aSection, "Add Remote Service",
+            "Fill in the information about the remote service and press OK");
+    rootPath = aRootPath;
+  }
+
+  protected Control createDialogArea(Composite parent) {
+
+    Composite composite = (Composite) super.createDialogArea(parent);
+
+    createWideLabel(composite, "Service kind: Analysis Engine or Cas Consumer:");
+
+    aeOrCcCombo = newCCombo(composite,
+            "Specify whether the Service is an Analysis Engine or a Cas Consumer");
+    aeOrCcCombo.add("AnalysisEngine");
+    aeOrCcCombo.add("CasConsumer");
+    aeOrCcCombo.select(0);
+
+    createWideLabel(composite, "Protocol Service Type:");
+
+    serviceTypeCombo = newCCombo(composite, S_);
+    serviceTypeCombo.add("SOAP");
+    serviceTypeCombo.add("Vinci");
+    serviceTypeCombo.select(0);
+
+    createWideLabel(composite, "URI:");
+
+    uriText = new Text(composite, SWT.BORDER);
+    uriText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+    uriText.addModifyListener(m_dialogModifyListener);
+
+    createWideLabel(composite, "Key (a short mnemonic for this service):");
+
+    keyText = new Text(composite, SWT.BORDER);
+    keyText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+    keyText.addModifyListener(m_dialogModifyListener);
+    keyText.addVerifyListener(new DialogVerifyListener());
+    keyTextPrev = ".xml";
+
+    createWideLabel(composite, "Where the generated remote descriptor file will be stored:");
+    genFilePathUI = new Text(composite, SWT.BORDER | SWT.H_SCROLL);
+    genFilePathUI.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+    genFilePathUI.setText(rootPath + ".xml");
+
+    createWideLabel(
+            composite,
+            "Timeout, in milliseconds.  This is ignored for the Vinci protocol.  Specify 0 to wait forever. If not specified, a default timeout is used.");
+    timeoutText = new Text(composite, SWT.BORDER);
+    timeoutText.setEnabled(false);
+
+    createWideLabel(composite,
+            "For the Vinci protocol, you can optionally specify the Host/Port for the Vinci Name Service");
+    Composite tc = new2ColumnComposite(composite);
+    setTextAndTip(vnsHostLabel = new Label(tc, SWT.NONE), "VNS HOST",
+            "An IP name or address, e.g. localhost");
+    vnsHostUI = newText(tc, SWT.NONE, "An IP name or address, e.g. localhost");
+    setTextAndTip(vnsPortLabel = new Label(tc, SWT.NONE), "VNS PORT", "A port number, e.g. 9000");
+    vnsPortUI = newText(tc, SWT.NONE, "A port number, e.g. 9000");
+
+    newErrorMessage(composite);
+
+    autoAddToFlowButton = new Button(composite, SWT.CHECK);
+    autoAddToFlowButton.setText("Add to end of flow");
+    autoAddToFlowButton.setSelection(true);
+
+    new Label(composite, SWT.NONE).setText("");
+    importByNameUI = new Button(composite, SWT.RADIO);
+    importByNameUI.setText("Import by Name");
+    importByNameUI
+            .setToolTipText("Importing by name looks up the name on the classpath and datapath.");
+    importByNameUI.setSelection(true);
+
+    importByLocationUI = new Button(composite, SWT.RADIO);
+    importByLocationUI.setText("Import By Location");
+    importByLocationUI.setToolTipText("Importing by location requires a relative or absolute URL");
+
+    String defaultBy = CDEpropertyPage.getImportByDefault(editor.getProject());
+    if (defaultBy.equals("location")) {
+      importByNameUI.setSelection(false);
+      importByLocationUI.setSelection(true);
+    } else {
+      importByNameUI.setSelection(true);
+      importByLocationUI.setSelection(false);
+    }
+
+    return composite;
+  }
+
+  public void enableOK() {
+    boolean isVinci = serviceTypeCombo.getSelectionIndex() == 1;
+    vnsHostLabel.setEnabled(isVinci);
+    vnsHostUI.setEnabled(isVinci);
+    vnsPortLabel.setEnabled(isVinci);
+    vnsPortUI.setEnabled(isVinci);
+    timeoutText.setEnabled(!isVinci);
+
+    boolean bEnableOk = (serviceTypeCombo.getText() != null && !serviceTypeCombo.getText().equals(
+            ""))
+            && (uriText != null && !uriText.getText().trim().equals(""))
+            && (keyText != null && !keyText.getText().trim().equals(""));
+
+    portNumberIsOK = true;
+    if (isVinci && vnsPortUI.getText().length() > 0) {
+      try {
+        Integer.parseInt(vnsPortUI.getText());
+      } catch (NumberFormatException e) {
+        bEnableOk = false;
+        portNumberWasBad = true;
+        portNumberIsOK = false;
+        setErrorMessage("Invalid number, please correct.");
+      }
+    }
+    okButton.setEnabled(bEnableOk);
+    if (portNumberWasBad && portNumberIsOK) {
+      setErrorMessage("");
+      portNumberWasBad = false;
+    }
+  }
+
+  public String getSelectedServiceTypeName() {
+    return m_selectedServiceTypeName;
+  }
+
+  public String getSelectedUri() {
+    return m_selectedUri;
+  }
+
+  public String getSelectedKey() {
+    return m_selectedKey;
+  }
+
+  public boolean getAutoAddToFlow() {
+    return m_bAutoAddToFlow;
+  }
+
+  /*
+   * (non-Javadoc)
+   * 
+   * @see org.apache.uima.taeconfigurator.editors.ui.dialogs.AbstractDialog#copyValuesFromGUI()
+   */
+  public void copyValuesFromGUI() {
+    genFilePath = genFilePathUI.getText();
+    isImportByName = importByNameUI.getSelection();
+    m_selectedServiceTypeName = serviceTypeCombo.getText();
+    aeOrCc = aeOrCcCombo.getText();
+    m_selectedUri = uriText.getText();
+    m_selectedKey = keyText.getText();
+    m_bAutoAddToFlow = autoAddToFlowButton.getSelection();
+    timeout = timeoutText.getText();
+    vnsHost = vnsHostUI.getText();
+    vnsPort = vnsPortUI.getText();
+    CDEpropertyPage.setImportByDefault(editor.getProject(), isImportByName ? "name" : "location");
+  }
+
+  public boolean isValid() {
+    return true;
+  }
+
+}
diff --git a/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/dialogs/AddSofaDialog.java b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/dialogs/AddSofaDialog.java
new file mode 100644
index 0000000..a694875
--- /dev/null
+++ b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/dialogs/AddSofaDialog.java
@@ -0,0 +1,199 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.uima.taeconfigurator.editors.ui.dialogs;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.StyledText;
+import org.eclipse.swt.events.VerifyEvent;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Label;
+
+import org.apache.uima.resource.metadata.Capability;
+import org.apache.uima.taeconfigurator.editors.ui.AbstractSection;
+import org.apache.uima.taeconfigurator.editors.ui.CapabilitySection;
+
+public class AddSofaDialog extends AbstractDialogKeyVerify {
+
+  private StyledText sofaNameUI;
+
+  private CapabilitySection capabilitySection;
+
+  private Capability capability;
+
+  private String existingSofa;
+
+  private boolean existingIsInput;
+
+  private String originalSofa;
+
+  public String sofaName;
+
+  public boolean isInput;
+
+  private Button inputButton;
+
+  private Button outputButton;
+
+  public AddSofaDialog(AbstractSection aSection, Capability c) {
+    super(aSection, "Add a Sofa", "Use this panel to specify a Sofa Name.");
+    capabilitySection = (CapabilitySection) aSection;
+    capability = c;
+  }
+
+  /**
+   * Constructor for Editing an existing Sofa Name
+   * 
+   * @param aSection
+   * @param aExistingTd
+   */
+  public AddSofaDialog(AbstractSection aSection, Capability c, String aExistingSofa,
+          boolean aIsInput) {
+    this(aSection, c);
+    existingSofa = aExistingSofa;
+    existingIsInput = aIsInput;
+  }
+
+  protected Control createDialogArea(Composite parent) {
+    Composite mainArea = (Composite) super.createDialogArea(parent, existingSofa);
+    createWideLabel(mainArea, "Sofa names must be unique within a Capability Set, and are"
+            + " simple names without name spaces (no dots in the name).\n\n"
+            + "Type the name in the box below, and specify if it is an input Sofa\n"
+            + "(created outside of this component), or an output Sofa (created by this component).");
+
+    // This part of the form looks like this sketch
+    //   
+    // SofaName: Text field << in 2 grid composite
+    // Input / Output: 2 radio checkboxes << in 2 grid composite
+    //
+    // Later: for Aggregates:
+    // a table with sofa name, component key-name, input / output x's in columns
+    // to allow easy "picking" for same-name things
+
+    Composite twoCol = new Composite(mainArea, SWT.NONE);
+    twoCol.setLayout(new GridLayout(2, false)); // false = not equal width
+    twoCol.setLayoutData(new GridData(GridData.FILL_BOTH));
+
+    sofaNameUI = newLabeledSingleLineStyledText(twoCol, "Sofa Name", S_);
+    sofaNameUI.setText("someNewSofaName");
+
+    new Label(twoCol, SWT.NONE).setText("Input / Output:");
+    Composite io = new Composite(twoCol, SWT.NONE);
+    io.setLayout(new GridLayout(2, true));
+    io.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+    inputButton = newButton(io, SWT.RADIO, "Input", "Click here to specify this Sofa is an input.");
+    outputButton = newButton(io, SWT.RADIO, "Output",
+            "Click here to specify this Sofa as an output.");
+    inputButton.setSelection(true);
+    outputButton.setSelection(false);
+
+    newErrorMessage(twoCol, 2);
+
+    if (null != existingSofa) {
+      sofaNameUI.setText(originalSofa = existingSofa);
+      if (existingIsInput) {
+        inputButton.setSelection(true);
+        outputButton.setSelection(false);
+      } else {
+        outputButton.setSelection(true);
+        inputButton.setSelection(false);
+      }
+    }
+    return mainArea;
+  }
+
+  public void copyValuesFromGUI() {
+    sofaName = sofaNameUI.getText();
+    isInput = inputButton.getSelection();
+  }
+
+  /**
+   * Duplicate validity check: Duplicates are OK for sofas belonging to other capability sets,
+   * provided they have the same Input or Output setting.
+   */
+  public boolean isValid() {
+    if (sofaName.length() == 0)
+      return false;
+    if (!sofaName.equals(originalSofa) || // true for adding new sofa, or sofa name changed on edit
+            isInput != existingIsInput) { // true if input / output switched for editing
+      // sofa, not changed name
+      String errMsg = checkDuplSofaName();
+      if (null != errMsg) {
+        setErrorMessage(errMsg);
+        return false;
+      }
+    }
+    return true;
+  }
+
+  public void enableOK() {
+    copyValuesFromGUI();
+    okButton.setEnabled(sofaName.length() > 0);
+  }
+
+  private String checkDuplSofaName() {
+
+    Capability[] cSets = capabilitySection.getCapabilities();
+    // check for dis-allowed duplicates in other capability sets
+    for (int i = 0; i < cSets.length; i++) {
+      Capability ci = cSets[i];
+      if (ci == capability)
+        continue;
+      // "reverse" i and o - if input validate name not exist as output in other sets, etc.
+      String[] sofaNames = isInput ? ci.getOutputSofas() : ci.getInputSofas();
+      if (null != sofaNames)
+        for (int j = 0; j < sofaNames.length; j++) {
+          if (sofaName.equals(sofaNames[j]))
+            return "This name exists as an " + (isInput ? "output" : "input")
+                    + " in some capability set.  Please choose another name, or "
+                    + "switch the input/output specification to the opposite setting.";
+        }
+    }
+    // check for duplicates in this capability
+    if (!sofaName.equals(originalSofa)) { // means adding new sofa or changing name of existing one
+      if (checkDuplSofaName1(sofaName, capability.getInputSofas())
+              || checkDuplSofaName1(sofaName, capability.getOutputSofas()))
+        return "This name already in use; please choose a different name.";
+    }
+    return null;
+  }
+
+  private boolean checkDuplSofaName1(String name, String[] names) {
+    if (null == names)
+      return false;
+    for (int i = 0; i < names.length; i++) {
+      if (name.equals(names[i]))
+        return true;
+    }
+    return false;
+  }
+
+  public boolean verifyKeyChecks(VerifyEvent event) {
+    if (event.keyCode == SWT.CR || event.keyCode == SWT.TAB)
+      return true;
+    if (Character.isJavaIdentifierPart(event.character))
+      return true;
+    return false;
+  }
+
+}
diff --git a/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/dialogs/AddTypeDialog.java b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/dialogs/AddTypeDialog.java
new file mode 100644
index 0000000..495950b
--- /dev/null
+++ b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/dialogs/AddTypeDialog.java
@@ -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.
+ */
+
+package org.apache.uima.taeconfigurator.editors.ui.dialogs;
+
+import java.util.Arrays;
+import java.util.Comparator;
+
+import org.apache.uima.cas.CAS;
+import org.apache.uima.cas.Type;
+import org.apache.uima.resource.metadata.TypeDescription;
+import org.apache.uima.taeconfigurator.editors.ui.AbstractSection;
+import org.apache.uima.taeconfigurator.editors.ui.TypeSection;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.StyledText;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Text;
+
+public class AddTypeDialog extends AbstractDialogKeyVerifyJavaNames {
+
+  private StyledText typeNameUI;
+
+  private Text supertypeNameUI;
+
+  private Text descriptionUI;
+
+  public String typeName;
+
+  private String originalTypeName;
+
+  public String supertypeName;
+
+  public String description;
+
+  private TypeSection typeSection;
+
+  private TypeDescription existingTd = null;
+
+  private TypesWithNameSpaces allTypesList;
+
+  // private boolean seenThisAlready = false;
+
+  public AddTypeDialog(AbstractSection aSection) {
+    super(aSection, "Add a Type", "Use this panel to specify a type.");
+    typeSection = (TypeSection) aSection;
+  }
+
+  /**
+   * Constructor for Editing an existing Type DescriptionD
+   * 
+   * @param aSection
+   * @param aExistingTd
+   */
+  public AddTypeDialog(AbstractSection aSection, TypeDescription aExistingTd) {
+    this(aSection);
+    existingTd = aExistingTd;
+  }
+
+  protected Control createDialogArea(Composite parent) {
+    Composite mainArea = (Composite) super.createDialogArea(parent, existingTd);
+    createWideLabel(mainArea,
+            "Type names must be globally unique, unless you are intentionally redefining another type.");
+
+    // This part of the form looks like this sketch
+    //   
+    // typeName: Text field << in 2 grid composite
+    // supertypeName: Text field << in 2 grid composite
+    // description: Text field << in 2 grid composite
+
+    Composite twoCol = new Composite(mainArea, SWT.NONE);
+    twoCol.setLayout(new GridLayout(2, false)); // false = not equal width
+    twoCol.setLayoutData(new GridData(GridData.FILL_BOTH));
+
+    typeNameUI = newLabeledSingleLineStyledText(twoCol, "Type Name", S_);
+    typeNameUI.setText("some.typename.you.Choose");
+
+    new Label(twoCol, SWT.NONE).setText("Supertype:");
+    supertypeNameUI = newTypeInput(section, twoCol);
+    descriptionUI = newDescription(twoCol, S_);
+    newErrorMessage(twoCol, 2);
+
+    if (null != existingTd) {
+      descriptionUI.setText(convertNull(existingTd.getDescription()));
+      typeNameUI.setText(originalTypeName = existingTd.getName());
+      supertypeNameUI.setText(convertNull(existingTd.getSupertypeName()));
+    }
+    // setting this triggers the handle event for modify
+    // so this has to follow setting up the other widgets
+    // because handle event reads them
+    else
+      supertypeNameUI.setText(CAS.TYPE_NAME_ANNOTATION);
+
+    return mainArea;
+  }
+
+  /*
+   * Supplies the list of valid types
+   * 
+   * @see org.apache.uima.taeconfigurator.editors.ui.dialogs.AbstractDialog#getTypeSystemInfoList()
+   */
+  public TypesWithNameSpaces getTypeSystemInfoList() {
+    TypesWithNameSpaces result = super.getTypeSystemInfoList();
+    boolean hasFeatures = false;
+    boolean hasAllowedValues = false;
+    if (null != existingTd) {
+      hasFeatures = ((null != existingTd.getFeatures()) && (existingTd.getFeatures().length > 0));
+      hasAllowedValues = ((null != existingTd.getAllowedValues()) && (existingTd.getAllowedValues().length > 0));
+      if (hasAllowedValues) {
+        result.add(CAS.TYPE_NAME_STRING);
+        allTypesList = result;
+        return result;
+      }
+    }
+    Type[] allTypes = (Type[]) editor.allTypes.get().values().toArray(new Type[0]);
+    Arrays.sort(allTypes, new Comparator() {
+      public int compare(Object o1, Object o2) {
+        Type t1 = (Type) o1;
+        Type t2 = (Type) o2;
+        return t1.getShortName().compareTo(t2.getShortName());
+      }
+    });
+
+    for (int i = 0; i < allTypes.length; i++) {
+      Type type = allTypes[i];
+      if (type.isInheritanceFinal() && !CAS.TYPE_NAME_STRING.equals(type.getName()))
+        continue;
+      if (hasFeatures && CAS.TYPE_NAME_STRING.equals(type.getName()))
+        continue;
+      result.add(type.getName());
+    }
+    allTypesList = result;
+    return result;
+  }
+
+  public void copyValuesFromGUI() {
+    typeName = typeNameUI.getText();
+    description = nullIf0lengthString(descriptionUI.getText());
+    supertypeName = supertypeNameUI.getText();
+  }
+
+  public boolean isValid() {
+    if (typeName.length() == 0)
+      return false;
+    if (typeName.charAt(typeName.length() - 1) == '.') {
+      setErrorMessage("Name cannot end with a period (.)");
+      return false;
+    }
+    if (!typeName.equals(originalTypeName)) {
+      String errMsg = typeSection.checkDuplTypeName(typeName);
+      if (null != errMsg) {
+        setErrorMessage(errMsg);
+        return false;
+      }
+    }
+    if (!typeContainedInTypeSystemInfoList(supertypeName, allTypesList)) {
+      setErrorMessage("SuperType '" + supertypeName
+              + "' is unknown. If this is intended, please define it first.");
+      return false;
+    }
+    TypeDescription importedType = editor.getImportedTypeSystemDesription().getType(typeName);
+    if (null != importedType) {
+      if (!supertypeName.equals(importedType.getSupertypeName())) {
+        setErrorMessage("The supertype specified must be '" + importedType.getSupertypeName()
+                + "' due to merging with imported types.  Please change it to this type.");
+        return false;
+      }
+    }
+    return true;
+  }
+
+  public void enableOK() {
+    copyValuesFromGUI();
+    okButton.setEnabled(typeName.length() > 0);
+  }
+}
diff --git a/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/dialogs/AddTypeToPriorityListDialog.java b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/dialogs/AddTypeToPriorityListDialog.java
new file mode 100644
index 0000000..308735d
--- /dev/null
+++ b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/dialogs/AddTypeToPriorityListDialog.java
@@ -0,0 +1,116 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS 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.taeconfigurator.editors.ui.dialogs;
+
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.List;
+
+import org.apache.uima.cas.CAS;
+import org.apache.uima.taeconfigurator.editors.ui.AbstractSection;
+
+public class AddTypeToPriorityListDialog extends AbstractDialog {
+
+  private String[] m_selectedTypeNames; // this is the selection
+
+  private String[] m_availableTypeNames;
+
+  private List typeList;
+
+  /**
+   * @param parentShell
+   */
+  public AddTypeToPriorityListDialog(AbstractSection aSection, Set allowableTypeNameHash,
+          String[] typesInList) {
+    super(aSection, "Add Types to Priority List", "Select one or more types and press OK");
+
+    m_availableTypeNames = getAvailableTypeNames(allowableTypeNameHash, typesInList);
+  }
+
+  private String[] getAvailableTypeNames(Set allowableTypeNameHash, String[] alreadyUsedTypes) {
+
+    Arrays.sort(alreadyUsedTypes);
+
+    HashSet availableHash = new HashSet();
+    Iterator typeNameIterator = allowableTypeNameHash.iterator();
+
+    while (typeNameIterator.hasNext()) {
+      String sTypeName = (String) typeNameIterator.next();
+      if (0 > Arrays.binarySearch(alreadyUsedTypes, sTypeName)
+              && !CAS.TYPE_NAME_TOP.equals(sTypeName)) {
+        availableHash.add(sTypeName);
+      }
+    }
+
+    String[] availableTypeNames = (String[]) availableHash.toArray(stringArray0);
+    Arrays.sort(availableTypeNames);
+
+    return availableTypeNames;
+  }
+
+  protected Control createDialogArea(Composite parent) {
+    // create composite
+    Composite composite = (Composite) super.createDialogArea(parent);
+
+    typeList = new List(composite, SWT.MULTI | SWT.BORDER | SWT.V_SCROLL);
+    GridData gridData = new GridData(GridData.FILL_HORIZONTAL);
+    gridData.heightHint = 100;
+    typeList.setLayoutData(gridData);
+
+    for (int i = 0; i < m_availableTypeNames.length; i++) {
+      typeList.add(m_availableTypeNames[i]);
+    }
+
+    return composite;
+  }
+
+  public String[] getSelectedTypeNames() {
+    return (String[]) m_selectedTypeNames.clone();
+  }
+
+  public void copyValuesFromGUI() {
+    m_selectedTypeNames = new String[typeList.getSelectionCount()];
+    for (int i = 0, j = 0; i < m_availableTypeNames.length; i++) {
+      if (typeList.isSelected(i)) {
+        m_selectedTypeNames[j++] = m_availableTypeNames[i];
+      }
+    }
+  }
+
+  public boolean isValid() {
+    return true;
+  }
+
+  /*
+   * (non-Javadoc)
+   * 
+   * @see org.apache.uima.taeconfigurator.editors.ui.dialogs.AbstractDialog#enableOK()
+   */
+  public void enableOK() {
+    okButton.setEnabled(true);
+  }
+}
diff --git a/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/dialogs/CommonInputDialog.java b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/dialogs/CommonInputDialog.java
new file mode 100644
index 0000000..5cfcc95
--- /dev/null
+++ b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/dialogs/CommonInputDialog.java
@@ -0,0 +1,149 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS 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.taeconfigurator.editors.ui.dialogs;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.StyledText;
+import org.eclipse.swt.events.VerifyEvent;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+
+import org.apache.uima.taeconfigurator.editors.ui.AbstractSection;
+
+/**
+ */
+public class CommonInputDialog extends AbstractDialogKeyVerify {
+
+  public static final int PLAIN_NAME = 1;
+
+  public static final int DOTTED_NAME = 1 << 1;
+
+  public static final int SPACED_NAMES = 1 << 2;
+
+  public static final int LANGUAGE = 1 << 3;
+
+  public static final int ALLOK = 1 << 4;
+
+  public static final int TRUE_FALSE = 1 << 5;
+
+  public static final int INTEGER = 1 << 6;
+
+  public static final int FLOAT = 1 << 7;
+
+  public static final int GROUP_NAMES = DOTTED_NAME | SPACED_NAMES | LANGUAGE;
+
+  private int validation;
+
+  private String existing;
+
+  private StyledText text;
+
+  private String result;
+
+  public CommonInputDialog(AbstractSection aSection, String title, String dialogDescription,
+          int aKind) {
+    super(aSection, title, dialogDescription);
+    validation = aKind;
+  }
+
+  public CommonInputDialog(AbstractSection aSection, String title, String dialogDescription,
+          int aKind, String aExisting) {
+    this(aSection, title, dialogDescription, aKind);
+    existing = aExisting;
+  }
+
+  protected Control createDialogArea(Composite parent) {
+    Composite mainArea = (Composite) super.createDialogArea(parent, existing);
+
+    text = newSingleLineStyledText(mainArea, "");
+    AbstractSection.spacer(mainArea);
+    newErrorMessage(mainArea);
+
+    if (null != existing)
+      text.setText(existing);
+    else
+      text.setText(S_);
+
+    return mainArea;
+  }
+
+  public boolean verifyKeyChecks(VerifyEvent event) {
+    char ch = event.character;
+
+    boolean validateDottedName = ((validation & DOTTED_NAME) == DOTTED_NAME);
+    boolean validateSpaces = ((validation & SPACED_NAMES) == SPACED_NAMES);
+    boolean validateLanguage = ((validation & LANGUAGE) == LANGUAGE);
+    boolean validateAllOK = ((validation & ALLOK) == ALLOK);
+    boolean validateTrueFalse = ((validation & TRUE_FALSE) == TRUE_FALSE);
+    boolean validateInteger = ((validation & INTEGER) == INTEGER);
+    boolean validateFloat = ((validation & FLOAT) == FLOAT);
+
+    if (event.keyCode == SWT.CR || event.keyCode == SWT.TAB || event.keyCode == SWT.BS)
+      return true;
+
+    if (validateTrueFalse) {
+      return ("truefalse".indexOf(ch) >= 0);
+    }
+
+    if (validateSpaces && ch == ' ')
+      return true;
+
+    if (validateDottedName && ch == '.')
+      return true;
+
+    if ((!validateTrueFalse) && (!validateInteger) && (!validateFloat)
+            && Character.isJavaIdentifierPart(ch))
+      return true;
+
+    if (validateLanguage && ch == '-')
+      return true;
+
+    if (validateAllOK)
+      return true;
+
+    if (validateInteger)
+      if (Character.isDigit(ch) || ch == '-')
+        return true;
+
+    if (validateFloat) {
+      if (Character.isDigit(ch) || ch == '-' || ch == 'E' || ch == 'e' || ch == '.')
+        return true;
+    }
+    return false;
+  }
+
+  public String getValue() {
+    return result;
+  }
+
+  public void enableOK() {
+    copyValuesFromGUI();
+    okButton.setEnabled("".equals(errorMessageUI.getText()) && (text.getText().length() > 0));
+  }
+
+  public void copyValuesFromGUI() {
+    result = text.getText();
+  }
+
+  public boolean isValid() {
+    return true;
+  }
+
+}
diff --git a/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/dialogs/ContentAssistField32.java b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/dialogs/ContentAssistField32.java
new file mode 100644
index 0000000..23b6c49
--- /dev/null
+++ b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/dialogs/ContentAssistField32.java
@@ -0,0 +1,45 @@
+/*

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

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

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

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

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

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

+ * 

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

+ * 

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

+ * software distributed under the License is distributed on an

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

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

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+

+/*

+ * Isolates Eclipse 3.2 content assist types

+ */

+package org.apache.uima.taeconfigurator.editors.ui.dialogs;

+

+import org.eclipse.swt.SWT;

+import org.eclipse.swt.widgets.Composite;

+import org.eclipse.swt.widgets.Text;

+import org.eclipse.ui.fieldassist.ContentAssistField;

+

+public class ContentAssistField32 {

+  

+  final private ContentAssistField caf;

+  

+  ContentAssistField32(Composite tc, TypesWithNameSpaces candidatesToPickFrom) {

+    TypesWithNameSpaces32 twns32 = new TypesWithNameSpaces32(candidatesToPickFrom);

+    caf = new ContentAssistField(tc, SWT.BORDER, new org.eclipse.jface.fieldassist.TextControlCreator(), 

+            new org.eclipse.jface.fieldassist.TextContentAdapter(), twns32,

+            null, null);

+    caf.getContentAssistCommandAdapter().setProposalAcceptanceStyle(org.eclipse.jface.fieldassist.ContentProposalAdapter.PROPOSAL_REPLACE);

+  }

+

+  public Text getControl() {

+    return (Text) caf.getControl();

+  }

+}

diff --git a/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/dialogs/EditSofaBindingsDialog.java b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/dialogs/EditSofaBindingsDialog.java
new file mode 100644
index 0000000..214486c
--- /dev/null
+++ b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/dialogs/EditSofaBindingsDialog.java
@@ -0,0 +1,107 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS 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.taeconfigurator.editors.ui.dialogs;
+
+import java.util.Iterator;
+import java.util.Map;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.TableItem;
+
+import org.apache.uima.taeconfigurator.editors.ui.AbstractSection;
+
+public class EditSofaBindingsDialog extends AbstractDialog {
+
+  public String[] selectedSofaNames; // this is the selection indexes into next
+
+  private Map availAndBoundSofas;
+
+  private String aggrSofaName;
+
+  private Table table;
+
+  /**
+   * @param parentShell
+   */
+  public EditSofaBindingsDialog(AbstractSection aSection, String aAggrSofaName,
+          Map aAvailAndBoundSofas) {
+    super(aSection, "Assign Components and their sofas to an Aggregate Sofa Name",
+            "Change the selection as needed to reflect bindings.");
+    availAndBoundSofas = aAvailAndBoundSofas;
+    aggrSofaName = aAggrSofaName;
+  }
+
+  protected Control createDialogArea(Composite parent) {
+    // create composite
+    //   
+    // Bindings for aggregate sofa name xxxxxx:
+    // <Table with multi-select, one column>
+    // component/sofa-name
+    // component
+    //
+
+    Composite composite = (Composite) super.createDialogArea(parent);
+    Label info = new Label(composite, SWT.NONE);
+    info.setText("Select all the delegate sofas from the list below which should be "
+            + "associated with the aggregate sofa name \"" + aggrSofaName + "\".\n"
+            + "Hold down the Shift or Control keys to select multiple items.");
+
+    table = newTable(composite, SWT.MULTI | SWT.BORDER | SWT.V_SCROLL);
+
+    int i = 0;
+    for (Iterator it = availAndBoundSofas.entrySet().iterator(); it.hasNext(); i++) {
+      TableItem item = new TableItem(table, SWT.NONE);
+      Map.Entry entry = (Map.Entry) it.next();
+      item.setText((String) entry.getKey());
+      if (null != entry.getValue())
+        table.select(i);
+    }
+    table.pack();
+
+    return composite;
+  }
+
+  public void copyValuesFromGUI() {
+    selectedSofaNames = new String[table.getSelectionCount()];
+    for (int i = 0, j = 0; i < table.getItemCount(); i++) {
+      if (table.isSelected(i)) {
+        selectedSofaNames[j++] = table.getItem(i).getText();
+      }
+    }
+  }
+
+  public boolean isValid() {
+    // TODO Auto-generated method stub
+    return true;
+  }
+
+  /*
+   * (non-Javadoc)
+   * 
+   * @see org.apache.uima.taeconfigurator.editors.ui.dialogs.AbstractDialog#enableOK()
+   */
+  public void enableOK() {
+    okButton.setEnabled(true);
+  }
+}
diff --git a/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/dialogs/ExportImportablePartDialog.java b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/dialogs/ExportImportablePartDialog.java
new file mode 100644
index 0000000..df94b7d
--- /dev/null
+++ b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/dialogs/ExportImportablePartDialog.java
@@ -0,0 +1,152 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS 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.taeconfigurator.editors.ui.dialogs;
+
+import java.text.MessageFormat;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.events.VerifyEvent;
+import org.eclipse.swt.events.VerifyListener;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Text;
+
+import org.apache.uima.taeconfigurator.CDEpropertyPage;
+import org.apache.uima.taeconfigurator.editors.ui.AbstractSection;
+
+public class ExportImportablePartDialog extends AbstractDialog {
+
+  private Text baseFileNameUI;
+
+  private Button importByNameUI;
+
+  private Button importByLocationUI;
+
+  public boolean isImportByName;
+
+  private String rootPath;
+
+  private DialogModifyListener m_dialogModifyListener = new DialogModifyListener();
+
+  private Text genFilePathUI;
+
+  public String genFilePath;
+
+  public String baseFileName;
+
+  private class DialogModifyListener implements ModifyListener {
+    public void modifyText(ModifyEvent e) {
+      String text = genFilePathUI.getText();
+      int pos = text.lastIndexOf(baseFileName + ".xml");
+      if (pos == -1)
+        pos = text.length();
+      baseFileName = baseFileNameUI.getText();
+      genFilePathUI.setText(text.substring(0, pos) + baseFileName + ".xml");
+      if (okButton != null)
+        enableOK();
+    }
+  }
+
+  private class DialogVerifyListener implements VerifyListener {
+    public void verifyText(VerifyEvent e) {
+      if (0 <= e.text.indexOf('.')) {
+        setErrorMessage(MessageFormat.format("invalid character(s): ''{0}''",
+                new Object[] { e.text }));
+        e.doit = false;
+      } else
+        setErrorMessage("");
+    }
+  }
+
+  public ExportImportablePartDialog(AbstractSection aSection) {
+    super(aSection, "Export an importable part",
+            "Specify a base file name, and perhaps alter the path where it should be stored, and press OK");
+    rootPath = aSection.editor.getFile().getParent().getLocation().toString() + '/';
+  }
+
+  protected Control createDialogArea(Composite parent) {
+
+    Composite composite = (Composite) super.createDialogArea(parent);
+    AbstractSection.spacer(composite);
+
+    createWideLabel(composite, "Base file name (without path or following \".xml\":");
+
+    baseFileNameUI = new Text(composite, SWT.BORDER);
+    baseFileNameUI.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+    baseFileNameUI.addModifyListener(m_dialogModifyListener);
+    baseFileNameUI.addVerifyListener(new DialogVerifyListener());
+    baseFileName = "";
+
+    newErrorMessage(composite);
+
+    createWideLabel(composite, "Where the generated part descriptor file will be stored:");
+    genFilePathUI = new Text(composite, SWT.BORDER | SWT.H_SCROLL);
+    genFilePathUI.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+    genFilePathUI.setText(rootPath + ".xml");
+
+    new Label(composite, SWT.NONE).setText("");
+    importByNameUI = new Button(composite, SWT.RADIO);
+    importByNameUI.setText("Import by Name");
+    importByNameUI
+            .setToolTipText("Importing by name looks up the name on the classpath and datapath.");
+
+    importByLocationUI = new Button(composite, SWT.RADIO);
+    importByLocationUI.setText("Import By Location");
+    importByLocationUI.setToolTipText("Importing by location requires a relative or absolute URL");
+
+    String defaultBy = CDEpropertyPage.getImportByDefault(editor.getProject());
+    if (defaultBy.equals("location")) {
+      importByNameUI.setSelection(false);
+      importByLocationUI.setSelection(true);
+    } else {
+      importByNameUI.setSelection(true);
+      importByLocationUI.setSelection(false);
+    }
+
+    baseFileNameUI.setFocus();
+    return composite;
+  }
+
+  public void enableOK() {
+    boolean bEnableOk = (baseFileNameUI != null && !baseFileNameUI.getText().trim().equals(""));
+    okButton.setEnabled(bEnableOk);
+  }
+
+  /*
+   * (non-Javadoc)
+   * 
+   * @see org.apache.uima.taeconfigurator.editors.ui.dialogs.AbstractDialog#copyValuesFromGUI()
+   */
+  public void copyValuesFromGUI() {
+    genFilePath = genFilePathUI.getText();
+    isImportByName = importByNameUI.getSelection();
+    CDEpropertyPage.setImportByDefault(editor.getProject(), isImportByName ? "name" : "location");
+  }
+
+  public boolean isValid() {
+    return true;
+  }
+
+}
diff --git a/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/dialogs/FindComponentDialog.java b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/dialogs/FindComponentDialog.java
new file mode 100644
index 0000000..7d0668e
--- /dev/null
+++ b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/dialogs/FindComponentDialog.java
@@ -0,0 +1,222 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS 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.taeconfigurator.editors.ui.dialogs;
+
+import java.util.List;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.CCombo;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Text;
+
+import org.apache.uima.taeconfigurator.TAEConfiguratorPlugin;
+import org.apache.uima.taeconfigurator.editors.ui.AbstractSection;
+
+public class FindComponentDialog extends AbstractDialog {
+
+  private Text searchByNameText, inputTypeText, outputTypeText;
+
+  private CCombo lookInCombo;
+
+  private List m_matchingDelegateComponetDescriptors;
+
+  private List m_matchingDelegateComponentDescriptions;
+
+  private Button cancelButton;
+
+  public static final String ALL_PROJECTS = "All projects";
+
+  private Label statusLabel1, statusLabel2;
+
+  private SearchThread m_searchThread = null;
+
+  private String[] componentHeaders;
+
+  /**
+   * @param parentShell
+   */
+  public FindComponentDialog(AbstractSection aSection, String title, String header,
+          String[] componentHeaders) {
+    super(aSection, title, header);
+    this.componentHeaders = componentHeaders;
+  }
+
+  protected Control createDialogArea(Composite parent) {
+    Composite composite = (Composite) super.createDialogArea(parent);
+
+    AbstractSection.spacer(composite);
+
+    new Label(composite, SWT.WRAP).setText("Descriptor file name pattern (e.g. ab*cde):");
+    searchByNameText = new Text(composite, SWT.BORDER);
+    searchByNameText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+    new Label(composite, SWT.WRAP).setText("Descriptor must specify the input type:");
+    inputTypeText = new Text(composite, SWT.BORDER);
+    inputTypeText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+    new Label(composite, SWT.WRAP).setText("Descriptor must specify the output type:");
+    outputTypeText = new Text(composite, SWT.BORDER);
+    outputTypeText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+    new Label(composite, SWT.WRAP).setText("Look in:");
+
+    lookInCombo = new CCombo(composite, SWT.FLAT | SWT.BORDER | SWT.READ_ONLY);
+    String[] projectNames = getProjectNames();
+    lookInCombo.add(' ' + ALL_PROJECTS);
+    for (int i = 0; i < projectNames.length; i++) {
+      lookInCombo.add(' ' + projectNames[i]);
+    }
+    lookInCombo.setText(' ' + ALL_PROJECTS);
+
+    statusLabel1 = new Label(composite, SWT.NONE);
+    statusLabel1.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+    statusLabel2 = new Label(composite, SWT.NONE);
+    statusLabel2.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+    newErrorMessage(composite);
+
+    return composite;
+  }
+
+  protected void createButtonsForButtonBar(Composite parent) {
+    // create OK and Cancel buttons by default
+    createButton(parent, IDialogConstants.OK_ID, "Search", true);
+    cancelButton = createButton(parent, IDialogConstants.CANCEL_ID, "Stop Search", false);
+
+    cancelButton.setEnabled(false);
+  }
+
+  private String[] getProjectNames() {
+    IProject[] projects = TAEConfiguratorPlugin.getWorkspace().getRoot().getProjects();
+    String[] projectNames = new String[projects.length];
+    for (int i = 0; i < projects.length; i++) {
+      projectNames[i] = projects[i].getName();
+    }
+
+    return projectNames;
+  }
+
+  // also called by Search Monitoring Thread when
+  // it notices the search thread is finished
+  protected void buttonPressed(int buttonId) {
+    if (buttonId == IDialogConstants.OK_ID) { // start search
+      if (null != m_searchThread)
+        errorMessageUI.setText("Search already in progress");
+      else
+        copyValuesFromGUI();
+    } else { // cancel in-progress search
+      if (m_searchThread.isDone()) {
+        m_matchingDelegateComponetDescriptors = m_searchThread
+                .getMatchingDelegateComponentDescriptors();
+        m_matchingDelegateComponentDescriptions = m_searchThread
+                .getMatchingDelegateComponentDescriptions();
+        m_searchThread = null;
+        super.superButtonPressed(IDialogConstants.OK_ID);
+      } else {
+        m_searchThread.setDieNow();
+        this.handleShellCloseEvent();
+      }
+      return;
+    }
+  }
+
+  private static final String needToEscapeTheseChars = 
+    ".+{}()\\";
+  private String convertToRegexSearchPattern(String searchPattern) {
+    if (searchPattern == null || searchPattern.equals("")) {
+      return null;
+    }
+    String searchPatternLowerCase = searchPattern.toLowerCase();
+    StringBuffer buffer = new StringBuffer("(?i)"); // case insensitive
+    for (int i = 0; i < searchPatternLowerCase.length(); i++) {
+      char ch = searchPatternLowerCase.charAt(i);
+      if (ch == '*') {
+        buffer.append(".*");
+      } else if (0 <= needToEscapeTheseChars.indexOf(ch)) {
+        buffer.append('\\').append(ch);
+      } else {
+        buffer.append(ch);
+      }
+    }
+
+    return new String(buffer);
+  }
+
+  public List getMatchingDelegateComponentDescriptors() {
+    return m_matchingDelegateComponetDescriptors;
+  }
+
+  public List getMatchingDelegateComponentDescriptions() {
+    return m_matchingDelegateComponentDescriptions;
+  }
+
+  public Label getStatusLabel1() {
+    return statusLabel1;
+  }
+
+  public Label getStatusLabel2() {
+    return statusLabel2;
+  }
+
+  /*
+   * (non-Javadoc)
+   * 
+   * @see org.apache.uima.taeconfigurator.editors.ui.dialogs.AbstractDialog#copyValuesFromGUI()
+   */
+  public void copyValuesFromGUI() {
+    String fileNameSearch = convertToRegexSearchPattern(searchByNameText.getText());
+    String inputTypeSearch = convertToRegexSearchPattern(inputTypeText.getText());
+    String outputTypeSearch = convertToRegexSearchPattern(outputTypeText.getText());
+    String projectToSearch = lookInCombo.getText().substring(1);
+    m_searchThread = new SearchThread(this, section, fileNameSearch, inputTypeSearch,
+            outputTypeSearch, projectToSearch, componentHeaders);
+    cancelButton.setEnabled(true);
+    Thread searchThreadThread = new Thread(m_searchThread);
+    searchThreadThread.start();
+
+    SearchMonitoringThread monitoringThread = new SearchMonitoringThread(this, m_searchThread);
+    monitoringThread.start();
+  }
+
+  /*
+   * (non-Javadoc)
+   * 
+   * @see org.apache.uima.taeconfigurator.editors.ui.dialogs.AbstractDialog#isValid()
+   */
+  public boolean isValid() {
+    return true;
+  }
+
+  /*
+   * (non-Javadoc)
+   * 
+   * @see org.apache.uima.taeconfigurator.editors.ui.dialogs.AbstractDialog#enableOK()
+   */
+  public void enableOK() {
+  }
+
+}
diff --git a/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/dialogs/PickTaeForTypesDialog.java b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/dialogs/PickTaeForTypesDialog.java
new file mode 100644
index 0000000..590ba6e
--- /dev/null
+++ b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/dialogs/PickTaeForTypesDialog.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.taeconfigurator.editors.ui.dialogs;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.List;
+import org.eclipse.swt.widgets.Text;
+
+import org.apache.uima.analysis_engine.TypeOrFeature;
+import org.apache.uima.resource.ResourceCreationSpecifier;
+import org.apache.uima.resource.ResourceSpecifier;
+import org.apache.uima.resource.metadata.Capability;
+import org.apache.uima.taeconfigurator.CDEpropertyPage;
+import org.apache.uima.taeconfigurator.editors.ui.AbstractSection;
+
+public class PickTaeForTypesDialog extends AbstractDialog {
+  private java.util.List m_DelegateComponentDescriptors, m_delegateComponentDescriptions;
+
+  private String[] m_selectedDelegateComponentDescriptors;
+
+  // private boolean m_bAutoAddToFlow;
+  private String m_aggregateFileName;
+
+  private Text delegateComponentDescriptionText;
+
+  List delegateComponentListGUI;
+
+  private List inputTypesList;
+
+  private List outputTypesList;
+
+  // private Button autoAddToFlowButton;
+  private DialogSelectionListener dialogSelectionListener = new DialogSelectionListener();
+
+  private Button importByNameUI;
+
+  private Button importByLocationUI;
+
+  public boolean isImportByName;
+
+  public class DialogSelectionListener implements SelectionListener {
+    public void widgetSelected(SelectionEvent e) {
+      if (e.widget == delegateComponentListGUI) {
+        update();
+      } else {
+        if (okButton != null)
+          enableOK();
+      }
+    }
+
+    public void widgetDefaultSelected(SelectionEvent e) {
+      // nothing to do in this case
+    }
+  }
+
+  /**
+   * @param parentShell
+   */
+  public PickTaeForTypesDialog(AbstractSection aSection, String aggregateFileName,
+          java.util.List delegateComponentDescriptors, java.util.List delegateComponentDescriptions) {
+
+    super(aSection, "Select Delegate Component Descriptor(s)",
+            "Select one or more delegate components to add and press OK");
+    m_aggregateFileName = aggregateFileName;
+    m_DelegateComponentDescriptors = delegateComponentDescriptors;
+    m_delegateComponentDescriptions = delegateComponentDescriptions;
+  }
+
+  protected Control createDialogArea(Composite parent) {
+    Composite composite = (Composite) super.createDialogArea(parent);
+    Label specialMsgLabel = new Label(composite, SWT.WRAP);
+    AbstractSection.spacer(composite);
+
+    // create m_taePrompt
+    createWideLabel(composite, "Delegate Components:");
+
+    delegateComponentListGUI = new List(composite, SWT.MULTI | SWT.BORDER | SWT.V_SCROLL);
+    GridData gridData = new GridData(GridData.FILL_HORIZONTAL);
+    gridData.heightHint = 100;
+    delegateComponentListGUI.setLayoutData(gridData);
+    boolean bContainsConstituentsAlreadyInAggregate = false;
+    boolean bContainsAggregate = false;
+    for (int i = 0; i < m_DelegateComponentDescriptors.size(); i++) {
+      String sAdditional = "";
+      if (m_aggregateFileName.equals(m_DelegateComponentDescriptors.get(i))) {
+        sAdditional = "**";
+        bContainsAggregate = true;
+      }
+      delegateComponentListGUI.add((String) m_DelegateComponentDescriptors.get(i) + sAdditional);
+    }
+    delegateComponentListGUI.addSelectionListener(dialogSelectionListener);
+
+    if (bContainsConstituentsAlreadyInAggregate && bContainsAggregate) {
+      specialMsgLabel
+              .setText("(* indicates delegate component is already part of aggregate, ** is aggregate currently being configured)");
+    } else if (bContainsConstituentsAlreadyInAggregate) {
+      specialMsgLabel.setText("(* indicates delegate component is already part of aggregate)");
+    } else if (bContainsAggregate) {
+      specialMsgLabel.setText("(** is aggregate currently being configured)");
+    }
+
+    createWideLabel(composite, "Delegate Component Description:");
+
+    delegateComponentDescriptionText = new Text(composite, SWT.MULTI | SWT.WRAP | SWT.V_SCROLL
+            | SWT.BORDER);
+    delegateComponentDescriptionText.setLayoutData(new GridData(GridData.FILL_BOTH));
+    GridData dcgd = new GridData(GridData.FILL_HORIZONTAL);
+    dcgd.heightHint = 50;
+    delegateComponentDescriptionText.setLayoutData(dcgd);
+    delegateComponentDescriptionText.setEditable(false);
+
+    createWideLabel(composite, "Input Types:");
+
+    inputTypesList = new List(composite, SWT.BORDER | SWT.V_SCROLL);
+    inputTypesList.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+    createWideLabel(composite, "Output Types:");
+
+    outputTypesList = new List(composite, SWT.BORDER | SWT.V_SCROLL);
+    outputTypesList.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+    // autoAddToFlowButton = new Button(composite, SWT.CHECK);
+    // autoAddToFlowButton.setText("Add selected delegate components to end of flow");
+    // autoAddToFlowButton.setSelection(true);
+    // autoAddToFlowButton.setBackground(null);
+
+    importByNameUI = newButton(composite, SWT.RADIO, "Import by Name",
+            "Importing by name looks up the name on the classpath and datapath.");
+    importByLocationUI = newButton(composite, SWT.RADIO, "Import by Location",
+            "Importing by location requires a relative or absolute URL");
+
+    String defaultBy = CDEpropertyPage.getImportByDefault(editor.getProject());
+    if (defaultBy.equals("location")) {
+      importByNameUI.setSelection(false);
+      importByLocationUI.setSelection(true);
+    } else {
+      importByNameUI.setSelection(true);
+      importByLocationUI.setSelection(false);
+    }
+    return composite;
+  }
+
+  public void update() {
+
+    int nSelectedAeIndex = delegateComponentListGUI.getSelectionIndices()[0];
+    ResourceSpecifier rs = (ResourceSpecifier) m_delegateComponentDescriptions
+            .get(nSelectedAeIndex);
+
+    String description = rs instanceof ResourceCreationSpecifier ? ((ResourceCreationSpecifier) rs)
+            .getMetaData().getDescription() : "No Description - remote service descriptor";
+    delegateComponentDescriptionText.setText(convertNull(description));
+
+    inputTypesList.removeAll();
+    outputTypesList.removeAll();
+    Capability[] capabilities = AbstractSection.getCapabilities(rs);
+    if (capabilities != null && capabilities.length > 0) {
+      TypeOrFeature[] inputs = capabilities[0].getInputs();
+      if (inputs != null) {
+        for (int i = 0; i < inputs.length; i++) {
+          if (inputs[i].isType()) {
+            inputTypesList.add(section.formatName(inputs[i].getName()));
+          }
+        }
+      }
+
+      TypeOrFeature[] outputs = capabilities[0].getOutputs();
+      if (outputs != null) {
+        for (int i = 0; i < outputs.length; i++) {
+          if (outputs[i].isType()) {
+            outputTypesList.add(section.formatName(outputs[i].getName()));
+          }
+        }
+      }
+    }
+    if (okButton != null)
+      enableOK();
+  }
+
+  public void enableOK() {
+    boolean bEnableOk = false;
+    String[] selections = delegateComponentListGUI.getSelection();
+    for (int i = 0; i < selections.length; i++) {
+      if (!selections[i].endsWith("*")) {
+        bEnableOk = true;
+        i = selections.length;
+      }
+    }
+    okButton.setEnabled(bEnableOk);
+  }
+
+  public String[] getSelectedDelegateComponentDescriptors() {
+    return (String[]) m_selectedDelegateComponentDescriptors.clone();
+  }
+
+  // public boolean getAutoAddToFlow() {
+  // return m_bAutoAddToFlow;
+  // }
+
+  /*
+   * (non-Javadoc)
+   * 
+   * @see org.apache.uima.taeconfigurator.editors.ui.dialogs.AbstractDialog#copyValuesFromGUI()
+   */
+  public void copyValuesFromGUI() {
+    // this is where we do rollup and detect if we need any additional
+    // types based on types of features and whether we are a supertype
+    // of a type that is not yet defined
+
+    int[] selIndices = delegateComponentListGUI.getSelectionIndices();
+    int nRealCount = 0;
+    for (int i = 0; i < selIndices.length; i++) {
+      if (!delegateComponentListGUI.getItem(selIndices[i]).endsWith("*")) {
+        nRealCount++;
+      }
+    }
+    m_selectedDelegateComponentDescriptors = new String[nRealCount];
+
+    for (int i = 0, j = 0; i < selIndices.length; i++) {
+      if (!delegateComponentListGUI.getItem(selIndices[i]).endsWith("*")) {
+        m_selectedDelegateComponentDescriptors[j] = (String) m_DelegateComponentDescriptors
+                .get(selIndices[i]);
+      }
+    }
+
+    // m_bAutoAddToFlow = autoAddToFlowButton.getSelection();
+    isImportByName = importByNameUI.getSelection();
+    CDEpropertyPage.setImportByDefault(editor.getProject(), isImportByName ? "name" : "location");
+  }
+
+  /*
+   * (non-Javadoc)
+   * 
+   * @see org.apache.uima.taeconfigurator.editors.ui.dialogs.AbstractDialog#isValid()
+   */
+  public boolean isValid() {
+    return true;
+  }
+
+}
diff --git a/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/dialogs/ResourcePickerDialog.java b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/dialogs/ResourcePickerDialog.java
new file mode 100644
index 0000000..d671781
--- /dev/null
+++ b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/dialogs/ResourcePickerDialog.java
@@ -0,0 +1,159 @@
+/*

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

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

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

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

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

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

+ * 

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

+ * 

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

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS 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.taeconfigurator.editors.ui.dialogs;

+

+import java.util.Arrays;

+import java.util.Comparator;

+import java.util.List;

+

+import org.apache.uima.taeconfigurator.InternalErrorCDE;

+import org.apache.uima.taeconfigurator.TAEConfiguratorPlugin;

+import org.eclipse.core.resources.IContainer;

+import org.eclipse.core.resources.IFile;

+import org.eclipse.core.resources.IResource;

+import org.eclipse.core.resources.IWorkspaceRoot;

+import org.eclipse.core.runtime.CoreException;

+import org.eclipse.swt.SWT;

+import org.eclipse.swt.layout.GridData;

+import org.eclipse.swt.widgets.Composite;

+import org.eclipse.swt.widgets.Control;

+import org.eclipse.swt.widgets.Event;

+import org.eclipse.swt.widgets.Shell;

+import org.eclipse.swt.widgets.Tree;

+import org.eclipse.swt.widgets.TreeItem;

+

+public class ResourcePickerDialog extends AbstractDialog {

+

+  protected Tree resourcesUI;

+  public IResource pickedResource;

+  private Object [] result;

+    

+  public ResourcePickerDialog(Shell shell) {

+    super(shell, "Select a File", "Use this panel to select a file in the Workspace");

+  }

+  

+  private static final Comparator resourceComparator = new Comparator () {

+    public int compare(Object arg0, Object arg1) {

+       IResource r0 = (IResource) arg0;   

+       IResource r1 = (IResource) arg1;   

+        return r0.getName().compareTo(r1.getName());

+    }

+  };

+  

+  private void populate(TreeItem parent, IResource[] resources) {

+    Arrays.sort(resources, resourceComparator);

+    for (int i = 0; i < resources.length; i++) {

+      TreeItem item = new TreeItem(parent, SWT.NULL);

+      IResource r = resources[i];

+      item.setText(r.getName());

+      item.setData(r);

+      if (r instanceof IContainer) {

+        new TreeItem(item, SWT.NULL);

+      }

+    }

+  }

+ 

+  protected Control createDialogArea(Composite parent) {

+    Composite mainArea = (Composite) super.createDialogArea(parent);

+    

+    resourcesUI = newTree(mainArea, SWT.SINGLE);

+    ((GridData)resourcesUI.getLayoutData()).heightHint = 400;

+    TreeItem topItem = new TreeItem(resourcesUI, SWT.NONE);

+    topItem.setText("Workspace");

+    IWorkspaceRoot root = TAEConfiguratorPlugin.getWorkspace().getRoot().getWorkspace().getRoot();

+    try {

+    IResource[] projects = root.members();

+    populate(topItem, projects);

+    } catch (CoreException e) {

+      throw new InternalErrorCDE("unhandled exception", e);

+    }

+    topItem.setExpanded(true);

+    resourcesUI.addListener(SWT.Expand, this);

+    resourcesUI.addListener(SWT.Selection, this);

+    return mainArea;

+  }

+  

+  /* (non-Javadoc)

+   * @see org.apache.uima.taeconfigurator.editors.ui.dialogs.AbstractDialog#handleEvent(org.eclipse.swt.widgets.Event)

+   */

+  public void handleEvent(Event event) {

+    if (event.widget == resourcesUI &&

+        event.type == SWT.Expand) {

+      TreeItem expandedNode = (TreeItem) event.item;

+      TreeItem maybeDummy = expandedNode.getItem(0);

+      if (null == maybeDummy.getData()) {

+        maybeDummy.dispose();

+        IResource parentResource = (IResource)expandedNode.getData();

+        try {

+          populate(expandedNode, ((IContainer)parentResource).members());

+        } catch (CoreException e) {

+          throw new InternalErrorCDE("unhandled exception", e);

+        }

+      }

+    } else if (event.widget == resourcesUI && event.type == SWT.Selection) {

+      copyValuesFromGUI();

+    }

+    super.handleEvent(event);

+  }

+  /* (non-Javadoc)

+   * @see org.apache.uima.taeconfigurator.editors.ui.dialogs.AbstractDialog#copyValuesFromGUI()

+   */

+  public void copyValuesFromGUI() {

+    if (resourcesUI.getSelectionCount() > 0) {

+      pickedResource = (IResource)resourcesUI.getSelection()[0].getData();

+      result = (null == pickedResource) ? null 

+                                        : new IFile[] { 

+        TAEConfiguratorPlugin.getWorkspace().getRoot().getFile(

+                pickedResource.getFullPath())};        

+    }

+  }

+

+  /* (non-Javadoc)

+   * @see org.apache.uima.taeconfigurator.editors.ui.dialogs.AbstractDialog#enableOK()

+   */

+  public void enableOK() {

+    if ( (0 < resourcesUI.getSelectionCount()) &&

+            (resourcesUI.getSelection()[0].getData() instanceof IFile)) {

+      okButton.setEnabled(true);

+    } else {

+      okButton.setEnabled(false);

+    }

+  }

+

+  /* (non-Javadoc)

+   * @see org.apache.uima.taeconfigurator.editors.ui.dialogs.AbstractDialog#isValid()

+   */

+  public boolean isValid() {

+    return true;

+  }

+

+  public Object[] getResult() {

+    return result; 

+  }

+  

+  public void setResult(List aResult) {

+    if (null == aResult) {

+      result = null;

+    } else {

+      aResult.toArray(result = new Object[aResult.size()]);

+    }

+  }

+  

+}

diff --git a/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/dialogs/SearchMonitoringThread.java b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/dialogs/SearchMonitoringThread.java
new file mode 100644
index 0000000..f2698ca
--- /dev/null
+++ b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/dialogs/SearchMonitoringThread.java
@@ -0,0 +1,55 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.uima.taeconfigurator.editors.ui.dialogs;
+
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.swt.widgets.Display;
+
+public class SearchMonitoringThread extends Thread {
+  private SearchThread m_searchThread;
+
+  FindComponentDialog m_dialog;
+
+  public SearchMonitoringThread(FindComponentDialog dialog, SearchThread searchThread) {
+    m_dialog = dialog;
+    m_searchThread = searchThread;
+  }
+
+  public void run() {
+    while (true) {
+      if (m_searchThread.isDone()) {
+        if (!m_dialog.getStatusLabel1().isDisposed()) {
+          Display display = m_dialog.getStatusLabel1().getDisplay();
+          display.syncExec(new Runnable() {
+            public void run() {
+              m_dialog.buttonPressed(IDialogConstants.CANCEL_ID);
+            }
+          });
+        }
+        return;
+      }
+
+      try {
+        Thread.sleep(500);
+      } catch (Exception ex) {
+      }
+    }
+  }
+}
diff --git a/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/dialogs/SearchThread.java b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/dialogs/SearchThread.java
new file mode 100644
index 0000000..ae25792
--- /dev/null
+++ b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/dialogs/SearchThread.java
@@ -0,0 +1,262 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS 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.taeconfigurator.editors.ui.dialogs;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Pattern;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IWorkspace;
+import org.eclipse.swt.widgets.Display;
+
+import org.apache.uima.analysis_engine.TypeOrFeature;
+import org.apache.uima.resource.ResourceCreationSpecifier;
+import org.apache.uima.resource.ResourceSpecifier;
+import org.apache.uima.resource.metadata.Capability;
+import org.apache.uima.taeconfigurator.TAEConfiguratorPlugin;
+import org.apache.uima.taeconfigurator.editors.MultiPageEditor;
+import org.apache.uima.taeconfigurator.editors.ui.AbstractSection;
+
+public class SearchThread implements Runnable /* extends Thread */{
+  private Pattern m_fileNameSearch; 
+  private Pattern m_inputTypeSearch;
+  private Pattern m_outputTypeSearch;
+  
+  private String  m_projectToSearch;
+
+  FindComponentDialog m_dialog;
+
+  private AbstractSection m_aggregateSection;
+
+  private List m_matchingDelegateComponentDescriptors;
+
+  private List m_matchingDelegateComponentDescriptions;
+
+  int m_nWhichStatusMsg;
+
+  String m_statusMsg;
+
+  private String[] m_componentHeaders;
+
+  public SearchThread(FindComponentDialog dialog, AbstractSection aggregateSection,
+          String fileNameSearch, String inputTypeSearch, String outputTypeSearch,
+          String projectToSearch, String[] componentHeaders) {
+
+    m_dialog = dialog;
+    m_aggregateSection = aggregateSection;
+    m_fileNameSearch = (null == fileNameSearch)? null : Pattern.compile(fileNameSearch);
+    m_inputTypeSearch = (null == inputTypeSearch)? null : Pattern.compile(inputTypeSearch);
+    m_outputTypeSearch = (null == outputTypeSearch)? null : Pattern.compile(outputTypeSearch);
+    m_projectToSearch = projectToSearch;
+    m_componentHeaders = componentHeaders;
+  }
+
+  private boolean m_bDieNow = false;
+
+  private boolean m_bDone = false;
+
+  public void setDieNow() {
+    m_bDieNow = true;
+  }
+
+  public boolean getDieNow() {
+    return m_bDieNow;
+  }
+
+  public boolean isDone() {
+    return m_bDone;
+  }
+
+  public void run() {
+    m_matchingDelegateComponentDescriptors = new ArrayList();
+    m_matchingDelegateComponentDescriptions = new ArrayList();
+    
+    
+
+    getDelegateComponentsByInputOutputTypes(m_projectToSearch);
+
+    m_bDone = true;
+  }
+
+  private void testOneResource(IResource resource) {
+    switch (resource.getType()) {
+      case IResource.FILE:
+        if (resource.getName().toLowerCase().endsWith(".xml")
+                // exclude potentially many data files, not descriptors
+                && !resource.getName().toLowerCase().endsWith(".txt.xml")
+                && (m_fileNameSearch == null || m_fileNameSearch.matcher(resource.getName()).find())) {
+          String fileDescriptorRelPath = m_aggregateSection.editor
+                  .getDescriptorRelativePath(resource.getLocation().toString());
+          setStatusMsg(2, "Examining " + getBriefDisplayVersion(fileDescriptorRelPath));
+          ResourceSpecifier rs = MultiPageEditor.getDelegateResourceSpecifier((IFile) resource,
+                  m_componentHeaders);
+          // rs == null if wrong kind of descriptor
+          if (null == rs)
+            return;
+          if (!(rs instanceof ResourceCreationSpecifier)) // is a remote descriptor
+            if (m_inputTypeSearch != null || m_outputTypeSearch != null)
+              return; // don't find remote descriptors when types are wanted
+
+          if (!(rs instanceof ResourceCreationSpecifier) || // is a remote descriptor
+                  delegateComponentMatchesCapabilityReqs((ResourceCreationSpecifier) rs,
+                          m_inputTypeSearch, m_outputTypeSearch)) {
+            m_matchingDelegateComponentDescriptors.add(fileDescriptorRelPath);
+            m_matchingDelegateComponentDescriptions.add(rs);
+          }
+        }
+        break;
+      case IResource.FOLDER:
+        getDelegateComponentsByIOTypesBeginningAt((IFolder) resource);
+        break;
+    }
+
+  }
+
+  // populates the Vector of matchingAnalysisEngineDescriptors and
+  // matchingAnalysisEngineDescriptions
+  private void getDelegateComponentsByInputOutputTypes(String projectToSearch) {
+
+    IWorkspace workspace = TAEConfiguratorPlugin.getWorkspace();
+    IProject[] projects = workspace.getRoot().getProjects();
+    if (projectToSearch.equals(FindComponentDialog.ALL_PROJECTS)) {
+      setStatusMsg(1, "0 of " + projects.length + " projects processed.");
+    }
+
+    for (int i = 0; i < projects.length; i++) {
+      try {
+        if (projectToSearch.equals(FindComponentDialog.ALL_PROJECTS)
+                || projects[i].getName().equals(projectToSearch)) {
+
+          if (projectToSearch.equals(FindComponentDialog.ALL_PROJECTS)) {
+            setStatusMsg(2, "Looking in " + projects[i].getName() + "....");
+          } else {
+            setStatusMsg(2, "Searching " + projects[i].getName() + " for matching TAEs...");
+          }
+
+          IResource[] projectContents = projects[i].members();
+          for (int j = 0; j < projectContents.length; j++) {
+            testOneResource(projectContents[j]);
+          }
+
+          if (projectToSearch.equals(FindComponentDialog.ALL_PROJECTS)) {
+            setStatusMsg(1, (i + 1) + " of " + projects.length + " projects processed.");
+          }
+        }
+      } catch (Exception ex) {
+        System.out.println(ex.getMessage());
+      }
+    }
+  }
+
+  // populates the Vector of matchingAnalysisEngineDescriptors and
+  // matchingAnalysisEngineDescriptions
+  private void getDelegateComponentsByIOTypesBeginningAt(IFolder beginFolder) {
+
+    if (m_bDieNow) {
+      return;
+    }
+
+    try {
+      for (int i = 0; i < beginFolder.members().length; i++) {
+        testOneResource(beginFolder.members()[i]);
+      }
+    } catch (Exception ex) {
+      ex.printStackTrace();
+    }
+  }
+
+  private boolean delegateComponentMatchesCapabilityReqs(ResourceCreationSpecifier rs,
+          Pattern inputTypeSearch, Pattern outputTypeSearch) {
+
+    if (inputTypeSearch == null && outputTypeSearch == null) {
+      return true;
+    }
+
+    Capability[] capabilities = AbstractSection.getCapabilities(rs);
+    if (capabilities == null || capabilities.length == 0) {
+      return false;
+    }
+
+    boolean inputSatisfied = matchCapabilitiesTo(capabilities, inputTypeSearch, INPUT);
+    boolean outputSatisfied = matchCapabilitiesTo(capabilities, outputTypeSearch, OUTPUT);
+    return inputSatisfied && outputSatisfied;
+  }
+
+  private static final boolean INPUT = true;
+
+  private static final boolean OUTPUT = false;
+
+  private boolean matchCapabilitiesTo(Capability[] capabilities, Pattern search, boolean isInput) {
+    if (null == search)
+      return true;
+    for (int i = 0; i < capabilities.length; i++) {
+      TypeOrFeature[] typeOrFeatures = isInput ? capabilities[i].getInputs() : capabilities[i]
+              .getOutputs();
+      if (null != typeOrFeatures) {
+        for (int j = 0; j < typeOrFeatures.length; j++) {
+          if (search.matcher(typeOrFeatures[j].getName()).find()) {
+            return true;
+          }
+        }
+      }
+    }
+    return false;
+  }
+
+  public List getMatchingDelegateComponentDescriptors() {
+    return m_matchingDelegateComponentDescriptors;
+  }
+
+  public List getMatchingDelegateComponentDescriptions() {
+    return m_matchingDelegateComponentDescriptions;
+  }
+
+  private void setStatusMsg(int nWhich, String msg) {
+    m_nWhichStatusMsg = nWhich;
+    m_statusMsg = msg;
+
+    if (m_dialog.getStatusLabel1().isDisposed())
+      return;
+    Display display = m_dialog.getStatusLabel1().getDisplay();
+    display.syncExec(new Runnable() {
+      public void run() {
+        if (m_nWhichStatusMsg == 1) {
+          m_dialog.getStatusLabel1().setText(m_statusMsg);
+        } else {
+          m_dialog.getStatusLabel2().setText(m_statusMsg);
+        }
+      }
+    });
+
+  }
+
+  private String getBriefDisplayVersion(String filePathName) {
+    if (filePathName == null) {
+      return null;
+    }
+    filePathName = AbstractSection.maybeShortenFileName(filePathName);
+    return filePathName;
+  }
+
+}
diff --git a/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/dialogs/SelectTypeDialog.java b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/dialogs/SelectTypeDialog.java
new file mode 100644
index 0000000..a172b0b
--- /dev/null
+++ b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/dialogs/SelectTypeDialog.java
@@ -0,0 +1,172 @@
+/*

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

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

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

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

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

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

+ * 

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

+ * 

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

+ * software distributed under the License is distributed on an

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

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

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+

+package org.apache.uima.taeconfigurator.editors.ui.dialogs;

+

+import java.util.Iterator;

+import java.util.Map;

+import java.util.Set;

+

+import org.apache.uima.taeconfigurator.editors.ui.AbstractSection;

+import org.eclipse.swt.SWT;

+import org.eclipse.swt.layout.GridData;

+import org.eclipse.swt.widgets.Composite;

+import org.eclipse.swt.widgets.Control;

+import org.eclipse.swt.widgets.Event;

+import org.eclipse.swt.widgets.Table;

+import org.eclipse.swt.widgets.TableItem;

+import org.eclipse.swt.widgets.Text;

+

+public class SelectTypeDialog extends AbstractDialog {

+

+  private Text typeNameUI;

+  private Table matchingTypesUI;

+  private Table nameSpacesUI;

+  public String typeName = "error-TypeName-never-set";

+  public String nameSpaceName = "error-NameSpaceName-never-set";

+  private TypesWithNameSpaces types;

+  /**

+   * @param aSection

+   * @param title

+   * @param description

+   */

+  public SelectTypeDialog(AbstractSection section, TypesWithNameSpaces types) {

+    super(section, "Select Type Name", "Select an Existing CAS Type name from the set of defined types");

+    this.types = types;

+  }

+

+  /*

+   * (non-Javadoc)

+   * @see org.apache.uima.taeconfigurator.editors.ui.dialogs.AbstractDialog#createDialogArea(org.eclipse.swt.widgets.Composite)

+   * 

+   * Use labels on left (2 column layout)

+   * Create a text input area labeled: Type:

+   * Create a list output area labeled: Matching:

+   * Create a list output area labeled: NameSpaces:

+   * Bottom gets normal OK / Cancel buttons

+   */

+  protected Control createDialogArea(Composite parent) {

+    Composite mainArea = (Composite)super.createDialogArea(parent);

+    createWideLabel(mainArea, "Type Name:");

+    

+    typeNameUI = newText(mainArea, SWT.SINGLE, "Specify the type name");

+    typeNameUI.addListener(SWT.Modify, this);

+    

+    createWideLabel(mainArea, "Matching Types:");

+    

+    matchingTypesUI = newTable(mainArea, SWT.SINGLE);

+    ((GridData)matchingTypesUI.getLayoutData()).heightHint = 250;

+    ((GridData)matchingTypesUI.getLayoutData()).minimumHeight = 100;

+    typeNameUI.addListener(SWT.Selection, this);

+

+    

+    createWideLabel(mainArea, "NameSpaces:");

+    

+    nameSpacesUI = newTable(mainArea, SWT.SINGLE);

+    ((GridData)nameSpacesUI.getLayoutData()).heightHint = 75;

+    ((GridData)nameSpacesUI.getLayoutData()).minimumHeight = 40;

+    

+    displayFilteredTypes("");

+        

+    return mainArea;

+  }

+   

+  private void displayFilteredTypes(String aTypeName) {

+    matchingTypesUI.setRedraw(false);

+    matchingTypesUI.removeAll();

+    Map.Entry topEntry = null;

+    aTypeName = aTypeName.toLowerCase();

+    for (Iterator it = types.sortedNames.entrySet().iterator(); it.hasNext();) {

+      Map.Entry entry = (Map.Entry) it.next();

+      String candidateTypeName = ((String)entry.getKey()).toLowerCase();

+      if (candidateTypeName.startsWith(aTypeName)) {

+        if (null == topEntry)

+          topEntry = entry;

+        TableItem item = new TableItem(matchingTypesUI, SWT.NULL);

+        item.setText((String) entry.getKey());

+        item.setData(entry);

+      }

+    }

+    if (matchingTypesUI.getItemCount() > 0) {

+      matchingTypesUI.select(0);

+      displayNameSpacesForSelectedItem(topEntry);

+    }

+    

+    matchingTypesUI.setRedraw(true);    

+  }

+

+  private void displayNameSpacesForSelectedItem(Map.Entry entry) {

+    Set nameSpaces = (Set)entry.getValue();

+    nameSpacesUI.removeAll();

+    for (Iterator it = nameSpaces.iterator(); it.hasNext();) {

+      String nameSpace = (String) it.next();

+      TableItem item = new TableItem(nameSpacesUI, SWT.NULL);

+      item.setText(nameSpace);

+      item.setData(entry);

+    }

+    if (nameSpacesUI.getItemCount() > 0) {

+      nameSpacesUI.select(0);

+    }

+  }

+

+  /* (non-Javadoc)

+   * @see org.apache.uima.taeconfigurator.editors.ui.dialogs.AbstractDialog#handleEvent(org.eclipse.swt.widgets.Event)

+   */

+  public void handleEvent(Event event) {

+    if (event.widget == typeNameUI && event.type == SWT.Modify) {

+      typeName = typeNameUI.getText(); 

+      displayFilteredTypes(typeName);

+    }

+    

+    else if (event.widget == matchingTypesUI && event.type == SWT.Selection) {

+      displayNameSpacesForSelectedItem(

+              (Map.Entry)(matchingTypesUI.getSelection()[0].getData()));

+    }

+    super.handleEvent(event);

+  }

+

+  /* (non-Javadoc)

+   * @see org.apache.uima.taeconfigurator.editors.ui.dialogs.AbstractDialog#copyValuesFromGUI()

+   */

+  public void copyValuesFromGUI() {

+    if (0 < matchingTypesUI.getSelectionCount()) {

+      typeName = matchingTypesUI.getSelection()[0].getText();

+    }

+    if (0 < nameSpacesUI.getSelectionCount()) {

+      nameSpaceName = nameSpacesUI.getSelection()[0].getText();

+    }

+  }

+

+  /* (non-Javadoc)

+   * @see org.apache.uima.taeconfigurator.editors.ui.dialogs.AbstractDialog#enableOK()

+   */

+  public void enableOK() {

+    copyValuesFromGUI();

+    okButton.setEnabled( (0 < nameSpacesUI.getSelectionCount()) &&

+                         (0 < matchingTypesUI.getSelectionCount()));

+  }

+

+  /* (non-Javadoc)

+   * @see org.apache.uima.taeconfigurator.editors.ui.dialogs.AbstractDialog#isValid()

+   */

+  public boolean isValid() {

+    return true;

+  }

+

+}

diff --git a/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/dialogs/TypesWithNameSpaces.java b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/dialogs/TypesWithNameSpaces.java
new file mode 100644
index 0000000..6aeb09e
--- /dev/null
+++ b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/dialogs/TypesWithNameSpaces.java
@@ -0,0 +1,45 @@
+/*

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

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

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

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

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

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

+ * 

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

+ * 

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

+ * software distributed under the License is distributed on an

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

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

+ * specific language governing permissions and limitations

+ * under the License.

+ */

+

+package org.apache.uima.taeconfigurator.editors.ui.dialogs;

+

+import java.util.Set;

+import java.util.SortedMap;

+import java.util.TreeMap;

+import java.util.TreeSet;

+

+import org.apache.uima.taeconfigurator.editors.ui.AbstractSection;

+

+public class TypesWithNameSpaces {

+

+  public SortedMap sortedNames = new TreeMap();

+  

+  public void add(String fullname) {

+    String key = AbstractSection.getShortName(fullname);

+    String nameSpace = AbstractSection.getNameSpace(fullname);

+    Set entry = (Set) sortedNames.get(key);

+    if (null == entry) {

+      entry = new TreeSet();

+      entry.add(nameSpace);

+      sortedNames.put(key, entry);

+    } else {

+      entry.add(nameSpace);

+    }

+  }   

+}

diff --git a/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/dialogs/TypesWithNameSpaces32.java b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/dialogs/TypesWithNameSpaces32.java
new file mode 100644
index 0000000..10752ce
--- /dev/null
+++ b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/ui/dialogs/TypesWithNameSpaces32.java
@@ -0,0 +1,149 @@
+/*

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

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

+ * distributed with this work for additional information

+ * regarding copyright ownership.  The ASF licenses this file

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

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

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

+ * 

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

+ * 

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

+ * software distributed under the License is distributed on an

+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS 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.taeconfigurator.editors.ui.dialogs;

+

+import java.util.ArrayList;

+import java.util.Arrays;

+import java.util.Iterator;

+import java.util.List;

+import java.util.Map;

+import java.util.Set;

+import java.util.SortedMap;

+

+import org.eclipse.jface.fieldassist.IContentProposal;

+import org.eclipse.jface.fieldassist.IContentProposalProvider;

+

+/*

+ * This class forwards to TypesWithNameSpaces

+ * Purpose: provide content assist under Eclipse 3.2

+ * (The other class is set up to provide browse assist under 3.1 or higher Eclipse)

+ */

+

+public class TypesWithNameSpaces32 implements IContentProposalProvider {

+

+  final private SortedMap sortedNames;

+  

+  public TypesWithNameSpaces32(TypesWithNameSpaces aBase) {

+    sortedNames = aBase.sortedNames;

+  }

+  

+  private CasTypeProposal [] proposalArray = null;

+  

+  public static class CasTypeProposal 

+      implements IContentProposal, Comparable {

+    private final String labelForm;

+    private final String fullName;

+    private final String compareKey;

+    /* (non-Javadoc)

+     * @see org.eclipse.jface.fieldassist.IContentProposal#getContent()

+     */

+    CasTypeProposal(String aCompareKey, String shortName, String nameSpace) {

+      fullName = (null == nameSpace || "".equals(nameSpace))? shortName : nameSpace + "." + shortName;

+      labelForm = (null == nameSpace || "".equals(nameSpace))? shortName : shortName + " - " + nameSpace;

+      compareKey = aCompareKey.toLowerCase();

+    }

+       

+    public String getContent() {

+      return fullName;

+    }

+    /* (non-Javadoc)

+     * @see org.eclipse.jface.fieldassist.IContentProposal#getCursorPosition()

+     */

+    public int getCursorPosition() {

+      return fullName.length();

+    }

+    /* (non-Javadoc)

+     * @see org.eclipse.jface.fieldassist.IContentProposal#getDescription()

+     */

+    public String getDescription() {

+      return null;

+    }

+    /* (non-Javadoc)

+     * @see org.eclipse.jface.fieldassist.IContentProposal#getLabel()

+     */

+    public String getLabel() {

+      if (labelForm.toLowerCase().startsWith(compareKey))

+        return labelForm;

+      else

+        return fullName;

+    }

+    

+    public String getCompareKey() {

+      return compareKey;

+    }

+    /* (non-Javadoc)

+     * @see java.lang.Comparable#compareTo(java.lang.Object)

+     */

+    public int compareTo(Object arg0) throws ClassCastException {

+        final CasTypeProposal c = (CasTypeProposal) arg0;

+        return this.compareKey.compareTo(c.getCompareKey()); 

+    }

+  }

+ 

+  public void createProposalArray() {

+    List r = new ArrayList(sortedNames.size()*2);

+    

+    // item a.b.c.name creates 2 entries in the suggestions:

+    //   compare key: a.b.c.name  label:  name - a.b.c    content: a.b.c.name

+    //   compare key: name        label:  name - a.b.c    content: a.b.c.name 

+    

+    for (Iterator it = sortedNames.entrySet().iterator(); it.hasNext();) {

+      Map.Entry entry = (Map.Entry)it.next();

+      Set nameSpaces = (Set)entry.getValue();

+      for (Iterator nsi = nameSpaces.iterator(); nsi.hasNext();) {

+        String nameSpace = (String)nsi.next();

+        String shortName = (String)entry.getKey();

+        r.add(new CasTypeProposal(shortName, shortName, nameSpace));

+        if (null != nameSpace) {

+          r.add(new CasTypeProposal(nameSpace + "." + shortName, shortName, nameSpace));

+        }

+      }

+    }

+    proposalArray = (CasTypeProposal[])r.toArray(new CasTypeProposal[r.size()]);

+    Arrays.sort(proposalArray);

+  }

+  

+  public CasTypeProposal [] getProposalArray() {

+    return proposalArray;

+  }

+  

+  /* (non-Javadoc)

+   * @see org.eclipse.jface.fieldassist.IContentProposalProvider#getProposals(java.lang.String, int)

+   */

+  public IContentProposal[] getProposals(String contents, int position) {

+    if (null == proposalArray)

+      createProposalArray();

+    String keyString = contents.substring(0, position).toLowerCase();

+    CasTypeProposal key = new CasTypeProposal(keyString, null, null); 

+    int i = Arrays.binarySearch(proposalArray, key);

+    

+    if (i < 0) {

+      i = Math.abs(i + 1);

+    }

+    List rl = new ArrayList(proposalArray.length - i);

+    for (; i < proposalArray.length; i++) {

+      if (proposalArray[i].getCompareKey().startsWith(keyString)) {

+        rl.add(proposalArray[i]);

+      } else

+        break;

+    }

+    return (CasTypeProposal[])rl.toArray(new CasTypeProposal[rl.size()]);

+  } 

+}

diff --git a/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/xml/ColorManager.java b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/xml/ColorManager.java
new file mode 100644
index 0000000..b238644
--- /dev/null
+++ b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/xml/ColorManager.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.taeconfigurator.editors.xml;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.RGB;
+import org.eclipse.swt.widgets.Display;
+
+public class ColorManager {
+
+  protected Map fColorTable = new HashMap(10);
+
+  public void dispose() {
+    Iterator e = fColorTable.values().iterator();
+    while (e.hasNext())
+      ((Color) e.next()).dispose();
+  }
+
+  public Color getColor(RGB rgb) {
+    Color color = (Color) fColorTable.get(rgb);
+    if (color == null) {
+      color = new Color(Display.getCurrent(), rgb);
+      fColorTable.put(rgb, color);
+    }
+    return color;
+  }
+}
diff --git a/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/xml/IXMLColorConstants.java b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/xml/IXMLColorConstants.java
new file mode 100644
index 0000000..ba1d7c1
--- /dev/null
+++ b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/xml/IXMLColorConstants.java
@@ -0,0 +1,34 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.uima.taeconfigurator.editors.xml;
+
+import org.eclipse.swt.graphics.RGB;
+
+public interface IXMLColorConstants {
+  RGB XML_COMMENT = new RGB(128, 0, 0);
+
+  RGB PROC_INSTR = new RGB(128, 128, 128);
+
+  RGB STRING = new RGB(0, 128, 0);
+
+  RGB DEFAULT = new RGB(0, 0, 0);
+
+  RGB TAG = new RGB(0, 0, 128);
+}
diff --git a/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/xml/NonRuleBasedDamagerRepairer.java b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/xml/NonRuleBasedDamagerRepairer.java
new file mode 100644
index 0000000..6fd22e7
--- /dev/null
+++ b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/xml/NonRuleBasedDamagerRepairer.java
@@ -0,0 +1,138 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.uima.taeconfigurator.editors.xml;
+
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.DocumentEvent;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.ITypedRegion;
+import org.eclipse.jface.text.Region;
+import org.eclipse.jface.text.TextAttribute;
+import org.eclipse.jface.text.TextPresentation;
+import org.eclipse.jface.text.presentation.IPresentationDamager;
+import org.eclipse.jface.text.presentation.IPresentationRepairer;
+import org.eclipse.jface.util.Assert;
+import org.eclipse.swt.custom.StyleRange;
+
+public class NonRuleBasedDamagerRepairer implements IPresentationDamager, IPresentationRepairer {
+
+  /** The document this object works on */
+  protected IDocument fDocument;
+
+  /** The default text attribute if non is returned as data by the current token */
+  protected TextAttribute fDefaultTextAttribute;
+
+  /**
+   * Constructor for NonRuleBasedDamagerRepairer.
+   */
+  public NonRuleBasedDamagerRepairer(TextAttribute defaultTextAttribute) {
+    Assert.isNotNull(defaultTextAttribute);
+
+    fDefaultTextAttribute = defaultTextAttribute;
+  }
+
+  /**
+   * @see IPresentationRepairer#setDocument(IDocument)
+   */
+  public void setDocument(IDocument document) {
+    fDocument = document;
+  }
+
+  /**
+   * Returns the end offset of the line that contains the specified offset or if the offset is
+   * inside a line delimiter, the end offset of the next line.
+   * 
+   * @param offset
+   *          the offset whose line end offset must be computed
+   * @return the line end offset for the given offset
+   * @exception BadLocationException
+   *              if offset is invalid in the current document
+   */
+  protected int endOfLineOf(int offset) throws BadLocationException {
+
+    IRegion info = fDocument.getLineInformationOfOffset(offset);
+    if (offset <= info.getOffset() + info.getLength())
+      return info.getOffset() + info.getLength();
+
+    int line = fDocument.getLineOfOffset(offset);
+    try {
+      info = fDocument.getLineInformation(line + 1);
+      return info.getOffset() + info.getLength();
+    } catch (BadLocationException x) {
+      return fDocument.getLength();
+    }
+  }
+
+  /**
+   * @see IPresentationDamager#getDamageRegion(ITypedRegion, DocumentEvent, boolean)
+   */
+  public IRegion getDamageRegion(ITypedRegion partition, DocumentEvent event,
+          boolean documentPartitioningChanged) {
+    if (!documentPartitioningChanged) {
+      try {
+
+        IRegion info = fDocument.getLineInformationOfOffset(event.getOffset());
+        int start = Math.max(partition.getOffset(), info.getOffset());
+
+        int end = event.getOffset()
+                + (event.getText() == null ? event.getLength() : event.getText().length());
+
+        if (info.getOffset() <= end && end <= info.getOffset() + info.getLength()) {
+          // optimize the case of the same line
+          end = info.getOffset() + info.getLength();
+        } else
+          end = endOfLineOf(end);
+
+        end = Math.min(partition.getOffset() + partition.getLength(), end);
+        return new Region(start, end - start);
+
+      } catch (BadLocationException x) {
+      }
+    }
+
+    return partition;
+  }
+
+  /**
+   * @see IPresentationRepairer#createPresentation(TextPresentation, ITypedRegion)
+   */
+  public void createPresentation(TextPresentation presentation, ITypedRegion region) {
+    addRange(presentation, region.getOffset(), region.getLength(), fDefaultTextAttribute);
+  }
+
+  /**
+   * Adds style information to the given text presentation.
+   * 
+   * @param presentation
+   *          the text presentation to be extended
+   * @param offset
+   *          the offset of the range to be styled
+   * @param length
+   *          the length of the range to be styled
+   * @param attr
+   *          the attribute describing the style of the range to be styled
+   */
+  protected void addRange(TextPresentation presentation, int offset, int length, TextAttribute attr) {
+    if (attr != null)
+      presentation.addStyleRange(new StyleRange(offset, length, attr.getForeground(), attr
+              .getBackground(), attr.getStyle()));
+  }
+}
diff --git a/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/xml/TagRule.java b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/xml/TagRule.java
new file mode 100644
index 0000000..091cac9
--- /dev/null
+++ b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/xml/TagRule.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.taeconfigurator.editors.xml;
+
+import org.eclipse.jface.text.rules.*;
+
+public class TagRule extends MultiLineRule {
+
+  public TagRule(IToken token) {
+    super("<", ">", token);
+  }
+
+  protected boolean sequenceDetected(ICharacterScanner scanner, char[] sequence, boolean eofAllowed) {
+    int c = scanner.read();
+    if (sequence[0] == '<') {
+      if (c == '?') {
+        // processing instruction - abort
+        scanner.unread();
+        return false;
+      }
+      if (c == '!') {
+        scanner.unread();
+        // comment - abort
+        return false;
+      }
+    } else if (sequence[0] == '>') {
+      scanner.unread();
+    }
+    return super.sequenceDetected(scanner, sequence, eofAllowed);
+  }
+}
diff --git a/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/xml/XMLConfiguration.java b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/xml/XMLConfiguration.java
new file mode 100644
index 0000000..a9ab1c7
--- /dev/null
+++ b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/xml/XMLConfiguration.java
@@ -0,0 +1,109 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS 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.taeconfigurator.editors.xml;
+
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.ITextDoubleClickStrategy;
+import org.eclipse.jface.text.TextAttribute;
+import org.eclipse.jface.text.presentation.IPresentationReconciler;
+import org.eclipse.jface.text.presentation.PresentationReconciler;
+import org.eclipse.jface.text.rules.DefaultDamagerRepairer;
+import org.eclipse.jface.text.rules.Token;
+import org.eclipse.jface.text.source.ISourceViewer;
+import org.eclipse.jface.text.source.SourceViewerConfiguration;
+
+import org.apache.uima.taeconfigurator.editors.MultiPageEditorContributor;
+
+public class XMLConfiguration extends SourceViewerConfiguration {
+  private XMLDoubleClickStrategy doubleClickStrategy;
+
+  private XMLTagScanner tagScanner;
+
+  private XMLScanner scanner;
+
+  private ColorManager colorManager;
+
+  public XMLConfiguration(ColorManager colorManager) {
+    this.colorManager = colorManager;
+  }
+
+  public String[] getConfiguredContentTypes(ISourceViewer sourceViewer) {
+    return new String[] { IDocument.DEFAULT_CONTENT_TYPE, XMLPartitionScanner.XML_COMMENT,
+        XMLPartitionScanner.XML_TAG };
+  }
+
+  public ITextDoubleClickStrategy getDoubleClickStrategy(ISourceViewer sourceViewer,
+          String contentType) {
+    if (doubleClickStrategy == null)
+      doubleClickStrategy = new XMLDoubleClickStrategy();
+    return doubleClickStrategy;
+  }
+
+  protected XMLScanner getXMLScanner() {
+    if (scanner == null) {
+      scanner = new XMLScanner(colorManager);
+      scanner.setDefaultReturnToken(new Token(new TextAttribute(colorManager
+              .getColor(IXMLColorConstants.DEFAULT))));
+    }
+    return scanner;
+  }
+
+  protected XMLTagScanner getXMLTagScanner() {
+    if (tagScanner == null) {
+      tagScanner = new XMLTagScanner(colorManager);
+      tagScanner.setDefaultReturnToken(new Token(new TextAttribute(colorManager
+              .getColor(IXMLColorConstants.TAG))));
+    }
+    return tagScanner;
+  }
+
+  public IPresentationReconciler getPresentationReconciler(ISourceViewer sourceViewer) {
+    PresentationReconciler reconciler = new PresentationReconciler();
+
+    DefaultDamagerRepairer dr = new DefaultDamagerRepairer(getXMLTagScanner());
+    reconciler.setDamager(dr, XMLPartitionScanner.XML_TAG);
+    reconciler.setRepairer(dr, XMLPartitionScanner.XML_TAG);
+
+    dr = new DefaultDamagerRepairer(getXMLScanner());
+    reconciler.setDamager(dr, IDocument.DEFAULT_CONTENT_TYPE);
+    reconciler.setRepairer(dr, IDocument.DEFAULT_CONTENT_TYPE);
+
+    NonRuleBasedDamagerRepairer ndr = new NonRuleBasedDamagerRepairer(new TextAttribute(
+            colorManager.getColor(IXMLColorConstants.XML_COMMENT)));
+    reconciler.setDamager(ndr, XMLPartitionScanner.XML_COMMENT);
+    reconciler.setRepairer(ndr, XMLPartitionScanner.XML_COMMENT);
+
+    return reconciler;
+  }
+
+  // these 2 functions don't seem to control indent
+  public int getTabWidth(ISourceViewer sourceViewer) {
+    return MultiPageEditorContributor.getXMLindent();
+  }
+
+  public String[] getIndentPrefixes(ISourceViewer sourceViewer, String contentType) {
+    StringBuffer spaces = new StringBuffer(4);
+    int indent = getTabWidth(null);
+    for (int i = 0; i < indent; i++)
+      spaces.append(' ');
+    return new String[] { "\t", spaces.toString() /* , "" */}; //$NON-NLS-1$ //$NON-NLS-2$ 
+  }
+
+}
diff --git a/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/xml/XMLDocumentProvider.java b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/xml/XMLDocumentProvider.java
new file mode 100644
index 0000000..95e14a1
--- /dev/null
+++ b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/xml/XMLDocumentProvider.java
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.uima.taeconfigurator.editors.xml;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IDocumentPartitioner;
+import org.eclipse.jface.text.rules.DefaultPartitioner;
+import org.eclipse.ui.editors.text.FileDocumentProvider;
+
+public class XMLDocumentProvider extends FileDocumentProvider {
+
+  protected IDocument createDocument(Object element) throws CoreException {
+    IDocument document = super.createDocument(element);
+    if (document != null) {
+      IDocumentPartitioner partitioner = new DefaultPartitioner(new XMLPartitionScanner(),
+              new String[] { XMLPartitionScanner.XML_TAG, XMLPartitionScanner.XML_COMMENT });
+      partitioner.connect(document);
+      document.setDocumentPartitioner(partitioner);
+    }
+    return document;
+  }
+}
diff --git a/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/xml/XMLDoubleClickStrategy.java b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/xml/XMLDoubleClickStrategy.java
new file mode 100644
index 0000000..32087de
--- /dev/null
+++ b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/xml/XMLDoubleClickStrategy.java
@@ -0,0 +1,133 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS 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.taeconfigurator.editors.xml;
+
+import org.eclipse.jface.text.*;
+
+public class XMLDoubleClickStrategy implements ITextDoubleClickStrategy {
+  protected ITextViewer fText;
+
+  public void doubleClicked(ITextViewer part) {
+    int pos = part.getSelectedRange().x;
+
+    if (pos < 0)
+      return;
+
+    fText = part;
+
+    if (!selectComment(pos)) {
+      selectWord(pos);
+    }
+  }
+
+  protected boolean selectComment(int caretPos) {
+    IDocument doc = fText.getDocument();
+    int startPos, endPos;
+
+    try {
+      int pos = caretPos;
+      char c = ' ';
+
+      while (pos >= 0) {
+        c = doc.getChar(pos);
+        if (c == '\\') {
+          pos -= 2;
+          continue;
+        }
+        if (c == '\n' || c == '\"')
+          break;
+        --pos;
+      }
+
+      if (c != '\"')
+        return false;
+
+      startPos = pos;
+
+      pos = caretPos;
+      int length = doc.getLength();
+      c = ' ';
+
+      while (pos < length) {
+        c = doc.getChar(pos);
+        if (c == Character.LINE_SEPARATOR || c == '\"')
+          break;
+        ++pos;
+      }
+      if (c != '\"')
+        return false;
+
+      endPos = pos;
+
+      int offset = startPos + 1;
+      int len = endPos - offset;
+      fText.setSelectedRange(offset, len);
+      return true;
+    } catch (BadLocationException x) {
+    }
+
+    return false;
+  }
+
+  protected boolean selectWord(int caretPos) {
+
+    IDocument doc = fText.getDocument();
+    int startPos, endPos;
+
+    try {
+
+      int pos = caretPos;
+      char c;
+
+      while (pos >= 0) {
+        c = doc.getChar(pos);
+        if (!Character.isJavaIdentifierPart(c))
+          break;
+        --pos;
+      }
+
+      startPos = pos;
+
+      pos = caretPos;
+      int length = doc.getLength();
+
+      while (pos < length) {
+        c = doc.getChar(pos);
+        if (!Character.isJavaIdentifierPart(c))
+          break;
+        ++pos;
+      }
+
+      endPos = pos;
+      selectRange(startPos, endPos);
+      return true;
+
+    } catch (BadLocationException x) {
+    }
+
+    return false;
+  }
+
+  private void selectRange(int startPos, int stopPos) {
+    int offset = startPos + 1;
+    int length = stopPos - offset;
+    fText.setSelectedRange(offset, length);
+  }
+}
diff --git a/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/xml/XMLEditor.java b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/xml/XMLEditor.java
new file mode 100644
index 0000000..67d53a4
--- /dev/null
+++ b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/xml/XMLEditor.java
@@ -0,0 +1,203 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS 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.taeconfigurator.editors.xml;
+
+import java.lang.reflect.InvocationTargetException;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IWorkspace;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.jface.dialogs.IMessageProvider;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.dialogs.ProgressMonitorDialog;
+import org.eclipse.jface.text.ITextListener;
+import org.eclipse.jface.text.TextEvent;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.IFileEditorInput;
+import org.eclipse.ui.actions.WorkspaceModifyOperation;
+import org.eclipse.ui.dialogs.SaveAsDialog;
+import org.eclipse.ui.editors.text.TextEditor;
+import org.eclipse.ui.part.FileEditorInput;
+import org.eclipse.ui.texteditor.IDocumentProvider;
+
+import org.apache.uima.taeconfigurator.editors.MultiPageEditor;
+
+public class XMLEditor extends TextEditor {
+
+  MultiPageEditor editor;
+
+  private ColorManager colorManager;
+
+  private EditorsTextListener m_textListener = new EditorsTextListener();
+
+  // next set to true when we are setting the text of the
+  // editor so that just switching to source page doesn't
+  // cause editor to think source file is dirty
+  boolean m_bIgnoreTextEvent = false;
+
+  public class EditorsTextListener implements ITextListener {
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see org.eclipse.jface.text.ITextListener#textChanged(org.eclipse.jface.text.TextEvent)
+     */
+    public void textChanged(TextEvent event) {
+      if (!m_bIgnoreTextEvent) {
+        editor.sourceChanged = true;
+        editor.setFileDirty();
+      }
+    }
+  }
+
+  public XMLEditor(MultiPageEditor editor) {
+    super();
+    colorManager = new ColorManager();
+    setSourceViewerConfiguration(new XMLConfiguration(colorManager));
+    setDocumentProvider(new XMLDocumentProvider());
+    this.editor = editor;
+  }
+
+  public void createPartControl(Composite parent) {
+    super.createPartControl(parent);
+    getSourceViewer().addTextListener(m_textListener);
+  }
+
+  public void dispose() {
+    colorManager.dispose();
+    super.dispose();
+  }
+
+  public void doSaveAs() {
+    IProgressMonitor progressMonitor = getProgressMonitor();
+    Shell shell = getSite().getShell();
+    IEditorInput input = getEditorInput();
+
+    SaveAsDialog dialog = new SaveAsDialog(shell);
+
+    IFile original = (input instanceof IFileEditorInput) ? ((IFileEditorInput) input).getFile()
+            : null;
+    if (original != null)
+      dialog.setOriginalFile(original);
+
+    dialog.create();
+
+    IDocumentProvider provider = getDocumentProvider();
+    if (provider == null) {
+      // editor has programatically been closed while the dialog was open
+      return;
+    }
+
+    if (provider.isDeleted(input) && original != null) {
+      String message = "The original file, '" + original.getName() + "' has been deleted";
+      dialog.setErrorMessage(null);
+      dialog.setMessage(message, IMessageProvider.WARNING);
+    }
+
+    if (dialog.open() == Dialog.CANCEL) {
+      if (progressMonitor != null)
+        progressMonitor.setCanceled(true);
+      editor.setSaveAsStatus(MultiPageEditor.SAVE_AS_CANCELLED);
+      return;
+    }
+
+    IPath filePath = dialog.getResult();
+    if (filePath == null) {
+      if (progressMonitor != null)
+        progressMonitor.setCanceled(true);
+      editor.setSaveAsStatus(MultiPageEditor.SAVE_AS_CANCELLED);
+      return;
+    }
+
+    IWorkspace workspace = ResourcesPlugin.getWorkspace();
+    IFile file = workspace.getRoot().getFile(filePath);
+    final IEditorInput newInput = new FileEditorInput(file);
+
+    WorkspaceModifyOperation op = new WorkspaceModifyOperation() {
+      public void execute(final IProgressMonitor monitor) throws CoreException {
+        getDocumentProvider().saveDocument(monitor, newInput,
+                getDocumentProvider().getDocument(getEditorInput()), true);
+      }
+    };
+
+    boolean success = false;
+    try {
+
+      provider.aboutToChange(newInput);
+      new ProgressMonitorDialog(shell).run(false, true, op);
+      success = true;
+
+    } catch (InterruptedException x) {
+    } catch (InvocationTargetException x) {
+
+      Throwable targetException = x.getTargetException();
+
+      String title = "Error saving"; // TextEditorMessages.getString("Editor.error.save.title");
+      // //$NON-NLS-1$
+      String msg = "Error occurred during save operation"; // MessageFormat.format(TextEditorMessages.getString("Editor.error.save.message"),
+      // new Object[] {
+      // targetException.getMessage()});
+      // //$NON-NLS-1$
+
+      if (targetException instanceof CoreException) {
+        CoreException coreException = (CoreException) targetException;
+        IStatus status = coreException.getStatus();
+        if (status != null) {
+          switch (status.getSeverity()) {
+            case IStatus.INFO:
+              MessageDialog.openInformation(shell, title, msg);
+              break;
+            case IStatus.WARNING:
+              MessageDialog.openWarning(shell, title, msg);
+              break;
+            default:
+              MessageDialog.openError(shell, title, msg);
+          }
+        } else {
+          MessageDialog.openError(shell, title, msg);
+        }
+      }
+
+    } finally {
+      provider.changed(newInput);
+      if (success) {
+        setInput(newInput);
+        editor.setSaveAsStatus(MultiPageEditor.SAVE_AS_CONFIRMED);
+      } else {
+        editor.setSaveAsStatus(MultiPageEditor.SAVE_AS_CANCELLED);
+      }
+    }
+
+    if (progressMonitor != null)
+      progressMonitor.setCanceled(!success);
+  }
+
+  public void setIgnoreTextEvent(boolean bIgnoreTextEvent) {
+    m_bIgnoreTextEvent = bIgnoreTextEvent;
+  }
+
+}
diff --git a/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/xml/XMLPartitionScanner.java b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/xml/XMLPartitionScanner.java
new file mode 100644
index 0000000..3499e29
--- /dev/null
+++ b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/xml/XMLPartitionScanner.java
@@ -0,0 +1,43 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.uima.taeconfigurator.editors.xml;
+
+import org.eclipse.jface.text.rules.*;
+
+public class XMLPartitionScanner extends RuleBasedPartitionScanner {
+  public final static String XML_DEFAULT = "__xml_default";
+
+  public final static String XML_COMMENT = "__xml_comment";
+
+  public final static String XML_TAG = "__xml_tag";
+
+  public XMLPartitionScanner() {
+
+    IToken xmlComment = new Token(XML_COMMENT);
+    IToken tag = new Token(XML_TAG);
+
+    IPredicateRule[] rules = new IPredicateRule[2];
+
+    rules[0] = new MultiLineRule("<!--", "-->", xmlComment);
+    rules[1] = new TagRule(tag);
+
+    setPredicateRules(rules);
+  }
+}
diff --git a/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/xml/XMLScanner.java b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/xml/XMLScanner.java
new file mode 100644
index 0000000..0faf184
--- /dev/null
+++ b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/xml/XMLScanner.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.taeconfigurator.editors.xml;
+
+import org.eclipse.jface.text.rules.*;
+import org.eclipse.jface.text.*;
+
+public class XMLScanner extends RuleBasedScanner {
+
+  public XMLScanner(ColorManager manager) {
+    IToken procInstr = new Token(new TextAttribute(manager.getColor(IXMLColorConstants.PROC_INSTR)));
+
+    IRule[] rules = new IRule[2];
+    // Add rule for processing instructions
+    rules[0] = new SingleLineRule("<?", "?>", procInstr);
+    // Add generic whitespace rule.
+    rules[1] = new WhitespaceRule(new XMLWhitespaceDetector());
+
+    setRules(rules);
+  }
+}
diff --git a/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/xml/XMLTagScanner.java b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/xml/XMLTagScanner.java
new file mode 100644
index 0000000..d3d7198
--- /dev/null
+++ b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/xml/XMLTagScanner.java
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.uima.taeconfigurator.editors.xml;
+
+import org.eclipse.jface.text.*;
+import org.eclipse.jface.text.rules.*;
+
+public class XMLTagScanner extends RuleBasedScanner {
+
+  public XMLTagScanner(ColorManager manager) {
+    IToken string = new Token(new TextAttribute(manager.getColor(IXMLColorConstants.STRING)));
+
+    IRule[] rules = new IRule[3];
+
+    // Add rule for double quotes
+    rules[0] = new SingleLineRule("\"", "\"", string, '\\');
+    // Add a rule for single quotes
+    rules[1] = new SingleLineRule("'", "'", string, '\\');
+    // Add generic whitespace rule.
+    rules[2] = new WhitespaceRule(new XMLWhitespaceDetector());
+
+    setRules(rules);
+  }
+}
diff --git a/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/xml/XMLWhitespaceDetector.java b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/xml/XMLWhitespaceDetector.java
new file mode 100644
index 0000000..5bf1763
--- /dev/null
+++ b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/editors/xml/XMLWhitespaceDetector.java
@@ -0,0 +1,29 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS 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.taeconfigurator.editors.xml;
+
+import org.eclipse.jface.text.rules.IWhitespaceDetector;
+
+public class XMLWhitespaceDetector implements IWhitespaceDetector {
+
+  public boolean isWhitespace(char c) {
+    return (c == ' ' || c == '\t' || c == '\n' || c == '\r');
+  }
+}
diff --git a/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/files/ContextForPartDialog.java b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/files/ContextForPartDialog.java
new file mode 100644
index 0000000..88f5caa
--- /dev/null
+++ b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/files/ContextForPartDialog.java
@@ -0,0 +1,170 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS 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.taeconfigurator.files;
+
+import java.text.MessageFormat;
+
+import org.apache.uima.resource.metadata.FsIndexCollection;
+import org.apache.uima.resource.metadata.ResourceManagerConfiguration;
+import org.apache.uima.resource.metadata.TypePriorities;
+import org.apache.uima.taeconfigurator.editors.MultiPageEditor;
+import org.apache.uima.taeconfigurator.editors.ui.AbstractSection;
+import org.apache.uima.taeconfigurator.editors.ui.dialogs.ResourcePickerDialog;
+import org.apache.uima.util.XMLizable;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Text;
+
+public class ContextForPartDialog extends /*LimitedResourceSelectionDialog*/ 
+        ResourcePickerDialog /*implements
+        ICheckStateListener*/ {
+
+  // private MultiPageEditor editor;
+  private Text contextPathGUI;
+
+  public String contextPath;
+
+  private String initialPath;
+
+  private XMLizable tbe;
+
+  public ContextForPartDialog(Shell parentShell, IAdaptable rootElement,
+          XMLizable thingBeingEdited, IPath aExcludeDescriptor, MultiPageEditor aEditor,
+          String aInitialPath) {
+
+    super(parentShell);
+    initialPath = aInitialPath;
+    setTitle("Context for importable part");
+    tbe = thingBeingEdited;
+
+/*
+    super(parentShell, rootElement, "Context for importable part");
+    // editor = aEditor;
+    initialPath = aInitialPath;
+    setTitle("Context for importable part");
+    tbe = thingBeingEdited;
+    setShellStyle(getShellStyle() | SWT.RESIZE);
+    */
+  }
+
+  protected Control createDialogArea(Composite parent) {
+    parent = new Composite(parent, SWT.NONE);
+    parent.setLayout(new GridLayout(1, true));
+    parent.setLayoutData(new GridData(SWT.LEAD, SWT.BEGINNING, true, false));
+    ((GridLayout) parent.getLayout()).marginWidth = 15;
+    // Show a text field with the path, allow editing
+    // anything picked overrides the text field
+    AbstractSection.spacer(parent);
+    Label instructions = new Label(parent, SWT.WRAP);
+    instructions
+            .setText(MessageFormat
+                    .format(
+                            "You are about to edit a UIMA {0} descriptor.  \n"
+                                    + "In order to do this, you need to specify another UIMA descriptor, which will supply "
+                                    + "the needed context for this file.\n"
+                                    + "It can be any of the following kinds of descriptors:\n\n    "
+                                    + "{1}\n\n"
+                                    + "The file below is a suggested context.  \n\n"
+                                    + "     >>>  If it is correct, just push OK.  <<<\n\n"
+                                    + "Otherwise you can change it by overtyping it,\n"
+                                    + "or use the project explorer window below to pick the context file to use.",
+                            new Object[] {
+                                (tbe instanceof FsIndexCollection) ? "Index Definition"
+                                        : (tbe instanceof TypePriorities) ? "Type Priority Definition"
+                                                : (tbe instanceof ResourceManagerConfiguration) ? "Resource Manager Configuration"
+                                                        : "unhandled - error",
+
+                                (tbe instanceof FsIndexCollection) ? "A Type System or any descriptor containing or "
+                                        + "importing the type system associated with this Index Definition,\n    other than a Collection Processing Engine"
+                                        : (tbe instanceof TypePriorities) ? "A Type System or any descriptor containing or "
+                                                + "importing the type system associated with this TypePriority Definition,\n    other than a Collection Processing Engine"
+                                                : (tbe instanceof ResourceManagerConfiguration) ? "A descriptor (such as an Analysis Engine) containing "
+                                                        + "(directly or via aggregate delegates)\n    "
+                                                        + "the External Resource Dependencies referenced by this Resource Manager Configuration"
+                                                        : "unhandled - error" }));
+
+    AbstractSection.spacer(parent);
+
+    contextPathGUI = new Text(parent, SWT.BORDER);
+    contextPathGUI.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+    contextPathGUI.setText(null == initialPath ? "" : initialPath);
+    // AbstractSection.spacer(parent);
+
+    Composite composite = (Composite) super.createDialogArea(parent);
+    return composite;
+  }
+
+  /* (non-Javadoc)
+   * @see org.apache.uima.taeconfigurator.editors.ui.dialogs.AbstractDialog#handleEvent(org.eclipse.swt.widgets.Event)
+   */
+  public void handleEvent(Event event) {
+    super.handleEvent(event);
+    
+    if (event.widget == resourcesUI && event.type == SWT.Selection) {
+      if (null != pickedResource) { 
+        IFile f = (IFile)getResult()[0];
+        contextPathGUI.setText(f.getLocation().toOSString());
+      }   
+    }
+  }
+
+  protected void okPressed() {
+    contextPath = contextPathGUI.getText();
+    super.okPressed();
+  }
+  
+  /* (non-Javadoc)
+   * @see org.apache.uima.taeconfigurator.editors.ui.dialogs.AbstractDialog#enableOK()
+   */
+  public void enableOK() {
+    super.enableOK();
+    String path = contextPathGUI.getText();
+    if (null != path && 
+        !"".equals(path))
+      okButton.setEnabled(true);
+  }
+
+  
+  /*
+  public void checkStateChanged(CheckStateChangedEvent event) {
+    // event.getChecked(); // true if checked
+    // event.getElement(); // File with workspace-relative path
+    if (event.getChecked() && event.getElement() instanceof IFile) {
+      contextPathGUI.setText(((IFile) event.getElement()).getLocation().toString());
+    }
+    okButton.setEnabled(
+            selectionGroup.getCheckedElementCount() > 0 || contextPathGUI.getText().length() > 0);
+  }
+
+  protected void initializeDialog() {
+    selectionGroup.addCheckStateListener(this);
+    getOkButton().setEnabled(contextPathGUI.getText().length() > 0);
+  }
+  */
+}
diff --git a/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/files/MultiResourceSelectionDialog.java b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/files/MultiResourceSelectionDialog.java
new file mode 100644
index 0000000..155af7e
--- /dev/null
+++ b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/files/MultiResourceSelectionDialog.java
@@ -0,0 +1,141 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.uima.taeconfigurator.files;
+
+import java.util.ArrayList;
+
+import org.apache.uima.taeconfigurator.CDEpropertyPage;
+import org.apache.uima.taeconfigurator.Messages;
+import org.apache.uima.taeconfigurator.TAEConfiguratorPlugin;
+import org.apache.uima.taeconfigurator.editors.MultiPageEditor;
+import org.apache.uima.taeconfigurator.editors.ui.dialogs.ResourcePickerDialog;
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.FileDialog;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Listener;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.forms.widgets.FormToolkit;
+
+public class MultiResourceSelectionDialog extends ResourcePickerDialog {
+
+  private Button browseButton; // for browsing the file system
+
+  private Button importByNameUI;
+
+  private Button importByLocationUI;
+
+  public boolean isImportByName;
+
+  private MultiPageEditor editor;
+
+  public MultiResourceSelectionDialog(Shell parentShell, IAdaptable rootElement, String message,
+          IPath aExcludeDescriptor, MultiPageEditor aEditor) {
+    super(parentShell);
+    editor = aEditor;
+
+    /*
+    super(parentShell, rootElement, message);
+    editor = aEditor;
+    setTitle(Messages.getString("ResourceSelectionDialog.title")); //$NON-NLS-1$
+
+    if (message != null)
+      setMessage(message);
+    else
+      setMessage(Messages.getString("ResourceSelectionDialog.message")); //$NON-NLS-1$
+    setShellStyle(getShellStyle() | SWT.RESIZE);
+ */
+  }
+
+  protected Control createDialogArea(Composite parent) {
+    // page group
+    Composite composite = (Composite) super.createDialogArea(parent);
+    FormToolkit factory = new FormToolkit(TAEConfiguratorPlugin.getDefault().getFormColors(
+            parent.getDisplay()));
+    Label label = new Label(composite, SWT.WRAP /* SWT.CENTER */);
+    label.setText(Messages.getString("MultiResourceSelectionDialog.Or")); //$NON-NLS-1$
+    browseButton = factory.createButton(composite, Messages
+            .getString("MultiResourceSelectionDialog.BrowseFileSys"), //$NON-NLS-1$
+            SWT.PUSH);
+    browseButton.setLayoutData(new GridData(GridData.VERTICAL_ALIGN_BEGINNING));
+    browseButton.pack(false);
+    browseButton.addListener(SWT.MouseUp, new Listener() {
+      public void handleEvent(Event event) {
+        FileDialog dialog = new FileDialog(getShell(), /* SWT.OPEN | */
+        SWT.MULTI);
+        String[] extensions = { Messages.getString("MultiResourceSelectionDialog.starDotXml") }; //$NON-NLS-1$
+        dialog.setFilterExtensions(extensions);
+        String sStartDir = TAEConfiguratorPlugin.getWorkspace().getRoot().getLocation()
+                .toOSString();
+        dialog.setFilterPath(sStartDir);
+        String file = dialog.open();
+
+        if (file != null && !file.equals("")) { //$NON-NLS-1$
+          // close();
+          okPressed();
+          ArrayList list = new ArrayList();
+          IPath iPath = new Path(file);
+          list.add(iPath);
+          localSetResult(list);
+        }
+      }
+
+    });
+
+    new Label(composite, SWT.NONE).setText("");
+    importByNameUI = new Button(composite, SWT.RADIO);
+    importByNameUI.setText("Import by Name");
+    importByNameUI
+            .setToolTipText("Importing by name looks up the name on the datapath, and if not found there, on the classpath.");
+
+    importByLocationUI = new Button(composite, SWT.RADIO);
+    importByLocationUI.setText("Import By Location");
+    importByLocationUI.setToolTipText("Importing by location requires a relative or absolute URL");
+
+    String defaultBy = CDEpropertyPage.getImportByDefault(editor.getProject());
+    if (defaultBy.equals("location")) {
+      importByNameUI.setSelection(false);
+      importByLocationUI.setSelection(true);
+    } else {
+      importByNameUI.setSelection(true);
+      importByLocationUI.setSelection(false);
+    }
+    return composite;
+  }
+
+  protected void okPressed() {
+    isImportByName = importByNameUI.getSelection();
+    CDEpropertyPage.setImportByDefault(editor.getProject(), isImportByName ? "name" : "location");
+    super.okPressed();
+  }
+
+  // This is to avoid synthetic access method warning
+  protected void localSetResult(ArrayList list) {
+    setResult(list);
+  }
+
+}
diff --git a/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/files/MultiResourceSelectionDialogWithFlowOption.java b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/files/MultiResourceSelectionDialogWithFlowOption.java
new file mode 100644
index 0000000..f3eb9a6
--- /dev/null
+++ b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/files/MultiResourceSelectionDialogWithFlowOption.java
@@ -0,0 +1,79 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS 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.taeconfigurator.files;
+
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.forms.widgets.FormToolkit;
+
+import org.apache.uima.taeconfigurator.Messages;
+import org.apache.uima.taeconfigurator.TAEConfiguratorPlugin;
+import org.apache.uima.taeconfigurator.editors.MultiPageEditor;
+
+public class MultiResourceSelectionDialogWithFlowOption extends MultiResourceSelectionDialog {
+
+  private Button autoAddToFlowButton;
+
+  private boolean m_bAutoAddToFlow = true;
+
+  /**
+   * @param parentShell
+   * @param rootElement
+   * @param message
+   * @param excludeDescriptor
+   */
+  public MultiResourceSelectionDialogWithFlowOption(Shell parentShell, IAdaptable rootElement,
+          String message, IPath excludeDescriptor, MultiPageEditor editor) {
+    super(parentShell, rootElement, message, excludeDescriptor, editor);
+  }
+
+  protected Control createDialogArea(Composite parent) {
+    Composite composite = (Composite) super.createDialogArea(parent);
+
+    new Label(composite, SWT.WRAP).setText(""); //$NON-NLS-1$
+
+    String sAddToFlowPrompt = Messages
+            .getString("MultiResourceSelectionDialogWithFlowOption.addSelectedAEsToEndOfFlow"); //$NON-NLS-1$
+    FormToolkit factory = new FormToolkit(TAEConfiguratorPlugin.getDefault().getFormColors(
+            parent.getDisplay()));
+
+    autoAddToFlowButton = factory.createButton(composite, sAddToFlowPrompt, SWT.CHECK);
+    autoAddToFlowButton.setSelection(m_bAutoAddToFlow);
+    autoAddToFlowButton.setBackground(null);
+
+    return composite;
+  }
+
+  protected void okPressed() {
+    m_bAutoAddToFlow = autoAddToFlowButton.getSelection();
+    super.okPressed();
+  }
+
+  public boolean getAutoAddToFlow() {
+    return m_bAutoAddToFlow;
+  }
+
+}
diff --git a/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/files/PickOverrideKeysAndParmName.java b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/files/PickOverrideKeysAndParmName.java
new file mode 100644
index 0000000..464a9cf
--- /dev/null
+++ b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/files/PickOverrideKeysAndParmName.java
@@ -0,0 +1,399 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS 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.taeconfigurator.files;
+
+import java.util.Iterator;
+import java.util.Map;
+
+import org.apache.uima.analysis_engine.AnalysisEngineDescription;
+import org.apache.uima.collection.CasConsumerDescription;
+import org.apache.uima.flow.FlowControllerDescription;
+import org.apache.uima.resource.ResourceCreationSpecifier;
+import org.apache.uima.resource.ResourceSpecifier;
+import org.apache.uima.resource.metadata.ConfigurationGroup;
+import org.apache.uima.resource.metadata.ConfigurationParameter;
+import org.apache.uima.resource.metadata.ConfigurationParameterDeclarations;
+import org.apache.uima.taeconfigurator.editors.ui.AbstractSection;
+import org.apache.uima.taeconfigurator.editors.ui.ParameterDelegatesSection;
+import org.apache.uima.taeconfigurator.editors.ui.dialogs.AbstractDialog;
+import org.apache.uima.taeconfigurator.editors.ui.dialogs.AddParameterDialog;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.TableItem;
+
+
+public class PickOverrideKeysAndParmName extends AbstractDialog {
+
+  private AddParameterDialog parameterDialog = null; // not currently used
+
+  private ConfigurationParameter cp;
+
+  private ConfigurationParameterDeclarations cpd;
+
+  private boolean adding;
+
+  private Table paramsUI;
+
+  private Table keysUI;
+
+  private Map delegates;
+  
+  //returned values
+  public String delegateKeyName;
+  public String delegateParameterName;
+
+   /*
+   * Shows 2 side-by-side windows.
+   * 
+   * Left one is a list of keys of next-level-delegates
+   * Right one is a list of parms of those delegates that 
+   *   match sufficiently to be overridden by this overriding parm
+   * If adding to existing override - current overrides are not shown as
+   *   candidates.
+   * If editing - all are shown (you can delete)  
+   *
+   */
+  public PickOverrideKeysAndParmName(AbstractSection aSection,
+          Map delegateMap,
+          String message, ConfigurationParameter aCp, ConfigurationParameterDeclarations aCpd,
+          boolean aAdding) {
+    super(aSection, "Delegate Keys and Parameter Name Selection", message);
+    delegates = delegateMap;
+    cp = aCp;
+    cpd = aCpd;
+    adding = aAdding; // true if we're adding, not editing
+  }
+
+  protected Control createDialogArea(Composite parent) {
+    Composite mainArea = (Composite)super.createDialogArea(parent);
+    
+    Composite twoCol = new2ColumnComposite(mainArea);
+    
+    
+    keysUI = newTable(twoCol, SWT.SINGLE);
+    paramsUI = newTable(twoCol, SWT.SINGLE);
+    
+    for (Iterator it = delegates.entrySet().iterator(); it.hasNext();) {
+      Map.Entry entry = (Map.Entry)it.next();
+      TableItem item = new TableItem(keysUI, SWT.NULL);
+      item.setText((String)entry.getKey());
+      item.setData(entry);
+    }
+    keysUI.addListener(SWT.Selection, this);
+    if (0 < keysUI.getItemCount()) {
+      keysUI.setSelection(0);
+    }
+    
+    return mainArea;
+  }
+    
+  
+  
+  /* (non-Javadoc)
+   * @see org.apache.uima.taeconfigurator.editors.ui.dialogs.AbstractDialog#handleEvent(org.eclipse.swt.widgets.Event)
+   */
+  public void handleEvent(Event event) {
+    if (event.widget == keysUI && event.type == SWT.Selection) {
+      fillParameterCandidates();
+      super.handleEvent(event);
+    }
+    
+    else if (event.widget == paramsUI && event.type == SWT.Selection) {
+      copyValuesFromGUI();
+      super.handleEvent(event);
+    }
+  }
+
+  private void fillParameterCandidates() {
+    paramsUI.setRedraw(false);
+    paramsUI.removeAll();
+    TableItem selectedItem = keysUI.getSelection()[0];
+
+    Map.Entry entry = (Map.Entry) selectedItem.getData();
+    String keyName = (String) entry.getKey();
+    // support CasConsumers also
+    // support Flow Controllers too
+    // and skip remote service descriptors
+
+    ResourceSpecifier rs = (ResourceSpecifier) entry.getValue();
+    if (rs instanceof AnalysisEngineDescription || rs instanceof CasConsumerDescription
+            || rs instanceof FlowControllerDescription) {
+      ConfigurationParameterDeclarations delegateCpd = ((ResourceCreationSpecifier) rs)
+              .getMetaData().getConfigurationParameterDeclarations();
+      addSelectedParms(delegateCpd.getCommonParameters(), keyName);
+
+      ConfigurationGroup[] groups = delegateCpd.getConfigurationGroups();
+      if (null != groups) {
+        for (int i = 0; i < groups.length; i++) {
+          addSelectedParms(groups[i].getConfigurationParameters(), keyName);
+        }
+      }
+      addSelectedParms(delegateCpd.getConfigurationParameters(), keyName);
+    }
+    if (0 < paramsUI.getItemCount()) {
+      paramsUI.setSelection(0);
+    }
+    paramsUI.setRedraw(true);
+  }
+ 
+  /*
+   * Filter overridable parameters to exclude: - already overridden (can't override same parameter
+   * twice) - those with different type or multi-valued-ness (Group match not required)
+   */
+  private void addSelectedParms(ConfigurationParameter[] parms, String keyName) {
+    boolean isMultiValued = (null != parameterDialog) ? parameterDialog.multiValueUI
+            .getSelection() : cp.isMultiValued();
+    String type = (null != parameterDialog) ? parameterDialog.parmTypeUI.getText() : cp.getType();
+
+    if (null != parms) {
+      for (int i = 0; i < parms.length; i++) {
+        // multi-valued-ness must match
+        if ((isMultiValued != parms[i].isMultiValued()))
+          continue;
+        // types must match, but we also allow if no type is spec'd - not sure if this is useful
+        if ((null != type && !"".equals(type) && //$NON-NLS-1$
+        !type.equals(parms[i].getType())))
+          continue;
+        // parameter must not be already overridden, unless we're editing an existing one
+        String override = keyName + '/' + parms[i].getName();
+        if (adding && null != ParameterDelegatesSection.getOverridingParmName(override, cpd))
+          continue;
+
+        TableItem tableItem = new TableItem(paramsUI, SWT.NULL);
+        tableItem.setText(parms[i].getName());
+        tableItem.setData(parms[i]);
+      }
+    }
+  }
+  
+  /* (non-Javadoc)
+   * @see org.apache.uima.taeconfigurator.editors.ui.dialogs.AbstractDialog#copyValuesFromGUI()
+   */
+  public void copyValuesFromGUI() {
+    delegateKeyName = keysUI.getSelection()[0].getText();
+    delegateParameterName = paramsUI.getSelection()[0].getText();
+  }
+
+  /* (non-Javadoc)
+   * @see org.apache.uima.taeconfigurator.editors.ui.dialogs.AbstractDialog#enableOK()
+   */
+  public void enableOK() {
+    okButton.setEnabled( (0 < keysUI.getSelectionCount()) && 
+                         (0 < paramsUI.getSelectionCount()));   
+  }
+
+  /* (non-Javadoc)
+   * @see org.apache.uima.taeconfigurator.editors.ui.dialogs.AbstractDialog#isValid()
+   */
+  public boolean isValid() {
+    return true;
+  }
+
+    /*
+  protected TreeGroup createTreeGroup(Composite composite, Object rootObject) {
+    return new TreeGroup(composite, rootObject, (keyTreeProvider = new KeyTreeProvider()),
+            new KeyTreeLabelProvider(), new ParmNameProvider(), new ParmNameLabelProvider(),
+            SWT.NONE, -1, -1, true); // set single selection
+    // mode
+  }
+
+  protected void okPressed() {
+    Iterator resultEnum = selectionGroup.getAllCheckedTreeItems().iterator();
+    ArrayList list = new ArrayList();
+    while (resultEnum.hasNext()) {
+      Map.Entry entry = (Map.Entry) resultEnum.next();
+      list.add(entry);
+      while (null != (entry = (Map.Entry) keyTreeProvider.getParent(entry)))
+        list.add(entry);
+    }
+
+    super.okPressed();
+    List result = new ArrayList(2);
+    result.add(list.toArray(new Map.Entry[list.size()]));
+    result.add(getResult());
+    setResult(result);
+  }
+
+  Map keyTreeParent = new HashMap();
+
+  class KeyTreeProvider implements ITreeContentProvider {
+ */
+    /**
+     * for a given map of delegates, return an array of maps representing the those delegates having
+     * children. Not called for the top element, but called for subsequent layers
+     */
+  /* 
+  public Object[] getChildren(Object parentElement) {
+      return objectArray0;
+    }
+
+    public Object getParent(Object element) {
+      return keyTreeParent.get(element);
+    }
+
+    public boolean hasChildren(Object element) {
+      return false;
+    }
+ */
+    /**
+     * returns an array of Map.Entry elements: Key and AE or flow ctlr Description. Called only for
+     * the top element
+     */
+  /*
+    public Object[] getElements(Object inputElement) {
+      AbstractList items = new ArrayList();
+      if (inputElement instanceof ArrayList)
+        inputElement = ((ArrayList) inputElement).get(0);
+      Map delegatesMap = (Map) inputElement;
+
+      for (Iterator it = delegatesMap.entrySet().iterator(); it.hasNext();) {
+        items.add(it.next());
+      }
+      return items.toArray();
+    }
+
+    public void dispose() {
+    }
+
+    public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+      keyTreeParent.clear();
+    }
+*/
+
+  /**
+   * elements are Map.Entry
+   */
+  /*
+  static class KeyTreeLabelProvider implements ILabelProvider {
+
+    public Image getImage(Object element) {
+      return null;
+    }
+
+    public String getText(Object element) {
+      return ((String) ((Map.Entry) element).getKey());
+    }
+
+    public void addListener(ILabelProviderListener listener) {
+    }
+
+    public void dispose() {
+    }
+
+    public boolean isLabelProperty(Object element, String property) {
+      return false;
+    }
+
+    public void removeListener(ILabelProviderListener listener) {
+    }
+
+  }
+  */
+  /**
+   * Element is: Map Entry Set ConfigurationParameterDeclarations
+   */
+  /*
+  class ParmNameProvider implements ITreeContentProvider {
+
+    public Object[] getChildren(Object parentElement) {
+      return null;
+    }
+
+    public Object getParent(Object element) {
+      // TODO Auto-generated method stub
+      return null;
+    }
+
+    public boolean hasChildren(Object element) {
+      // TODO Auto-generated method stub
+      return false;
+    }
+ */
+    /*
+     * Get elements (which are overridable parameters) for one delegate
+     * 
+     * @see org.eclipse.jface.viewers.IStructuredContentProvider#getElements(java.lang.Object)
+     */
+  /*
+    public Object[] getElements(Object inputElement) {
+      AbstractList items = new ArrayList();
+      Map.Entry entry = (Map.Entry) inputElement;
+      String keyName = (String) entry.getKey();
+      // support CasConsumers also
+      // support Flow Controllers too
+      // and skip remote service descriptors
+
+      ResourceSpecifier rs = (ResourceSpecifier) entry.getValue();
+      if (rs instanceof AnalysisEngineDescription || rs instanceof CasConsumerDescription
+              || rs instanceof FlowControllerDescription) {
+        ConfigurationParameterDeclarations delegateCpd = ((ResourceCreationSpecifier) rs)
+                .getMetaData().getConfigurationParameterDeclarations();
+        addSelectedParms(delegateCpd.getCommonParameters(), items, keyName);
+
+        ConfigurationGroup[] groups = delegateCpd.getConfigurationGroups();
+        if (null != groups) {
+          for (int i = 0; i < groups.length; i++) {
+            addSelectedParms(groups[i].getConfigurationParameters(), items, keyName);
+          }
+        }
+        addSelectedParms(delegateCpd.getConfigurationParameters(), items, keyName);
+      }
+
+      return items.toArray();
+    }
+
+
+    public void dispose() {
+    }
+
+    public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+    }
+  }
+
+  static class ParmNameLabelProvider implements ILabelProvider {
+
+    public Image getImage(Object element) {
+      return null;
+    }
+
+    public String getText(Object element) {
+      return (String) element;
+    }
+
+    public void addListener(ILabelProviderListener listener) {
+    }
+
+    public void dispose() {
+    }
+
+    public boolean isLabelProperty(Object element, String property) {
+      return false;
+    }
+
+    public void removeListener(ILabelProviderListener listener) {
+    }
+  }
+ */
+
+
+}
diff --git a/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/model/AbstractModelPart.java b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/model/AbstractModelPart.java
new file mode 100644
index 0000000..f8f8e03
--- /dev/null
+++ b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/model/AbstractModelPart.java
@@ -0,0 +1,49 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.uima.taeconfigurator.model;
+
+import java.util.Properties;
+
+import org.apache.uima.UIMAFramework;
+import org.apache.uima.taeconfigurator.editors.MultiPageEditor;
+
+/**
+ */
+public class AbstractModelPart {
+
+  public static final Properties casCreateProperties = new Properties();
+  static {
+    casCreateProperties.setProperty(UIMAFramework.CAS_INITIAL_HEAP_SIZE, "200");
+  }
+
+  protected MultiPageEditor modelRoot;
+
+  protected boolean dirty;
+
+  public AbstractModelPart(MultiPageEditor pMPE) {
+    modelRoot = pMPE;
+    dirty = true;
+  }
+
+  public void markDirty() {
+    dirty = true;
+  }
+
+}
diff --git a/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/model/AllTypes.java b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/model/AllTypes.java
new file mode 100644
index 0000000..dfe6ecc
--- /dev/null
+++ b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/model/AllTypes.java
@@ -0,0 +1,80 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.uima.taeconfigurator.model;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.apache.uima.cas.CAS;
+import org.apache.uima.cas.Type;
+import org.apache.uima.cas.TypeSystem;
+import org.apache.uima.resource.ResourceInitializationException;
+import org.apache.uima.taeconfigurator.editors.MultiPageEditor;
+
+/**
+ * Model part: Map of all defined types Key = string = typename, fully qualified Value = CAS
+ * TypeSystem Type object
+ */
+public class AllTypes extends AbstractModelPart {
+
+  private Map cachedResult;
+
+  public AllTypes(MultiPageEditor pModelRoot) {
+    super(pModelRoot);
+    cachedResult = new HashMap(modelRoot.INITIAL_SIZE_TYPE_COLLECTIONS);
+  }
+
+  /**
+   * @return a map of Types, keyed by type name, including not only types defined in this TAE, but
+   *         also supertypes of said types.
+   * @throws ResourceInitializationException
+   */
+  public Map get() {
+    if (dirty) {
+      update();
+      dirty = false;
+    }
+    return cachedResult;
+  }
+
+  // create a hash table of all types
+  private void update() {
+    cachedResult.clear();
+
+    CAS tcas = modelRoot.getCurrentView();
+    if (null == tcas)
+      return;
+    TypeSystem typeSystem = tcas.getTypeSystem();
+
+    if (typeSystem == null)
+      return;
+
+    Iterator typeIterator = typeSystem.getTypeIterator();
+
+    while (typeIterator.hasNext()) {
+      Type type = (Type) typeIterator.next();
+      String typeName = type.getName();
+      if (null != typeName && !typeName.endsWith("[]")) {
+        cachedResult.put(type.getName(), type);
+      }
+    }
+  }
+}
diff --git a/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/model/BuiltInTypes.java b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/model/BuiltInTypes.java
new file mode 100644
index 0000000..6abab94
--- /dev/null
+++ b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/model/BuiltInTypes.java
@@ -0,0 +1,98 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.uima.taeconfigurator.model;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.TreeMap;
+
+import org.apache.uima.cas.CAS;
+import org.apache.uima.cas.Feature;
+import org.apache.uima.cas.Type;
+import org.apache.uima.cas.TypeSystem;
+import org.apache.uima.cas.impl.CASImpl;
+import org.apache.uima.resource.ResourceInitializationException;
+import org.apache.uima.resource.metadata.FeatureDescription;
+import org.apache.uima.resource.metadata.FsIndexDescription;
+import org.apache.uima.resource.metadata.TypeDescription;
+import org.apache.uima.resource.metadata.TypeSystemDescription;
+import org.apache.uima.resource.metadata.impl.FeatureDescription_impl;
+import org.apache.uima.resource.metadata.impl.TypeDescription_impl;
+import org.apache.uima.taeconfigurator.InternalErrorCDE;
+import org.apache.uima.util.CasCreationUtils;
+
+/**
+ * Gets and caches an array list of all the built-in tcas types
+ */
+public class BuiltInTypes extends AbstractModelPart {
+
+  public static final TypeSystem typeSystem;
+
+  public static final Map typeDescriptions = new TreeMap();
+
+  static {
+    CAS tcas = null;
+    try {
+      tcas = CasCreationUtils.createCas((TypeSystemDescription) null, null,
+              new FsIndexDescription[0], casCreateProperties);
+
+    } catch (ResourceInitializationException e1) {
+      throw new InternalErrorCDE("invalid ResourceInitializationException", e1);
+    }
+    ((CASImpl) tcas).commitTypeSystem();
+    typeSystem = tcas.getTypeSystem();
+
+    for (Iterator it = typeSystem.getTypeIterator(); it.hasNext();) {
+      Type type = (Type) it.next();
+      String typeName = type.getName();
+      TypeDescription td = new TypeDescription_impl();
+      td.setName(typeName);
+      Type parent = typeSystem.getParent(type);
+      td.setSupertypeName(null == parent ? null : parent.getName());
+      List fs = type.getFeatures();
+      FeatureDescription[] fds = null;
+      if (null != fs) {
+        List validFs = new ArrayList();
+        for (int i = 0; i < fs.size(); i++) {
+          Feature f = (Feature) fs.get(i);
+          String fName = f.getName();
+          String fTypeName = fName.substring(0, fName.indexOf(':'));
+          if (typeName.equals(fTypeName))
+            validFs.add(f);
+        }
+        fds = new FeatureDescription[validFs.size()];
+        for (int i = 0; i < fds.length; i++) {
+          fds[i] = new FeatureDescription_impl();
+          Feature f = (Feature) validFs.get(i);
+          fds[i].setName(f.getShortName());
+          fds[i].setRangeTypeName(f.getRange().getName());
+        }
+      }
+      td.setFeatures(fds);
+      typeDescriptions.put(typeName, td);
+    }
+  }
+
+  BuiltInTypes() {
+    super(null);
+  }
+}
diff --git a/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/model/ConfigGroup.java b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/model/ConfigGroup.java
new file mode 100644
index 0000000..cc1b220
--- /dev/null
+++ b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/model/ConfigGroup.java
@@ -0,0 +1,126 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS 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.taeconfigurator.model;
+
+import org.apache.uima.resource.metadata.ConfigurationGroup;
+import org.apache.uima.resource.metadata.ConfigurationParameter;
+import org.apache.uima.resource.metadata.ConfigurationParameterDeclarations;
+import org.apache.uima.taeconfigurator.InternalErrorCDE;
+import org.apache.uima.taeconfigurator.editors.ui.AbstractSection;
+import org.apache.uima.taeconfigurator.editors.ui.AbstractSectionParm;
+
+/**
+ * Instances of this class model the 3 varients of configuration parameter sets.
+ * 
+ */
+public class ConfigGroup {
+
+  private ConfigurationParameterDeclarations cpd;
+
+  private int kind;
+
+  private ConfigurationGroup namedCg = null;
+
+  public final static int NOT_IN_ANY_GROUP = 1;
+
+  public final static int COMMON = 2;
+
+  public final static int NAMED_GROUP = 4;
+
+  public ConfigGroup(ConfigurationParameterDeclarations aCpd, int aKind) {
+    cpd = aCpd;
+    kind = aKind;
+    fixupCpd();
+  }
+
+  public ConfigGroup(ConfigurationParameterDeclarations aCpd, ConfigurationGroup aNamedCg) {
+    cpd = aCpd;
+    kind = NAMED_GROUP;
+    namedCg = aNamedCg;
+    fixupCpd();
+  }
+
+  private void fixupCpd() {
+    if (null == cpd.getConfigurationParameters())
+      cpd.setConfigurationParameters(AbstractSection.configurationParameterArray0);
+    if (null == cpd.getCommonParameters())
+      cpd.setCommonParameters(AbstractSection.configurationParameterArray0);
+    if (null == cpd.getConfigurationGroups())
+      cpd.setConfigurationGroups(AbstractSection.configurationGroupArray0);
+    ConfigurationGroup[] cgs = cpd.getConfigurationGroups();
+    for (int i = 0; i < cgs.length; i++) {
+      if (null == cgs[i].getConfigurationParameters())
+        cgs[i].setConfigurationParameters(AbstractSection.configurationParameterArray0);
+    }
+  }
+
+  public ConfigurationParameter[] getConfigParms() {
+    switch (kind) {
+      case NOT_IN_ANY_GROUP:
+        return cpd.getConfigurationParameters();
+      case COMMON:
+        return cpd.getCommonParameters();
+      case NAMED_GROUP:
+        return namedCg.getConfigurationParameters();
+      default:
+        throw new InternalErrorCDE("invalid state");
+    }
+  }
+
+  public String getName() {
+    switch (kind) {
+      case NOT_IN_ANY_GROUP:
+        return AbstractSectionParm.NOT_IN_ANY_GROUP;
+      case COMMON:
+        return AbstractSectionParm.COMMON_GROUP;
+      case NAMED_GROUP:
+        return AbstractSectionParm.groupNameArrayToString(namedCg.getNames());
+      default:
+        throw new InternalErrorCDE("invalid state");
+    }
+  }
+
+  public String[] getNameArray() {
+    switch (kind) {
+      case NOT_IN_ANY_GROUP:
+        return new String[] { AbstractSectionParm.NOT_IN_ANY_GROUP };
+      case COMMON:
+        return new String[] { AbstractSectionParm.COMMON_GROUP };
+      case NAMED_GROUP:
+        return namedCg.getNames();
+      default:
+        throw new InternalErrorCDE("invalid state");
+    }
+  }
+
+  public void setNameArray(String[] names) {
+    if (kind != NAMED_GROUP)
+      throw new InternalErrorCDE("invalid call");
+    namedCg.setNames(names);
+  }
+
+  public int getKind() {
+    return kind;
+  }
+
+  public ConfigurationParameterDeclarations getCPD() {
+    return cpd;
+  }
+}
diff --git a/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/model/DefinedTypesWithSupers.java b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/model/DefinedTypesWithSupers.java
new file mode 100644
index 0000000..4286832
--- /dev/null
+++ b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/model/DefinedTypesWithSupers.java
@@ -0,0 +1,82 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.uima.taeconfigurator.model;
+
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.uima.cas.Type;
+import org.apache.uima.cas.TypeSystem;
+import org.apache.uima.resource.metadata.TypeDescription;
+import org.apache.uima.resource.metadata.TypeSystemDescription;
+import org.apache.uima.taeconfigurator.editors.MultiPageEditor;
+
+/**
+ * Model part: names of the defined types, augmented with their supertypes This means that some of
+ * the built-ins (those in the super chain) will be included.
+ */
+public class DefinedTypesWithSupers extends AbstractModelPart {
+
+  private Set cachedResult;
+
+  public DefinedTypesWithSupers(MultiPageEditor pModelRoot) {
+    super(pModelRoot);
+    cachedResult = new HashSet(modelRoot.INITIAL_SIZE_TYPE_COLLECTIONS);
+  }
+
+  /**
+   * @return a set of strings, including not only types defined in this TAE, but also supertypes of
+   *         said types.
+   */
+  public Set get() {
+    if (dirty) {
+      update();
+      dirty = false;
+    }
+    return cachedResult;
+  }
+
+  private void update() {
+    cachedResult.clear();
+
+    // for aggregates, this is the fully-merged type system
+    // for all systems, it is the type system with imports resolved
+    TypeSystemDescription typeSystemDescription = modelRoot.getMergedTypeSystemDescription();
+
+    if (typeSystemDescription == null)
+      return; // cleared table
+
+    TypeDescription[] types = typeSystemDescription.getTypes();
+    TypeSystem typeSystem = modelRoot.descriptorCAS.get().getTypeSystem();
+
+    String typeName;
+    Map allTypes = modelRoot.allTypes.get();
+    for (int i = 0; i < types.length; i++) {
+      cachedResult.add(typeName = types[i].getName());
+      Type nextType = (Type) allTypes.get(typeName);
+      while (nextType != null) {
+        nextType = typeSystem.getParent(nextType);
+        if (nextType != null)
+          cachedResult.add(nextType.getName());
+      }
+    }
+  }
+}
diff --git a/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/model/DescriptorMetaData.java b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/model/DescriptorMetaData.java
new file mode 100644
index 0000000..78177b3
--- /dev/null
+++ b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/model/DescriptorMetaData.java
@@ -0,0 +1,153 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.uima.taeconfigurator.model;
+
+import org.apache.uima.taeconfigurator.InternalErrorCDE;
+import org.apache.uima.taeconfigurator.editors.MultiPageEditor;
+
+/**
+ * Instances of this class model the varients of getting and setting metadata.
+ * 
+ */
+public class DescriptorMetaData {
+
+  private MultiPageEditor editor;
+
+  public DescriptorMetaData(MultiPageEditor editor) {
+    this.editor = editor;
+  }
+
+  public String getName() {
+    if (editor.isLocalProcessingDescriptor())
+      return editor.getAeDescription().getMetaData().getName();
+    if (editor.isTypeSystemDescriptor())
+      return editor.getTypeSystemDescription().getName();
+    if (editor.isTypePriorityDescriptor())
+      return editor.getTypePriorities().getName();
+    if (editor.isFsIndexCollection())
+      return editor.getFsIndexCollection().getName();
+    if (editor.isExtResAndBindingsDescriptor())
+      return editor.getExtResAndBindings().getName();
+    throw new InternalErrorCDE("invalid state");
+  }
+
+  public void setName(String name) {
+    if (editor.isLocalProcessingDescriptor())
+      editor.getAeDescription().getMetaData().setName(name);
+    else if (editor.isTypeSystemDescriptor())
+      editor.getTypeSystemDescription().setName(name);
+    else if (editor.isTypePriorityDescriptor())
+      editor.getTypePriorities().setName(name);
+    else if (editor.isFsIndexCollection())
+      editor.getFsIndexCollection().setName(name);
+    else if (editor.isExtResAndBindingsDescriptor())
+      editor.getExtResAndBindings().setName(name);
+    else
+      throw new InternalErrorCDE("invalid state");
+  }
+
+  public String getVersion() {
+    if (editor.isLocalProcessingDescriptor())
+      return editor.getAeDescription().getMetaData().getVersion();
+    if (editor.isTypeSystemDescriptor())
+      return editor.getTypeSystemDescription().getVersion();
+    if (editor.isTypePriorityDescriptor())
+      return editor.getTypePriorities().getVersion();
+    if (editor.isFsIndexCollection())
+      return editor.getFsIndexCollection().getVersion();
+    if (editor.isExtResAndBindingsDescriptor())
+      return editor.getExtResAndBindings().getVersion();
+    throw new InternalErrorCDE("invalid state");
+  }
+
+  public void setVersion(String name) {
+    if (editor.isLocalProcessingDescriptor())
+      editor.getAeDescription().getMetaData().setVersion(name);
+    else if (editor.isTypeSystemDescriptor())
+      editor.getTypeSystemDescription().setVersion(name);
+    else if (editor.isTypePriorityDescriptor())
+      editor.getTypePriorities().setVersion(name);
+    else if (editor.isFsIndexCollection())
+      editor.getFsIndexCollection().setVersion(name);
+    else if (editor.isExtResAndBindingsDescriptor())
+      editor.getExtResAndBindings().setVersion(name);
+    else
+      throw new InternalErrorCDE("invalid state");
+  }
+
+  public String getVendor() {
+    if (editor.isLocalProcessingDescriptor())
+      return editor.getAeDescription().getMetaData().getVendor();
+    if (editor.isTypeSystemDescriptor())
+      return editor.getTypeSystemDescription().getVendor();
+    if (editor.isTypePriorityDescriptor())
+      return editor.getTypePriorities().getVendor();
+    if (editor.isFsIndexCollection())
+      return editor.getFsIndexCollection().getVendor();
+    if (editor.isExtResAndBindingsDescriptor())
+      return editor.getExtResAndBindings().getVendor();
+    throw new InternalErrorCDE("invalid state");
+  }
+
+  public void setVendor(String name) {
+    if (editor.isLocalProcessingDescriptor())
+      editor.getAeDescription().getMetaData().setVendor(name);
+    else if (editor.isTypeSystemDescriptor())
+      editor.getTypeSystemDescription().setVendor(name);
+    else if (editor.isTypePriorityDescriptor())
+      editor.getTypePriorities().setVendor(name);
+    else if (editor.isFsIndexCollection())
+      editor.getFsIndexCollection().setVendor(name);
+    else if (editor.isExtResAndBindingsDescriptor())
+      editor.getExtResAndBindings().setVendor(name);
+    else
+      throw new InternalErrorCDE("invalid state");
+  }
+
+  public String getDescription() {
+    if (editor.isLocalProcessingDescriptor())
+      return editor.getAeDescription().getMetaData().getDescription();
+    if (editor.isTypeSystemDescriptor())
+      return editor.getTypeSystemDescription().getDescription();
+    if (editor.isTypePriorityDescriptor())
+      return editor.getTypePriorities().getDescription();
+    if (editor.isFsIndexCollection())
+      return editor.getFsIndexCollection().getDescription();
+    if (editor.isExtResAndBindingsDescriptor())
+      return editor.getExtResAndBindings().getDescription();
+    throw new InternalErrorCDE("invalid state");
+  }
+
+  public void setDescription(String name) {
+    if (editor.isAeDescriptor() || editor.isLocalProcessingDescriptor())
+      editor.getAeDescription().getMetaData().setDescription(name);
+    else if (editor.isTypeSystemDescriptor())
+      editor.getTypeSystemDescription().setDescription(name);
+    else if (editor.isTypePriorityDescriptor())
+      editor.getTypePriorities().setDescription(name);
+    else if (editor.isFsIndexCollection())
+      editor.getFsIndexCollection().setDescription(name);
+    else if (editor.isExtResAndBindingsDescriptor())
+      editor.getExtResAndBindings().setDescription(name);
+    else
+      throw new InternalErrorCDE("invalid state");
+  }
+
+}
diff --git a/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/model/DescriptorTCAS.java b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/model/DescriptorTCAS.java
new file mode 100644
index 0000000..5e4327e
--- /dev/null
+++ b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/model/DescriptorTCAS.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.taeconfigurator.model;
+
+import java.util.ArrayList;
+import java.util.Collection;
+
+import org.apache.uima.analysis_engine.AnalysisEngineDescription;
+import org.apache.uima.cas.admin.CASAdminException;
+import org.apache.uima.cas.CAS;
+import org.apache.uima.resource.ResourceInitializationException;
+import org.apache.uima.resource.metadata.TypeSystemDescription;
+import org.apache.uima.taeconfigurator.InternalErrorCDE;
+import org.apache.uima.taeconfigurator.editors.MultiPageEditor;
+import org.apache.uima.util.CasCreationUtils;
+
+/**
+ * Model part: CAS corresponding to the descriptor being edited
+ */
+
+public class DescriptorTCAS extends AbstractModelPart {
+
+  private CAS cachedResult;
+
+  public DescriptorTCAS(MultiPageEditor modelRoot) {
+    super(modelRoot);
+  }
+
+  public void validate() throws ResourceInitializationException {
+
+    Collection aes = new ArrayList(1);
+
+    AnalysisEngineDescription ae = (AnalysisEngineDescription) modelRoot.getAeDescription().clone();
+    // speedup = replace typeSystem with resolved imports version
+    if (ae.isPrimitive()) {
+      TypeSystemDescription tsd = modelRoot.getMergedTypeSystemDescription();
+      if (null != tsd)
+        tsd = (TypeSystemDescription) tsd.clone();
+      ae.getAnalysisEngineMetaData().setTypeSystem(tsd);
+    }
+    ae.getAnalysisEngineMetaData().setFsIndexCollection(modelRoot.getMergedFsIndexCollection());
+    ae.getAnalysisEngineMetaData().setTypePriorities(modelRoot.getMergedTypePriorities());
+    aes.add(ae);
+    try {
+      // long time = System.currentTimeMillis();
+      // System.out.println("Creating TCas model");
+      cachedResult = CasCreationUtils.createCas(aes, casCreateProperties, modelRoot
+              .createResourceManager());
+      // System.out.println("Finished Creating TCas model; time= " +
+      // (System.currentTimeMillis() - time));
+      if (null == cachedResult)
+        throw new InternalErrorCDE("null result from createTCas");
+    } catch (CASAdminException e) {
+      throw new ResourceInitializationException(e);
+    }
+    dirty = false;
+    modelRoot.allTypes.dirty = true;
+  }
+
+  /**
+   * @return a CAS for the model descriptor
+   */
+  public CAS get() {
+    if (dirty) {
+      update();
+    }
+    return cachedResult;
+  }
+
+  public void set(CAS tcas) {
+    cachedResult = tcas;
+    dirty = false;
+  }
+
+  private void update() {
+    try {
+      validate();
+    } catch (ResourceInitializationException e) {
+      throw new InternalErrorCDE("Invalid Exception", e);
+    }
+  }
+}
diff --git a/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/model/FlowNodes.java b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/model/FlowNodes.java
new file mode 100644
index 0000000..3a7ba2c
--- /dev/null
+++ b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/model/FlowNodes.java
@@ -0,0 +1,65 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.uima.taeconfigurator.model;
+
+import org.apache.uima.analysis_engine.metadata.CapabilityLanguageFlow;
+import org.apache.uima.analysis_engine.metadata.FixedFlow;
+import org.apache.uima.analysis_engine.metadata.FlowConstraints;
+
+/**
+ * Instances of this class model the varients of flow nodes in a uniform way.
+ * 
+ */
+public class FlowNodes {
+
+  private FixedFlow fixedFlow;
+
+  private CapabilityLanguageFlow capabilityLanguageFlow;
+
+  public FlowNodes(FlowConstraints flow) {
+    if (flow instanceof FixedFlow)
+      fixedFlow = (FixedFlow) flow;
+    else if (flow instanceof CapabilityLanguageFlow)
+      capabilityLanguageFlow = (CapabilityLanguageFlow) flow;
+      // can be null if omitted
+  }
+
+  public String[] getFlow() {
+    if (fixedFlow != null)
+      return fixedFlow.getFixedFlow();
+    if (capabilityLanguageFlow != null)
+      return capabilityLanguageFlow.getCapabilityLanguageFlow();
+    return null;
+    // throw new InternalErrorCDE("invalid state");
+  }
+
+  public void setFlow(String[] newFlow) {
+    if (fixedFlow != null) {
+      fixedFlow.setFixedFlow(newFlow);
+      return;
+    }
+    if (capabilityLanguageFlow != null) {
+      capabilityLanguageFlow.setCapabilityLanguageFlow(newFlow);
+      return;
+    }
+    // throw new InternalErrorCDE("invalid state");
+    return; // ignore in null case
+  }
+}
diff --git a/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/wizards/AbstractNewWizard.java b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/wizards/AbstractNewWizard.java
new file mode 100644
index 0000000..4426927
--- /dev/null
+++ b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/wizards/AbstractNewWizard.java
@@ -0,0 +1,193 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS 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.taeconfigurator.wizards;
+
+import java.io.ByteArrayInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.PrintWriter;
+import java.lang.reflect.InvocationTargetException;
+
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IWorkspaceRoot;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.operation.IRunnableWithProgress;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.wizard.Wizard;
+import org.eclipse.ui.INewWizard;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.PartInitException;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.part.FileEditorInput;
+
+import org.apache.uima.taeconfigurator.InternalErrorCDE;
+import org.apache.uima.taeconfigurator.TAEConfiguratorPlugin;
+
+/**
+ * Create a new file resource in the provided container. If the container resource (a folder or a
+ * project) is selected in the workspace when the wizard is opened, it will accept it as the target
+ * container. If a sample multi-page editor is registered for the same extension, it will be able to
+ * open it.
+ * 
+ * Following Eclipse conventions, the new Wizard will actually create the resource in the file
+ * system and in the Eclipse resource space, with initial contents, and then open the resource with
+ * the CDE.
+ */
+
+public abstract class AbstractNewWizard extends Wizard implements INewWizard {
+
+  public final static String XMLNS_PART = "xmlns=\"http://uima.apache.org/resourceSpecifier\">\n";
+
+  protected AbstractNewWizardPage page;
+
+  protected ISelection selection;
+
+  private String windowTitle;
+
+  public AbstractNewWizard(String windowTitle) {
+    super();
+    setDialogSettings(TAEConfiguratorPlugin.getDefault().getDialogSettings());
+    setNeedsProgressMonitor(true);
+    setForcePreviousAndNextButtons(false);
+    this.windowTitle = windowTitle;
+  }
+
+  /*
+   * (non-Javadoc)
+   * 
+   * @see org.eclipse.jface.wizard.Wizard#performFinish()
+   */
+  /**
+   * Called when 'Finish' button is pressed in the wizard. Create an operation and run it using
+   * wizard as execution context.
+   */
+  public boolean performFinish() {
+    final String containerName = page.getContainerName();
+    final String fileName = page.getFileName();
+    IRunnableWithProgress op = new IRunnableWithProgress() {
+      public void run(IProgressMonitor monitor) throws InvocationTargetException {
+        try {
+          doFinish(containerName, fileName, monitor);
+        } catch (CoreException e) {
+          throw new InvocationTargetException(e);
+        } finally {
+          monitor.done();
+        }
+      }
+    };
+    try {
+      getContainer().run(true, false, op);
+    } catch (InterruptedException e) {
+      return false;
+    } catch (InvocationTargetException e) {
+      Throwable realException = e.getTargetException();
+      MessageDialog.openError(getShell(), "Error", realException.getMessage());
+      return false;
+    }
+    return true;
+  }
+
+  public abstract String getPrototypeDescriptor(String name);
+
+  void doFinish(String containerName, String fileName, IProgressMonitor monitor)
+          throws CoreException {
+    // create a sample file
+    monitor.beginTask("Creating " + fileName, 2);
+    IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
+    IResource resource = root.findMember(new Path(containerName));
+    if (!resource.exists() || !(resource instanceof IContainer)) {
+      throwCoreException("Container \"" + containerName + "\" does not exist.");
+    }
+    IContainer container = (IContainer) resource;
+    final IFile file = container.getFile(new Path(fileName));
+    if (file.exists()) {
+      throwCoreException("New Wizard creating file '" + fileName + "', but it already exists.");
+    } else {
+      int indexOfXml = file.getName().toLowerCase().indexOf(".xml");
+      String name = (indexOfXml > 0) ? file.getName().substring(0, indexOfXml) : file.getName();
+      String descriptor = getPrototypeDescriptor(name);
+
+      PrintWriter printWriter = null;
+      FileOutputStream fileOutputStream = null;
+      InputStream stream = null;
+
+      try {
+        try {
+          fileOutputStream = new FileOutputStream(file.getLocation().toOSString());
+        } catch (FileNotFoundException e) {
+          throw new InternalErrorCDE("unexpected Exception", e);
+        }
+        printWriter = new PrintWriter(fileOutputStream);
+        printWriter.println(descriptor);
+      } finally {
+        if (null != printWriter)
+          printWriter.close();
+        if (null != fileOutputStream)
+          try {
+            fileOutputStream.close();
+          } catch (IOException e1) {
+          }
+      }
+
+      stream = new ByteArrayInputStream(descriptor.getBytes());
+      file.create(stream, true, monitor);
+      try {
+        stream.close();
+      } catch (IOException e1) {
+      }
+    }
+
+    monitor.worked(1);
+    monitor.setTaskName("Starting editor for new descriptor...");
+    getShell().getDisplay().asyncExec(new Runnable() {
+      public void run() {
+        IWorkbenchPage page1 = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
+        try {
+          page1.openEditor(new FileEditorInput(file), "taeconfigurator.editors.MultiPageEditor");
+        } catch (PartInitException e) {
+        }
+      }
+    });
+    monitor.worked(2);
+  }
+
+  private void throwCoreException(String message) throws CoreException {
+    IStatus status = new Status(IStatus.ERROR, "DescEditor", IStatus.OK, message, null);
+    throw new CoreException(status);
+  }
+
+  public void init(IWorkbench workbench, IStructuredSelection pSelection) {
+    selection = pSelection;
+    setWindowTitle(windowTitle);
+  }
+
+}
diff --git a/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/wizards/AbstractNewWizardPage.java b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/wizards/AbstractNewWizardPage.java
new file mode 100644
index 0000000..1c388c3
--- /dev/null
+++ b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/wizards/AbstractNewWizardPage.java
@@ -0,0 +1,179 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS 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.taeconfigurator.wizards;
+
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.wizard.WizardPage;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.ui.dialogs.ContainerSelectionDialog;
+
+import org.apache.uima.taeconfigurator.TAEConfiguratorPlugin;
+
+public abstract class AbstractNewWizardPage extends WizardPage {
+
+  protected ISelection selection;
+
+  protected Text containerText;
+
+  protected Text fileText;
+
+  private String defaultNewName;
+
+  public AbstractNewWizardPage(ISelection pSelection, String image, String title,
+          String description, String defaultNewName) {
+    super("wizardPage");
+    setTitle(title);
+    setDescription(description);
+    setImageDescriptor(TAEConfiguratorPlugin.getImageDescriptor("big_t_s.gif"));
+
+    selection = pSelection;
+    this.defaultNewName = defaultNewName;
+  }
+
+  public void createControl(Composite parent) {
+    Composite container = new Composite(parent, SWT.NULL);
+    GridLayout layout = new GridLayout();
+    container.setLayout(layout);
+    layout.numColumns = 3;
+    layout.verticalSpacing = 9;
+    Label label = new Label(container, SWT.NULL);
+    label.setText("Parent &Folder:");
+
+    containerText = new Text(container, SWT.BORDER | SWT.SINGLE);
+    GridData gd = new GridData(GridData.FILL_HORIZONTAL);
+    containerText.setLayoutData(gd);
+    containerText.addModifyListener(new ModifyListener() {
+      public void modifyText(ModifyEvent e) {
+        dialogChanged();
+      }
+    });
+
+    Button button = new Button(container, SWT.PUSH);
+    button.setText("Browse...");
+    button.addSelectionListener(new SelectionAdapter() {
+      public void widgetSelected(SelectionEvent e) {
+        handleBrowse();
+      }
+    });
+    label = new Label(container, SWT.NULL);
+    label.setText("&File name:");
+
+    fileText = new Text(container, SWT.BORDER | SWT.SINGLE);
+    gd = new GridData(GridData.FILL_HORIZONTAL);
+    fileText.setLayoutData(gd);
+    fileText.addModifyListener(new ModifyListener() {
+      public void modifyText(ModifyEvent e) {
+        dialogChanged();
+      }
+    });
+    initialize();
+    dialogChanged();
+    setControl(container);
+  }
+
+  private void initialize() {
+
+    if (selection != null && selection.isEmpty() == false
+            && selection instanceof IStructuredSelection) {
+      IStructuredSelection ssel = (IStructuredSelection) selection;
+      if (ssel.size() > 1)
+        return;
+      Object obj = ssel.getFirstElement();
+
+      if (!(obj instanceof IResource) && obj instanceof IAdaptable)
+        obj = ((IAdaptable) obj).getAdapter(IResource.class);
+
+      if (obj instanceof IResource) {
+        IContainer container = null;
+        if (obj instanceof IContainer)
+          container = (IContainer) obj;
+        else
+          container = ((IResource) obj).getParent();
+        if (container.isAccessible())
+          containerText.setText(container.getFullPath().toString());
+      }
+    }
+    fileText.setText(defaultNewName);
+  }
+
+  void handleBrowse() {
+    ContainerSelectionDialog dialog = new ContainerSelectionDialog(getShell(), ResourcesPlugin
+            .getWorkspace().getRoot(), false, "Select a containing folder");
+    if (dialog.open() == ContainerSelectionDialog.OK) {
+      Object[] result = dialog.getResult();
+      if (result.length == 1) {
+        containerText.setText(((Path) result[0]).toOSString());
+      }
+    }
+  }
+
+  void dialogChanged() {
+    String container = getContainerName();
+    String fileName = getFileName();
+
+    if (container.length() == 0) {
+      updateStatus("Parent folder must be specified");
+      return;
+    }
+    if (fileName.length() == 0) {
+      updateStatus("File name must be specified");
+      return;
+    }
+    int dotLoc = fileName.lastIndexOf('.');
+    if (dotLoc != -1) {
+      String ext = fileName.substring(dotLoc + 1);
+      if (ext.equalsIgnoreCase("xml") == false) {
+        updateStatus("File extension must be \"xml\"");
+        return;
+      }
+    }
+    updateStatus(null);
+  }
+
+  public String getContainerName() {
+    return containerText.getText();
+  }
+
+  public String getFileName() {
+    return fileText.getText();
+  }
+
+  private void updateStatus(String message) {
+    setErrorMessage(message);
+    setPageComplete(message == null);
+  }
+
+}
diff --git a/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/wizards/CasConsumerNewWizard.java b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/wizards/CasConsumerNewWizard.java
new file mode 100644
index 0000000..e1ac0ca
--- /dev/null
+++ b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/wizards/CasConsumerNewWizard.java
@@ -0,0 +1,61 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.uima.taeconfigurator.wizards;
+
+import org.eclipse.ui.INewWizard;
+
+/**
+ * Create a new file resource in the provided container. If the container resource (a folder or a
+ * project) is selected in the workspace when the wizard is opened, it will accept it as the target
+ * container. If a sample multi-page editor is registered for the same extension, it will be able to
+ * open it.
+ */
+
+public class CasConsumerNewWizard extends AbstractNewWizard implements INewWizard {
+
+  public CasConsumerNewWizard() {
+    super("Cas Consumer Descriptor File");
+  }
+
+  public void addPages() {
+    page = new CasConsumerNewWizardPage(selection);
+    addPage(page);
+  }
+
+  public String getPrototypeDescriptor(String name) {
+    return "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n" + "<casConsumerDescription "
+            + XMLNS_PART
+            + "<frameworkImplementation>org.apache.uima.java</frameworkImplementation>\n"
+            + "<implementationName></implementationName>\n" + "<processingResourceMetaData>\n"
+            + "<name>" + name + "</name>\n" + "<description></description>\n"
+            + "<version>1.0</version>\n" + "<vendor></vendor>\n"
+            + "<configurationParameters></configurationParameters>\n"
+            + "<configurationParameterSettings></configurationParameterSettings>\n"
+            + "<typeSystemDescription></typeSystemDescription>\n"
+            + "<typePriorities></typePriorities>\n" + "<fsIndexCollection></fsIndexCollection>\n"
+            + "<capabilities>\n" + "<capability>\n" + "<inputs></inputs>\n"
+            + "<outputs></outputs>\n" + "<languagesSupported></languagesSupported>\n"
+            + "</capability>\n" + "</capabilities>\n" + "</processingResourceMetaData>\n"
+            + "<externalResourceDependencies></externalResourceDependencies>\n"
+            + "<resourceManagerConfiguration></resourceManagerConfiguration>\n"
+            + "</casConsumerDescription>\n";
+  }
+
+}
diff --git a/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/wizards/CasConsumerNewWizardPage.java b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/wizards/CasConsumerNewWizardPage.java
new file mode 100644
index 0000000..b9eee8a
--- /dev/null
+++ b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/wizards/CasConsumerNewWizardPage.java
@@ -0,0 +1,37 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.uima.taeconfigurator.wizards;
+
+import org.eclipse.jface.viewers.ISelection;
+
+/**
+ * The "New" wizard page allows setting the container for the new file as well as the file name.
+ * Will only accept file name without the extension OR with the extension that matches the expected
+ * one (xml).
+ */
+
+public class CasConsumerNewWizardPage extends AbstractNewWizardPage {
+
+  public CasConsumerNewWizardPage(ISelection selection) {
+    super(selection, "big_ae.gif", "Cas Consumer Descriptor File",
+            "Create a new Cas Consumer Descriptor file", "casConsumerDescriptor.xml");
+  }
+
+}
diff --git a/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/wizards/CasInitializerNewWizard.java b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/wizards/CasInitializerNewWizard.java
new file mode 100644
index 0000000..2ce467f
--- /dev/null
+++ b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/wizards/CasInitializerNewWizard.java
@@ -0,0 +1,61 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.uima.taeconfigurator.wizards;
+
+import org.eclipse.ui.INewWizard;
+
+/**
+ * Create a new file resource in the provided container. If the container resource (a folder or a
+ * project) is selected in the workspace when the wizard is opened, it will accept it as the target
+ * container. If a sample multi-page editor is registered for the same extension, it will be able to
+ * open it.
+ */
+
+public class CasInitializerNewWizard extends AbstractNewWizard implements INewWizard {
+
+  public CasInitializerNewWizard() {
+    super("Cas Initializer Descriptor File");
+  }
+
+  public void addPages() {
+    page = new CasInitializerNewWizardPage(selection);
+    addPage(page);
+  }
+
+  public String getPrototypeDescriptor(String name) {
+    return "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n" + "<casInitializerDescription "
+            + XMLNS_PART
+            + "<frameworkImplementation>org.apache.uima.java</frameworkImplementation>\n"
+            + "<implementationName></implementationName>\n" + "<processingResourceMetaData>\n"
+            + "<name>" + name + "</name>\n" + "<description></description>\n"
+            + "<version>1.0</version>\n" + "<vendor></vendor>\n"
+            + "<configurationParameters></configurationParameters>\n"
+            + "<configurationParameterSettings></configurationParameterSettings>\n"
+            + "<typeSystemDescription></typeSystemDescription>\n"
+            + "<typePriorities></typePriorities>\n" + "<fsIndexCollection></fsIndexCollection>\n"
+            + "<capabilities>\n" + "<capability>\n" + "<inputs></inputs>\n"
+            + "<outputs></outputs>\n" + "<languagesSupported></languagesSupported>\n"
+            + "</capability>\n" + "</capabilities>\n" + "</processingResourceMetaData>\n"
+            + "<externalResourceDependencies></externalResourceDependencies>\n"
+            + "<resourceManagerConfiguration></resourceManagerConfiguration>\n"
+            + "</casInitializerDescription>\n";
+  }
+
+}
diff --git a/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/wizards/CasInitializerNewWizardPage.java b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/wizards/CasInitializerNewWizardPage.java
new file mode 100644
index 0000000..f5335bf
--- /dev/null
+++ b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/wizards/CasInitializerNewWizardPage.java
@@ -0,0 +1,37 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.uima.taeconfigurator.wizards;
+
+import org.eclipse.jface.viewers.ISelection;
+
+/**
+ * The "New" wizard page allows setting the container for the new file as well as the file name.
+ * Will only accept file name without the extension OR with the extension that matches the expected
+ * one (xml).
+ */
+
+public class CasInitializerNewWizardPage extends AbstractNewWizardPage {
+
+  public CasInitializerNewWizardPage(ISelection selection) {
+    super(selection, "big_ae.gif", "Cas Initializer Descriptor File",
+            "Create a new Cas Initializer Descriptor file", "casInitializerDescriptor.xml");
+  }
+
+}
diff --git a/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/wizards/CollectionReaderNewWizard.java b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/wizards/CollectionReaderNewWizard.java
new file mode 100644
index 0000000..92189e1
--- /dev/null
+++ b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/wizards/CollectionReaderNewWizard.java
@@ -0,0 +1,61 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.uima.taeconfigurator.wizards;
+
+import org.eclipse.ui.INewWizard;
+
+/**
+ * Create a new file resource in the provided container. If the container resource (a folder or a
+ * project) is selected in the workspace when the wizard is opened, it will accept it as the target
+ * container. If a sample multi-page editor is registered for the same extension, it will be able to
+ * open it.
+ */
+
+public class CollectionReaderNewWizard extends AbstractNewWizard implements INewWizard {
+
+  public CollectionReaderNewWizard() {
+    super("Collection Reader Descriptor File");
+  }
+
+  public void addPages() {
+    page = new CollectionReaderNewWizardPage(selection);
+    addPage(page);
+  }
+
+  public String getPrototypeDescriptor(String name) {
+    return "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n" + "<collectionReaderDescription "
+            + XMLNS_PART
+            + "<frameworkImplementation>org.apache.uima.java</frameworkImplementation>\n"
+            + "<implementationName></implementationName>\n" + "<processingResourceMetaData>\n"
+            + "<name>" + name + "</name>\n" + "<description></description>\n"
+            + "<version>1.0</version>\n" + "<vendor></vendor>\n"
+            + "<configurationParameters></configurationParameters>\n"
+            + "<configurationParameterSettings></configurationParameterSettings>\n"
+            + "<typeSystemDescription></typeSystemDescription>\n"
+            + "<typePriorities></typePriorities>\n" + "<fsIndexCollection></fsIndexCollection>\n"
+            + "<capabilities>\n" + "<capability>\n" + "<inputs></inputs>\n"
+            + "<outputs></outputs>\n" + "<languagesSupported></languagesSupported>\n"
+            + "</capability>\n" + "</capabilities>\n" + "</processingResourceMetaData>\n"
+            + "<externalResourceDependencies></externalResourceDependencies>\n"
+            + "<resourceManagerConfiguration></resourceManagerConfiguration>\n"
+            + "</collectionReaderDescription>\n";
+  }
+
+}
diff --git a/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/wizards/CollectionReaderNewWizardPage.java b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/wizards/CollectionReaderNewWizardPage.java
new file mode 100644
index 0000000..bf1071c
--- /dev/null
+++ b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/wizards/CollectionReaderNewWizardPage.java
@@ -0,0 +1,37 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.uima.taeconfigurator.wizards;
+
+import org.eclipse.jface.viewers.ISelection;
+
+/**
+ * The "New" wizard page allows setting the container for the new file as well as the file name.
+ * Will only accept file name without the extension OR with the extension that matches the expected
+ * one (xml).
+ */
+
+public class CollectionReaderNewWizardPage extends AbstractNewWizardPage {
+
+  public CollectionReaderNewWizardPage(ISelection selection) {
+    super(selection, "big_ae.gif", "Collection Reader Descriptor File",
+            "Create a new Collection Reader Descriptor file", "collectionReaderDescriptor.xml");
+  }
+
+}
diff --git a/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/wizards/FlowControllerNewWizard.java b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/wizards/FlowControllerNewWizard.java
new file mode 100644
index 0000000..a7d9df7
--- /dev/null
+++ b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/wizards/FlowControllerNewWizard.java
@@ -0,0 +1,65 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.uima.taeconfigurator.wizards;
+
+import org.eclipse.ui.INewWizard;
+
+/**
+ * Create a new file resource in the provided container. If the container resource (a folder or a
+ * project) is selected in the workspace when the wizard is opened, it will accept it as the target
+ * container. If a sample multi-page editor is registered for the same extension, it will be able to
+ * open it.
+ * 
+ * Following Eclipse conventions, the new Wizard will actually create the resource in the file
+ * system and in the Eclipse resource space, with initial contents, and then open the resource with
+ * the CDE.
+ */
+
+public class FlowControllerNewWizard extends AbstractNewWizard implements INewWizard {
+
+  public FlowControllerNewWizard() {
+    super("New Flow Controller Descriptor File");
+  }
+
+  public void addPages() {
+    page = new FlowControllerNewWizardPage(selection);
+    addPage(page);
+  }
+
+  public String getPrototypeDescriptor(String name) {
+    return "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n"
+            + "<flowControllerDescription xmlns=\"http://uima.apache.org/resourceSpecifier\">\n"
+            + "<frameworkImplementation>org.apache.uima.java</frameworkImplementation>\n"
+            + "<implementationName></implementationName>\n" + "<processingResourceMetaData>\n"
+            + "<name>" + name + "</name>\n" + "<description></description>\n"
+            + "<version>1.0</version>\n" + "<vendor></vendor>\n"
+            + "<configurationParameters></configurationParameters>\n"
+            + "<configurationParameterSettings></configurationParameterSettings>\n"
+            + "<typeSystemDescription></typeSystemDescription>\n"
+            + "<typePriorities></typePriorities>\n" + "<fsIndexCollection></fsIndexCollection>\n"
+            + "<capabilities>\n" + "<capability>\n" + "<inputs></inputs>\n"
+            + "<outputs></outputs>\n" + "<languagesSupported></languagesSupported>\n"
+            + "</capability>\n" + "</capabilities>\n" + "</processingResourceMetaData>\n"
+            + "<externalResourceDependencies></externalResourceDependencies>\n"
+            + "<resourceManagerConfiguration></resourceManagerConfiguration>\n"
+
+            + "</flowControllerDescription>";
+  }
+}
diff --git a/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/wizards/FlowControllerNewWizardPage.java b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/wizards/FlowControllerNewWizardPage.java
new file mode 100644
index 0000000..113a5fe
--- /dev/null
+++ b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/wizards/FlowControllerNewWizardPage.java
@@ -0,0 +1,36 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.uima.taeconfigurator.wizards;
+
+import org.eclipse.jface.viewers.ISelection;
+
+/**
+ * The "New" wizard page allows setting the container for the new file as well as the file name.
+ * Will only accept file name without the extension OR with the extension that matches the expected
+ * one (xml).
+ */
+
+public class FlowControllerNewWizardPage extends AbstractNewWizardPage {
+
+  public FlowControllerNewWizardPage(ISelection selection) {
+    super(selection, "big_ae.gif", "Flow Controller Descriptor File",
+            "Create a new Flow Controller Descriptor file", "flowControllerDescriptor.xml");
+  }
+}
diff --git a/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/wizards/FsIndexCollectionNewWizard.java b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/wizards/FsIndexCollectionNewWizard.java
new file mode 100644
index 0000000..ff344ef
--- /dev/null
+++ b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/wizards/FsIndexCollectionNewWizard.java
@@ -0,0 +1,58 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.uima.taeconfigurator.wizards;
+
+import java.text.MessageFormat;
+
+import org.eclipse.ui.INewWizard;
+
+/**
+ * Create a new file resource in the provided container. If the container resource (a folder or a
+ * project) is selected in the workspace when the wizard is opened, it will accept it as the target
+ * container. If a sample multi-page editor is registered for the same extension, it will be able to
+ * open it.
+ */
+
+public class FsIndexCollectionNewWizard extends AbstractNewWizard implements INewWizard {
+
+  public static final String FSINDEXCOLLECTION_TEMPLATE = "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n"
+          + "<fsIndexCollection "
+          + XMLNS_PART
+          + "<name>{0}</name>\n"
+          + "<description></description>\n"
+          + "<version>1.0</version>\n"
+          + "<vendor></vendor>\n"
+          + "{1}" + "</fsIndexCollection>\n";
+
+  public FsIndexCollectionNewWizard() {
+    super("New Index Collection Descriptor File");
+  }
+
+  public void addPages() {
+    page = new FsIndexCollectionNewWizardPage(selection);
+    addPage(page);
+  }
+
+  public String getPrototypeDescriptor(String name) {
+    return MessageFormat.format(FSINDEXCOLLECTION_TEMPLATE, new Object[] { name,
+        "<fsIndexDescription></fsIndexDescription>\n" });
+  }
+
+}
diff --git a/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/wizards/FsIndexCollectionNewWizardPage.java b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/wizards/FsIndexCollectionNewWizardPage.java
new file mode 100644
index 0000000..935cc96
--- /dev/null
+++ b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/wizards/FsIndexCollectionNewWizardPage.java
@@ -0,0 +1,37 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.uima.taeconfigurator.wizards;
+
+import org.eclipse.jface.viewers.ISelection;
+
+/**
+ * The "New" wizard page allows setting the container for the new file as well as the file name.
+ * Will only accept file name without the extension OR with the extension that matches the expected
+ * one (xml).
+ */
+
+public class FsIndexCollectionNewWizardPage extends AbstractNewWizardPage {
+
+  public FsIndexCollectionNewWizardPage(ISelection selection) {
+    super(selection, "big_ae.gif", "Index Collection Descriptor File",
+            "Create a new Index Collection Descriptor file", "indexCollectionDescriptor.xml");
+  }
+
+}
diff --git a/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/wizards/ResourceManagerConfigurationNewWizard.java b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/wizards/ResourceManagerConfigurationNewWizard.java
new file mode 100644
index 0000000..acf71ef
--- /dev/null
+++ b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/wizards/ResourceManagerConfigurationNewWizard.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.taeconfigurator.wizards;
+
+import java.text.MessageFormat;
+
+import org.eclipse.ui.INewWizard;
+
+/**
+ * Create a new file resource in the provided container. If the container resource (a folder or a
+ * project) is selected in the workspace when the wizard is opened, it will accept it as the target
+ * container. If a sample multi-page editor is registered for the same extension, it will be able to
+ * open it.
+ */
+
+public class ResourceManagerConfigurationNewWizard extends AbstractNewWizard implements INewWizard {
+
+  public static final String RESOURCEMANGERCONFIGURATION_TEMPLATE = "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n"
+          + "<resourceManagerConfiguration "
+          + XMLNS_PART
+          + "<name>{0}</name>\n"
+          + "<description></description>\n"
+          + "<version>1.0</version>\n"
+          + "{1}"
+          + "</resourceManagerConfiguration>\n";
+
+  public ResourceManagerConfigurationNewWizard() {
+    super("External Resource and Bindings (Resource Manager Configuration) Descriptor File");
+  }
+
+  public void addPages() {
+    page = new ResourceManagerConfigurationNewWizardPage(selection);
+    addPage(page);
+  }
+
+  public String getPrototypeDescriptor(String name) {
+    return MessageFormat.format(RESOURCEMANGERCONFIGURATION_TEMPLATE, new Object[] {
+        name,
+        "<externalResources></externalResources>\n"
+                + "<externalResourceBindings></externalResourceBindings>\n" });
+  }
+
+}
diff --git a/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/wizards/ResourceManagerConfigurationNewWizardPage.java b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/wizards/ResourceManagerConfigurationNewWizardPage.java
new file mode 100644
index 0000000..d821e6e
--- /dev/null
+++ b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/wizards/ResourceManagerConfigurationNewWizardPage.java
@@ -0,0 +1,41 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.uima.taeconfigurator.wizards;
+
+import org.eclipse.jface.viewers.ISelection;
+
+/**
+ * The "New" wizard page allows setting the container for the new file as well as the file name.
+ * Will only accept file name without the extension OR with the extension that matches the expected
+ * one (xml).
+ */
+
+public class ResourceManagerConfigurationNewWizardPage extends AbstractNewWizardPage {
+
+  public ResourceManagerConfigurationNewWizardPage(ISelection selection) {
+    super(
+            selection,
+            "big_ae.gif",
+            "External Resources and Bindings (Resource Manager Configuration) Descriptor File",
+            "Create a new External Resource and Bindings (Resource Manager Configuration) Descriptor file",
+            "extResAndBindingsDescriptor.xml");
+  }
+
+}
diff --git a/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/wizards/TAEConfiguratorNewWizard.java b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/wizards/TAEConfiguratorNewWizard.java
new file mode 100644
index 0000000..7a09210
--- /dev/null
+++ b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/wizards/TAEConfiguratorNewWizard.java
@@ -0,0 +1,65 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.uima.taeconfigurator.wizards;
+
+import org.eclipse.ui.INewWizard;
+
+/**
+ * Create a new file resource in the provided container. If the container resource (a folder or a
+ * project) is selected in the workspace when the wizard is opened, it will accept it as the target
+ * container. If a sample multi-page editor is registered for the same extension, it will be able to
+ * open it.
+ * 
+ * Following Eclipse conventions, the new Wizard will actually create the resource in the file
+ * system and in the Eclipse resource space, with initial contents, and then open the resource with
+ * the CDE.
+ */
+
+public class TAEConfiguratorNewWizard extends AbstractNewWizard implements INewWizard {
+
+  public TAEConfiguratorNewWizard() {
+    super("New Analysis Engine Descriptor File");
+  }
+
+  public void addPages() {
+    page = new TAEConfiguratorNewWizardPage(selection);
+    addPage(page);
+  }
+
+  public String getPrototypeDescriptor(String name) {
+    return "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n" + "<analysisEngineDescription "
+            + XMLNS_PART
+            + "<frameworkImplementation>org.apache.uima.java</frameworkImplementation>\n"
+            + "<primitive>true</primitive>\n"
+            + "<annotatorImplementationName></annotatorImplementationName>\n"
+            + "<analysisEngineMetaData>\n" + "<name>" + name + "</name>\n"
+            + "<description></description>\n" + "<version>1.0</version>\n" + "<vendor></vendor>\n"
+            + "<configurationParameters></configurationParameters>\n"
+            + "<configurationParameterSettings></configurationParameterSettings>\n"
+            + "<typeSystemDescription></typeSystemDescription>\n"
+            + "<typePriorities></typePriorities>\n" + "<fsIndexCollection></fsIndexCollection>\n"
+            + "<capabilities>\n" + "<capability>\n" + "<inputs></inputs>\n"
+            + "<outputs></outputs>\n" + "<languagesSupported></languagesSupported>\n"
+            + "</capability>\n" + "</capabilities>\n" + "</analysisEngineMetaData>\n"
+            + "<externalResourceDependencies></externalResourceDependencies>\n"
+            + "<resourceManagerConfiguration></resourceManagerConfiguration>\n"
+            + "</analysisEngineDescription>\n";
+  }
+}
diff --git a/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/wizards/TAEConfiguratorNewWizardPage.java b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/wizards/TAEConfiguratorNewWizardPage.java
new file mode 100644
index 0000000..0dd383c
--- /dev/null
+++ b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/wizards/TAEConfiguratorNewWizardPage.java
@@ -0,0 +1,36 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.uima.taeconfigurator.wizards;
+
+import org.eclipse.jface.viewers.ISelection;
+
+/**
+ * The "New" wizard page allows setting the container for the new file as well as the file name.
+ * Will only accept file name without the extension OR with the extension that matches the expected
+ * one (xml).
+ */
+
+public class TAEConfiguratorNewWizardPage extends AbstractNewWizardPage {
+
+  public TAEConfiguratorNewWizardPage(ISelection selection) {
+    super(selection, "big_ae.gif", "Analysis Engine (AE) Descriptor File",
+            "Create a new AE Descriptor File", "aeDescriptor.xml");
+  }
+}
diff --git a/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/wizards/TypePrioritiesNewWizard.java b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/wizards/TypePrioritiesNewWizard.java
new file mode 100644
index 0000000..48865c2
--- /dev/null
+++ b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/wizards/TypePrioritiesNewWizard.java
@@ -0,0 +1,58 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.uima.taeconfigurator.wizards;
+
+import java.text.MessageFormat;
+
+import org.eclipse.ui.INewWizard;
+
+/**
+ * Create a new file resource in the provided container. If the container resource (a folder or a
+ * project) is selected in the workspace when the wizard is opened, it will accept it as the target
+ * container. If a sample multi-page editor is registered for the same extension, it will be able to
+ * open it.
+ */
+
+public class TypePrioritiesNewWizard extends AbstractNewWizard implements INewWizard {
+
+  public static final String TYPEPRIORITIES_TEMPLATE = "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n"
+          + "<typePriorities "
+          + XMLNS_PART
+          + "<name>{0}</name>\n"
+          + "<description></description>\n"
+          + "<version>1.0</version>\n"
+          + "<vendor></vendor>\n"
+          + "{1}" + "</typePriorities>\n";
+
+  public TypePrioritiesNewWizard() {
+    super("New Type Priorities Descriptor File");
+  }
+
+  public void addPages() {
+    page = new TypePrioritiesNewWizardPage(selection);
+    addPage(page);
+  }
+
+  public String getPrototypeDescriptor(String name) {
+    return MessageFormat.format(TYPEPRIORITIES_TEMPLATE, new Object[] { name,
+        "<priorityLists></priorityLists>\n" });
+  }
+
+}
diff --git a/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/wizards/TypePrioritiesNewWizardPage.java b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/wizards/TypePrioritiesNewWizardPage.java
new file mode 100644
index 0000000..a5ed1dd
--- /dev/null
+++ b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/wizards/TypePrioritiesNewWizardPage.java
@@ -0,0 +1,37 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.uima.taeconfigurator.wizards;
+
+import org.eclipse.jface.viewers.ISelection;
+
+/**
+ * The "New" wizard page allows setting the container for the new file as well as the file name.
+ * Will only accept file name without the extension OR with the extension that matches the expected
+ * one (xml).
+ */
+
+public class TypePrioritiesNewWizardPage extends AbstractNewWizardPage {
+
+  public TypePrioritiesNewWizardPage(ISelection selection) {
+    super(selection, "big_t_s_.gif", "Type Priorities Descriptor File",
+            "Create a new Type Priorities Descriptor file", "typePrioritiesDescriptor.xml");
+  }
+
+}
diff --git a/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/wizards/TypeSystemNewWizard.java b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/wizards/TypeSystemNewWizard.java
new file mode 100644
index 0000000..91a39f0
--- /dev/null
+++ b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/wizards/TypeSystemNewWizard.java
@@ -0,0 +1,53 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.uima.taeconfigurator.wizards;
+
+import java.text.MessageFormat;
+
+import org.eclipse.ui.INewWizard;
+
+/**
+ * Create a new file resource in the provided container. If the container resource (a folder or a
+ * project) is selected in the workspace when the wizard is opened, it will accept it as the target
+ * container. If a sample multi-page editor is registered for the same extension, it will be able to
+ * open it.
+ */
+
+public class TypeSystemNewWizard extends AbstractNewWizard implements INewWizard {
+
+  public static final String TYPESYSTEM_TEMPLATE = "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n"
+          + "<typeSystemDescription " + XMLNS_PART + "<name>{0}</name>\n"
+          + "<description></description>\n" + "<version>1.0</version>\n" + "<vendor></vendor>\n"
+          + "{1}" + "</typeSystemDescription>\n";
+
+  public TypeSystemNewWizard() {
+    super("New Type System Descriptor File");
+  }
+
+  public void addPages() {
+    page = new TypeSystemNewWizardPage(selection);
+    addPage(page);
+  }
+
+  public String getPrototypeDescriptor(String name) {
+    return MessageFormat.format(TYPESYSTEM_TEMPLATE, new Object[] { name, "<types></types>\n" });
+  }
+
+}
diff --git a/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/wizards/TypeSystemNewWizardPage.java b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/wizards/TypeSystemNewWizardPage.java
new file mode 100644
index 0000000..61a3a67
--- /dev/null
+++ b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/java/org/apache/uima/taeconfigurator/wizards/TypeSystemNewWizardPage.java
@@ -0,0 +1,37 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.uima.taeconfigurator.wizards;
+
+import org.eclipse.jface.viewers.ISelection;
+
+/**
+ * The "New" wizard page allows setting the container for the new file as well as the file name.
+ * Will only accept file name without the extension OR with the extension that matches the expected
+ * one (xml).
+ */
+
+public class TypeSystemNewWizardPage extends AbstractNewWizardPage {
+
+  public TypeSystemNewWizardPage(ISelection selection) {
+    super(selection, "big_t_s_.gif", "Type System Descriptor File",
+            "Create a new Type System Descriptor file", "typeSystemDescriptor.xml");
+  }
+
+}
diff --git a/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/readme/DISCLAIMER b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/readme/DISCLAIMER
new file mode 100644
index 0000000..b56e305
--- /dev/null
+++ b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/readme/DISCLAIMER
@@ -0,0 +1,7 @@
+Apache UIMA is an effort undergoing incubation at The Apache Software
+Foundation (ASF). Incubation is required of all newly accepted projects
+until a further review indicates that the infrastructure, communications,
+and decision making process have stabilized in a manner consistent with
+other successful ASF projects. While incubation status is not necessarily
+a reflection of the completeness or stability of the code, it does
+indicate that the project has yet to be fully endorsed by the ASF.
diff --git a/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/readme/LICENSE b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/readme/LICENSE
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/readme/LICENSE
@@ -0,0 +1,202 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
diff --git a/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/readme/NOTICE b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/readme/NOTICE
new file mode 100644
index 0000000..0f71a22
--- /dev/null
+++ b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/readme/NOTICE
@@ -0,0 +1,17 @@
+Apache UIMA
+Copyright 2006, 2007 The Apache Software Foundation
+
+This product includes software developed at
+The Apache Software Foundation (http://www.apache.org/).
+
+Portions of UIMA were originally developed by
+International Business Machines Corporation and are
+licensed to the Apache Software Foundation under the
+"Software Grant License Agreement", informally known as the 
+"IBM UIMA License Agreement".
+
+The following copyright notice(s) were affixed to portions of the code
+with which this file is now or was at one time distributed
+and are placed here unaltered.
+
+Copyright (c) 2003, 2006 IBM Corporation.  All rights reserved.
diff --git a/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/readme/README-HOTFIX-1 b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/readme/README-HOTFIX-1
new file mode 100644
index 0000000..87c19a1
--- /dev/null
+++ b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/readme/README-HOTFIX-1
@@ -0,0 +1,29 @@
+HotFix 1: Apache UIMA 2.1.0 for the Component Descriptor Editor Eclipse Plugin

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

+

+This README describes the version of the Component Descriptor Editor (CDE)

+for HOTFIX-1.  This fix includes only the Jira issue:

+

+http://issues.apache.org/jira/browse/UIMA-364

+

+This hotfix consists only of a replacement for the Eclipse plugin for

+the Component Descriptor Editor.

+

+To use, unzip the hotfix 

+  org.apache.uima.desceditor.2.1.0.incubating-hotfix-1 

+into your Eclipse plugins directory, and remove the

+previous version of this plugin called

+  org.apache.uima.desceditor.2.1.0.incubating

+  

+Then restart Eclipse using the -clean parameter.

+

+Disclaimer

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

+

+Apache UIMA is an effort undergoing incubation at The Apache Software

+Foundation (ASF). Incubation is required of all newly accepted projects

+until a further review indicates that the infrastructure, communications,

+and decision making process have stabilized in a manner consistent with

+other successful ASF projects. While incubation status is not necessarily

+a reflection of the completeness or stability of the code, it does

+indicate that the project has yet to be fully endorsed by the ASF.

diff --git a/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/resources/org/apache/uima/taeconfigurator/messages.properties b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/resources/org/apache/uima/taeconfigurator/messages.properties
new file mode 100644
index 0000000..e05f95a
--- /dev/null
+++ b/uimaj-ep-configurator-2.1.0-hotfix-1-RC1/uimaj-ep-configurator/src/main/resources/org/apache/uima/taeconfigurator/messages.properties
@@ -0,0 +1,112 @@
+#	 ***************************************************************
+#	 * Licensed to the Apache Software Foundation (ASF) under one
+#	 * or more contributor license agreements.  See the NOTICE file
+#	 * distributed with this work for additional information
+#	 * regarding copyright ownership.  The ASF licenses this file
+#	 * to you under the Apache License, Version 2.0 (the
+#	 * "License"); you may not use this file except in compliance
+#	 * with the License.  You may obtain a copy of the License at
+#    *
+#	 *   http://www.apache.org/licenses/LICENSE-2.0
+#	 * 
+#	 * Unless required by applicable law or agreed to in writing,
+#	 * software distributed under the License is distributed on an
+#	 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+#	 * KIND, either express or implied.  See the License for the
+#	 * specific language governing permissions and limitations
+#	 * under the License.
+#	 ***************************************************************
+
+AbstractSection.0=
+AbstractSectionParm.16=Integer
+AbstractSectionParm.common=<Common>
+AbstractSectionParm.delegateKeyName=Delegate Key Name: 
+AbstractSectionParm.headerCommon=<Common>
+AbstractSectionParm.headerGroupNames=GROUP Names: 
+AbstractSectionParm.headerNotInAnyGroup=<Not in any group>
+AbstractSectionParm.notInAnyGroup=<Not in any group>
+AbstractSectionParm.overrides=Overrides: 
+FlowSection.ComponentEngineFlowDescription=Choose a flow type and describe the execution order of your engines.\nThe table shows the delegates using their key names.
+FlowSection.ComponentEngineFlowTitle=Component Engine Flow
+FlowSection.downTip=Click here to move the selected engine one position lower in the flow list.
+FlowSection.FlowKind=Flow Kind:
+FlowSection.FlowKindTip=Pick the kind of flow sequencing to use
+FlowSection.notUsed=Not Used
+FlowSection.onlyForAggregates=This section is only applicable for Aggregate descriptors.
+FlowSection.upTip=Click here to move the selected engine one position higher in the flow list.
+LimitedResourceSelectionDialog.ResourceSelectionDialog=Resource Selection Dialog
+MultiPageEditor.aggregateTab=Aggregate
+MultiPageEditor.capabilityTab=Capabilities
+MultiPageEditor.causedBy=\r\nCaused by: 
+MultiPageEditor.EditExisting=Edit existing
+MultiPageEditor.errorInDesc=The descriptor has one or more errors. Please fix in the source editor.
+MultiPageEditor.errorInDescTitle=Error in Descriptor
+MultiPageEditor.failedAeValidation=Error in AE Descriptor
+MultiPageEditor.failedAeValidationMsg=The Descriptor is invalid for the following reason: 
+MultiPageEditor.failedCollRdrValidation=Error in Collection Reader Descriptor
+MultiPageEditor.failedCollRdrValidationMsg=The Descriptor is invalid for the following reason:
+MultiPageEditor.failedCollRdreValidationMsg=The Descriptor is invalid for the following reason: 
+MultiPageEditor.failedCasInitValidation=Error in Cas Initializer Descriptor
+MultiPageEditor.failedCasInitValidationMsg=The Descriptor is invalid for the following reason: 
+MultiPageEditor.failedCasConsValidation=Error in Cas Consumer Descriptor
+MultiPageEditor.failedCasConsValidationMsg=The Descriptor is invalid for the following reason:
+MultiPageEditor.failedCasConsAeValidationMsg=The Descriptor is invalid for the following reason: 
+MultiPageEditor.indexDefProblem=There is a problem in the index definition.\r\n
+MultiPageEditor.indexDefProblemTitle=Index Definition Problem
+MultiPageEditor.indexesTab=Indexes
+MultiPageEditor.invalidInputClass=Invalid Input: Must be IFileEditorInput
+MultiPageEditor.invalidTypeSpec=Your edited XML is valid but results in an invalid TCAS.\n
+MultiPageEditor.invalidTypeSpecTitle=Invalid Type Specification
+MultiPageEditor.invalidXML=Your edited XML is invalid.\n
+MultiPageEditor.invalidXMLTitle=Invalid XML
+MultiPageEditor.IOError=I/O Error reading file ''{0}''
+MultiPageEditor.jcasGenErr=An error has occured running JCasGen: {0}. You may have to generate the java source for your type files by hand.
+MultiPageEditor.JCasGenErr=Error from within JCasGen: 
+MultiPageEditor.JCasGenErrorTitle=JCasGen Error
+MultiPageEditor.noSrcDir=No Source Directory
+MultiPageEditor.noSrcNoJCas=No source directories have been defined.  JCasGen will not be run\!
+MultiPageEditor.overviewTab=Overview
+MultiPageEditor.parameterTab=Parameters
+MultiPageEditor.resourcesTab=Resources
+MultiPageEditor.revertToLastValid=Revert to last valid
+MultiPageEditor.settingsTab=Parameter Settings
+MultiPageEditor.sourceTab=Source
+MultiPageEditor.typeTab=Type System
+MultiPageEditor.0=Analysis Engine
+MultiPageEditor.1=Type System
+MultiPageEditor.2=Index
+MultiPageEditor.3=Type Priorities
+MultiPageEditor.4=Resource Manager Configuration
+MultiPageEditor.5=Collection Reader
+MultiPageEditor.6=CAS Initializier
+MultiPageEditor.7=CAS Consumer
+MultiPageEditor.8=invalid state
+MultiPageEditor.9=\ descriptor
+MultiPageEditor.10=\n
+MultiPageEditor.11=\n
+MultiPageEditor.12=org.apache.uima.taeconfigurator.messages
+MultiPageEditor.13=MultiPageEditor.descriptorKindChanged
+MultiPageEditor.14=Exception should not happen
+MultiPageEditor.15=Exception should not happen
+MultiPageEditor.16=encoding="
+MultiPageEditor.17=UTF-8
+MultiPageEditor.18="
+MultiPageEditor.19=Error
+MultiPageEditor.20=Error
+MultiPageEditor.21=invalid state
+MultiPageEditor.22=Unexpected Exception
+MultiPageEditor.23=Unexpected Exception
+MultiPageEditor.24=invalid Null Argument
+MultiPageEditor.25=Error Writing JCasGen Java files
+MultiPageEditor.26=I/O error while writing the generated JCas files.\n
+MultiPageEditor.unrecognizedDescType=Unrecognized descriptor type for file ''{0}''.
+MultiPageEditor.XMLerrorInDescriptor=The descriptor has one or more XML errors, and can''t be parsed. Please fix in the source editor.
+MultiPageEditor.XMLerrorInDescriptorTitle=XML Error in Descriptor
+MultiPageEditorContributor.autoGenJCas=Auto generate JCAS source java files when changing types
+MultiPageEditorContributor.showFullNames=Display fully qualified type names
+MultiResourceSelectionDialog.BrowseFileSys=Browse the file system...
+MultiResourceSelectionDialog.Or=OR
+MultiResourceSelectionDialog.starDotXml=*.xml
+MultiResourceSelectionDialogWithFlowOption.addSelectedAEsToEndOfFlow=Add selected AEs to end of flow
+ResourceSelectionDialog.message=Resource Selection
+ResourceSelectionDialog.title=Resource Selection